C++ 处理WM_NCHITTEST返回时的任性行为
我正在完全重新绘制非客户端区域,但愿意保留一些默认功能。Windows不允许我将关闭按钮放在任何我想要的地方。虽然当我对windows说我希望整个窗口都是标题,而不是关闭按钮时,它非常有效。我知道我可以很容易地去做一个适当的直接api调用。但总有一些疑问,如果windows做了一些我不知道的额外的事情怎么办。为什么Windows会这样做?也许你知道有什么解决办法。请分享C++ 处理WM_NCHITTEST返回时的任性行为,c++,windows,winapi,C++,Windows,Winapi,我正在完全重新绘制非客户端区域,但愿意保留一些默认功能。Windows不允许我将关闭按钮放在任何我想要的地方。虽然当我对windows说我希望整个窗口都是标题,而不是关闭按钮时,它非常有效。我知道我可以很容易地去做一个适当的直接api调用。但总有一些疑问,如果windows做了一些我不知道的额外的事情怎么办。为什么Windows会这样做?也许你知道有什么解决办法。请分享 #include <windows.h> LRESULT CALLBACK msg_proc(HWND hwnd
#include <windows.h>
LRESULT CALLBACK msg_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); // inform frame change
break;
case WM_NCCALCSIZE:
if (wParam) return 0; // removing the standard frame
break;
case WM_NCHITTEST:
return HTCLOSE; // HTCAPTION perfectly works
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = msg_proc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = 0;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"huge close button";
wcex.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
RegisterClassEx(&wcex);
HWND hwnd = CreateWindowExW(
WS_EX_TOPMOST,
L"huge close button", L"huge close button", WS_OVERLAPPEDWINDOW,
100, 100, 1000, 1000,
NULL, NULL, hInstance, 0 );
ShowWindow(hwnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
这段代码意味着只要用户按下鼠标按钮,应用程序就会关闭。但事实并非如此。您需要单独处理
wParam
结果是DefWindowProc函数返回的命中测试值
处理WM_NCHITTEST消息的方法。对于命中测试值列表,
参见WM_NCHITTEST
因此,您从WM_NCHITTEST返回的值将在其他消息的wParam中发送,特别是WM_NCLBUTTONDOWN和WM_NCLBUTTONUP
修改如下:
LRESULT CALLBACK msg_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); // inform frame change
break;
case WM_NCCALCSIZE:
if (wParam) return 0; // removing the standard frame
break;
case WM_NCHITTEST:
return HTCLOSE; // HTCAPTION perfectly works
case WM_NCLBUTTONDOWN:
if (wParam == HTCLOSE)
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
...
案例WM_销毁:PostQuitMessage0;中断@HansPassant,我忘记了这个例子,但它没有帮助。问题在于windows对HTCLOSE的处理。它假定按钮始终必须是windows定义的矩形。谢谢。我需要3张反对票才能得到答案。我不太明白为什么人们不喜欢它。也许标题不好。也许他们不喜欢这个美丽的节目。@olekstolar别介意,你所需要做的就是提问并提供足够的细节。