• 締切済み

アクティブウインドウが閉じた後のフォーカスの制御について質問です。

アクティブウインドウが閉じた後のフォーカスの制御について質問です。 開発環境はVisual Studio.NET2003 VC++ MFCです。 二つのアプリケーション(アプリA、B)を立ち上げる、ランチャのようなアプリを作成しています。 両アプリ起動後、数秒すると、ランチャはbottomへ移動します。 Zオーダーは、前から、アプリA、アプリB、ランチャ、となります。 その後、最前面のアプリAを、アプリAの終了ボタンで閉じます。 すると、ランチャがアクティブになり、勝手にアプリBの前に出てきてしまいます。 希望としては、アプリBにアクティブになって欲しいのですが…。 アクティブウィンドウが消えた後にどのウィンドウをアクティブにするか、指定するような事は可能なのでしょうか。

  • lee_g
  • お礼率50% (1/2)

みんなの回答

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.2

ランチャをZオーダのボトムに、というのは、SetWindowPosで HWND_BOTTOMにしているということですか。 不思議ですね。アプリA,アプリBがZオーダでは前にあるはずなのに、 ランチャが前に来てしまうのは。 A・Bアプリの起動コードと、ランチャのZオーダーを下げる処理を 提示してみれば、何か解決のヒントが得られるかもしれませんので、 補足していただくことは可能ですか? また、A・Bアプリを、電卓アプリやNotepadなどに変えてみても、挙動は同じでしょうか? #A・Bアプリが独自のフォーカス制御を行っている可能性もあるので。 合わせて確認してみて下さい。

lee_g
質問者

補足

遅くなりすみません。 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にいるはずのランチャがノートパッドの前に表示されてしまいます。

  • hanmemomo
  • ベストアンサー率35% (205/580)
回答No.1

考え方をかえて、 上に出したいアプリにフォーカスをセットして、 逆に閉じるアプリを後ろに移動してから終了してもらえたら うまくいくと思いますよ。

lee_g
質問者

お礼

とっても迅速にお返事をいただけて、助かります。 なるほど~!!やってみますね!! 自分の頭の固さにびっくり。 ありがとうございました!

lee_g
質問者

補足

すみません、できませんでした・・・・。 私の説明不足でしたが、アプリA,Bはexeをたたく以外の事ができません(ソースはいじれない)。 ランチャはアプリA,Bを監視しているので、終了は検知することができますが、終了前にZオーダーをいじる事ができません。 終了検知後にZオーダーをいじっても、一瞬ランチャが画面上にちらついてしまいます。。。。

関連するQ&A

  • フォーカスとドラッグ

    focus()すると、フォーカスされたウインドウが、マウスの左を押しっぱなしのようになってしまい、マウスを動かすと文字が選択されてしまいます。 そのウインドウを最前面でタイトルバーを活性にしたいので、focus()を実行するのをやめるわけにいきません。 その後、どうしたらマウス左クリックのような状態を解除できるでしょうか。 それは、マウスを使うのではなく、JavaScriptでです。

  • Shellコマンドで別のexeを起動するとフォーカスが別exeにいかない

    2本のEXE(AとB)があって、 AからBを呼び出して、Bの終了ボタンを 押すとAに戻るようなプログラムがあります。 Bを最前面にして起動しているのですが、 Bにフォーカスがいってくれません。 (Aに残ったままになっている?) ちなみにAもBもウィンドウスタイルは、 青いバーが出ている状態(動かせる状態)です。 Bが起動している間、Aはその後ろでまっている ようなイメージです。 どうやったらフォーカスを渡すことが できるでしょうか? <条件> Bのプログラムは修正することができません。 Aのプログラムは自由に修正できます。 どなたか教えて下さい。

  • 別プロセスのコントロールにフォーカスをあてたい

    VC++5.0 または VC++6.0 の環境で、MFC を使ってダイアログベースの EXEを造っています。 (OS は NT4.0 または 2000 です) 以下のことをしたいと思っています。 ・プロセスA、Bがあります。 ・プロセスAがプロセスBをフォアグランドにします。 →SetForegroundWindow() します。 ・プロセスAがプロセスBのボタンやエディットボックスなどのコントロールに フォーカスをあてる。 で、この最後のフォーカスをあてる処理は実現可能でしょうか? 自分のプロセス内のコントロールに対しては、SetFocus() で フォーカスをあてられたのですが、別プロセスではフォーカスを あてることができませんでした。 識者の方、ご教授願います。

  • MDIの子フォームでフォーカスアウトを制御したい

    MDIの子フォームでフォーカスアウトを制御したい VB2005で開発を行っています。 ・MDIの子フォームA、Bが存在します。 ・子フォームA、Bともに、表示されています。 ・子フォームAにはテキストコントロールAA、ABの2つが存在します。 ・テキストコントロールAAのLostFocus()に、テキストコントロールAA.Focus()が  記されています。 この状態で、子フォームAのテキストコントロールAAからABへフォーカスが移った時、 コントロールAAのLostFocus()で制御するのはうまくいきます。 が、子フォームAのテキストコントロールAAから子フォームBへフォーカスが移った時、 コントロールAAのLostFocus()が動作しますが、無限ループっぽい動きに陥ったり、 子フォームAにフォーカスが設定されません。 子フォームを最小化させたり、全然関係のないアプリケーションやデスクトップに フォーカスを遷移したあとにフォーカスを戻してみても同じような現象になります。 イメージとしては、フォーカスアウトでエラーになったんだから、フォーカスを移し たくないです。 Private Sub ControlAA_LostFocus(ByVal sender As System.Object, ByVal e As System.EventArgs)  If "".Equals(ControlAA.Text) Then   MessageBox.Show("hoge")   ControlAA.Focus()   Return  End If End Sub フォーカスアウト時に項目チェックなどをやる関係で、どうしてもLostFocus()上で 処理をやらなければならないと思われるのですが、フォーカスアウトされた時のオペ レーションの違いに限らず上手く制御させる方法はありませんでしょうか? 調べてはみましたが、MDIの概念でそもそもそういうことするなというような事らしいですが、 フォーカスアウト時に検索処理が走るというような仕様の為、どうしても解決させたいです。

  • マウスカーソルを移動すると自動的にフォーカスか切り替わってしまいます

    マウスのカーソルを移動すると、自動的に(勝手に)アクティブのフォーカスが切り替わるようになってしまいました。 恐らくなにかしらの設定をしたのだと思いますが、どの項目から解除すればいいのか思い出せません…。 例:ウィンドウAとウィンドウBを開き、Aをアクティブ(バーが青)にした状態でマウスのカーソルをAからBに移動すると、自動的にウィンドウBがアクティブになり、ウィンドウAは前面にでたまま非アクティブ(バーがグレー)になります。 ご存じの方いらっしゃいましたら教えていただけないでしょうか。 よろしくお願いします。

  • コントロールでのフォーカスの取得

    WNDOWSXP + VC++2010Express + SDKです。VC++ExpressなのでMFCなどは使えません。 ウィンドウのフォーカスの取得方法について質問します。 メインウィンドウにコントロールを3つ貼り付けます。 エディットコントロール2つと、自分で作成したコントロールが1つです。 自分で作成したコントロールのウィンドウプロシージャは仮に↓こんなものだとします。 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if(message==WM_KEYDOWN) { if(wParam=='A'){ MessageBox(NULL,_T("A"),_T("KEYDOWN"),NULL); } return 0; } return DefWindowProc(hWnd, message, wParam, lParam); } プログラムを起動し、エディットコントロールAをクリックすると エディットコントロールAにフォーカスが移動します。 キーボードのAボタンを押下すると、エディットコントロールAに「a」と入力されます。 エディットコントロールB、自分で作成したコントロールは無反応です。 エディットコントロールBをクリックすると、エディットコントロールBにフォーカスが移動します。 キーボードのAボタンを押下すると、エディットコントロールBに「a」と入力されます。 エディットコントロールA、自分で作成したコントロールは無反応です。 次に、自分で作成したコントロールをクリックした場合、 フォーカスはエディットコントロールBにあります。キーイベントなども エディットコントロールBのみが反応します。 ここで、自分で作成したコントロールをクリックした場合に 自分で作成したコントロールがフォーカスを取得し、 キーイベントなどを独占的に受け取れるようにしたいのですが、方法がわかりません。 どなたか方法をご存知の方がいらっしゃいましたら、ご教授いただけないでしょうか。

  • ファイルの排他制御について

    こんにちは。 Visual Studio 2005 のC#を使って、ファイルを加工するアプリを書いていますが、 ファイルの排他制御についてよく分らなくて困っています。 プログラムの構成としては、以下の通りです。 1:プログラムAがファイルXYZを作成します。 2:プログラムAとは別々に動く、プログラムBが、このファイルXYZを読み込んで データベースに書込む処理をします。 この処理で、もしもプログラムAがファイルXYZの作成中の時に、 プログラムBが同じタイミングでファイルXYZを開いてしまった場合、 ファイルが中途半端な状態で開いてしまうのではないかと思ってます。 こういう状態を回避するためにはどういう処理にすればよいのでしょうか? よろしくお願いいたします。

  • VB.NET 外部アプリの制御

    VB.NET(VB2010)で二つアプリケーションの制御を考えています。 親アプリA、子アプリBとして、基本的にはアプリAからアプリBの起動・停止を行います。 ただ稀に、アプリB単体でアプリ停止をする必要があります。 その際、常時稼働中のアプリAから、アプリBが停止したことまで検出できます。 しかし、その後のアプリBの起動をアプリAから行わず、ショートカットから行った場合 アプリAからアプリBを制御できるのでしょうか? 単純にするには、全てアプリA経由でやるべきですが、アプリB単体でも起動したいという ニーズがあり困っています。 技術的に可能でしょうか?

  • VC++6.0 MFC 日時指定コントロールの秒へのセットフォーカス

    VC++6.0 MFC 日時指定コントロールの秒へのセットフォーカス 以下の環境でプログラミングを実施しています。 開発環境:Visual Studio 6.0 言語:Visual C++ プロジェクト:MFCアプリケーション 日時指定コントロールのスピンを最初にクリックすると 時間が変化しますが、これを初期設定で秒にしたいのですが どうしたらいいのか全くわかりません。 教えてください!

  • ★WindowsのForm表示をVBで制御したい

    お世話になります。 さて「アプリA」という無料ソフトがあって、 それは「OEM」ボタンなるものを提供しており、 自作ソフトMeから通信で制御できるのです。 つまりアプリAの機能を自由に使えるわけです。 そこで、アプリAのボタンをMeから押して、 アプリAのメニュー画面が出して見ると、 自作ソフトMeが最前面のままとなるのです。 これではAかAメニューのどこかをクリックして、 Aを最前面にするか、Meを最小化しないと、 メニュー操作ができません。 ましてやMe画面を最大化しているときは、 AとAメニューは裏に隠れて見えすらしません。 タスクバーをクリック操作すればよいでしょうが、 そうした操作なしに自動化したいのです。 (添付の画像を参照してください) そこで現状は自作ソフトMeから、 1)アプリAを最小化するメッセージを送る SendMessage(p.MainWindowHandle,&H112,&HF020,0) 上記関数の引数の意味はよく分かりませんが。 2)アプリAの目的のボタンを通信で押す。 AppliObj.DoButton( TARGET_BUTTOM ) ここからが困っています。 。 3a)アプリAを元のサイズにするメッセージを送る SendMessage(p.MainWindowHandle,&H112,&HF120,0) ところが!、2)をした後では反応しません。 Aメニューがモーダルフォームだからのようです。 順序を逆にしたら、このやっていること自体が無意味。 3b)アプリAの最小化アイコンを手動クリックする これは成功! Aメニューだけがポップ表示されました。 しかも自作ソフトMeの前面に! しかし手動クリックをすることは目的から外れます。 3c)アプリAの最小化アイコンを自動クリックする ところがそのアイコンのX座標が状況で変わるため 自動クリックの位置が定まりません。 なにか解決策を教えてもらえないでしょうか! よろしくお願い申し上げます m(__)m