4

WPF プロジェクトに次の C# コードがあります。

private static void RunConfig(string owner)  
{  
    long ownerHandle;  
    var settingsWindow = new SettingsWindow();  
    if (long.TryParse(owner, out ownerHandle))  
    {  
        WindowInteropHelper helper = new WindowInteropHelper(settingsWindow);  
        helper.Owner = new IntPtr(ownerHandle);  
    }  
    settingsWindow.ShowDialog();  
}

SettingsWindow は、オーナー ウィンドウに対して適切にモーダルではありません (つまり、SettingsWindow がまだ開いているときに、オーナー ウィンドウに集中したり、対話したり、閉じたりすることさえできます)。私は何を間違っていますか?

文脈上、このコードはスクリーン セーバー プログラムの一部であり、オーナー ウィンドウはコントロール パネルのスクリーン セーバー選択ウィンドウです (コマンド ライン パラメーターを介してオーナーとして使用するハンドルを渡します)。IF ステートメントが true と評価され、ハンドルを正しく解析していることはわかっています。

また、ここで簡単に説明され、使用法がここに示されている(x64用にコンパイルするため、使用しない)方法をSetWindowLongPtr使用してみました。このメソッドは WinForms では機能しますが、WPF では機能しないようです。助けてオビ=ワン・ケノービ、あなただけが頼りです。user32.dllSetWindowLong

4

1 に答える 1

7

WindowInteropHelperネイティブ ウィンドウを WPF ウィンドウの所有者として設定することは機能しますが、すべての機能を実行するわけではありません。このように設定すると、ネイティブ ウィンドウにフォーカスがある場合でも、WPF ウィンドウはネイティブ ウィンドウの上に表示されたままになります。ただし、得られる効果はそれだけです。WPF Window はネイティブ Window との対話を妨げません。WPF Window を閉じたり、影響を受けたりすることなく、ネイティブ ウィンドウを閉じることもできます。

残りの目的の動作を実現するには、WPF ウィンドウを呼び出す前にEnableWindow関数user32.dllを使用してネイティブ ウィンドウを無効にしShowDialog、WPF ウィンドウが閉じたら再度有効にする必要があります。

変更されたコードは次のようになります。

private static void RunConfig(string owner)
{
    long ownerHandle;
    var settingsForm = new SettingsWindow();
    if (long.TryParse(owner, out ownerHandle))
    {
        WindowInteropHelper helper = new WindowInteropHelper(settingsForm);
        helper.Owner = new IntPtr(ownerHandle);
        NativeMethods.EnableWindow(helper.Owner, false);
        settingsForm.ShowDialog();
        NativeMethods.EnableWindow(helper.Owner, true);
    }
    else
    {
        settingsForm.ShowDialog();
    }
}

(注: 上記のコードは一般的に正しいですが、このコードが実際に使用されているスクリーン セーバーの場合は不完全です。このコードがスクリーン セーバーの構成ウィンドウに使用されている場合、オーナー ハンドルに渡される文字列は、オーナーとして使用されるコントロール パネル ウィンドウのハンドルではなく、コントロール パネル ウィンドウの子であるコントロールのハンドルです。この場合の追加の手順は、ハンドルを取得することです。そのコントロールの親の. これは、渡されたハンドルGetParentでを呼び出して行うことができますuser32.dll. これにより、所有者に使用したい実際のハンドルが返され、EnableWindow呼び出しが行われます.)

Microsoft の誰かがこれを見つけた場合は、モーダル ウィンドウの適切な完全な動作であるため、が割り当てられて使用さWindowInteropHelperれるときに、これらすべてを適切に設定するように変更することを検討してください。OwnerShowDialog

于 2013-01-18T00:06:20.877 に答える