我可以在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。这有效,但按钮不是无父的..
那么有没有办法给一个按钮一个ID(以便在WM_COMMAND中识别它),同时让它的父ID为NULL,以便我可以在以后设置父项? Windows Forms如何做到这一点?在您执行Form.add(ButtonName);
之前,按钮可以是无父按钮在WINAPI中可以达到同样的效果吗?
答案 0 :(得分:4)
这表面看来是一个非常愚蠢的问题。
按钮控件根据定义是子控件,因此用于创建按钮的CreateWindowEx
函数的调用也应该指定WS_CHILD
样式。
当然,正如您所提到的,您无法创建没有父级的子控件;你会收到一个错误。没有顶级子窗口。
那么,最初问题的答案
显然没有。按钮是子控件,所有子控件都必须有父控件。我可以在WINAPI中创建没有父级的按钮吗?
只是因为Windows让你在创建按钮控件时指定WS_POPUP
标志,并不意味着它是一个有效的组合。
我强烈建议您重新阅读CreateWindowEx
功能the documentation。特别要注意hMenu
参数的含义是否过载。如果要创建重叠或弹出窗口(WS_OVERLAPPED
或WS_POPUP
),则会指定菜单的句柄。如果您正在创建子窗口(WS_CHILD
),则它指定子窗口的标识符。事实上,根据窗口的样式,两个事物都使用相同的参数,这应该告诉你一些事情。
他们肯定不能。在将它们添加到窗体或其他父控件之前,不会创建按钮控件。Windows Forms如何做到这一点?在您执行Form.add(ButtonName);
之前,按钮可以是无父按钮
System.Windows.Forms.Button
类构造函数不会创建Win32窗口。它只包含一组必要的样式,用于在适当的时候创建底层的Win32窗口。
当然,你可以通过编写C ++ Button
类来做同样的事情。一个简单的实现只有成员变量对应于CreateWindowEx
和Create
成员函数的参数,一旦设置了所有成员,它们实际上会调用CreateWindowEx
来创建Win32窗口。如果其中一个必要成员尚未设置为有效值,则Create
方法可能会抛出异常。
我解决了。我必须传递HWND_MESSAGE作为父参数。当您调用SetParent时,该参数将更改为Parent的句柄,一切都很好。
不,这确实不是问题的“解决方案”。作为kero points out,您只需将按钮控件的父级设置为message-only window即可。同样,这似乎可行,但这是一件相当奇怪的事情,我几乎不推荐它作为解决方案。
如果您真的想破解它,我建议您创建自己的隐藏顶级窗口,以用作“未授权”子控件的父级。然后你可以使用调用SetParent
的相同技巧重新表达它们。
答案 1 :(得分:1)
我解决了。我必须传递HWND_MESSAGE作为父参数。什么时候 您调用SetParent,该参数将更改为Parent的句柄 一切都很好。
不,你没有得到“无父按钮”:仅消息按钮的父窗口是“主要”仅消息窗口(“消息”类)。