양식이 비활성화 될 때 활성화가 어디로 가는지 결정
-
03-07-2019 - |
문제
양식이 비활성화 될 때 어떤 창이 초점을 맞출 것인지 결정하는 방법을 아는 사람이 있습니까?
해결책
나는 대답을 찾았다. 활성화 및 비활성화 이벤트를 구독하는 대신 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();
}
}
제휴하지 않습니다 StackOverflow