Form.ShowDialog(IWin32Window)は、任意のウィンドウハンドルで作業する必要がありますか?
-
06-09-2019 - |
質問
System.Windows.Forms.ShowDialog(IWin32Window)
を使用する場合は、、私は任意のウィンドウハンドルを表すIWin32Window
に通過することができ、それはそのウィンドウに対してモーダルである持っているか?
私は、Internet Explorerのタブに対するウィンドウのモーダルを開くしようとしているInternet Explorer 7の拡張の一環として。これは、現在選択されているタブはありませんが、私は、タブの[OK]のHWNDを取得することができます。しかし、私は自分のフォームをShowDialogのためにこれを渡す際には示されたが、それは何に対するモーダルではありませんされています。私はまだInternet Explorerで物事を行うことができ、所有者であるはずのタブ内に含みます。私のフォームは、Internet Explorerのウィンドウの上に浮い示され、それが上にとどまるので、それだけで通常のフォームとして開かれています好きではないですが、それは正しくモーダルではありません。
スパイ++ を使用して、私は自分のフォームを見つけることができますし、それは所有者のハンドルが正しく設定されているのです。
これは何かが間違っている、または私が何か間違ったことをやっているということを意味していますか?どのように私は自分のフォームが正しくモーダル作るのですか?
ちなみに、私はIWin32Window
(感謝からhwnd
を作成するには、このラッパークラスを使用してい<のhref =「http://ryanfarley.com/blog/archive/2004/03/23/465.aspx」のrel = "nofollowをnoreferrer">ライアンの):!
/// <summary>
/// Wrapper class so that we can return an IWin32Window given a hwnd
/// </summary>
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}
UPDATE:Internet Explorer 7の&.NET 2.0を使用して
UPDATE:いくつかのより多く++、それが公開されるハンドルスパイで遊んで、私が見つけ、私は別のhwnd
を使用している場合、私はタブに私のウィンドウをモーダルに作ることができます:
hwndを使用していたhref="http://msdn.microsoft.com/en-us/library/aa752126(VS.85).aspx" rel="nofollow noreferrer">スパイ++でクラスTabWindowClass
として表示されますIWebBrowser2.HWNDドキュメントに、。それはInternet_Explorer_Serverの子を持つクラスShell DocObject View
、の子を持っています。私はhwnd
のInternet Explorer_Server
を使用する場合、それは例えば、正常に動作しますが、私は他のタブ上でマウスをクリックすると、Internet Explorerが正常に反応します。私が興味のタブをマウスでクリックすると、ウィンドウがD'ああ音と何もしません果たします。
私はまだプログラム的Internet_Explorer_Serverのhwnd
を取得する方法を知りませんが、それは可能なはずです。
また、他のウィンドウでプレイする私は、一般的に、他のアプリケーションとのダイアログに自分のフォームをモーダルに作ることができた扱いながら、それは、価値がある何のため。だから私は私の質問への答えが「多くのではなく、すべてのハンドル」です...多分それはアプリケーションに依存思う?
UPDATE:もう一つの側面ノート:私は、全体ではなく、ウィンドウのタブに私のフォームモーダルは、その所有者としてフォームを渡し、私のフォームからMessageBox
を開くときに、MessageBox
だろう常に開かれていないにしたかった元々の理由私のフォームの上に。 Internet Explorerの新しいタブがちょうど開いたが、アクティブではありませんでしたされていた場合、MessageBox
が隠されてしまうと、そのタブが点滅を開始します。ただし、Internet Explorer以来、私のフォームで無効になっていたInternet Explorerがフリーズされますので、そのタブに切り替えることはできませんでしたモーダル開きました。私はタブに私のフォームのモーダルを開くとこの問題を解決するだろうと思ったが、私は別の解決策はMessageBox
を使用しないようにすることです見つけた:私は私の最初のフォームから二番目の形式とShowDialog(this)
を使用するならば、2番目の形式は、正しく前面に開きます。だから、Form.ShowDialog()
は、いくつかのケースでMessageBox.Show()
より良い作品と思われます。 のでもっと議論モーダルダイアログやメッセージボックスの問題のの
解決
あなたのコードが正しいです。あなたはおそらくかかわらに実行されている問題は、IEがそのタブに関連するスレッドモデルを持っていることです。私は、正確な詳細を知らないが、ショートバージョンは、各タブには、おそらく他のタブとは別のスレッドで実行されているということです。
ダイアログのModal'nessは、ダイアログが実行されているスレッドに固有のものです。他のスレッドのUIは、別のスレッド上のモデルダイアログの影響を受けないだろう。それはあなたがこのような理由のために別のスレッドで実行されているタブにアクセスすることができます完全に可能です。
他のヒント
にShowDialog()は、2つの重要なことを行います。それは、呼び出し元のコードにモーダルに動作するように、メッセージループをポンピング開始します。そして、それはEnableWindow(偽)API呼び出しを使用してアプリケーション内の任意の他のウィンドウを無効にします。後者は、あなたのケースで何が起こっていないものです。無効にする必要がありますウィンドウがWFウィンドウではないことを考慮すると、全く驚くべきことではありません。
あなたはEnableWindow()を自分で呼び出す必要があります。ダイアログが閉じまたはWindowsへのフォーカスを与えるために別のアプリケーションのウィンドウのために狩りに行くする前にそれを再度有効にしてくださいます。
ここでライアン/ロリーのWindowWrapperコードのより簡潔なバージョンがあります
internal class WindowWrapper : IWin32Window
{
public IntPtr Handle { get; private set; }
public WindowWrapper(IntPtr hwnd) { Handle = hwnd; }
}
私は、IEの拡張子からこれを試したことがないが、私は勘を持っているIEではない「尊重」のWin32スタイルのモーダルウィンドウそれはwindow.open().
を使用して、JavaScriptから上げモーダルウィンドウを同じ方法かもしれない。
あなたはそれはそれは、他のアプリケーションのためにすべきであるように動作を確認するために、IE以外のものに対して、このコードをテストしたことがありますか?