본문 바로가기
C & C++/MFC 컨트롤

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

by izen8 2013. 7. 5.
반응형

 

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

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

아래 소스로 해결

'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도 활성화 된다는 것.


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

 

 

 

반응형

댓글