自定义最小-最大关闭按钮实现

Custom Min Max Close Button implementation

本文关键字:关闭按钮 实现 自定义      更新时间:2023-10-16

我使用纯C++(不带MFC)来实现应用程序。我想添加自定义最小/最大/关闭按钮

下面的代码就是我使用的代码。对于HTCAPTION和其他与边界相关的定义像符咒一样工作,但我无法让HTMINBUTTON、HTMINBUTTEN、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);

如果您正在绘制程序的整个非客户端区域(即,您有一个自定义窗口标题栏和边框),那么您的最佳选择是删除默认标题栏和边界,并将整个客户端区域用作您的窗口。通过这种方式,您可以使用最小/最大/退出按钮所需的图形制作一个自定义按钮(或所有者绘制的按钮),并将它们作为按钮控件放置在标题栏区域中。因为您正在处理WM_NCHITTEST消息,所以您的程序仍然会像有标题栏和边框一样运行。我今天刚刚对我的自定义窗口做了这件事,效果很好。

编辑:我忘了添加返回HTMAX/HTMIN/HTCLOSE不会导致窗口做出反应。从WM_NCHITTEST返回的值在其他消息的WPARAM中发送,特别是WM_NCLBUTTONDOWN和WM_NCLBUTTONUP。不幸的是,WM_NCLBUTTONUP消息没有正确发送,因为当您单击标题栏时,它会捕获鼠标。

我有一个适合我的解决方案

1.WM_NCHITTEST

订阅WM_NCHITTEST。现在你必须处理消息并返回你的击球结果。

这可能会帮助您:http://msdn.microsoft.com/en-us/library/windows/desktop/ms645618(v=vs.85).aspx

对我来说,我在表格上创建了几个区域。左上、上、右上、标题、左、右、下、下、右、最小按钮、最大按钮、关闭按钮

它们中的每一个都是一个矩形,在我的表单中定义了一个区域。我只需检查鼠标光标是否在其中一个区域,并返回正确的HT-CODE。

2.WM_ncl按钮

现在订阅WM_NCLBUTTONDOWN。检查WPARAM中要处理的NCHITTEST值用于最小化HTMINBUTTON(0x0008)的按钮检查

但在这里,我只是在结果中返回IntPtr.Zero。这表明我已经处理了这条消息。

3.WM_ncl按钮

之后订阅WM_NCLBUTTONUP。检查WPARAM中的目标NCHITTEST值,并在此处执行您想要的操作。

我稍后会上传我的源代码!