您可以使用 SetWindowPos 以您想要的 Z 顺序定位您的窗口。我建议你拦截 WM_FOCUS 消息(当它收到焦点时发送到你的窗口)
在你的 wndProc 函数中,也许你可以尝试这样的事情:
LRESULT wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
// other stuff..
switch (msg){
case WM_FOCUS:
{
HWND firstWindow; // get the first window here
HWND secondWindow; // this would be the second window
HWND thirdWindow; // this would be the third window
// TODO: initialize the windows correctly, based on your priority
SetWindowPos(firstWindow, secondWindow, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE); // position the second window below the first window
SetWindowPos(secondWindow, thirdWindow, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE); // position the third window below the second window
}
return 0;
}
// other messages..
}
我不太确定 SetWindowPos 参数的顺序,因为我现在无法测试代码,但也许这可以让你继续前进?
如果您需要拦截所有 WM_ 消息,我会建议应用程序调用的 Window 类(我猜)而不是调用CreateWindowEx
自己。例如:
class Window {
public
Window(){
...
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = wndProc; // <- Note this one
...
}
static LRESULT WINAPI wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
// reference: http://www.gamedev.net/community/forums/topic.asp?topic_id=303854 - Evil Steve [Moderator]
Window* parent;
// Get pointer to window
if(msg == WM_CREATE){
parent = (Window*)((LPCREATESTRUCT)lParam)->lpCreateParams;
SetWindowLongPtr(hwnd,GWL_USERDATA,(LONG_PTR)parent);
}
else{
parent = (Window*)GetWindowLongPtr(hwnd,GWL_USERDATA);
if(!parent) return DefWindowProc(hwnd,msg,wParam,lParam);
}
HWND prev = parent->mWin;
parent->mWin = hwnd;
LRESULT ret = parent->wndProc(msg,wParam,lParam);
parent->mWin = prev;
return ret;
}
virtual LRESULT wndProc(UINT msg, WPARAM wParam, LPARAM lParam){
}
};
在此示例中,您的应用程序将从 Window 继承,基本上提供了稍微修改的 wndProc 函数(它将缺少 HWND,因此需要将其存储在某个地方,除非您从 Userdata 中获取它)。
每次您收到消息时,该Window::wndProc(HWND, UINT, WPARAM, LPARAM)
功能都会将其接收。在这里,您可以检查任何消息,包括(但不限于)WM_WINDOWPOSCHANGING
。
另一件事是:
在wndProc(UINT, WPARAM, LPARAM)
, 而不是打电话给DefWindowProc(..)
你 call Window::wndProc(UINT, WPARAM, LPARAM)
。然后你可以在那里进行检查(以免堵塞第一个wndProc
功能):)
这样做的缺点是,如果应用程序是由其他人编写的,他们将需要遵守您的窗口类。正如您所解释的,用户不需要与您的窗口管理器交互,但是,使用这种方法,唯一的交互是让您的窗口管理器为用户创建窗口。
否则,我认为您将不得不使用其他答案中解释的钩子