确定表单被停用时激活的位置

Zac*_*son 4 .net focus lost-focus winforms

有没有人知道在停用表单时确定哪个窗口将获得焦点的方法?

Zac*_*son 7

我找到了答案.在WndProc中处理WM_ACTIVATE消息(用于激活和取消激活),而不是订阅激活和取消激活事件.由于它报告窗口的句柄被激活,我可以将该句柄与我的表单的句柄进行比较,并确定焦点是否正在改变它们中的任何一个.

const int WM_ACTIVATE = 0x0006;
const int WA_INACTIVE = 0;
const int WA_ACTIVE = 1;  
const int WA_CLICKACTIVE = 2;  

protected override void WndProc(ref Message m)  
{  
    if (m.Msg == WM_ACTIVATE)  
    {  
         // When m.WParam is WA_INACTIVE, the window is being deactivated and
         // m.LParam is the handle of the window that will be activated.

         // When m.WParam is WA_ACTIVE or WA_CLICKACTIVE, the window is being 
         // activated and m.LParam is the handle of the window that has been 
         // deactivated.
    }  

    base.WndProc(ref m);  
} 
Run Code Online (Sandbox Code Playgroud)

编辑:此方法可以在其应用的窗口之外使用(例如,在弹出窗口外部).

您可以使用NativeWindow根据其句柄附加到任何窗口并查看其消息循环.请参阅以下代码示例:

public class Popup : Form
{
    const int WM_ACTIVATE = 0x0006;
    const int WA_INACTIVE = 0;
    private ParentWindowIntercept parentWindowIntercept;

    public Popup(IntPtr hWndParent)
    {
        this.parentWindowIntercept = new ParentWindowIntercept(hWndParent);
    }

    private class ParentWindowIntercept : NativeWindow
    {
        public ParentWindowIntercept(IntPtr hWnd)
        {
            this.AssignHandle(hWnd);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_ACTIVATE)
            {
                if ((int)m.WParam == WA_INACTIVE)
                {
                    IntPtr windowFocusGoingTo = m.LParam;
                    // Compare handles here
                }
            }

            base.WndProc(ref m);
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)