0

システムリソースを大量に消費するシステム監視プログラムがあります。フォームがユーザーに表示されているときにのみ、プログラムがタスクを実行することを願っています。1 つの方法は、フォームがフォアグラウンド ウィンドウかアクティブ ウィンドウかを確認することです。

しかし、フォームがアクティブ化されていないのにユーザーに表示されている場合 (たとえば、次の図では 2 つのウィンドウが表示されています。そのうちの 1 つのウィンドウはアクティブ化されていませんが、ユーザーに表示されています)、状況をうまく処理できません。

ウィンドウの例 http://www.chip.de/ii/117599040_a933fb45fe.gif

何か案は?ありがとうございます。

編集:同僚の提案に従って解決策を見つけました。

これが私の解決策です:

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
    }

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool IsZoomed(IntPtr hwnd);

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool IsWindowVisible(IntPtr hwnd);

    [DllImport("user32.dll", EntryPoint = "GetWindow", SetLastError = true)]
    static extern IntPtr GetNextWindow(IntPtr hWnd, uint cmd);

    [DllImport("user32.dll", EntryPoint = "GetWindowText", SetLastError = true)]
    public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

    [DllImport("user32.dll", EntryPoint = "GetForegroundWindow")]
    private static extern IntPtr GetForegroundWindow();

    //I have made some simplifications. My form is maximized. If the form is not 
    // maximized, you should calculate the region of current form and top level form
    // to check it.
    private bool IsShowing()
    {
        if(this.Visible == false || this.WindowState = FormWindowState.Minimized)
            return false;

        IntPtr currentHandler = this.Handle;

        if (currentHandler == GetForegroundWindow())
            return true;

        while (currentHandler != GetForegroundWindow())
        {
            IntPtr hwnd = GetNextWindow(currentHandler, (uint)GetWindow_Cmd.GW_HWNDPREV);

            currentHandler = hwnd;

            if (IsZoomed(currentHandler) && IsWindowVisible(currentHandler))
            {
                StringBuilder sb = new StringBuilder(255);
                GetWindowText(currentHandler, sb, sb.Capacity + 1);
                Debug.WriteLine("masked by:" + sb.ToString());
                return false;
            }
        }

        if (IsZoomed(currentHandler) && IsWindowVisible(currentHandler))
        {
            StringBuilder sb = new StringBuilder(255);
            GetWindowText(currentHandler, sb, sb.Capacity + 1);
            Debug.WriteLine("masked by:" + sb.ToString());
            return false;
        }

        return true;
    }
4

1 に答える 1

0

いつタスクを実行するかしないかは明確ではありませんが、いずれにせよ、フォームのアクティブ状態または可視状態が変化したときにシステムに通知させることが最善の方法だと思います。この場合、アクティブ化および非アクティブ化タスクのコードをフォーム イベントの Activated、Deactivate、および/または VisibleChanged に記述する必要があります。

MSDN から

Deactivate : フォームがフォーカスを失い、アクティブなフォームではなくなったときに発生します。

Activated : フォームがコードまたはユーザーによってアクティブ化されたときに発生します。

VisibleChanged : Visible プロパティ値が変更されたときに発生します。

フォームの読み込みと終了におけるイベントの順序を示すこの記事を参照することも役立ちます。

于 2013-11-09T08:52:31.777 に答える