您可以使用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_消息,我会建议调用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){
}
};
在这个例子中你的应用程序会从窗口继承,基本上提供了一个稍微修改的WndProc功能(这将是缺少HWND所以这将需要存储在某个地方,除非你选择它向上用户数据)。
每当您收到消息时,Window::wndProc(HWND, UINT, WPARAM, LPARAM)
函数都会检测到它。在这里,您可以对任何消息进行检查,包括(但不限于)WM_WINDOWPOSCHANGING
。
其他的事情将是:
在wndProc(UINT, WPARAM, LPARAM)
,而不是调用DefWindowProc(..)
你打电话Window::wndProc(UINT, WPARAM, LPARAM)
。然后,你可以做你的支票在那里,而不是(如不cludge第一wndProc
功能):)
这个的缺点是,如果应用程序是别人写的,他们需要遵守你的windowclass。正如你解释的那样,用户不需要与窗口管理器交互,但是,采用这种方法,唯一的交互作用就是让窗口管理器为用户创建窗口。
否则我认为你将不得不去解决在其他答案中解释的钩子
我宁愿它,如果用户不应该被要求与'窗口管理器'应用程序进行交互。 我希望能有一些方法来检测窗口顺序何时改变,然后让'窗口管理器'应用程序自动响应。例如,使用kludgey的方法是设置一个计时器,以便'窗口管理器'应用程序每隔X个时间段检查窗口顺序并在必要时重新排序。 我希望能有一些其他的消息可以用来确定何时检查重新排序是否必要。 – JRT 2010-02-25 13:30:14