본문 바로가기
MFC

Switch MDI Active

by leo21c 2019. 11. 15.

MDI에서 ChildForm이 여러개 존재하는데 그 ChildForm을 사용자가 Active로 변경하고 싶을 경우가 있다.
여러개의 Sub Dialog가 열린 상태에서 Dialog를 선택하면 그 Dialog의 ChildForm이 Active 되게 처리를 해야 하는데 이럴 경우에 MFC에서는 WM_MDIACTIVATE 메시지를 이용해서 처리를 할 수가 있다.

 

1. 먼저 Sub Dialog에서 포커스를 확인 하는 방법은 OnActivate을 이용한다.
 - MessageMap에 WIM_ONACTIVATE을 추가한다.
 - Dialog의 virtual 함수인 OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)를 추가한다.

 

2. OnActivate함수에서 nState를 이용해서 포커스 여부를 확인한다.

void DialogBase::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
    switch(nState)
    {
        case WA_INACTIVE:    //(0) 포커스를 잃었을 때
            TRACE(_T("(0) focus inactive\n"));
            break;
        case WA_ACTIVE:        //(1) 포커스를 얻었을 때 (마우스 클릭으로 포커스 얻은 경우 제외)
            TRACE(_T("(1) focus active\n"));
            break;
        case WA_CLICKACTIVE://(2) 마우스 클릭으로 포커스를 얻을 때
            TRACE(_T("(2) click focus\n"));        
            ::SendMessage(this->m_pParentWnd->GetSafeHwnd(), DIALOGBASE_CLICK_ACTIVE, nState, 0);
            break;
    }
}

 DialogBase는 ChildForm에서 생성한 창이다. ChildForm에서 MDI 변경을 확인하기 위해서 USER_MESSAGE를 만들었다.

 

3. ChildForm에서 DIALOGBASE_CLICK_ACTIVE를 받아 ActiveFrame과 선택한 창의 ChildForm과 비교해서 다르면 선택창을 Active Form으로 변경을 한다.

LRESULT ChildFrame::OnDialogBaseClickActive(WPARAM wParam, LPARAM lParam)
{
    CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->GetMainWnd();
    // Get the active MDI child window.
    CMDIChildWnd *pChild = (CMDIChildWnd*)pFrame->GetActiveFrame();

    if (this!= (ChildFrame*)pChild)
    {
        HWND hwnd = pFrame->m_hWndMDIClient;
        ::SendMessage(hwnd, WM_MDIACTIVATE, (WPARAM)this->GetSafeHwnd(), 0);
    }
    return 0;
}

ActiveChild를 변경하기 위해서는 WM_MDIACTIVATE를 이용한다.

SendMessage (hwndClient, WM_MDIACTIVATE, (WPARAM)hWnd, 0);

위와 같이 MDI 클라리언트에 메시지를 보낸다.
hwndClient는 MDI 클라이언트 영역의 핸들, hWnd는 열고자 하는 창의 핸들입니다.