- 締切済み
アクティブウインドウが閉じた後のフォーカスの制御について質問です。
アクティブウインドウが閉じた後のフォーカスの制御について質問です。 開発環境はVisual Studio.NET2003 VC++ MFCです。 二つのアプリケーション(アプリA、B)を立ち上げる、ランチャのようなアプリを作成しています。 両アプリ起動後、数秒すると、ランチャはbottomへ移動します。 Zオーダーは、前から、アプリA、アプリB、ランチャ、となります。 その後、最前面のアプリAを、アプリAの終了ボタンで閉じます。 すると、ランチャがアクティブになり、勝手にアプリBの前に出てきてしまいます。 希望としては、アプリBにアクティブになって欲しいのですが…。 アクティブウィンドウが消えた後にどのウィンドウをアクティブにするか、指定するような事は可能なのでしょうか。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- hidebun
- ベストアンサー率50% (92/181)
ランチャをZオーダのボトムに、というのは、SetWindowPosで HWND_BOTTOMにしているということですか。 不思議ですね。アプリA,アプリBがZオーダでは前にあるはずなのに、 ランチャが前に来てしまうのは。 A・Bアプリの起動コードと、ランチャのZオーダーを下げる処理を 提示してみれば、何か解決のヒントが得られるかもしれませんので、 補足していただくことは可能ですか? また、A・Bアプリを、電卓アプリやNotepadなどに変えてみても、挙動は同じでしょうか? #A・Bアプリが独自のフォーカス制御を行っている可能性もあるので。 合わせて確認してみて下さい。
- hanmemomo
- ベストアンサー率35% (205/580)
考え方をかえて、 上に出したいアプリにフォーカスをセットして、 逆に閉じるアプリを後ろに移動してから終了してもらえたら うまくいくと思いますよ。
お礼
とっても迅速にお返事をいただけて、助かります。 なるほど~!!やってみますね!! 自分の頭の固さにびっくり。 ありがとうございました!
補足
すみません、できませんでした・・・・。 私の説明不足でしたが、アプリA,Bはexeをたたく以外の事ができません(ソースはいじれない)。 ランチャはアプリA,Bを監視しているので、終了は検知することができますが、終了前にZオーダーをいじる事ができません。 終了検知後にZオーダーをいじっても、一瞬ランチャが画面上にちらついてしまいます。。。。
補足
遅くなりすみません。 NotePadとIEでやってみましたが、現象は同じでした。 以下、A・Bアプリの起動コードと、ランチャのZオーダーを下げる処理です。 STARTUPINFO stStartInfo; PROCESS_INFORMATION stProInfo; ZeroMemory( &stProInfo , sizeof(PROCESS_INFORMATION)); ZeroMemory( &stStartInfo , sizeof(STARTUPINFO)); stStartInfo.cb = sizeof(STARTUPINFO); stStartInfo.dwFlags = STARTF_USESHOWWINDOW; stStartInfo.wShowWindow = SW_SHOWMAXIMIZED; (1)ノートパッド起動 BOOL bRet = CreateProcess ( "C:\\WINDOWS\\system32\\notepad.exe", NULL, NULL, NULL, FALSE, 0, NULL, "C:\\WINDOWS\\system32", &stStartInfo, &stProInfo ); (2)IE起動 BOOL bRet = CreateProcess ( "C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE", NULL, NULL, NULL, FALSE, 0, NULL, "C:\\Program Files\\Internet Explorer", &stStartInfo, &stProInfo ); (3)ランチャ背面移行 // アクティブなウィンドウハンドルを取得 CWnd* cwnd = GetForegroundWindow(); DWORD ActProcID = 0; // アクティブなスレッドのプロセス&スレッドID取得 DWORD ActThredID = ::GetWindowThreadProcessId( cwnd->GetSafeHwnd(), &ActProcID); // ランチャのスレッドID取得 DWORD MyThredID = ::GetCurrentThreadId(); // アクティブなのが自分なら if( ActThredID == MyThredID ) { SetWindowPos( &wndBottom, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ); UpdateWindow(); } else { // 別のプロセスがアクティブな場合は、そのプロセスにアタッチ ::AttachThreadInput( MyThredID, ActThredID, TRUE ); SetWindowPos( &wndBottom, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ); UpdateWindow(); // デタッチ ::AttachThreadInput( MyThredID, ActThredID, FALSE ); } <動作> 1、ランチャを起動、TopMost表示(ランチャ背面移行と同じ処理で、wndBottom->TopMostに変えただけ) 2、ボタン押下でノートパッド起動。 処理としては、 ランチャTopMost表示 -> (1)ノートパッド起動 -> ランチャTop表示 3、ボタン押下でIE起動 処理としては、 ランチャTopMost表示 -> (2)IE起動 -> ランチャTop表示 4、タイマーでランチャは背面へ 処理としては、(3)ランチャ背面移行 5、IEを、IEの×ボタンで消す そうすると、Bottomにいるはずのランチャがノートパッドの前に表示されてしまいます。