11

私が扱う特定のウィンドウについて、特定のウィンドウがモーダルであるかどうかを確認する方法が必要です。

私が知る限り、それを正確に行う方法はありません。そのため、これを解決するにはいくつかの巧妙な回避策が必要です。

ヘルプをいただければ幸いです。

編集:GetWindow(、GW_OWNER)が失敗するのはなぜですか?:(

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll", SetLastError = true)]
    internal static extern IntPtr GetWindow(IntPtr hWnd, GetWindow_Cmd uCmd);
    [DllImport("user32.dll", ExactSpelling = true)]
    internal static extern IntPtr GetAncestor(IntPtr hwnd, GetAncestor_Flags gaFlags);
    [DllImport("user32.dll", SetLastError = false)]
    internal static extern IntPtr GetDesktopWindow();
    [DllImport("user32.dll", SetLastError = true)]
    internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    const UInt32 WS_DISABLED = 0x8000000;


    internal enum GetAncestor_Flags
    {
        GetParent = 1,
        GetRoot = 2,
        GetRootOwner = 3
    }

    internal enum GetWindow_Cmd : uint
    {
        GW_HWNDFIRST = 0,
        GW_HWNDLAST = 1,
        GW_HWNDNEXT = 2,
        GW_HWNDPREV = 3,
        GW_OWNER = 4,
        GW_CHILD = 5,
        GW_ENABLEDPOPUP = 6
    }



IntPtr _inspHwnd = FindWindow("rctrl_renwnd32", inspector.Caption); // searching for a window with this name
        if (_inspHwnd.ToInt32() != 0) // found window with this name
        {
            IntPtr _ownerHwnd = GetWindow(_inspHwnd, GetWindow_Cmd.GW_OWNER);
            if (_ownerHwnd.ToInt32() != 0)
            {
                IntPtr _ancestorHwnd = GetAncestor(_ownerHwnd, GetAncestor_Flags.GetParent);
                if (_ancestorHwnd == GetDesktopWindow())
                {
                    if (GetWindowLong(_ancestorHwnd, -16) == WS_DISABLED) 
                    { 
                        // inspector is probably modal if you got all the way here
                        MessageBox.Show("modal flag tripped");
                    }
                }
            }
        }
4

3 に答える 3

8

モーダルウィンドウは通常、所有者を無効にすることで機能します。所有者はトップレベルのウィンドウです。したがって、この状況をテストする場合は、ダイアログがモーダルであるかどうかを確認する必要があります。

  • HWNDが実際にはトップレベルのダイアログであり、子ウィンドウではないことを確認してください
  • 所有者を取得します(GetWindow(GW_OWNER))
  • 所有者自体がトップレベルウィンドウであることを確認します(例:GetAncestor(GA_PARENT)== GetDesktopWindow())
  • 所有者が無効になっていることを確認します(GetWindowLong(GWL_STYLE)&WS_DISABLED)

これで、すべての標準のWin32スタイルのモーダルダイアログをキャッチできます。

親と所有者は微妙に異なる概念であることに注意してください。ここで確認したいのは所有者です。GetParentが所有者を返す可能性があるため、これは混乱を招く可能性があります...-レイモンドチェンからの詳細はこちら

于 2011-04-26T00:13:38.353 に答える
2

BrendanMckのソリューションが常に正しいかどうかはわかりません。ウィンドウWが最初にモードレスダイアログAを表示し、次にモーダルダイアログBを表示するとします。AとBの両方が親ウィンドウとしてWを持っています。Bが表示された時点で、Wは無効になっているため、AとBの両方にアルゴリズムを適用すると、両方がモーダルダイアログとして報告されます。

于 2012-11-07T16:15:59.947 に答える
-1

コードを書い GetWindowLong(GetWindow(Hwnd, GW_OWNER), GWL_STYLE) & WS_DISABLED & WS_POPUP たところです。

于 2012-06-20T07:57:01.853 に答える