title: "뽕빨! Windows Messaging"
description: "뽕빨! Windows Messaging"
cleanUrl: /sw-engineer/windows-messaging
ogImage: "<https://anyflower.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F7570d2fc-66b1-4e23-bb3c-ff7b56842b0d%2F8d64ae9a-91e1-413b-878a-b5fad17a1214%2FUntitled.png?table=block&id=270d6d75-2927-4aab-bff3-2760cad2498a&spaceId=7570d2fc-66b1-4e23-bb3c-ff7b56842b0d&width=2000&userId=&cache=v2>"
floatFirstTOC: right
<aside>
💡 Programming Applications for Microsoft Windows. (4th Editon) 에 담긴 내용입니다.
</aside>
쓰래드와 메시지 : 기본 규칙
- 프로세스 하나가 10,000개에 이르는 제각기 다른 종류의 사용자 객체(아이콘, 커서, 윈도우 클래스, 메뉴, 단축키 테이블 등)를 생성할 수 있다. 한 쓰래드에서 이들 객체 중 하나를 생성하는 함수를 호출했을 때, 생성된 객체는 그 쓰래드의 프로세스가 소유하게 된다(이 말은 프로세스가 죽으면 그 객체도 함께 죽는다는 말이다).
- 반면 윈도우(window)와 훅(hook) 객체는 그 윈도우를 생성하거나 훅을 설치한 쓰래드가 소유한다(이 말은 그 쓰래드가 죽으면 그 객체도 함께 죽는다는 뜻이다). -> 윈도우를 소유한 쓰래드가 그 윈도우의 모든 메시지를 관장한다. -> 하나 이상의 윈도우를 생성한 모든 쓰래드에는 메시지 큐가 할당되고, 그 때문에 그 쓰래드만의 메시지 루프를 갖게 된다.
- 또한 각각의 쓰래드는 키보드 포커스라던가, 윈도우 활성화, 마우스 캡쳐 등을 다루는 그 자신만의 환경(simulated environment)이 있다고 생각한다. 그러므로 각 쓰래드에는 이들 환경 변수를 저장할 THREADINFO 구조체가 있고, 이 구조체로써 그 쓰래드만의 붙여진(posted) 메시지 큐, 보내진(send) 메시지 큐, 응답(reply) 메시지 큐, 가상화된(virtualized) 입력 큐, wake 플래그와 그 외의 여러 환경 변수등을 식별해낼 수 있다. (메시지 큐가 하나로만 구성된 것이 아니더라..)
- 결국 THREADINFO 구조체는 윈도우즈 메시지 시스템의 주춧돌이 되더라. 하지만, UI관련 함수가 호출되기 전까지는 이 THREADINFO를 포함한 관련 리소스가 할당되지 않는다. (근데 이 구조체는 'internal', 'undocumented' 구조체라 직접 뜯어볼 수가 없다. 됀장 MS.)
POST 계열 메시지 함수
- 붙여진 메시지 큐에 메시지만 넣은 다음, 그 메시지의 처리 여부에 관계없이, 바로 호출자 함수로 되돌아온다.
- POST 계열 메시지 함수 : PostMessage, PostThreadMessage(다른 쓰래드에 메시지를 붙일 때), PostQuitMessage
SendMessage 함수
- 메시지를 윈도우 프로시저에 직접 보낸다. 오직 메시지가 처리되었을 때만 호출자 함수로 되돌아온다. 요러한 동기적 처리방식 때문에 주로 사용하게 된다.
- 다 른 쓰래드에 메시지를 넘길 경우 : 메시지를 보낸 쓰래드는 멈춰서서, 메시지를 받은 쓰래드가 그 메시지를 처리 완료하여 보낸 쓰래드의 응답 메시지 큐에 처리된 결과(SendMessage의 반환값)가 담긴 메시지를 붙일 때에야, 비로소 깨어나 그 결과 처리를 시작으로 다음 실행을 재개한다.
- 호출된 쓰래드에 문제가 있어 메시지를 처리 못할 경우 : 호출자 쓰래드와, 호출된 쓰래드 모두 deadlock에 걸린다! -> 이를 위해 SendMessageTimeout, SendMessageCallback, SendNotifyMessage, ReplyMessage 함수가 있는 것이다.
- SendMessageTimeOut 함수 : 보낸 메시지에 대한 응답을 받기까지의 최대 시간을 지정.
- SendMessageCallback 함 수 : 메시지를 보내고 잽싸게 되돌아온다. 호출된 쓰래드에서 메시지 처리를 마치고 응답을 보내면, 지정한 CallBack 함수가 호출된다. 호출되는 시점은 호출자 함수의 다음번에 응답 메시지 큐에서 메시질 가져올 때이다. 메시지 브로드케스팅에도 이용.
- SendNotifyMessage 함수 : 이 역시 메시지를 보내고 잽싸게 되돌아온다. 때문에 PostMessage와 비스무리할 수도 있지만, 윈도우에 직접 메시지를 보내기에 붙여진(Posted) 메시지보다 처리 우선순위가 높다.
- ReplyMessage 함 수 : (deadlock을 피하기 위해) 위의 함수들은 메시지를 보내는 측에서 호출하지만, 이 함수는 받는 쪽에서 호출한다. 이 함수를 호출한다는 것은 시스템에게 메시지 결과를 알 만큼 충분히 처리했고, 처음 메시지를 보낸 측에 결과 메시지를 싸서 보내라고 알리는 것이다. 그 결과, 처음 보낸 측은 깨어나 응답 메시지를 처리하게 될 것이야~