为什么SetParent会失败

SetParent是Windows提供的设置窗口父窗体的API,函数原型比较简单:

HWND SetParent(
[in] HWND hWndChild,
[in, optional] HWND hWndNewParent
);

我们通常的使用方法是:

if(!SetParent(hChild, hParent)) {
// Failed
}

这种使用方法在大多情况下不会失败,但有时却会失败。究其原因,其在微软官方文档中已有说明SetParent Doc

由于兼容性问题,SetParent函数不会修改hWndChild窗口的WS_CHILDWS_POPUP样式,因此:

  • 如果hWndNewParent为NULL,你需要在调用SetParent函数后清除WS_CHILD并设置WS_POPUP样式。
  • 如果hWndNewParent不为NULL并且hWndChild之前是桌面的子窗口,你需要在调用SetParent函数前清除WS_POPUP并设置WS_CHILD样式。

总结上述原因,SetParent的正确使用方法如下:

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;
}
https://winsoft666.github.io/post/3832058229.html

 

posted @ 2016-02-05 06:56  findumars  Views(211)  Comments(0)    收藏  举报