문제

양식이 비활성화 될 때 어떤 창이 초점을 맞출 것인지 결정하는 방법을 아는 사람이 있습니까?

도움이 되었습니까?

해결책

나는 대답을 찾았다. 활성화 및 비활성화 이벤트를 구독하는 대신 wm_activate WNDPROC의 메시지 (활성화 및 비활성화에 사용). 창의 핸들이 활성화되고 있다고보고하기 때문에 해당 핸들을 내 양식의 핸들과 비교하고 초점이 그 중 어느 쪽이든 변경되는지 결정할 수 있습니다.

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);  
} 

편집하다: 이 방법은 적용되는 창 밖에서 (예 : 팝업 창의 외부)를 사용할 수 있습니다.

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);
        } 
    }
}

다른 팁

당신은 Form.ActiveForm 정적 속성.

자동 완성 팝업 창을 구현할 때 동일한 문제가 있습니다 (VS의 IntelliSense 창과 유사).

문제 WndProc 접근 방식은 팝업을 호스팅하는 모든 양식에 코드를 추가해야한다는 것입니다.

대안적인 접근 방식은 타이머를 사용하고 양식을 확인하는 것입니다. 이런 식으로 코드는 더 잘 캡슐화됩니다. 편집기 컨트롤 또는 팝업 양식 내에서.

Form _txPopup;

// Subscribe whenever convenient
public void IntializeControlWithPopup(Form _hostForm)
{
    _hostForm.Deactivate + OnHostFormDeactivate;
}

Timer _deactivateTimer;
Form _hostForm;
void OnHostFormDeactivate(object sender, EventArgs e)
{
    if (_deactivateTimer == null) 
    {
        _mainForm = sender as Form;
        _deactivateTimer = new Timer();
        _deactivateTimer.Interval = 10;
        _deactivateTimer.Tick += DeactivateTimerTick;
    }
    _deactivateTimer.Start();
}

void  DeactivateTimerTick(object sender, EventArgs e)
{
    _deactivateTimer.Stop();
    Form activeForm = Form.ActiveForm;
    if (_txPopup != null && 
        activeForm != _txPopup && 
        activeForm != _mainForm) 
    { 
        _txPopup.Hide(); 
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top