Fix the mouse wheel to task list scroll crash issue

Closes #2982, fixes #1616, fixes #2603, fixes #2828, fixes #607
This commit is contained in:
Richard Brock 2017-03-01 13:43:12 -05:00 committed by Don HO
parent 71b3c499a3
commit 133977da67
4 changed files with 42 additions and 10 deletions

View File

@ -2805,17 +2805,19 @@ void Notepad_plus::command(int id)
if (nbDoc > 1) if (nbDoc > 1)
{ {
bool direction = (id == IDC_NEXT_DOC)?dirDown:dirUp; bool direction = (id == IDC_NEXT_DOC)?dirDown:dirUp;
if (!doTaskList) if (!doTaskList)
{ {
activateNextDoc(direction); activateNextDoc(direction);
} }
else else
{ {
TaskListDlg tld; if (TaskListDlg::_instanceCount == 0)
HIMAGELIST hImgLst = _docTabIconList.getHandle(); {
tld.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), hImgLst, direction); TaskListDlg tld;
tld.doDialog(); HIMAGELIST hImgLst = _docTabIconList.getHandle();
tld.init(_pPublicInterface->getHinst(), _pPublicInterface->getHSelf(), hImgLst, direction);
tld.doDialog();
}
} }
} }
_linkTriggered = true; _linkTriggered = true;

View File

@ -127,6 +127,11 @@ RECT TaskList::adjustSize()
ListView_SetColumnWidth(_hSelf, 0, _rc.right); ListView_SetColumnWidth(_hSelf, 0, _rc.right);
::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast<WPARAM>(_hFont), 0); ::SendMessage(_hSelf, WM_SETFONT, reinterpret_cast<WPARAM>(_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); reSizeTo(_rc);
// Task List's border is 1px smaller than ::GetSystemMetrics(SM_CYFRAME) returns // 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 // tells what item(s) to be repainted
ListView_RedrawItems(_hSelf, selected, selected); ListView_RedrawItems(_hSelf, selected, selected);
// repaint item(s) // repaint item(s)
UpdateWindow(_hSelf); UpdateWindow(_hSelf);
_currentIndex = selected; _currentIndex = selected;
} }
ListView_EnsureVisible(_hSelf, _currentIndex, true);
return TRUE; return TRUE;
} }
@ -267,6 +273,7 @@ LRESULT TaskList::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
UpdateWindow(_hSelf); UpdateWindow(_hSelf);
_currentIndex = selected; _currentIndex = selected;
} }
ListView_EnsureVisible(_hSelf, _currentIndex, true);
} }
else else
{ {

View File

@ -31,13 +31,26 @@
#include "Parameters.h" #include "Parameters.h"
#include "resource.h" #include "resource.h"
int TaskListDlg::_instanceCount = 0;
LRESULT CALLBACK hookProc(UINT nCode, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK hookProc(UINT nCode, WPARAM wParam, LPARAM lParam)
{ {
if ((nCode >= 0) && (wParam == WM_RBUTTONUP)) if ((nCode >= 0) && (wParam == WM_RBUTTONUP))
{ {
::PostMessage(hWndServer, WM_RBUTTONUP, 0, 0); ::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); 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); _taskList.display(true);
hWndServer = _hSelf; hWndServer = _hSelf;
windowsVersion = NppParameters::getInstance()->getWinVersion();
#ifndef WH_MOUSE_LL #ifndef WH_MOUSE_LL
#define WH_MOUSE_LL 14 #define WH_MOUSE_LL 14
@ -93,6 +107,7 @@ INT_PTR CALLBACK TaskListDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lP
{ {
_taskList.destroy(); _taskList.destroy();
::UnhookWindowsHookEx(_hHooker); ::UnhookWindowsHookEx(_hHooker);
_instanceCount--;
return TRUE; return TRUE;
} }
@ -103,6 +118,11 @@ INT_PTR CALLBACK TaskListDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lP
return TRUE; return TRUE;
} }
case WM_MOUSEWHEEL:
{
::SendMessage(_taskList.getHSelf(), WM_MOUSEWHEEL, wParam, lParam);
return TRUE;
}
case WM_DRAWITEM : case WM_DRAWITEM :
{ {

View File

@ -55,13 +55,14 @@ struct TaskListInfo {
static HWND hWndServer = NULL; static HWND hWndServer = NULL;
static HHOOK hook = NULL; static HHOOK hook = NULL;
static winVer windowsVersion = WV_UNKNOWN;
static LRESULT CALLBACK hookProc(UINT nCode, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK hookProc(UINT nCode, WPARAM wParam, LPARAM lParam);
class TaskListDlg : public StaticDialog class TaskListDlg : public StaticDialog
{ {
public : public :
TaskListDlg() : StaticDialog() {}; TaskListDlg() : StaticDialog() { _instanceCount++; };
void init(HINSTANCE hInst, HWND parent, HIMAGELIST hImgLst, bool dir) { void init(HINSTANCE hInst, HWND parent, HIMAGELIST hImgLst, bool dir) {
Window::init(hInst, parent); Window::init(hInst, parent);
_hImalist = hImgLst; _hImalist = hImgLst;
@ -81,5 +82,7 @@ private :
HHOOK _hHooker = nullptr; HHOOK _hHooker = nullptr;
void drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); void drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
public:
static int _instanceCount;
}; };