DOBON.NETプログラミング道掲示板
(現在 過去ログ3 を表示中)

[ 最新記事及び返信フォームをトピックトップへ ]

■34203 / inTopicNo.1)  起動ディスプレイの指定方法について
  
□投稿者/ masa 一般人(1回)-(2019/04/02(Tue) 09:51:32)
  • アイコン環境/言語:[C#、.NET Framework 4.5.2] 
    分類:[.NET] 

    いつもお世話になっております。

    現在、C#のWidowsアプリを作成しており、起動したPCがマルチウィンドウの場合、必ず「メインウィンドウ(PrimaryWindow)」に起動するように制御したいのですが、どうやればよいのかわかりません。

    ウィンドウ(Form)の場合には、ウィンドウの一覧を取得し、PrimaryWindowの座標を取得し、ウィンドウ座標をその位置に移動するという方法で制御できました。
    foreach (Screen s in Screen.AllScreens)
    {
    if (s.Primary)
    {
    this.StartPosition = FormStartPosition.Manual;
    this.Location = s.Bounds.Location;
    break;
    }
    }

    今回困っているのが、MessageBoxの起動位置です。
    Program.csにて処理してメッセージを表示しているのですが、MessageBoxの起動位置をメインウィンドウに指定する方法がわかりません。
    MessageBoxは「現在アクティブなウィンドウ」に起動することは分かっているのですが、このアクティブなウィンドウをメインウィンドウへ変更するようなことは可能なのでしょうか?

    お手数おかけしますがどなたかご教授下さい。
引用返信 削除キー/
■34204 / inTopicNo.2)  Re[1]: 起動ディスプレイの指定方法について
□投稿者/ 魔界の仮面弁士 大御所(1220回)-(2019/04/02(Tue) 13:06:45)
  • アイコン2019/04/02(Tue) 13:37:01 編集(投稿者)

    No34203に返信(masaさんの記事)
    > foreach (Screen s in Screen.AllScreens)
    > {
    >  if (s.Primary)
    Screen.AllScreens を使うよりも
    Screen.PrimaryScreen を使う方が手っ取り早いかと。


    > this.Location = s.Bounds.Location;
    .Bounds.Location ではなく、
    .WorkingArea.Location を使うべきです。

    表示位置を Bounds の左上にしてしまうと、
    タスクバー(あるいはそれに類するウィンドウ)が、
    画面の左端または上端に最前面表示で
    配置されていた場合に問題が生じます。



    > MessageBoxは「現在アクティブなウィンドウ」に起動することは分かっているのですが、
    > このアクティブなウィンドウをメインウィンドウへ変更するようなことは可能なのでしょうか?
    MessageBox.Show の第一引数(IWin32Window 型)に、
    PrimaryScreen 上にあるウィンドウ(Form や NativeWindow など)を
    渡すことで、プライマリ側の画面に表示されると思います。


    もし、PrimaryScreen 側に移動するだけでは不足で、
    その表示位置までも変更したいという要件の場合は、
    少々面倒ですが、API を使って下記の手順で対処することになります。

    SetWindowHookExW API に WH_CBT を指定して自スレッドをフックし、
    それによって通知される CBTProc のコールバックデリゲートにおいて、
    第 1 引数 int nCode が CBT_ACTIVATE (== 5) であった際に、
    第 2 引数 IntPtr wParam で示されるウィンドウハンドルに対して
    SetWindowPos API で位置(必要ならサイズも)指定する感じです。

    フックの後始末のために、UnhookWindowsHookEx API を呼び出すことも忘れずに。

    https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowshookexw
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms644977.aspx
    https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unhookwindowshookex
引用返信 削除キー/
■34207 / inTopicNo.3)  Re[2]: 起動ディスプレイの指定方法について
□投稿者/ masa 一般人(3回)-(2019/04/02(Tue) 15:27:47)
  • アイコン2019/04/02(Tue) 15:30:13 編集(投稿者)
    2019/04/02(Tue) 15:28:41 編集(投稿者)
    2019/04/02(Tue) 15:28:36 編集(投稿者)

    No34204に返信(魔界の仮面弁士さんの記事)

    魔界の仮面弁士さんご返答ありがとうございます。

    FormがPrimaryWindowに変更する例は元々Primary「ではない」ウィンドウへ移動する例でしたのでこのような処理になっていて、それをそのまま載せたのでループして検索する処理になっています。

    画面座標も、Formがフルスクリーンのアプリケーションでしたので座標はPrimaryWindowの範囲内ならどこでもよかったためこのような処理になっています。

    今回質問したかった内容とは関係なかった(Formの移動の仕方は分かってますという意味で載せただけ)ので、そのまま載せました。
    説明なくスミマセンでした。


    > MessageBox.Show の第一引数(IWin32Window 型)に、
    > PrimaryScreen 上にあるウィンドウ(Form や NativeWindow など)を
    > 渡すことで、プライマリ側の画面に表示されると思います。

    ということですが、今回困っているのは「Program.cs」での処理です。
    ですのでFormが表示される前の話で、第一引数に何も指定できない場合の話です。
     ※起動している他ウィンドウも何もない状態

    「第一引数に何も渡さない=現在アクティブなウィンドウに起動」なので、
    この状態で、どのように制御すればいいのか困っていての質問です。
引用返信 削除キー/
■34208 / inTopicNo.4)  Re[3]: 起動ディスプレイの指定方法について
□投稿者/ 魔界の仮面弁士 大御所(1221回)-(2019/04/02(Tue) 15:52:44)
  • アイコンNo34207に返信(masaさんの記事)
    > ということですが、今回困っているのは「Program.cs」での処理です。
    > ですのでFormが表示される前の話で、第一引数に何も指定できない場合の話です。

    Program.cs でも一緒ですよ。

    非表示でも構わないので、ダミーウィンドウを PrimaryScreen に配置して
    それを第一引数に指定するか、もしくはフックして SetWindowPos するかのいずれかです。
引用返信 削除キー/
■34210 / inTopicNo.5)  Re[4]: 起動ディスプレイの指定方法について
□投稿者/ masa 一般人(4回)-(2019/04/02(Tue) 18:39:11)
  • アイコンNo34208に返信(魔界の仮面弁士さんの記事)

    ご返答ありがとうございます。

    なるほど、ダミーのウィンドウを作成してみればよいのですね。
    早速、newしただけの空FormにPrimaryScreenのLocationを指定し、
    そのFormをMessegeBoxの第一引数に渡したところ、期待する動作をしました。

    Form form = new Form();
    form.Location = Screen.PrimaryScreen.Bounds.Location;
    MessageBox.Show(form, "test");


    こういうことで合っていますでしょうか?
引用返信 削除キー/
■34211 / inTopicNo.6)  Re[5]: 起動ディスプレイの指定方法について
□投稿者/ 魔界の仮面弁士 大御所(1222回)-(2019/04/02(Tue) 19:35:13)
  • アイコンNo34210に返信(masaさんの記事)
    > 早速、newしただけの空FormにPrimaryScreenのLocationを指定し、
    > そのFormをMessegeBoxの第一引数に渡したところ、期待する動作をしました。

    そんな感じで OK です。
    作成したダミーフォームは、不要になった時点で Dispose しておきましょう。


    API でフックして移動させるサンプルもありましたので、紹介しておきます。
    MessageBox の位置をピクセル単位で指定したい場合はこれで。
    https://www.ipentec.com/document/csharp-show-message-box-in-center-of-owner-window
引用返信 削除キー/
■34212 / inTopicNo.7)  Re[6]: 起動ディスプレイの指定方法について
□投稿者/ masa 一般人(5回)-(2019/04/03(Wed) 08:39:25)
  • アイコンNo34211に返信(魔界の仮面弁士さんの記事)

    ご教授ありがとうございました。

    APIでフックして移動させるサンプルも拝見してみます。
    これにて解決済みとします。

    ありがとうございました。
解決み!
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

Mode/  Pass/


- Child Tree -