none
フォームを非アクティブで最前面に表示させたいのですがどうしたらよいでしょうか。

    質問

  • New-Object System.Windows.Forms.Form を使用してフォーム(ウィンドウ)を表示させるのですが最前面に表示させて、かつそのフォーム(ウィンドウ)にフォーカスがあたらないようにしたいと考えています。

    formのプロパティにフォーカスがあたらないようにするものがないことはわかったのですが、C#や.NET、VBではShowWithoutActivationを使用して実現できるような情報がありました。$form.Topmost=$trueでは、最前面に表示されますがフォーカスを奪ってしまいます。

    PowershellからC#などの多言語を呼び出して使用することが可能内容ですが、ShowWithoutActivationを使用できるような記述の仕方がわかりません。

    単純に表示させるだけのフォームですが、表示したときに既存のアクティブウィンドウからフォーカスを奪いたくないのですが際前面に表示させたいと考えています。

    以下、単純にフォームを表示するスクリプトですが、どのようにすればフォーカスを奪わずに最前面に表示させることができるかご教授いただけないでしょうか。宜しくお願い致します。

    <test.sp1>

    Add-Type -AssemblyName System.Windows.Forms
    $form = New-Object System.Windows.Forms.Form 
    $form.size = "300,100"
    $form.Showdialog()

    2018年3月16日 15:30

回答

  • こんな?

    $cs =@'
    using System;
    using System.Windows.Forms;
    public static class FormFactory
    {
        public static System.Windows.Forms.Form CreateNoneActiveForm(bool neverActivate)
        {
            if (neverActivate)
            {
                return new Form1();
            }
            else
            {
                return new Form2();
            }
        }
    
        private class Form1 : Form
        {
            public Form1()
            {
                this.ShowInTaskbar = false;
                this.MinimizeBox = false;
                this.MaximizeBox = false;
                this.TopMost = true;
            }
    
            protected override CreateParams CreateParams
            {
                get
                {
                    const int WS_EX_NOACTIVATE = 0x8000000;
                    var p = base.CreateParams;
                    p.ExStyle = p.ExStyle | WS_EX_NOACTIVATE;
                    return p;
                }
            }
        }
        private class Form2 : Form
        {
            protected override bool ShowWithoutActivation
            {
                get { return true; }
            }
        }
    }
    '@
    
    Add-Type -AssemblyName System.Windows.Forms 
    Add-Type -TypeDefinition $cs -Language CSharp -ReferencedAssemblies System.Windows.Forms
    
    [System.Windows.Forms.Form] $frm = [FormFactory]::CreateNoneActiveForm($true)
    $frm.ShowDialog()



    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク nhy67ujm 2018年3月17日 4:11
    2018年3月16日 23:18

すべての返信

  • こんな?

    $cs =@'
    using System;
    using System.Windows.Forms;
    public static class FormFactory
    {
        public static System.Windows.Forms.Form CreateNoneActiveForm(bool neverActivate)
        {
            if (neverActivate)
            {
                return new Form1();
            }
            else
            {
                return new Form2();
            }
        }
    
        private class Form1 : Form
        {
            public Form1()
            {
                this.ShowInTaskbar = false;
                this.MinimizeBox = false;
                this.MaximizeBox = false;
                this.TopMost = true;
            }
    
            protected override CreateParams CreateParams
            {
                get
                {
                    const int WS_EX_NOACTIVATE = 0x8000000;
                    var p = base.CreateParams;
                    p.ExStyle = p.ExStyle | WS_EX_NOACTIVATE;
                    return p;
                }
            }
        }
        private class Form2 : Form
        {
            protected override bool ShowWithoutActivation
            {
                get { return true; }
            }
        }
    }
    '@
    
    Add-Type -AssemblyName System.Windows.Forms 
    Add-Type -TypeDefinition $cs -Language CSharp -ReferencedAssemblies System.Windows.Forms
    
    [System.Windows.Forms.Form] $frm = [FormFactory]::CreateNoneActiveForm($true)
    $frm.ShowDialog()



    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク nhy67ujm 2018年3月17日 4:11
    2018年3月16日 23:18
  • ご回答ありがとうございます。

    記載いただいたコードを実行してみました。

    コマンドプロンプトからPowershell.exe Script.ps1 というように実行しています。

    この場合想定していた動作となりました。最前面でアクティブにならずに表示することができました。

    次の場合は、想定どおりの動作となりませんでした。

    スクリプトを実行した後にコマンドプロンプト以外のウィンドウをアクティブにしていると最前面に表示されなくなりました。

    フォームの中にボタンをつけたくて$frm.Showdialog()の前に$frm.Controls.AddRange($Button)でボタンを追加したところ最前面に常に表示されるようになりました。

    目的は達成することができました。

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

    • 編集済み nhy67ujm 2018年3月17日 4:11
    2018年3月17日 0:36