0

私は、「MessageBox」に相当する機能をいくつか備えたクラス ライブラリを持っています。

メソッドを呼び出すとShowDialog(IWin32Owner)、これが機能し、フォームが親フォームの中央に表示されます。

ただし、このフォームがプロジェクトのクラスから呼び出されることがあるため、フォームの所有者にアクセスできません。この状況ではnullShowDialog()メソッドに渡すことができますが、これは「現在アクティブなウィンドウ」を認識せず、中央に表示していないようです。それは別のクラスライブラリにあるためだと思います。

ユーザーが作業している現在アクティブなフォーム (または少なくとも画面) を取得する方法はありますか?

編集

わかりました、これは FormStartPosition 列挙と関係があります。

これを使用する場合CentreScreen、MSDN に従って現在アクティブなモニターにデフォルト設定する必要があります。ただし、フォームがクラス ライブラリにある場合、これは既定のモニターに設定されているようです。

Ok:

これは問題のコードです:フォームを中央の画面に設定できません:

    public static DialogResult ShowYesNoCancel(string message)
    {
        using (frmMessage form = new frmMessage())
        {
            form.Text = @"Input Required";
            form.lblMessage.Text = message;
            form.btnNo.Visible = true;
            form.btnOK.Text = @"Yes";
            form.btnOK.DialogResult = DialogResult.Yes;
            form.StartPosition = FormStartPosition.CenterScreen;
            return form.ShowDialog();
        }
    }

解決策:

    /// <summary>
    /// Overridden to ensure its in the centre of the current screen
    /// </summary>
    /// <returns></returns>
    public new DialogResult ShowDialog()
    {
        Screen current = Screen.FromPoint(MousePosition);
        Rectangle s = current.WorkingArea;
        StartPosition = FormStartPosition.Manual;
        Location = new Point(s.Left + s.Width / 2 - Width / 2, s.Top + s.Height / 2 - Height / 2);
        return base.ShowDialog();
    }
4

3 に答える 3

1

これは、現在アクティブなモニターにデフォルト設定する必要があります

問題は次のとおりです。複数ある場合、「現在アクティブなモニター」はどれですか。2つ以上ある場合、それは混乱した質問になります。セカンダリモニターは、プライマリモニターよりも多かれ少なかれ「アクティブ」ではなく、ウィンドウを同様に表示できます。

Winforms が使用するヒューリスティックは、「マウス カーソルを表示するモニター」です。基になる呼び出しは次のとおりです。

  Screen desktop = Screen.FromPoint(Control.MousePosition);

MessageBox.Show() が所有者を見つけるために使用する動作をエミュレートする場合は、現在アクティブなウィンドウを見つけるようにコードを記述します。基礎となる winapi 呼び出しはGetActiveWindow()です。どの ShowDialog() が既に使用されているため、Winforms ウィンドウではないアクティブなウィンドウのように、目に見える以上のことが行われている可能性があります。ネイティブの MessageBox() winapi 関数は気にしませんが、ShowDialog() は気にします。これを診断するには、Spy++ を使用します。

于 2014-02-14T09:38:24.423 に答える
1

使用できますForm.ActiveForm

このアプリケーションの現在アクティブなフォームを取得します。

ただし、クラス ライブラリが UI を認識せずにこのメッセージを単独で表示しているという事実は、おそらく良い兆候ではありません。

于 2014-02-14T08:37:35.080 に答える
0

Form.ActiveFormアプリケーションのいずれかのフォームにフォーカスがある場合にのみ機能します。したがって、アプリケーションがバックグラウンドにある場合、それは役に立ちません。

Application.OpenForms代わりに使用してください。コレクション内の最後のアイテムを取得します。これは、最後のオープンエンド フォームを表します。

ShowInTaskBar などの特別なフォーム プロパティには注意してください。このコレクションには表示されない可能性があります。ここで説明: https://stackoverflow.com/a/3751748/2243584

于 2014-02-14T09:04:28.353 に答える