【发布时间】:2021-03-07 09:01:11
【问题描述】:
当光标悬停在标题区域(HTCAPTION)上时,按鼠标左键,然后可以拖动一个窗口并移动它。当您释放鼠标左键时,您可以停止此拖动动作。当您移动一个窗口时,它会触发消息 WM_MOVE。当释放鼠标按钮时,我不知道应该处理哪个消息来捕捉这个动作。
我正在做的是当你将一个窗口(比如说窗口 A)拖到另一个窗口的区域(窗口 B)中时,使窗口 A 成为窗口 B 的子窗口,当将窗口 A 拖出窗口 B 的区域时,使窗口 A 一个 WS_POPUP 窗口,没有 WS_CHILD 样式。
我处理了消息 WM_MOVE 和 WM_CAPTURECHANGED(我认为这不是正确的)。
在 WM_CAPTURECHANGED 中,我发现了一些有线的东西。 API SetWindowPos 似乎无法正常工作。准确地说,第 3 和第 4 个参数指定了窗口的位置不起作用。
case WM_CAPTURECHANGED: {
RECT rcc;
GetClientRect(main,&rcc);
// here main is the handler of window B , hwnd is for window A,as referrence above.
if(docker_mode==DOCKER_LEFT) {
// docker_mode is assigned by WM_MOVE message handler. recording which area window A was moved into.
if((WS_CHILD&GetWindowLongPtr(hwnd,GWL_STYLE))!=WS_CHILD) {
SetWindowLongPtr(hwnd,GWL_STYLE,(~WS_POPUP)&(WS_CHILD|GetWindowLongPtr(hwnd,GWL_STYLE)));
SetParent(hwnd,main);
}
//The following code not work. It should be moved into the left-top corner of window B,
//but NOT in fact.
SetWindowPos(hwnd,NULL,0,0,300,rcc.bottom-rcc.top,SWP_NOZORDER);
}
else {
if((WS_CHILD&GetWindowLongPtr(hwnd,GWL_STYLE))==WS_CHILD) {
SetWindowLongPtr(hwnd,GWL_STYLE,((~WS_CHILD)&GetWindowLongPtr(hwnd,GWL_STYLE))|WS_POPUP);
SetParent(hwnd,NULL);
SetWindowPos(hwnd,NULL,300,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
}
}
} break;
SetWindowLongPtr(...,GWL_STYLE,...) 被调用来设置窗口样式。顶层没有 WS_CHILD 样式,父窗口的句柄应该是 NULL ,我用 SetParent(hwnd,NULL) 来做这个。子窗口应该有 WS_CHILD 样式,并且应该分配父窗口。
我在窗口中放了一个按钮,并将这些代码复制到按钮单击事件的句柄中。单击按钮效果很好,将弹出窗口更改为子窗口,将子窗口放在正确的位置。 SetWindowPos 完全没有问题。我不知道为什么。
SetWindowPos 在处理 WM_CAPTURECHANGED 处理程序时是一个非常有趣的 API。怎么了?
【问题讨论】:
标签: windows