none
常に別プロセスの子ウインドウの手前にフォームを表示させたい RRS feed

  • 質問

  • 只今、常に特定のアプリケーションの子ウインドウの一つ手前に表示させるフォームアプリケーションを試行錯誤で作成しています。

     

    具体的に言えば、フォームアプリケーションを子ウインドウの座標、サイズはGetWindowRectというAPIを利用して取得することができて、タイマーイベントごとにフォームのサイズ、位置を調整するといったことは現在はできています。

     

    このことで、あるウインドウにくっついて行くようなアプリケーションは完成したように思えました。

     

    ところが実用的に使うとなると、フォームを最前面に表示させてしまうと別のアプリケーションのウインドウよりも手前に表示されてしまい、また最前面に表示しないと親ウインドウがアクティブになったときにフォームアプリケーションが子ウインドウの後ろに隠れてしまうという問題が出てきました。

     

    解決法を検索していると、SetWindowPos関数なるものがあって、それを利用すれば、ウインドウの手前や奥と言った情報を保持するZオーダをも自由に操ることが出来ると知りました。

     

    例えば今、フォームアプリケーションのウインドウハンドルをwHnd_A、フォームアプリケーションの奥に表示したい子ウインドウのウインドウハンドルをwHnd_Bとします。

    ネットでのサンプルなどから以下のようなコードを書いてみたのですが思惑通りに動いてくれません。

    SetWindowPos(hWnd_B, hWnd_A,
                    hWnd_Bの左端の座標, hWnd_Bの上端の座標,
                    hWnd_Bの幅, hWnd_Bの上端の高さ,
                    SWP_NOMOVE|SWP_NOSIZE);
    


    現在も色々試してみたり、検索してみたりしていますが。

    少し手詰まりの様子なので皆様のご知恵を拝借させていただきたく質問させて頂きました。

    2012年1月27日 6:00

回答

  • こんなクラスを作って、

    internal class Owner : IWin32Window
     {
    	public IntPtr Handle
    	 {
    		get
    		{
    			return Process.GetProcesses().FirstOrDefault(proc => proc.ProcessName == "calc").MainWindowHandle;
    		}
    	}
    }
    
    


    Mainで

    var form = new Form1();
    form.Show(new Owner());
    Application.Run(form);
    

    こうして、

    Windows の電卓を起動した状態でプログラムを実行すると、常に電卓の手前に表示されますね。

    やりたいこととはちょっとちがうかな?

    • 回答としてマーク 山本春海 2012年2月15日 4:45
    2012年1月27日 7:22

すべての返信

  • こんなクラスを作って、

    internal class Owner : IWin32Window
     {
    	public IntPtr Handle
    	 {
    		get
    		{
    			return Process.GetProcesses().FirstOrDefault(proc => proc.ProcessName == "calc").MainWindowHandle;
    		}
    	}
    }
    
    


    Mainで

    var form = new Form1();
    form.Show(new Owner());
    Application.Run(form);
    

    こうして、

    Windows の電卓を起動した状態でプログラムを実行すると、常に電卓の手前に表示されますね。

    やりたいこととはちょっとちがうかな?

    • 回答としてマーク 山本春海 2012年2月15日 4:45
    2012年1月27日 7:22
  • 回答誠に有難う御座います。

     

    なかなか私のような拙い日曜プログラマには高級なコードで少々試すのに時間がかかってしまい返信が遅れてしまいました申し訳ありません。

     

    上記で示して頂きましたクラスを、子ウインドウハンドルを返すように少し改変させていただいたり、色々試させて頂きました。

    結論から申させて頂きますと、残念ながら私の意図通りには動いてくれませんでした。

     

    子ウインドウに表示させたいと申しましたのは、作成するフォームを重ねて表示したいソフトウェアウインドウが、タブを使用しているもので、タブで切り替えを行った場合にもフォームが上部に重なって表示されてしまいます。

     

    しかし、それだけ目をつむれば、目的に一歩近づいた気がいたします。

    有益な情報を提供いただき誠にありがとうございます。

    2012年1月27日 8:23