DOBON.NET DOBON.NETプログラミング掲示板過去ログ

多重起動時に起動済みウィンドウを前面表示

環境/言語:[C#]
分類:[.NET]

DD.と申します。

タイトルの通り、多重起動時に起動済みウィンドウを前面表示したいと考えたのですがうまくいかず質問させて頂きました。

C# .Net3.5にてWindowsフォームアプリで作成を行っているのですが、複数フォームが遷移し、遷移した後、元フォームはVisible=falseされ非表示となります。なのでユーザから見えているのは現在アクティブとなっている1画面のみとなります。

調べてみるとProcess.GetProcessesByName()で該当アプリへのProcessクラスを取得して、SetForegroundWindow(Process.MainWindowHandle)で前面表示するサンプルが多々見受けられますが、「Process.MainWindowHandle は ShowInTaskbar が無効だとゼロを返す」という記事もあり、確かに画面遷移によりメインウィンドウがVisible=falseされるとMainWindowHandleが0になっていました。

これを受け、EnumWindows()にてAPIで列挙して取得しろと書かれている記事もありますが、例えばプロセスIDで該当プロセスを検索して見つかったプロセスのウィンドウハンドルでSetForegroundWindow()しようとしても、該当プロセスにはVisible=falseになっているだけで複数のフォームが存在している状態なので、同プロセスIDを持つウィンドウハンドルが複数取得できてしまい、どれが現在アクティブとなっているものなのかがわかりません。(また、当然ながらその時にどの画面がアクティブなのかも変わってくる)

これをうまく特定する方法があればご教授頂きたいのが1点目で、2点目として、
上記理由に伴い、同プロセスIDを持つウィンドウハンドルに対して全てSetForegroundWindow()を行ってみました。(Visible=falseとなっているものは非表示のため前面表示など関係なし)
すると、「GDI+ Window」というものがタスクバーに出現しプロセスを終了するまで消えない状態となります。「GDI+ Window」を検索しても有力な記事を見つけることができませんでした。(驚速XPがなんたらという記事がありますが、使用していません)

なんらかのアプローチにより、1点目の問題が解決したとしても、この2点目自体も非常に気になっており、ここで出現している「GDI+ Window」とは何者なのか?また、同プロセスIDを列挙する中から「GDI+ Window」だけを特定することは可能なのでしょうか?(できればウィンドウタイトルで判別する以外のアプローチ)

まったく別のアプローチからの解決策でも、ぜひご教授頂きたいのですが、上記疑問も解消できればうれしいと思っていますので、各々ご回答頂ければと思います。
IsWindowVisible 関数とか。
一番の問題は、起動時のMainWindowがHideされてしまっている点でしょうネ!
2番目に表示されているWindowをEnumWindowで検索して最前面化するのは正攻法
でしょうが、汎用化は難しいかと・・・

ややこしい方法になりますが、.NETリモーティングで、自分を最前面化する機能
を呼び出すインターフェースを別途作って、多重起動時にその機能をキックする
とか・・・

それとも最初に起動するフォームをHideしなくてもよい方法に変更するとか。

多重起動の部分では、シングルインスタンス機能に変更することはできないので
しょうか?そうすれば、自分自身がいつもトップレベルウィンドウとなれるよう
にフォームの表示時に細工するだけでよい・・・

回避策と言うか、方法は数種類あるので、仕様を融通できるのであれば、変更す
るのも柔軟な対応と思いますが。

以上。参考まで
Hongliangさん、返信有難う御座います。

> IsWindowVisible 関数とか。
IsWindowVisible()を使用してみたのですが、例の「GDI+ Window」も表示されてしまい断念しました。。。
オショウさん、返信有難う御座います。

汎用化は難しそうですか・・・
できれば各ウィンドウ毎に処理を埋め込むのは避けたいところですが。。。

やろうと思えば色々考えうるということですね。参考になります。

一番の疑問はやはり「GDI+ Window」ですね。
一体なにものなのか・・・
> 一番の疑問はやはり「GDI+ Window」ですね。
> 一体なにものなのか・・・

  解決する方法はありますが・・・
  OSは何?

  そのプロセスにアタッチして、最前面化するソースコードを
  公開しているサイトはあります。

  Googleで検索したらヒットしますヨ!

  因みに、Vista以降でしたら、プロセスにアタッチする段階で
  管理者権限必要だったかも。

以上。参考まで
オショウさん。回答ありがとうございます。

返信遅れすいません。

OSはXPになります。

サンプルは「GDI+ Window」に言及したものを見つけることができませんでした。。。

改めて色々探してみたいと思います!
> 改めて色々探してみたいと思います!

  http://d.hatena.ne.jp/gsf_zero1/20071211/p1

  では、これは如何?

※ Vista/Win7では、多分、管理者権限が必要かな〜
  XPなら大丈夫かと。

以上。参考まで
オショウさん。回答有難う御座います。

リンク頂いた処理を試してみたいと思います。
ただ、もっと楽にできたらいいですね^^;

WndProcまでオーバーライドすると・・・
でも、確かにそこからターゲットになるウィンドウのハンドルが取れるのであれば確実ですね。
解決チェック忘れていました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板