From 133977da678bdbe0fe70326deefaf81c031661c9 Mon Sep 17 00:00:00 2001 From: Richard Brock Date: Wed, 1 Mar 2017 13:43:12 -0500 Subject: [PATCH] Fix the mouse wheel to task list scroll crash issue Closes #2982, fixes #1616, fixes #2603, fixes #2828, fixes #607 --- PowerEditor/src/NppCommands.cpp | 12 ++++++---- .../src/WinControls/TaskList/TaskList.cpp | 9 ++++++- .../src/WinControls/TaskList/TaskListDlg.cpp | 24 +++++++++++++++++-- .../src/WinControls/TaskList/TaskListDlg.h | 7 ++++-- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index bda06e73..e55f5997 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -2805,17 +2805,19 @@ void Notepad_plus::command(int id) if (nbDoc > 1) { bool direction = (id == IDC_NEXT_DOC)?dirDown:dirUp; - if (!doTaskList) { activateNextDoc(direction); } else { - TaskListDlg tld; - HIMAGELIST hImgLst = _docTabIconList.getHandle(); - tld.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), hImgLst, direction); - tld.doDialog(); + if (TaskListDlg::_instanceCount == 0) + { + TaskListDlg tld; + HIMAGELIST hImgLst = _docTabIconList.getHandle(); + tld.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), hImgLst, direction); + tld.doDialog(); + } } } _linkTriggered = true; diff --git a/PowerEditor/src/WinControls/TaskList/TaskList.cpp b/PowerEditor/src/WinControls/TaskList/TaskList.cpp index ffc12a5d..fdf6eb26 100644 --- a/PowerEditor/src/WinControls/TaskList/TaskList.cpp +++ b/PowerEditor/src/WinControls/TaskList/TaskList.cpp @@ -127,6 +127,11 @@ RECT TaskList::adjustSize() ListView_SetColumnWidth(_hSelf, 0, _rc.right); ::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast(_hFont), 0); + //if the tasklist exceeds the height of the display, leave some space at the bottom + if (_rc.bottom > ::GetSystemMetrics(SM_CYSCREEN) - 120) + { + _rc.bottom = ::GetSystemMetrics(SM_CYSCREEN) - 120; + } reSizeTo(_rc); // Task List's border is 1px smaller than ::GetSystemMetrics(SM_CYFRAME) returns @@ -214,9 +219,10 @@ LRESULT TaskList::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) // tells what item(s) to be repainted ListView_RedrawItems(_hSelf, selected, selected); // repaint item(s) - UpdateWindow(_hSelf); + UpdateWindow(_hSelf); _currentIndex = selected; } + ListView_EnsureVisible(_hSelf, _currentIndex, true); return TRUE; } @@ -267,6 +273,7 @@ LRESULT TaskList::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) UpdateWindow(_hSelf); _currentIndex = selected; } + ListView_EnsureVisible(_hSelf, _currentIndex, true); } else { diff --git a/PowerEditor/src/WinControls/TaskList/TaskListDlg.cpp b/PowerEditor/src/WinControls/TaskList/TaskListDlg.cpp index f86b22a6..141989fa 100644 --- a/PowerEditor/src/WinControls/TaskList/TaskListDlg.cpp +++ b/PowerEditor/src/WinControls/TaskList/TaskListDlg.cpp @@ -31,13 +31,26 @@ #include "Parameters.h" #include "resource.h" +int TaskListDlg::_instanceCount = 0; + LRESULT CALLBACK hookProc(UINT nCode, WPARAM wParam, LPARAM lParam) { if ((nCode >= 0) && (wParam == WM_RBUTTONUP)) { ::PostMessage(hWndServer, WM_RBUTTONUP, 0, 0); - } - + } + else if ((nCode >= 0) && (wParam == WM_MOUSEWHEEL) && windowsVersion >= WV_WIN10) + { + MSLLHOOKSTRUCT* pMD = (MSLLHOOKSTRUCT*)lParam; + RECT rCtrl; + GetWindowRect(hWndServer, &rCtrl); + //to avoid duplicate messages, only send this message to the list control if it comes from outside the control window. if the message occurs whilst the mouse is inside the control, the control will have receive the mouse wheel message itself + if (false == PtInRect(&rCtrl, pMD->pt)) + { + ::PostMessage(hWndServer, WM_MOUSEWHEEL, (WPARAM)pMD->mouseData, MAKELPARAM(pMD->pt.x, pMD->pt.y)); + } + } + return ::CallNextHookEx(hook, nCode, wParam, lParam); } @@ -80,6 +93,7 @@ INT_PTR CALLBACK TaskListDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lP _taskList.display(true); hWndServer = _hSelf; + windowsVersion = NppParameters::getInstance()->getWinVersion(); #ifndef WH_MOUSE_LL #define WH_MOUSE_LL 14 @@ -93,6 +107,7 @@ INT_PTR CALLBACK TaskListDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lP { _taskList.destroy(); ::UnhookWindowsHookEx(_hHooker); + _instanceCount--; return TRUE; } @@ -103,6 +118,11 @@ INT_PTR CALLBACK TaskListDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lP return TRUE; } + case WM_MOUSEWHEEL: + { + ::SendMessage(_taskList.getHSelf(), WM_MOUSEWHEEL, wParam, lParam); + return TRUE; + } case WM_DRAWITEM : { diff --git a/PowerEditor/src/WinControls/TaskList/TaskListDlg.h b/PowerEditor/src/WinControls/TaskList/TaskListDlg.h index fff2ecdd..3a21d284 100644 --- a/PowerEditor/src/WinControls/TaskList/TaskListDlg.h +++ b/PowerEditor/src/WinControls/TaskList/TaskListDlg.h @@ -55,13 +55,14 @@ struct TaskListInfo { static HWND hWndServer = NULL; static HHOOK hook = NULL; +static winVer windowsVersion = WV_UNKNOWN; static LRESULT CALLBACK hookProc(UINT nCode, WPARAM wParam, LPARAM lParam); class TaskListDlg : public StaticDialog { -public : - TaskListDlg() : StaticDialog() {}; +public : + TaskListDlg() : StaticDialog() { _instanceCount++; }; void init(HINSTANCE hInst, HWND parent, HIMAGELIST hImgLst, bool dir) { Window::init(hInst, parent); _hImalist = hImgLst; @@ -81,5 +82,7 @@ private : HHOOK _hHooker = nullptr; void drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); +public: + static int _instanceCount; };