不占用客户端区域的子窗口

Child Windows that does not occupy client area

本文关键字:窗口 区域 客户端      更新时间:2023-10-16

在Win32 API(纯Win32)中,菜单栏不占用窗口客户端区域的任何区域。这意味着客户端区域的原点坐标就在左边菜单栏的正下方。

当我们使用CreateWindow(或任何其他方法)创建子窗口控件时,该窗口占用客户端区域的一些区域。

eg:-创建一个按钮,该按钮位于(xPos = 0, yPos = 0)和(width=width_of_client_area, height=20).

创建按钮后,如果你使用GDI函数,它将被绘制在按钮下方:

矩形(hdc, 0,0,200,200);

但是当创建菜单栏时,它不占用客户端区域。(GDI不会在菜单下绘制)。

最后一个问题:如何在父窗口(如菜单栏)上创建控件

菜单呈现在窗口的非客户端区域,这是由一组完全不同的窗口消息驱动的。请记住,您实际上并没有为这些类型的控件创建子窗口。您需要为您想要添加的自定义提供所有呈现和事件处理。这意味着如果您想要添加按钮或复选框,则需要自己实现它。你可以从几个步骤开始,但根据你的需求,可能还有其他事情需要做。

第一步是处理WM_NCCALCSIZE消息。这将允许您调整非客户端区域的大小,以便有更多的空间来绘制自定义控件。基本上,您将把此消息传递给默认窗口进程,然后在返回之前修改位置和尺寸(只需将顶部向下放置X像素)。

下一步处理WM_NCPAINT消息。将消息传递给默认窗口进程,然后在您保留的区域中绘制自定义视觉效果。您将使用窗口DC,因此您可以绘制到整个窗口。记住这一点很重要,这样您就不会破坏客户端区域中的任何内容。

需要做的最后一项是处理鼠标消息,如WM_NCMOUSEMOVE。如果鼠标事件发生在控件所在区域之外,则将消息传递给默认窗口进程,否则自己处理消息并跳过默认窗口进程。您将需要管理一些状态数据,以跟踪按钮何时按下或不按下,以免与默认窗口进程发生冲突。

请记住,当您想直接绘制到非客户端区域时,您需要调用GetWindowDC()而不是GetDC()来获取设备上下文。

[注:一个好的Google舞蹈将是类似于"WinAPI非客户端区域"]