Microsoft MVP성태의 닷넷 이야기
Windows: 237. Win32 - 모든 메시지 루프를 탈출하는 WM_QUIT 메시지 [링크 복사], [링크+제목 복사],
조회: 12068
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

(시리즈 글이 21개 있습니다.)
Windows: 226. Win32 C/C++ - Dialog에서 값을 반환하는 방법
; https://www.sysnet.pe.kr/2/0/13284

Windows: 227. Win32 C/C++ - Dialog Procedure를 재정의하는 방법
; https://www.sysnet.pe.kr/2/0/13285

Windows: 228. Win32 - 리소스에 포함된 대화창 Template의 2진 코드 해석 방법
; https://www.sysnet.pe.kr/2/0/13286

Windows: 229. Win32 - 대화창 템플릿의 2진 리소스를 읽어들여 윈도우를 직접 띄우는 방법
; https://www.sysnet.pe.kr/2/0/13287

Windows: 230. Win32 - 대화창의 DLU 단위를 pixel로 변경하는 방법
; https://www.sysnet.pe.kr/2/0/13288

Windows: 231. Win32 - 대화창 템플릿의 2진 리소스를 읽어들여 자식 윈도우를 생성하는 방법
; https://www.sysnet.pe.kr/2/0/13289

Windows: 232. C/C++ - 일반 창에도 사용 가능한 IsDialogMessage
; https://www.sysnet.pe.kr/2/0/13292

Windows: 233.  Win32 - modeless 대화창을 modal처럼 동작하게 만드는 방법
; https://www.sysnet.pe.kr/2/0/13295

Windows: 234. IsDialogMessage와 협업하는 WM_GETDLGCODE Win32 메시지
; https://www.sysnet.pe.kr/2/0/13296

Windows: 235. Win32 - Code Modal과 UI Modal
; https://www.sysnet.pe.kr/2/0/13297

Windows: 237. Win32 - 모든 메시지 루프를 탈출하는 WM_QUIT 메시지
; https://www.sysnet.pe.kr/2/0/13299

Windows: 238. Win32 - Modal UI 창에 올바른 Owner(HWND)를 설정해야 하는 이유
; https://www.sysnet.pe.kr/2/0/13300

Windows: 242. Win32 - 시간 만료를 갖는 MessageBox 대화창 구현 (쉬운 버전)
; https://www.sysnet.pe.kr/2/0/13305

Windows: 243. Win32 - 윈도우(cbWndExtra) 및 윈도우 클래스(cbClsExtra) 저장소 사용 방법
; https://www.sysnet.pe.kr/2/0/13306

Windows: 244. Win32 - 시간 만료를 갖는 MessageBox 대화창 구현 (개선된 버전)
; https://www.sysnet.pe.kr/2/0/13312

Windows: 245. Win32 - 시간 만료를 갖는 컨텍스트 메뉴와 윈도우 메시지의 영역별 정의
; https://www.sysnet.pe.kr/2/0/13315

Windows: 246. Win32 C/C++ - 직접 띄운 대화창 템플릿을 위한 Modal 메시지 루프 생성
; https://www.sysnet.pe.kr/2/0/13329

Windows: 247. Win32 C/C++ - CS_GLOBALCLASS 설명
; https://www.sysnet.pe.kr/2/0/13330

Windows: 248. Win32 C/C++ - 대화창을 위한 메시지 루프 사용자 정의
; https://www.sysnet.pe.kr/2/0/13332

Windows: 249. Win32 C/C++ - 대화창 템플릿을 런타임에 코딩해서 사용
; https://www.sysnet.pe.kr/2/0/13333

Windows: 250. Win32 C/C++ - Modal 메시지 루프 내에서 SetWindowsHookEx를 이용한 Thread 메시지 처리 방법
; https://www.sysnet.pe.kr/2/0/13334




Win32 - 모든 메시지 루프를 탈출하는 WM_QUIT 메시지

지난 2개의 글에서,

Win32 - modeless 대화창을 modal처럼 동작하게 만드는 방법
; https://www.sysnet.pe.kr/2/0/13295

Win32 - Code Modal과 UI Modal
; https://www.sysnet.pe.kr/2/0/13297

oldnewthing 블로그의 "Modality"와 관련해 part 1part 2를 다뤘는데요, 이번에는 part 3: The WM_QUIT message 이야기를 풀어보겠습니다. ^^




모든 메시지 루프는 WM_QUIT 메시지에 의해 종료되는 것을 원칙으로 합니다. 따라서 만약 여러분이 Modal 루프를, 즉 code-modal을 사용해 중첩 메시지 루프를 만들었다면 WM_QUIT 메시지를 받은 경우 여러분의 메시지 루프만 탈출하도록 만들어서는 안 되고, WM_QUIT 메시지를 PostQuitMessage API를 이용해 전파시켜야만 합니다. 그래야 중첩 메시지 루프를 벗어나면서, 원래의 Win32 응용 프로그램 구조로 만들어 두었던 메시지 루프까지 탈출해 응용 프로그램을 정상적으로 종료할 수 있게 됩니다.

결국, 여러분들의 code-modal 구현 코드는 다음과 같이 PostQuitMessage에 대한 처리를 함께 해야 합니다.

BOOL WaitForSomething(void)
{
  MSG msg;
  BOOL fResult = TRUE; // assume it worked
  while (!SomethingFinished()) {
    if (GetMessage(&msg, NULL, 0, 0)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    } else {}
      // We received a WM_QUIT message; bail out!
      CancelSomething();
      // Re-post the message that we retrieved
      PostQuitMessage(msg.wParam);
      fResult = FALSE; // quit before something finished
      break;
    }
  }
  return fResult;
}

그런데 혹시 g_fQuitting이라는 전역 변수를 둬서 전체의 메시지 루프를 빠져나가도록 만드는 것도 가능하지 않았을까요?

BOOL MyWaitForSomething(void) // code in italics is wrong
{
  MSG msg;
  while (!SomethingFinished()) {
    if (g_fQuitting) {}
    CancelSomething();
      return FALSE;
    }
    if (GetMessage(&msg, NULL, 0, 0)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }
  return TRUE;
}

물론 가능할 수 있습니다. 하지만, 저 방법이 가능하려면 모든 메시지 루프가 g_fQuitting을 고려해 만들어졌어야 합니다. 하지만, code-modal은 여러 군데에서 독자적인 메시지 루프를 만들어 구현하고 있습니다. 예를 들어, DialogBox API를 사용하면 그 내부에서 메시지 루프가 돌고 있습니다. 또한 메뉴를 보여줄 때나, 윈도우의 프레임을 마우스로 선택해 드래그하면서 크기를 변경하는 중에도 독자적인 메시지 루프가 사용됩니다.

당연히, 그런 식으로 만들어지는 메시지 루프는 g_fQuitting의 존재를 알지 못하기 때문에 문제가 발생합니다. 따라서, WM_QUIT를 전파하는 하나의 약속을 정함으로써 그런 모든 문제를 해결할 수 있게 된 것입니다.

아마 g_fQuitting과 같은 방식으로 했다면 마찬가지로 그 값을 설정하는 QuitAllMessageLoop와 같은 이름의 Win32 API가 생겼을 것이고 그것을 메시지 루프에서 호출하도록 만들었어야 할 것입니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 3/27/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 121  122  123  124  125  126  127  128  129  130  131  [132]  133  134  135  ...
NoWriterDateCnt.TitleFile(s)
1756정성태9/23/201427490기타: 48. NVidia 제품의 과다한 디스크 사용 [2]
1755정성태9/22/201434281오류 유형: 241. Unity Web Player를 설치해도 여전히 설치하라는 화면이 나오는 경우 [4]
1754정성태9/22/201424676VC++: 80. 내 컴퓨터에서 C++ AMP 코드가 실행이 될까요? [1]
1753정성태9/22/201420619오류 유형: 240. Lync로 세미나 참여 시 소리만 들리지 않는 경우 [1]
1752정성태9/21/201441071Windows: 100. 윈도우 8 - RDP 연결을 이용해 VNC처럼 사용자 로그온 화면을 공유하는 방법 [5]
1751정성태9/20/201438960.NET Framework: 464. 프로세스 간 통신 시 소켓 필요 없이 간단하게 Pipe를 열어 통신하는 방법 [1]파일 다운로드1
1750정성태9/20/201423834.NET Framework: 463. PInvoke 호출을 이용한 비동기 파일 작업파일 다운로드1
1749정성태9/20/201423734.NET Framework: 462. 커널 객체를 위한 null DACL 생성 방법파일 다운로드1
1748정성태9/19/201425388개발 환경 구성: 238. [Synergy] 여러 컴퓨터에서 키보드, 마우스 공유
1747정성태9/19/201428510오류 유형: 239. psexec 실행 오류 - The system cannot find the file specified.
1746정성태9/18/201426106.NET Framework: 461. .NET EXE 파일을 닷넷 프레임워크 버전에 상관없이 실행할 수 있을까요? - 두 번째 이야기 [6]파일 다운로드1
1745정성태9/17/201423042개발 환경 구성: 237. 리눅스 Integration Services 버전 업그레이드 하는 방법 [1]
1744정성태9/17/201431069.NET Framework: 460. GetTickCount / GetTickCount64와 0x7FFE0000 주솟값 [4]파일 다운로드1
1743정성태9/16/201420985오류 유형: 238. 설치 오류 - Failed to get size of pseudo bundle
1742정성태8/27/201426977개발 환경 구성: 236. Hyper-V에 설치한 리눅스 VM의 VHD 크기 늘리는 방법 [2]
1741정성태8/26/201421337.NET Framework: 459. GetModuleHandleEx로 알아보는 .NET 메서드의 DLL 모듈 관계파일 다운로드1
1740정성태8/25/201432525.NET Framework: 458. 닷넷 GC가 순환 참조를 해제할 수 있을까요? [2]파일 다운로드1
1739정성태8/24/201426569.NET Framework: 457. 교착상태(Dead-lock) 해결 방법 - Lock Leveling [2]파일 다운로드1
1738정성태8/23/201422058.NET Framework: 456. C# - CAS를 이용한 Lock 래퍼 클래스파일 다운로드1
1737정성태8/20/201419768VS.NET IDE: 93. Visual Studio 2013 동기화 문제
1736정성태8/19/201425583VC++: 79. [부연] CAS Lock 알고리즘은 과연 빠른가? [2]파일 다운로드1
1735정성태8/19/201418259.NET Framework: 455. 닷넷 사용자 정의 예외 클래스의 최소 구현 코드 - 두 번째 이야기
1734정성태8/13/201419919오류 유형: 237. Windows Media Player cannot access the file. The file might be in use, you might not have access to the computer where the file is stored, or your proxy settings might not be correct.
1733정성태8/13/201426367.NET Framework: 454. EmptyWorkingSet Win32 API를 사용하는 C# 예제파일 다운로드1
1732정성태8/13/201434482Windows: 99. INetCache 폴더가 다르게 보이는 이유
1731정성태8/11/201427088개발 환경 구성: 235. 점(.)으로 시작하는 파일명을 탐색기에서 만드는 방법
... 121  122  123  124  125  126  127  128  129  130  131  [132]  133  134  135  ...