C & C++/MFC 컨트롤

다이얼로그 작업표시줄에서 감추기기(이중 다이얼로그)

izen8 2013. 7. 5. 14:27

 

같은 프로젝트를 사용하는 다이얼로그 화면인데

왼쪽화면은 작업표시줄에 화면이 표시 되지않았고 오른쪽 다이얼로그는 작업표시줄에 표시되는 상황 발생... ㅡㅡ

아래 소스로 해결

'OnInitDialog' 에다가 다음 한줄을 넣어주면 해결된다.

 

ModifyStyleEx( WS_EX_APPWINDOW,WS_EX_TOOLWINDOW, 0 );

 

퍼온글
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 CDialog에 기반한 App를 개발할때, 작업표시줄에서 대화상자를 감추고 싶을때 써먹어 보자.
(WTL 프로젝트지만, MFC 프로젝트에도 약간만 바꾸면 쉽게 적용할 수 있다)가장 간단한 방법은?
OnInitDialog에다가 다음 한줄을 박아주면 된다.


ModifyStyleEx( WS_EX_APPWINDOW,WS_EX_TOOLWINDOW,0 )
LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) {     ...     ModifyStyleEx( WS_EX_APPWINDOW,WS_EX_TOOLWINDOW,0 );     return TRUE; }
참 쉽죠?-ㅅ-;
그런데!! 여기서 문제는, 작업표시줄에서 사라지면서 이녀석이 포커스를 잃게 되면 다시 활성화 시키기 귀찮아 진다는거다.

내가 원한 기능은 작업표시줄에는 표시되지 않고, Alt + Tab을 이용해서는 활성화 시킬 수 있어야 한다는 건데.. 
이 방법으로는 Alt + Tab을 통해 활성화 할 수 없었다. 아예 사라져 버리더군 orz...



그래서 두시간의 개삽질-_-끝에 다음과 같은 꽁수로 해결했다.


1. 우선 아무것도 안하는 바보 윈도우를 하나 만든다.
class CInvisibleWnd : public CWindowImpl<CInvisibleWnd > { public:     DECLARE_WND_CLASS(NULL);     BEGIN_MSG_MAP(CInvisibleWnd) END_MSG_MAP() };
(MFC의 경우라면 이 과정은 필요없다.)


2.  MFC라면 CWinApp::InitInstance()에서, WTL이라면 Run()에서 Dialog를 생성할 것이다.
그 시점에서 Dialog의 부모 윈도우로 바보윈도우를 설정해 준다.
눈치 채셨겠지만, 이 꽁수의 핵심은 Dialog의 부모로 설정한 바보윈도는 화면에 표시되면 안된다는 점이다.

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT) {     ...     CInvisibleWnd wndInvisible;     ATLASSERT( wndInvisible.Create( NULL, 0, NULL, WS_OVERLAPPEDWINDOW ) );     CMainDlg dlgMain;     if ( dlgMain.Create( wndInvisible ) == NULL )     {         ATLTRACE(_T("Main dialog creation failed!\n"));         return 0;     }     dlgMain.ShowWindow(nCmdShow);     int nRet = theLoop.Run();     _Module.RemoveMessageLoop();     if ( wndInvisible.IsWindow() )         wndInvisible.DestroyWindow();     return nRet; }
화면에 표시되지 않는 바보 윈도우를 만들고, Dialog의 부모로 설정해 준다.
그렇다. 바보 윈도는 화면에 표시되지 않고 있으니 작업표시줄에 나타나지 않지만, 인스턴스가 있으므로 Alt + Tab을 치면 나타난다!



MFC라면 좀 더 쉽다. CWindowImpl에서 상속된 바보 윈도는 따로 구현할 필요 없이 CWnd를 이용하면 된다.


BOOL CComaApp::InitInstance() {     ...     CWnd wndInvisible;     LPCTSTR pstrOwnerClass = AfxRegisterWndClass(0);     if (!wndInvisible.CreateEx(0,                             pstrOwnerClass,                             _T(""),                             WS_OVERLAPPEDWINDOW ,                             CW_USEDEFAULT,                             CW_USEDEFAULT,                             CW_USEDEFAULT,                             CW_USEDEFAULT,                             NULL,                             0 ))     {         TRACE(_T("failed to create invisible window"));         return FALSE;     }     CMainDlg dlg(&wndInvisible);     m_pMainWnd = &dlg;     dlg.DoModal();     if (wndInvisible.m_hWnd != NULL)         wndInvisible.DestroyWindow(); }
어쨌든 주의점은, 프로그램이 종료되는 시점에 바보윈도우도 함께 소멸시켜 줘야 한다는 점이다.


3. Dialog의 스타일을 작업표시줄에 표시되지 않도록 설정한다.


LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    ...

    ModifyStyleEx( WS_EX_APPWINDOW,0 );
    return TRUE;
}



결론은 바보 윈도우에서 Dialog를 띄웠으므로 Alt + Tab을 통해 바보윈도우에 접근하면 Dialog도 활성화 된다는 것.


...나날이 꽁수만 늘어 가는구나 -_-;