From 4bdf4af11ec1f51d3cc79ccf097c4f473aae4eaf Mon Sep 17 00:00:00 2001 From: Stephane Lussier Date: Tue, 18 Apr 2000 11:56:33 +0000 Subject: [PATCH] Implemented Mousewheel support. --- controls/combo.c | 8 +++++ controls/edit.c | 19 ++++++++++++ controls/listbox.c | 21 +++++++++++++ dlls/comctl32/listview.c | 64 +++++++++++++++++++++++++++++++++++++++- include/mouse.h | 4 --- include/winuser.h | 8 ++++- windows/input.c | 5 ++++ windows/spy.c | 3 +- windows/x11drv/event.c | 17 ++++++++--- 9 files changed, 138 insertions(+), 11 deletions(-) diff --git a/controls/combo.c b/controls/combo.c index f297845e53d..731c9b79423 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -1936,6 +1936,14 @@ static inline LRESULT WINAPI ComboWndProc_locked( WND* pWnd, UINT message, if( lphc->wState & CBF_CAPTURE ) COMBO_MouseMove( lphc, wParam, lParam ); return TRUE; + + case WM_MOUSEWHEEL: + if (wParam & (MK_SHIFT | MK_CONTROL)) + return DefWindowProcA( hwnd, message, wParam, lParam ); + if ((short) HIWORD(wParam) > 0) return SendMessageA(hwnd,WM_KEYDOWN,VK_UP,0); + if ((short) HIWORD(wParam) < 0) return SendMessageA(hwnd,WM_KEYDOWN,VK_DOWN,0); + return TRUE; + /* Combo messages */ case CB_ADDSTRING16: diff --git a/controls/edit.c b/controls/edit.c index 29cf1eee9f6..284b18a4f9c 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -870,6 +870,25 @@ LRESULT WINAPI EditWndProc( HWND hwnd, UINT msg, result = EDIT_WM_VScroll(wnd, es, LOWORD(wParam), SHIWORD(wParam), (HWND)(lParam)); break; + case WM_MOUSEWHEEL: + { + short gcWheelDelta = 0; + UINT pulScrollLines = 3; + SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0); + + if (wParam & (MK_SHIFT | MK_CONTROL)) { + result = DefWindowProcA(hwnd, msg, wParam, lParam); + break; + } + gcWheelDelta -= (short) HIWORD(wParam); + if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines) + { + int cLineScroll= (int) min((UINT) es->line_count, pulScrollLines); + cLineScroll *= (gcWheelDelta / WHEEL_DELTA); + result = EDIT_EM_LineScroll(wnd, es, 0, cLineScroll); + } + } + break; default: result = DefWindowProcA(hwnd, msg, wParam, lParam); break; diff --git a/controls/listbox.c b/controls/listbox.c index 6c697bb34ac..fa13ba78378 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -1767,6 +1767,23 @@ static LRESULT LISTBOX_HandleHScroll( WND *wnd, LB_DESCR *descr, return 0; } +static LRESULT LISTBOX_HandleMouseWheel(WND *wnd, LB_DESCR *descr,WPARAM wParam, LPARAM lParam ) +{ + short gcWheelDelta = 0; + UINT pulScrollLines = 3; + + SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0); + + gcWheelDelta -= (short) HIWORD(wParam); + + if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines) + { + int cLineScroll = (int) min((UINT) descr->page_size, pulScrollLines); + cLineScroll *= (gcWheelDelta / WHEEL_DELTA); + LISTBOX_SetTopItem( wnd, descr, descr->top_item + cLineScroll, TRUE ); + } + return 0; +} /*********************************************************************** * LISTBOX_HandleLButtonDown @@ -2668,6 +2685,10 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, return LISTBOX_HandleHScroll( wnd, descr, wParam, lParam ); case WM_VSCROLL: return LISTBOX_HandleVScroll( wnd, descr, wParam, lParam ); + case WM_MOUSEWHEEL: + if (wParam & (MK_SHIFT | MK_CONTROL)) + return DefWindowProcA( hwnd, msg, wParam, lParam ); + return LISTBOX_HandleMouseWheel( wnd, descr, wParam, lParam ); case WM_LBUTTONDOWN: return LISTBOX_HandleLButtonDown( wnd, descr, wParam, (INT16)LOWORD(lParam), diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index b473c6f105b..f3436f31de8 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -6024,6 +6024,12 @@ static LRESULT LISTVIEW_VScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos, case SB_THUMBTRACK: scrollInfo.nPos = nCurrentPos; + if (scrollInfo.nPos > scrollInfo.nMax) + scrollInfo.nPos=scrollInfo.nMax; + + if (scrollInfo.nPos < scrollInfo.nMin) + scrollInfo.nPos=scrollInfo.nMin; + break; } @@ -6111,6 +6117,12 @@ static LRESULT LISTVIEW_HScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos, case SB_THUMBTRACK: scrollInfo.nPos = nCurrentPos; + + if (scrollInfo.nPos > scrollInfo.nMax) + scrollInfo.nPos=scrollInfo.nMax; + + if (scrollInfo.nPos < scrollInfo.nMin) + scrollInfo.nPos=scrollInfo.nMin; break; } @@ -6132,6 +6144,52 @@ static LRESULT LISTVIEW_HScroll(HWND hwnd, INT nScrollCode, SHORT nCurrentPos, return 0; } +static LRESULT LISTVIEW_MouseWheel(HWND hwnd, INT wheelDelta) +{ + INT gcWheelDelta = 0; + UINT pulScrollLines = 3; + SCROLLINFO scrollInfo; + + UINT uView = GetWindowLongA(hwnd, GWL_STYLE) & LVS_TYPEMASK; + + SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0); + gcWheelDelta -= wheelDelta; + + ZeroMemory(&scrollInfo, sizeof(SCROLLINFO)); + scrollInfo.cbSize = sizeof(SCROLLINFO); + scrollInfo.fMask = SIF_POS | SIF_RANGE; + + switch(uView) + { + case LVS_ICON: + case LVS_SMALLICON: + /* + * listview should be scrolled by a multiple of 37 dependently on its dimension or its visible item number + * should be fixed in the future. + */ + if (GetScrollInfo(hwnd, SB_VERT, &scrollInfo) != FALSE) + LISTVIEW_VScroll(hwnd, SB_THUMBPOSITION, scrollInfo.nPos + (gcWheelDelta < 0) ? 37 : -37, 0); + break; + + case LVS_REPORT: + if (abs(gcWheelDelta) >= WHEEL_DELTA && pulScrollLines) + { + if (GetScrollInfo(hwnd, SB_VERT, &scrollInfo) != FALSE) + { + int cLineScroll = min(LISTVIEW_GetCountPerColumn(hwnd), pulScrollLines); + cLineScroll *= (gcWheelDelta / WHEEL_DELTA); + LISTVIEW_VScroll(hwnd, SB_THUMBPOSITION, scrollInfo.nPos + cLineScroll, 0); + } + } + break; + + case LVS_LIST: + LISTVIEW_HScroll(hwnd, (gcWheelDelta < 0) ? SB_LINELEFT : SB_LINERIGHT, 0, 0); + break; + } + return 0; +} + /*** * DESCRIPTION: * ??? @@ -7449,7 +7507,11 @@ static LRESULT WINAPI LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, return LISTVIEW_VScroll(hwnd, (INT)LOWORD(wParam), (INT)HIWORD(wParam), (HWND)lParam); -/* case WM_WINDOWPOSCHANGED: */ + case WM_MOUSEWHEEL: + if (wParam & (MK_SHIFT | MK_CONTROL)) + return DefWindowProcA( hwnd, uMsg, wParam, lParam ); + return LISTVIEW_MouseWheel(hwnd, (short int)HIWORD(wParam));/* case WM_WINDOWPOSCHANGED: */ + /* case WM_WININICHANGE: */ default: diff --git a/include/mouse.h b/include/mouse.h index dfb20d3870b..4fe6fb8f9c2 100644 --- a/include/mouse.h +++ b/include/mouse.h @@ -55,10 +55,6 @@ extern void MOUSE_SendEvent( DWORD mouseStatus, DWORD posX, DWORD posY, #define WHEEL_DELTA 120 -#ifndef WM_MOUSEWHEEL -#define WM_MOUSEWHEEL (WM_MOUSELAST+1) -#endif - #define MOUSEZ_CLASSNAME "MouseZ" #define MOUSEZ_TITLE "Magellan MSWHEEL" diff --git a/include/winuser.h b/include/winuser.h index ce27bf017d2..f8d81644daa 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -639,9 +639,14 @@ typedef struct #define WM_MBUTTONDOWN 0x0207 #define WM_MBUTTONUP 0x0208 #define WM_MBUTTONDBLCLK 0x0209 +#define WM_MOUSEWHEEL 0x020A #define WM_MOUSEFIRST WM_MOUSEMOVE -#define WM_MOUSELAST WM_MBUTTONDBLCLK + +#define WM_MOUSELAST WM_MOUSEWHEEL + +#define WHEEL_DELTA 120 +#define WHEEL_PAGESCROLL (UINT_MAX) #define WM_PARENTNOTIFY 0x0210 #define WM_ENTERMENULOOP 0x0211 #define WM_EXITMENULOOP 0x0212 @@ -1990,6 +1995,7 @@ typedef struct #define MOUSEEVENTF_RIGHTUP 0x0010 #define MOUSEEVENTF_MIDDLEDOWN 0x0020 #define MOUSEEVENTF_MIDDLEUP 0x0040 +#define MOUSEEVENTF_WHEEL 0x0800 #define MOUSEEVENTF_ABSOLUTE 0x8000 /* ExitWindows() flags */ diff --git a/windows/input.c b/windows/input.c index f124c0bcbdf..089e4680f5e 100644 --- a/windows/input.c +++ b/windows/input.c @@ -275,6 +275,11 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, hardware_event( WM_MBUTTONUP, keyState, 0L, PosX, PosY, time, extra ); } + if ( dwFlags & MOUSEEVENTF_WHEEL ) + { + hardware_event( WM_MOUSEWHEEL, + keyState, 0L, PosX, PosY, time, extra ); + } } /*********************************************************************** diff --git a/windows/spy.c b/windows/spy.c index 00d217fb5d7..eefc323443f 100644 --- a/windows/spy.c +++ b/windows/spy.c @@ -391,7 +391,8 @@ static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_MBUTTONDOWN", /* 0x0207 */ "WM_MBUTTONUP", /* 0x0208 */ "WM_MBUTTONDBLCLK", /* 0x0209 */ - NULL, NULL, NULL, NULL, NULL, NULL, + "WM_MOUSEWHEEL", /* 0x020A */ + NULL, NULL, NULL, NULL, NULL, "WM_PARENTNOTIFY", /* 0x0210 */ "WM_ENTERMENULOOP", /* 0x0211 */ diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c index b72a980adc4..3e63b9eae12 100644 --- a/windows/x11drv/event.c +++ b/windows/x11drv/event.c @@ -58,7 +58,8 @@ extern Atom dndSelection; extern void X11DRV_KEYBOARD_UpdateState(void); extern void X11DRV_KEYBOARD_HandleEvent(WND *pWnd, XKeyEvent *event); -#define NB_BUTTONS 3 /* Windows can handle 3 buttons */ +#define NB_BUTTONS 5 /* Windows can handle 3 buttons and the wheel too */ + #define DndNotDnd -1 /* OffiX drag&drop */ #define DndUnknown 0 @@ -716,13 +717,13 @@ static void EVENT_MotionNotify( HWND hWnd, XMotionEvent *event ) static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event ) { static WORD statusCodes[NB_BUTTONS] = - { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_RIGHTDOWN }; + { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_WHEEL, MOUSEEVENTF_WHEEL}; int buttonNum = event->button - 1; WND *pWnd = WIN_FindWndPtr(hWnd); int xOffset = pWnd? pWnd->rectWindow.left : 0; int yOffset = pWnd? pWnd->rectWindow.top : 0; - WORD keystate; + WORD keystate,wData = 0; WIN_ReleaseWndPtr(pWnd); @@ -748,11 +749,17 @@ static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event ) case 2: keystate |= MK_RBUTTON; break; + case 3: + wData = WHEEL_DELTA; + break; + case 4: + wData = -WHEEL_DELTA; + break; } MOUSE_SendEvent( statusCodes[buttonNum], xOffset + event->x, yOffset + event->y, - keystate, + MAKEWPARAM(keystate,wData), event->time - MSG_WineStartTicks, hWnd); } @@ -795,6 +802,8 @@ static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event ) case 2: keystate &= ~MK_RBUTTON; break; + default: + return; } MOUSE_SendEvent( statusCodes[buttonNum],