c++ - 无父按钮

标签 c++ winapi

我可以在 WINAPI 中创建没有父项的按钮吗?

我试过:

CreateWindowEx(0, "Button", "BTN", WS_POPUP | BS_PUSHBUTTON, 0, 0, 15, 15, nullptr, nullptr, nullptr, nullptr);

然后稍后将父级设置为指定窗口,并使用 ShowWindow 显示按钮。这确实创建了一个漂亮的按钮。

但是,该按钮没有 ID,并且无法在 WM_COMMAND 中识别,因为 ID 为 0。如果两个按钮没有父项,则无法区分它们。现在,如果我通过 HMENU 参数给它一个 ID:

CreateWindowEx(0, "Button", "BTN", WS_POPUP | BS_PUSHBUTTON, 0, 0, 15, 15, nullptr, 15, nullptr, nullptr);

GetLastError() 打印“无效菜单句柄”并且不会创建按钮。

如果我没有给它父级和 WS_CHILD,它会说无法创建一个可以理解的顶级子窗口。

所以我所做的是将 Parent 设置为 GetDesktopWindow() 并为按钮提供一个 ID。这行得通,但按钮不是没有 parent 的..

那么有没有办法给按钮一个 ID(以便在 WM_COMMAND 中识别它),同时让其父级为 NULL,以便我稍后可以设置父级? Windows 窗体是如何做到的?在您执行 Form.add(ButtonName); 之前,按钮可以是无父级的;

在WINAPI中可以实现同样的效果吗?

最佳答案

从表面上看,这是一个非常愚蠢的问题。

按钮控件根据定义是子控件,因此调用用于创建按钮的 CreateWindowEx 函数也应指定 WS_CHILD 样式。

当然,正如您提到的,您不能创建没有父控件的子控件;你会得到一个错误。没有顶级子窗口这样的东西。

那么,第一个问题的答案

Can I create a button without a parent in WINAPI?

显然不是。按钮是子控件,所有子控件都必须有一个父控件。

仅仅因为 Windows 允许您在创建按钮控件时指定 WS_POPUP 标志并不意味着它是一个有效的组合。

我强烈建议重新阅读 the documentation对于 CreateWindowEx 函数。特别要注意的是,hMenu 参数在其含义方面被重载了。如果您要创建重叠或弹出窗口(WS_OVERLAPPEDWS_POPUP),它会指定菜单句柄。如果您正在创建子窗口 (WS_CHILD),它会指定子窗口的标识符。根据窗口的样式,相同的参数用于这两种情况这一事实应该告诉您一些事情。

How does Windows Forms do it? The buttons can be parentless until you do Form.add(ButtonName);

他们肯定不能。在将按钮控件添加到窗体或其他父控件之前,它们不会被创建。 System.Windows.Forms.Button 类构造函数不创建 Win32 窗口。它只包含必要样式的集合,用于在适当的时候创建底层 Win32 窗口。

当然,您可以通过编写 C++ Button 类来做同样的事情。一个简单的实现只有与 CreateWindowEx 的参数对应的成员变量和一个实际调用 CreateWindowEx 来创建 Win32 窗口的 Create 成员函数一旦所有成员都设置好了。如果其中一个必需的成员尚未设置为有效值,则 Create 方法可能会引发异常。

I solved it. I had to pass HWND_MESSAGE as the Parent Parameter. When you call SetParent, that parameter gets changed to the Parent's handle and all is well.

不,这真的不是问题的“解决方案”。作为kero points out ,您只需将按钮控件的父级设置为 message-only window .同样,这似乎可行,但这是一件相当奇怪的事情,我几乎不推荐将其作为解决方案。

如果您真的想破解它,我建议您创建自己的隐藏顶层窗口以用作“无父级”子控件的父级。然后您可以使用调用 SetParent 的相同技巧来重新设置它们的父级。

关于c++ - 无父按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15308137/

相关文章:

c++ - 在 C++ 中,返回从本地 char 数组创建的字符串会导致内存泄漏或未定义的行为吗?

java - 有没有办法在 iphone 上阅读编程语言?

C++ : Is Namespaces definition allowed before '#include <files>' .

c++ - winapi中保存位图问题

c# - 如何在外部 Win32 应用程序窗口上添加 WPF 覆盖?

从 LPVOID 转换为全局变量 - C

c++ - 使用 Tab 在编辑控件之间切换?

c++ - do-while 中的输入验证

c++ - 按值传递共享指针并作为基类参数接受是如何工作的?

winapi - MOUSEEVENTF_ABSOLUTE 不起作用