我创建了顶级窗口,但由于未知原因,我的WNDPROC没有收到 WM_LBUTTONDOWN / WM_LBUTTONUP 或 WM_MOUSEMOVE 消息。
有什么建议吗?
相关代码:
WNDCLASSEX wc = {0};
Wc.cbSize = 48;
Wc.cbWndExtra = 80;
Wc.hCursor = LoadCursorW(g_hInstance, MAKEINTRESOURCEW(1002));
Wc.style = CS_GLOBALCLASS | CS_DBLCLKS;
Wc.lpszClassName = Ici[dItemIndex].sInit;
Wc.lpfnWndProc = Ici[dItemIndex].wInit;
RegisterClassExW(&Wc);
g_hRuler1 = CreateWindowExW(WS_EX_TOOLWINDOW,
RULER_CONTROL,
L"",
WS_POPUP|WS_VISIBLE|0x1,
100 ,100, 40, RECTHEIGHT(g_rScreen),
NULL, NULL, hInst, NULL);
LRESULT WINAPI Ruler_Window(HWND hWindow, UINT uWindow, WPARAM wParam, LPARAM lParam)
{
if (uWindow == WM_GETMINMAXINFO)
{
goto DODEFAULT;
}
if (uWindow == WM_NCCREATE)
{
g_pGRI = RULER_ALLOCATE();
RULER_SET_POINTER(hWindow, (LONG_PTR)g_pGRI);
return 1L;
}
g_pGRI = RULER_GET_POINTER(hWindow);
g_pGRI->hWindow = hWindow;
switch(uWindow)
{
case WM_CREATE:
{
return Ruler_OnCreate(wParam, lParam);
}
case WM_PAINT:
{
return Ruler_OnPaint(wParam, lParam);
}
case WM_MOUSEMOVE:
{
return Ruler_OnMouseMove(wParam, lParam);
}
case WM_DESTROY:
{
return Ruler_OnDestroy(wParam, lParam);
}
case WM_SETCURSOR:
{
return Ruler_OnSetCursor(wParam, lParam);
}
case WM_LBUTTONDOWN:
{
return Ruler_OnLeftButtonDown(wParam, lParam);
}
case WM_LBUTTONUP:
{
return Ruler_OnLeftButtonUp(wParam, lParam);
}
case GM_SETINDICATORS:
{
return Ruler_OnSetIndicators(wParam, lParam);
}
DODEFAULT:
return DefWindowProcW(hWindow, uWindow, wParam, lParam);
}
}
左键单击后的窗口间谍++消息。
答案 0 :(得分:5)
我认为这里的问题是您很可能不会使用自定义DefWindowProc
方法(wndProc
)来调用Ruler_Window
。
wndProc
中的代码结构有点......很有趣。
您在switch语句中处理您感兴趣的消息(WM_NCCREATE
除外,这很好),但您的switch语句实际上没有default:
条目...相反,您创建了一个名为DODEFAULT
的标签,您只引用一次 - 当消息为WM_GETMINMAXINFO
时goto DODEFAULT
。忽略在此处使用goto
的问题,您基本上不处理除代码中列出的消息之外的任何消息,更重要的是,您没有将其他消息传递给默认处理程序
快速,非常简单地重写Ruler_Window
方法:
LRESULT WINAPI Ruler_Window(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_NCCREATE)
{
g_pGRI = RULER_ALLOCATE();
RULER_SET_POINTER(hWindow, (LONG_PTR)g_pGRI);
return DefWindowProcW(hWindow, uMsg, wParam, lParam);
}
// not sure what g_pGRI is, guessing it's a global?
// should this actually be passed into the handlers below?
g_pGRI = RULER_GET_POINTER(hWindow);
g_pGRI->hWindow = hWindow;
switch(uMsg)
{
case WM_CREATE:
return Ruler_OnCreate(wParam, lParam);
case WM_PAINT:
return Ruler_OnPaint(wParam, lParam);
case WM_MOUSEMOVE:
return Ruler_OnMouseMove(wParam, lParam);
case WM_DESTROY:
return Ruler_OnDestroy(wParam, lParam);
case WM_SETCURSOR:
return Ruler_OnSetCursor(wParam, lParam);
case WM_LBUTTONDOWN:
return Ruler_OnLeftButtonDown(wParam, lParam);
case WM_LBUTTONUP:
return Ruler_OnLeftButtonUp(wParam, lParam);
case GM_SETINDICATORS:
return Ruler_OnSetIndicators(wParam, lParam);
default:
break;
}
return DefWindowProcW(hWindow, uMsg, wParam, lParam);
}
注意,我还将消息参数的名称更改为uMsg
,因为它使得更容易阅读代码,恕我直言。
答案 1 :(得分:3)
我怀疑问题是你没有为WM_NCCREATE和WM_CREATE调用DefWindowProc。这意味着窗口永远不会设置其客户区域,因此消息将以WM_NC *。
形式传入您应该始终将WM_NCCREATE和WM_CREATE传递给DefWindowProc。