我使用普通的C ++(没有MFC)来实现一个应用程序。 我想添加自定义最小/最大/关闭按钮
以下代码就是我使用的代码。 对于HTCAPTION和其他边框相关的定义就像魅力一样, 但我不能让HTMINBUTTON,HTMINBUTTON,HTCLOSE以同样的方式工作。 是否还需要实施NCHITTEST才能生效?
// Defining min/max/close
if ((p.x > rt.right - 130) && (p.x < rt.right - 104) &&
(p.y > 41) && (p.y < 67))
return HTMINBUTTON;
else if ((p.x > rt.right - 100) && (p.x < rt.right - 74) &&
(p.y > 41) && (p.y < 67))
return HTMAXBUTTON;
else if ((p.x > rt.right - 70) && (p.x < rt.right - 44) &&
(p.y > 41) && (p.y < 67))
return HTCLOSE;
// Defining window border and caption
else if ((p.x > EDGE) && (p.x < rt.right-EDGE) &&
(p.y > EDGE) && (p.y < rt.bottom-EDGE))
return HTCAPTION;
else if (p.x <= EDGE && p.y <= EDGE)
return HTTOPLEFT;
else if (p.x <= EDGE && p.y >= rt.bottom - EDGE)
return HTBOTTOMLEFT;
else if (p.x >= rt.right - EDGE && p.y <= EDGE)
return HTTOPRIGHT;
else if (p.x >= rt.right - EDGE && p.y >= rt.bottom - EDGE)
return HTBOTTOMRIGHT;
else if (p.x <= EDGE)
return HTLEFT;
else if (p.x >= rt.right - EDGE)
return HTRIGHT;
else if (p.y <= EDGE)
return HTTOP;
else if (p.y >= rt.top - EDGE)
return HTBOTTOM;
else
return DefWindowProc(hWnd, message, wParam, lParam);
答案 0 :(得分:1)
如果您正在绘制程序的整个非客户区域(即您有自定义窗口标题栏和边框),那么您最好的选择是删除默认标题栏和边框并使用整个客户端区域作为您的窗口。这样,您可以使用最小/最大/退出按钮所需的图形制作自定义按钮(或所有者绘制的按钮),并将它们作为按钮控件放在标题栏区域中。您的程序仍然会像标题栏和边框一样,因为您正在处理WM_NCHITTEST消息。我今天只用我的自定义窗口做了这件事,效果很好。
编辑:我忘了添加返回HTMAX / HTMIN / HTCLOSE不会导致窗口做出反应。从WM_NCHITTEST返回的值是在其他消息的WPARAM中发送的,特别是WM_NCLBUTTONDOWN和WM_NCLBUTTONUP。遗憾的是,WM_NCLBUTTONUP消息无法正常发送,因为当您在标题栏中单击时,它会捕获鼠标。
答案 1 :(得分:0)
我有一个适合我的解决方案。以下是我重现的步骤
订阅WM_NCHITTEST。现在你必须处理这个消息并返回你的命中结果。
这可能会对您有所帮助:http://msdn.microsoft.com/en-us/library/windows/desktop/ms645618(v=vs.85).aspx
对我来说,我在表单上创建了几个区域。 TopLeft,Top,TopRight,Caption,Left,Right,BottomLeft,Bottom,BottomRight,MinButton,MaxButton,CloseButton
每个都是一个Rectangle,在我的表单中定义一个区域。我只是检查鼠标光标是否位于其中一个区域并返回正确的HT-CODE。
现在订阅WM_NCLBUTTONDOWN。检查WPARAM以获取要处理的NCHITTEST值。 用于最小化按钮检查HTMINBUTTON(0x0008)
但是在这里我只是在结果中返回IntPtr.Zero。这表明我已经处理了这条消息。
之后订阅WM_NCLBUTTONUP。检查WPARAM以获取目标NCHITTEST值,并在此处执行您想要的操作。
我稍后会上传我的来源!