SetParent是Windows提供的设置窗口父窗体的API,函数原型比较简单:
1 2 3 4
| HWND SetParent( [in] HWND hWndChild, [in, optional] HWND hWndNewParent );
|
我们通常的使用方法是:
1 2 3
| if(!SetParent(hChild, hParent)) { }
|
这种使用方法在大多情况下不会失败,但有时却会失败。究其原因,其在微软官方文档中已有说明SetParent Doc。
由于兼容性问题,SetParent函数不会修改hWndChild窗口的WS_CHILD
和WS_POPUP
样式,因此:
- 如果hWndNewParent为NULL,你需要在调用SetParent函数后清除
WS_CHILD
并设置WS_POPUP
样式。
- 如果hWndNewParent不为NULL并且hWndChild之前是桌面的子窗口,你需要在调用SetParent函数前清除
WS_POPUP
并设置WS_CHILD
样式。
总结上述原因,SetParent的正确使用方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| bool SetWinParent(HWND hChild, HWND hNewParent) { HWND hOldParent = NULL; if (hNewParent) { LONG newStyle = GetWindowLong(hChild, GWL_STYLE);
newStyle &= ~WS_POPUP; newStyle |= WS_CHILD;
SetWindowLong(hChild, GWL_STYLE, newStyle);
hOldParent = ::SetParent(hChild, hNewParent); } else { hOldParent = ::SetParent(hChild, hNewParent);
LONG newStyle = GetWindowLong(hChild, GWL_STYLE);
newStyle &= ~WS_CHILD; newStyle |= WS_POPUP;
SetWindowLong(hChild, GWL_STYLE, newStyle); } return !!hOldParent; }
|