【问题标题】:Child Windows that does not occupy client area不占用客户区的子窗口
【发布时间】:2013-05-13 23:07:40
【问题描述】:

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

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

例如:- 创建一个位于 (xPos = 0, yPos = 0) 和 (width=width_of_client_area, height=20) 的按钮。

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

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

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

最后一个问题: 如何在我的父窗口上创建一个控件,比如菜单栏?

【问题讨论】:

标签: c++ c windows winapi


【解决方案1】:

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

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

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

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

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

[注意:一个好的谷歌舞会类似于“WinAPI 非客户区”]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 2021-01-27
    • 2011-03-15
    相关资源
    最近更新 更多