0

我有一个系统监控程序,它消耗大量系统资源。我希望程序仅在向用户显示表单时才运行任务。一种方法是检查窗体是前景窗口还是活动窗口。

但是如果表单没有激活但正在向用户显示(例如,您可以在下图中看到两个窗口,其中一个窗口没有激活但向用户显示),我无法很好地处理这种情况。

窗口示例 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:当窗体失去焦点并且不再是活动窗体时发生。

已激活:当表单在代码中或由用户激活时发生。

VisibleChanged:在 Visible 属性值更改时发生。

您还可以参考这篇文章,该文章显示了表单加载和关闭中的事件顺序

于 2013-11-09T08:52:31.777 回答