前回の対策を全体に利かせるにはマウスのグローバルフックを使えばOKなんじゃないかと思いついたので早速作ってみました。
Tablacus Windows 10 Fall Creators Update(RS3) のバグ対策
DLLの対策部分はこんな感じです。
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if (nCode >= 0 || nCode != HC_NOREMOVE) {
if (nCode == HC_ACTION){
MOUSEHOOKSTRUCTEX *pmse = (MOUSEHOOKSTRUCTEX *)lParam;
switch (wParam) {
case WM_MOUSEMOVE:
if (GetKeyState(VK_LBUTTON) < 0 || GetKeyState(VK_RBUTTON) < 0) {
WCHAR pszClass[MAX_CLASS_NAME];
if (GetClassName(pmse->hwnd, pszClass, MAX_CLASS_NAME)) {
if (PathMatchSpec(pszClass, L"*listview*")) {
RECT rc = {0, 0, 1, 1};
RedrawWindow(GetParent(pmse->hwnd), &rc, 0, RDW_NOERASE | RDW_INVALIDATE);
}
}
}
break;
}
}
}
return CallNextHookEx(g_hHookMouseWnd, nCode, wParam, lParam);
}
DllExport HHOOK CALLBACK MouseHookInstall(void)
{
if (g_hDll) {
ChangeWindowMessageFilter(WM_MOUSEMOVE, MSGFLT_ADD);
return g_hHookMouseWnd = SetWindowsHookEx(WH_MOUSE,(HOOKPROC)MouseProc, g_hDll, 0);
}
return NULL;
}
DllExport void CALLBACK MouseHookUninstall(void)
{
if (g_hHookMouseWnd){
UnhookWindowsHookEx(g_hHookMouseWnd);
}
}
WM_MOUSEMOVEが来たら、左右のボタンが押されているかチェック
押されたら、クラス名に「listview」が含まれているかチェック
(VC++等ではリストビューのクラス名は「SysListView32」、Delphi等では「TShListView」等になるので)
含まれていたら、(0,0)-(1,1)の範囲の親ウインドウをRedrawWindow
で再描画しています。
(0,0)-(1,1)の範囲に狭めているのが前回からの改良点です。何でこんなので直るのかは不明ですが…
(0,0)-(0,0)にすると上手く動きません。
一応、管理者権限で実行したときの事を考えてChangeWindowMessageFilter(WM_MOUSEMOVE, MSGFLT_ADD);
を入れています。
マウスのグローバルフック、Windows 10 Fall Creators Updateでテストした感じ、64ビット版で32ビットも64ビットも拾えるし、逆に32ビット版でも32ビットも64ビットも拾えた。32ビットは32ビットじゃなきゃフックできないみたいな仕様だと思ってました。
ソース全体はGitHubで公開しています。
https://github.com/tablacus/TablacusWindows10FCUBugFix
2018年1月19日 追記
しらいとブログ/Windows 10 Fall Creators Update (非公式)バグ修正パッチ
この不具合の原因と解決方法が書かれている上記ブログを教えてもらいました。