Dialog 창이 전체 화면에 뿌려지는것을 막고 싶습니다

안녕하세요? 고수는 절대 아니지만... 제가 아는 문제인것 같아서 답변을
적어봅니다.
^^;...
이 글은 님께서 Pocket PC Version으로 작업 하신다는 가정하에 말씀드립니다.
해주셔야 할 작업은 총 3개가 존재합니다.
그럼... ^^;...


1. PocketPC에는 멤버 변수로 m_bFullScreen를 가지고
있습니다.
  일반 WinCE Version에서 있는지는 잘 모르겠구요... ^^;...
  이 값은 기본적으로 TRUE로 설정되어 있습니다. 속성은 눈치
채셨듯이...
Full Screen으로 할지 안할지를 결정하는 인자입니다.
이 값만 바꿔준다면, 화면이 초기에 뜰때, 아마 최대화가 아닌 설정한
값으로,
다이얼로그 박스가 나타날 것입니다.
설정은.... 다이얼로그의 생성자 함수에서...
  m_bFullScreen = FALSE;              //
Full Screen 금지
이렇게 해주시면 됩니다.
위와 같이 한다고 하더라도 Pocket PC Version에서 보면 문제가 생깁니다.
  SIP던가요? 키보드를 위로 올리거나, 닫거나 하면 이넘의 다이얼로그가
허락도 안받구...
  지 맴데로 전체 창으로 가버립니다.
  희한한 화면 구성이 되는데요....
  이것은 SIP 관련 이벤트에 구현되어 있는 부분에 문제(?)가
있어서 그렇습니다.
  물론 MFC가 구현해준 부분이라 찾아야 하는데요...
  딱 2 부분만 고치면 됩니다.




2. 첫번째로 바꿔줘야 할 부분은
  OnActivate 이벤트입니다.
  dlgcore.cpp 파일을 열어서 찾아보면,
void CDialog::OnActivate(UINT nState, CWnd* pWndOther,  BOOL bMinimized)
{
       if (!(GetStyle() & WS_CHILD))
       {
               _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
               SHHandleWMActivate(m_hWnd, pThreadState->m_lastSentMsg.wParam,
                                  pThreadState->m_lastSentMsg.lParam, &m_sai, FALSE);
       }

       CWnd::OnActivate(nState, pWndOther, bMinimized);
}


이 부분을 찾으실 수 있을 겁니다.
이 부분에서 SHHandleWMActive를 호출하는데요.
MSDN에서 이 함수에 대해서 찾아보면 다음과 같이 나오는군요.
This function is used to help manage the input panel and your application.
In Windows for Pocket PC, when a window is activated, the input panel should
be restored to the state it was in when the window lost activation.
This function helps manage the restoration of the original state
해석을 보면...(참고루... 전 해석 능력이 짧은 관계로 영어랑 욜라 친한 울 회사분께서
번역해주셨음... ㅋㅋㅋ)
이 기능은 입력패널과 당신은 어플리케이션의 관리를 도울때 쓴다.
포켓PC용 윈도우 안에서, 하나의 창이 활성화 되었을 때,
입력 패널은 그 창이 비활성화 될 때 상태로 되돌려져야 한다.
이 기능은 원상태의 복원에 도움을 준다.


결국에는 이 함수를 호출해서 다이얼로그 창이 input panel 의 동작 상태에 따라서,
사이즈가 마음데로... 왔다갔다 하게 되죠.
CDialog의 OnActiveate 에서는 결국 하는 일은 저 함수를 호출 하는 일 밖에 없으므로,
님께서 구현하신 Dialog함수에서 OnActivate함수내부에서,
바로 CWnd::OnActivate를 호출하셔서 저 SHHandleWMActive를 호출하지 않도록
막으시면 될겁니다.
그럼... 다음과 같이...


void CUsrnDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)

{
       CDialog::OnActivate(nState, pWndOther, bMinimized);
}
이렇게 되어 있는 부분을요.. 주석으로 냅따~~~ 막아버리시구요.
CWnd::OnActivate를 호출하시면 될것입니다.


void CUsrnDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)

{
       // CDialog::OnActivate(nState, pWndOther, bMinimized);        // FullScrean금지를
위해 주석처리
       CWnd::OnActivate(nState, pWndOther, bMinimized);
}




3. 아직도 input pannel에 영향을 받을 겁니다.
그 이유는 바로 ON_WM_SETTINGCHANGE() 와 관련이
있는데요.
CDialog class내에 함수 구현된 부분을 찾아보면 다음과 같이 되어 있습니다.


void CDialog::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
       if (!(GetStyle() & WS_CHILD))
       {
               _AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();

               SHHandleWMSettingChange(m_hWnd, pThreadState->m_lastSentMsg.wParam,
                       pThreadState->m_lastSentMsg.lParam, &m_sai);
       }

       CWnd::OnSettingChange(uFlags, lpszSection);
}
이 부분의 SHHandleWMSettingChange함수를 MSDN을
찾아보면 다음과 같이 나올 것입니다.
This function is used to help manage the input panel and your application.
If hwnd should size based on the position of the input panel,
then call this function to size your window when the window receives the
WM_SETTINGCHANGE message.
해석을 보면... (역시 이 부분도 영어 고수님의 도움을 받아서... ㅋㅋㅋ, 아!~
난 왜 이리두 영어 실력이 짧은가... ㅡㅡa...)
이 기능은 입력패널과 당신 어플리케이션의 관리를 도울때 쓴다.
만약, hwnd 가 입력패널의 위치에 기반을 두고 어떤 크기로 만들어져야 한다고
가정을 한다면,
그 창이 WM_SETTINGCHANGE 메시지를 받을 때 당신의 창을 사이즈 하기 위해서
이 기능을 사용하라!


이 부분도 결국에는 다이얼로그 창이 마음데로 왔다갔다 하는 몰상식한(?) 기능을
수행하는데요.. ㅋㅋㅋ
이유는 다 아시겠지만 SHHandleWMSettingChange 이 함수를 호출하기 때문에 발생하는 문제입니다.
이 부분도 역시 위와 동일하게 바로 CWnd::OnSettingChange함수를 님께서 구현하신
Dialog 클래스내에서 저 함수를 구현해 놓으시고, 내부에 상위 CDialog 내의 OnSettingChange를 호출하시는게 아니라, 더 상위인 CWnd::OnSettingChange를 호출하시면 됩니다.


따라서 다음과 같이 멤버 함수로,
afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
을 헤더 파일에 넣어주시구요.


MESSAGE_MAP 부분에 ON_WM_SETTINGCHANGE()를 추가하시구요.


BEGIN_MESSAGE_MAP(CUsrDlg, CDialog)
       ON_WM_SETTINGCHANGE()
END_MESSAGE_MAP()



내부에는 다음과 같이 처리하면 되겠죠? ^^;
void CUsrDlg::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
       CWnd::OnSettingChange(uFlags, lpszSection);        // Full Screen 금지
}

이와 같이 고쳐 놓으면 아마(?) 다이얼로그의 사이즈가 반항(?)하는 것을 찾기
힘드실 것입니다.
물론... 위의 항목에서 2, 3번 항목은  if (!(GetStyle() & WS_CHILD))
조건에 걸릴 경우만 타는 겁니다.


참고루요..
다이얼로그가 PocketPC Version에서는 모달로 띄우거나, 모달리스로 띄우거나,
메인 메뉴가 자동적으로 사라집니다.
어떻게 해볼라고 해도 안되더군요.
물론 모달리스로 띄우면 메뉴는 선택할 수 있어야 하는 것인데...(WinCE Version에서는 메뉴 사용 가능)
얼마동안 찾아봤는데 잘 안되더군요.


전 이렇게 해서 그 문제를 해결했습니다.
Test환경은 PocketPC Version에서 Test했습니다.


올만에 개발실루 왔더니 아는 부분이 있어서 몇자 적어봤습니다.
만약 틀린 부분이 있다면... 괜한 삽질(?)로 고생시키게 해서 죄송하구요... ^^;...
그럼 이만... ^^;...






[출처]

데브피아