반응형

SendMessage() PostMessage()





■ PostMessage()

1. 원형

BOOL PostMessage(
    HWND hWnd,     // 이 메시지를 받을 윈도우 핸들
    UINT Msg,      // 전달할 메시지
    WPARAM wParam, // 여분 데이터
    LPARAM lParam  // 여분 데이터
);  


2. 동작
   - Msg 인수로 지정된 메시지를 hWnd 윈도우의 메시지 큐에 집어 넣는다.
   - 메시지를 받은 윈도우는 윈도우 프로시저에서 이 메시지를 처리한다.
   - 메시지를 메시지 큐에 넣기만 하고 바로 리턴 한다.
   - 큐에 붙인 메시지는 GetMessage() 에 의해 읽혀지고, DispatchMessage() 에 의해 윈도우 프로시저로 보내짐

3. 리턴값에 대하여
    - TRUE : 메시지를 메시지 큐에 붙이기 성공
    - FALSE : 메시지를 메시지 큐에 붙이기 실패
    ※ 가급적이면 리턴값을 점검해 보는 것이 좋다.
        메시지 큐는 크기가 한정되어 있기 때문에 고속으로 전송되는 모든 메시지를 다 수용하지 못할 수도 있기때문

4. 장점
   - 메시지를 메시지 큐에 넣기만 하고 곧바로 리턴 하므로 보내는 쪽에서 "블록(Block)" 시키지 않는다.
      따라서 바로 다른 작업을 할 수 있다.

5. 단점
   - 메시지를 메시지 큐에 넣고 리턴한다. 이때 메시지 큐에 대기하고 있는 다른 메시지가 있으면 해당 메시지가
     바로 처리되지 않을 수도 있다.
   - 메시지가 언제 처리 될지도 예측할 수 없으므로 메시지의 wParam, lParam 에는 지역 포인터를 사용하지 
     않아야 한다.

     (메시지를 붙일 시점에는 포인터가 존재했더라고 메시지가 처리될 시점에는 포인터가 무효해 질수도 있다.) - 그러므로 보통 SendMessage에서는 받아지던 CString 값이 PostMessage 에서는 못받는 경우를 볼 수 있다. PostMessage를 호출한 후 해당 함수의 루틴이 끝나 지역 변수가 반환되어서 그렇다. 그럴경우 char *p 변수를 선언하여 PostMessage로 넘긴 후, 메시지 처리 루틴에서 해당 선언된 변수를 delete 해주면 된다.
     
6. 활용
   - 급하게 처리할 필요가 없는 처리의 메시지
   - 지금 하고 있는 작업을(메시지를 보내는 입장에서) 완전히 끝내야만 처리할 수 있는 메시지

7. 첫 번째 인수 hWnd 가 NULL 인 경우
   - 특정 윈도우에게 신호를 보내기 위한 것이 아니라 응용 프로그램 전반에 걸친 작업 지시를 보낼 때 사용
   - 대상 윈도우가 없기 때문에 이 메시지는 윈도우 프로시저가 처리할 수 없으며 윈도우 프로시저로 가기전인
     메시지 루프에서 직접 처리해 주어야 한다.
while (GetMessage(&Message, 000)) {
    if (Message.message == WM_SOME) {
        // 직접 처리
    } else {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }
}
 
   - GetMessage로 메시지를 꺼낸 후 곧바로 메시지 ID를 비교해 보고 스레드를 위한 메시지 인지 검사해 본다
   - 만약 스레드를 위한 메시지라면 메시지 루프에서 직접 처리해야 하며 DispatchMessage 함수로 보내지말것
   - 대상 윈도우가 지정되지 않은 메시지이기 때문에 이 메시지를 받아줄 윈도우 프로시저가 없기 때문.
   - PostMessage 함수가 메시지를 붙여넣는 큐가 윈도우를 위한 큐가 아니라 스레드를 위한 큐이기 때문에 가능




■ PostThreadMessage()

1. 원형
BOOL PostThreadMessage(
     DWORD idThread,    // 스레드 ID
     UINT Msg,          // 전달할 메시지
     WPARAM wParam,
     LPARAM lParam
);
  
2. 사용 목적
   - 다른 스레드의 메시지 큐에 메시지를 붙일 때 사용
   - 스레드 외부에서 특정 스레드로 메시지를 전달할 때

3. 한계
   - 작업자 스레드에선 사용할 수 없고, 사용자 인터페이스 스레드 에서만 사용 가능




■ SendMessage()

1. 원형
BOOL SendMessage(
    HWND hWnd,     // 이 메시지를 받을 윈도우 핸들
    UINT Msg,      // 전달할 메시지
    WPARAM wParam, // 여분 데이터
    LPARAM lParam  // 여분 데이터
); 


            ※ SendMessage() 와 PostMessage() 함수의 원형은 동일

2. 동작
   - 메시지를 메시지 큐에 넣는 것이 아니라 곧바로 윈도우 프로시저로 보내 즉각 처리하도록 한다.
   - 메시지가 완전히 처리되기 전에 리턴하지 않는다. (블록 시킴)

3. 장점
   - 보낸 메시지의 정확한 처리 보장

4. 단점
   - 보낸 메시지가 완전히 처리 될때까지 기다리므로, 메시지를 보낸쪽은 블록 상태에 머물게 된다.
     영영 블록되어 프로그램이 죽을 수도 있다.
   ※ 메인 스레드에서 다른 스레드로 메시지를 보낼때 SendMessage() 의 사용은 위험하다

5. 활용
   - 부모 윈도우와 차일드 컨트롤 간의 통신
   - 윈도우간 정확한 데이터 전송 및 처리를 위한 통신
   - 윈도우의 특정 메시지는 SendMessage() 만을 사용해야 하는 경우도 있다. (WM_COPYDATA)




cf)참고 - Windows API 정복 (김상형)


■  사용 예

1. SendMessage() 함수로 출력 시켰을때

2. PostMessage() 함수로 출력 시켰을때

※ SendMessage() 함수로 출력 시킨 결과가 올바른 값이다.
   하지만 PostMessage() 함수로 출력 시키면 제일 처음에 전송된 데이터가 처리 되기 전에 나중에 
   나중에 전송된 데이터로 값을 찍어 버려서 올바른 값이 출력되지 않는다.


반응형
Posted by tislqhf

블로그 이미지
개인적인 공부자료 정리하는 공간
tislqhf

태그목록

공지사항

Yesterday
Today
Total

달력

 « |  » 2025.2
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함