モーダルで表示している場合のWindowsアプリケーションをアクティブ化するには?

解決


みなみ  2005-02-14 08:40:49  No: 119585

VB.NET初心者のみなみです。以前こちらへ書き込みしたとき、親切に教えて下さった方が多数いらしたので今回また質問しました。
VB.NETてシステム開発を行っています。特定のWindowsアプリケーションを
起動するときに、API関数でProcessを確認して存在すればアクティブにしているのですが、作成したWindowsアプリケーションの中でFormAからFormBをモーダルで表示した際に、どうしてもアクティブにする事が出来ません・・・(泣)
FormAがアクティブフォームのときは問題ないのですが。
どなたかご親切な方教えて下さい。初心者ですみません。
宜しくお願いします。


じゃんぬねっと  URL  2005-02-14 19:28:59  No: 119586

じゃんぬねっと です。

モーダル表示が何たるか、もう 1 度考えてみてください。


特攻隊長まるるう  2005-02-14 19:39:30  No: 119587

>モーダル表示が何たるか、もう 1 度考えてみてください。
うむうむ。モーダルとは何の関係も無いですよね?
Windows の仕様です。
[Form.Activate メソッド]MSDN(オンラインヘルプ)より抜粋
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemwindowsformsformclassactivatetopic.asp
>解説
>アクティブなアプリケーションであるフォームをアクティブにした場合は、
>そのフォームが最前面に移動します。アクティブなアプリケーションでは
>ないフォームの場合は、そのフォームのウィンドウ キャプションが点滅します。

>FormAがアクティブフォームのときは問題ないのですが。
アクティブでないという事は、ユーザが他のアプリで作業中だという
事ですので、最前面には出ないのが一般的な考え方です。アクティブな
フォームと最前面のフォームは異なります。モーダルの意味とも異なります。
そのあたりを区別せずに質問されていますので何が正しい結果なのか判断
できません。

それを踏まえた上で、重要なメッセージをユーザの作業を中断して最前面に
表示するなどの場合は .TopMost プロパティを設定してみてはどうでしょうか?。


みなみ  2005-02-14 20:09:04  No: 119588

特攻隊長まるるうさん、ご解答ありがとうございます。でもすみません、V6の経験もない初心者でよく分かりませんでした(>_<)
複数のFormを持つWindowsアプリケーションを実行させたときのプロセスって
そのWindowsアプリケーションのどのFormがアクティブの時も同じではないんですかねぇ?んっ、根本的な考え方が間違っているのでしょうか??・・・(T_T)


。。。  2005-02-14 21:24:12  No: 119589

>複数のFormを持つWindowsアプリケーションを実行させたときのプロセスって
>そのWindowsアプリケーションのどのFormがアクティブの時も同じではないんですかねぇ
だから何?
そこから何をどう推測するわけ?


特攻隊長まるるう  2005-02-14 22:29:44  No: 119590

同じアプリケーション内で起こっているんですか?…うーむ。違う
アプリケーションを立ち上げてた時には同じような状況になった事が
あるので…推測できなくは無いと思うんですが、原因を特定するには
もっと限定した条件でテストしてみないと何とも言えません。

いくつか考えられる原因は
1、
>API関数でProcessを確認して存在すればアクティブにしているのですが
の処理でアプリケーションがちゃんとアクティブになっていない。
[対策]その処理を調べなおす。
2、
>FormAからFormBをモーダルで表示した際に、どうしてもアクティブにする事が出来ません・・・(泣)
の処理でアクティブになるようなコードを書いていない。
[対策]アクティブになる条件を調べてその条件を満たすコードを書く。
3、
いくつかの条件が重なってアクティブにできない状態にある。
[対策]どの条件が関係してるか調べて回避できないか考える。

どれも調べないと分からない状態なので何とも言えません。
とりあえずボクに回答させようと思うなら上の条件のどれが
根本的な原因か?くらいは調べてサンプルコードを提供して
頂かないと…調べられないです。


みなみ  2005-02-14 22:30:31  No: 119591

推測といいますか、最初に書き込みしたように、
P1.exe →起動 →P2.exe(スタートフォームはFormA)
上記の時、P2.exeのプロセスが存在していれば、API関数(?)で最前面に表示したいのですが、P2.exeのアプリケーション側でFormAからFormBを呼び出している場合のときのみP2.exeのプロセスを最前面に表示させる事が出来ないのでございます・・・。なんか自分だけ分かっている様でスミマセン(T_T)


特攻隊長まるるう  2005-02-14 22:39:21  No: 119592

ああ、やっぱり複数アプリを立ち上げてますね…でも
>P2.exeのアプリケーション側でFormAからFormBを呼び出している場合のときのみ
というのがボクの経験した結果と違うんだよなぁ(^^;)
>FormAがアクティブフォームのときは問題ないのですが。
FormB を予備出さなければ問題ないんですよね?呼び出してる
部分のコードを公開してもらえませんか?。


特攻隊長まるるう  2005-02-14 22:54:44  No: 119593

…やっと過去ログ見つかった(汗)
OS が 2000 で SetForegroundWindow を使ってるなら↓このへんが原因かも?
http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200402/04020031.txt
つまり P1.exe がフォアグラウンドウィンドウとして有効なのでは?って事です。


みなみ  2005-02-14 23:51:03  No: 119594

>呼び出してる部分のコードを公開してもらえませんか?
FormAからFormBの呼び出しは、
Dim frm As New FormB
frm.ShowDialog(Me)
と至って普通の呼び出しなのですが・・・。
FormBを呼び出さなければ問題ないです!
ただ、ふと思ったのですが、FormBはInheritsで継承元のフォームが存在します。(何か関係なるのかなー?)
ちなみにOSはWinXP(SP2)です。
特攻隊長まるるうさんにはなんとなく状況が伝わっているので安心してます(^^♪


。。。  2005-02-15 00:17:16  No: 119595

>P2.exeのプロセスを最前面に表示させる事が出来ないのでございます
これが勘違いの元凶じゃないでしょうか。
「ウィンドウを最前面にする」なら分かりますが「プロセスを最前面にする」
なんて言葉は聞いた事がないです。

>呼び出してる部分のコードを公開してもらえませんか?。
とおっしゃっているのはFormBを呼び出しているコードじゃなくて
P2.exeのFormBを最前面にしようとしているP1.exeのコードを書いてくれ
ということなんじゃないでしょうか。

外してたらスミマセン


特攻隊長まるるう  2005-02-15 00:28:42  No: 119596

>特攻隊長まるるうさんにはなんとなく状況が伝わっているので安心してます(^^♪
いや、ゴメン。ボクの経験した状況と違うわ。状況自体はあまり
伝わってないデスw。…というか原因を特定する情報が少ないの。
えと、とりあえず
>frm.ShowDialog(Me)
の Me 削除して
   frm.ShowDialog()
にしてテストしてもらえます?。結果報告お願いします。

>>呼び出してる部分のコードを公開してもらえませんか?。
>とおっしゃっているのはFormBを呼び出しているコードじゃなくて
>P2.exeのFormBを最前面にしようとしているP1.exeのコードを書いてくれ
>ということなんじゃないでしょうか。
今回は FormB の呼び出しについて聞きたかったのでみなみさんの解釈で
合ってます。一応
[INFO] Form.ShowDialog メソッドの制限事項
http://support.microsoft.com/default.aspx?scid=kb;ja;841074
↑なんて記事とかもありますので…
ただ、フォアグラウンドウィンドウの問題なら。。。ご想像の通り
>P2.exeのFormBを最前面にしようとしているP1.exeのコードを書いてくれ
>ということなんじゃないでしょうか。
そっちに根本的な原因がある可能性大です。


みなみ  2005-02-15 00:52:11  No: 119597

結果報告です。
ShowDialog()で実行するとFormBが最前面にはくるのですが、FormBを最小化した場合、FormAが最前面にきます。ちなみに最小化はIsIconicで確認して、ShowWindowAsyncで元のサイズに戻してます。
やはりFormAはHideしたいって言うのがございまして・・・。他の方法でFormAを非表示にするとかすれば良いのですかねぇ?難しいです(T_T)


特攻隊長まるるう  2005-02-15 01:14:55  No: 119598

ここにきてじゃんぬねっとさんの書き込みが生きてきますねぇ。
>モーダル表示が何たるか、もう 1 度考えてみてください。
…考えられないくらいの先見の明で結果に結びつくからここの
掲示板に書き込む人の書き込みってコワいデスw。…というか
>FormAがアクティブフォームのときは問題ないのですが。
で分かってたんでしょうね(汗)。

↑の意味分かります?みなみさんはモーダル表示の使い方間違っ
てます。
>難しいです(T_T)
難しいのは良いんだけど、…何でボクが Me 削除したのか?その
結果が何で FormB が最前面に来るのか分かったのかなぁ?。
分かって無いならまた同じ失敗繰り返すだけだよ?。


みなみ  2005-02-15 01:24:41  No: 119599

・・・モーダル表示の使い方理解不足のようです。。。分かってたら書き込みしてなかったですかねぇ・・・(T_T)
簡単でも良いので解説して下さいマセm(__)m


特攻隊長まるるう  2005-02-15 03:28:39  No: 119600

普通はそこは自分で調べます。ってゆーかヒントとなる事も
ほぼ答えな事も既に書いてるんですが…(泣)。
『モーダルダイアログ』自体が分からないなら辞書で調べて下さい。
http://e-words.jp/w/E383A2E383BCE38380E383ABE38380E382A4E382A2E383ADE382B0.html
ヘルプでも、過去ログ検索でも、WEB検索でも情報はあります(必要な
情報に辿り着くには苦労するでしょうが、その過程で覚えるべき事が
存在します)。ボクは初心者でも調べれば分かる事をいちいち解説したり
しません。

今回、回り道をしてしまいましたが、アプリケーション1つ(P2.exe)
の中での問題でしたので実行アプリ(P2.exe)でアクティブなフォーム
が最前面に来ると考えます。以下、アクティブ = 最前面と解釈します。

既に書きましたが、モーダルとアクティブは意味が違います。
モーダル表示したらアクティブになるわけではありません。従って
みなみさんのコードはアクティブになるような条件が揃えられて
おらず、アクティブにするコードも書かれていなかった事になります。
…当然の結果だったわけです。

何故、引数の Me を削除して動きが変わったのかは、それぞれの関数の
ヘルプを読んで下さい。違う動作が記述されてます。
[Form.ShowDialog メソッドのオーバーロード一覧]MSDN(オンラインヘルプ)
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemwindowsformsformclassshowdialogtopic.asp

モーダル表示したウィンドウがアクティブになる必要があるのであれば
アクティブなウィンドウをオーナーウィンドウに指定してみて下さい。
(確かめてませんが(←確かめられない理由は以下↓))

ここからおまけ。
今回の問題、内容的には P2.exe 単体起動でも起こるハズです。
ハズってのはボクの環境(Win2000)ではモーダルダイアログが
アクティブで無いフォームを引き連れて最前面に出てきてしまう
からです(滅)。上の解説と真逆の事言ってますが見なかった事に…(ー人ー)。
New したフォームが最前面に出てる感も(?)暇が無いので調べませんが。
…で(ぇ、P2.exe 単体起動の質問であればじゃんぬねっとさんの
書き込みで解決してたでしょう。無駄な…とまでは言いたくない
ですが、回り道したくなければ問題点は切り分けて、少しでも限定
される質問を心がけると良いでしょう(ってゆーかそーしてもらえると
恥をかかなくて有難いですw)。

…しかしここで P2.exe 単体起動したらモーダルウィンドウが
最前面に出てきたりしたら…w。Xp マシンの方、ボク以外の 2000
マシンの方…ご報告をお待ちしておりますw。

以下サンプルテストコード////////////////////////
[VB.NET]
    Public Sub ShowDialogNewForm1()
        Dim wForm1 As New Form1
        With wForm1
            .Text = "孫"
            .ShowDialog() ' ←↓ここを変更して下さい。
            '.ShowDialog(Me)
            '.Show()
        End With
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim wForm As New Form1
        Me.Text = "親"
        With wForm
            .Text = "子"
            .Show()
            Me.Activate() '親フォームアクティブ
            System.Windows.Forms.Application.DoEvents()
            System.Threading.Thread.Sleep(1000)
            .ShowDialogNewForm1()
        End With
    End Sub


じゃんぬねっと  URL  2005-02-15 05:35:59  No: 119601

まるるう様からお褒め頂けるとは光栄です。

> > FormAがアクティブフォームのときは問題ないのですが。
> で分かってたんでしょうね(汗)。

実は、私は「そこ」しか見てませんでした。
だからこそ、ああいった答えになってしまいました。

C# で申し訳ない && 今さら感のある どうしようもないリンク
http://jeanne.wankuma.com/tips/process/03-activewindow.html

# 駄レス、申し訳ありませんm(_ _)m > 皆さま


みなみ  2005-02-15 06:35:30  No: 119602

みなさまありがとうございました。勉強になりました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加