diff --git a/modules/highgui/include/opencv2/highgui/highgui_c.h b/modules/highgui/include/opencv2/highgui/highgui_c.h index 1a42e5804..d1aa93b02 100644 --- a/modules/highgui/include/opencv2/highgui/highgui_c.h +++ b/modules/highgui/include/opencv2/highgui/highgui_c.h @@ -170,7 +170,9 @@ enum CV_EVENT_MBUTTONUP =6, CV_EVENT_LBUTTONDBLCLK =7, CV_EVENT_RBUTTONDBLCLK =8, - CV_EVENT_MBUTTONDBLCLK =9 + CV_EVENT_MBUTTONDBLCLK =9, + CV_EVENT_MOUSEWHEEL =10, + CV_EVENT_MOUSEHWHEEL =11 }; enum @@ -183,6 +185,11 @@ enum CV_EVENT_FLAG_ALTKEY =32 }; + +#define CV_GET_WHEEL_DELTA(event) ((short)((event >> 16) & 0xffff)) // upper 16 bits +#define CV_GET_MOUSEWHEEL_EVENT(event) (event & 0xffff) // lower 16 bits + + typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param); /* assign callback for mouse events */ diff --git a/modules/highgui/src/window_w32.cpp b/modules/highgui/src/window_w32.cpp index 222f0b0ab..70a29d402 100644 --- a/modules/highgui/src/window_w32.cpp +++ b/modules/highgui/src/window_w32.cpp @@ -40,6 +40,7 @@ //M*/ #include "precomp.hpp" +#include // required for GET_X_LPARAM() and GET_Y_LPARAM() marco #if defined WIN32 || defined _WIN32 @@ -1377,6 +1378,43 @@ MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) SetFocus(window->hwnd); break; + case WM_MOUSEWHEEL: + case WM_MOUSEHWHEEL: + if( window->on_mouse ) + { + int flags = (wParam & MK_LBUTTON ? CV_EVENT_FLAG_LBUTTON : 0)| + (wParam & MK_RBUTTON ? CV_EVENT_FLAG_RBUTTON : 0)| + (wParam & MK_MBUTTON ? CV_EVENT_FLAG_MBUTTON : 0)| + (wParam & MK_CONTROL ? CV_EVENT_FLAG_CTRLKEY : 0)| + (wParam & MK_SHIFT ? CV_EVENT_FLAG_SHIFTKEY : 0)| + (GetKeyState(VK_MENU) < 0 ? CV_EVENT_FLAG_ALTKEY : 0); + int event = (uMsg == WM_MOUSEWHEEL ? CV_EVENT_MOUSEWHEEL : CV_EVENT_MOUSEHWHEEL); + + // Set the wheel delta of mouse wheel to be in the upper word of 'event' + int delta = GET_WHEEL_DELTA_WPARAM(wParam); + event |= (delta << 16); + + POINT pt; + { + // since The coordinates are relative to screen so get screen size. + RECT windowRect; + ::GetWindowRect( window->hwnd, &windowRect ); + pt.x = GET_X_LPARAM( lParam ) - windowRect.left; + pt.y = GET_Y_LPARAM( lParam ) - windowRect.top; + } + + RECT rect; + GetClientRect( window->hwnd, &rect ); + + SIZE size = {0,0}; + icvGetBitmapData( window, &size, 0, 0 ); + + window->on_mouse( event, pt.x*size.cx/MAX(rect.right - rect.left,1), + pt.y*size.cy/MAX(rect.bottom - rect.top,1), flags, + window->on_mouse_param ); + } + break; + case WM_ERASEBKGND: { RECT cr, tr, wrc;