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
自分自身を呼び出すのではなく (おそらく) 呼び出す Window クラスをお勧めします。例えば:
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(..)
ますWindow::wndProc(UINT, WPARAM, LPARAM)
。次に、代わりにチェックを行うことができます(最初のwndProc
関数を詰め込まないように):)
これの欠点は、アプリケーションが他の誰かによって書かれた場合、ウィンドウクラスに準拠する必要があることです。あなたが説明したように、ユーザーはウィンドウマネージャーとやり取りする必要はありませんが、このアプローチでは、ウィンドウマネージャーにユーザーのウィンドウを作成させることが唯一のやり取りになります。
それ以外の場合は、他の回答で説明されているフックを使用する必要があると思います