c++ - 响应 WM_NCHITTEST 处理返回的任性行为
问题描述
我正在完全重绘非客户区,但愿意保留一些默认功能。Windows 不允许我在任何需要的地方放置关闭按钮。虽然当我对窗口说我希望整个窗口都是 HTCAPTION 而不是关闭按钮时,它非常有效。我知道我可以轻松地进行适当的直接 api 调用。但是总有一些疑问,如果windows做了一些我不知道的额外事情怎么办。为什么 Windows 会这样做?也许有一些你知道的解决方案。请分享。
#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;
}
这段代码意味着无论用户按下鼠标按钮,应用程序都应该关闭。但事实并非如此。
解决方案
您需要单独处理WM_NCLBUTTONDOWN。
参数
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);
}
...
推荐阅读
- azure - 如何将 Microsoft Graph 集成到 ASP.NET Core Web Api 项目中?
- vue.js - 动态显示包含不同大小嵌套数组的数据的表列/行?
- python - 在python中的二维列表中连接各个一维列表的元素
- ios - 使用 PDFKit Swift 在 pdf 中的上一页上添加图像后插入空白页
- c# - 以 c# Xamarin 形式完成 aync 调用后,如何转换到新页面?
- python - 全码 - 电影票(进行中)
- javascript - ng-click 未在 span 元素中触发
- data-cleaning - OpenRefine - 根据另一列中的值替换一列中的字符串值
- docker - 在没有 Kubernetes 的本地开发环境中运行 Ambassador
- swift - 有没有办法使用泛型函数调用数据?