기본 콘텐츠로 건너뛰기

C++ - 윈도우간 통신 SendMessage() 와 PostMessage(), PostThreadMessage()

윈도우간 통신
SendMessage() 와 PostMessage(), PostThreadMessage()




■ 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 에는 지역 포인터를 사용하지
     않아야 한다.

     (메시지를 붙일 시점에는 포인터가 존재했더라고 메시지가 처리될 시점에는 포인터가 무효해 질수도 있다.)
    
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)


출처: http://six605.tistory.com/203 [As time goes by]

댓글

이 블로그의 인기 게시물

C# - Serial Port ASCII/HEX Format

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.Ports; namespace SerialTest1 {     public partial class Form1 : Form     {         delegate void MyDelegate();      //델리게이트 선언(크로스 쓰레드 해결하기 위한 용도)         bool SendForamt = true;          // true : ASCII   false : HEX         bool ReceiveFormat = true;       // true : ASCII   false : HEX         public Form1()         {             InitializeComponent();          ...

C# - Windows Form 에 있는 control 찾기

// 아래 코드는 form 의 최상위 control만 찾을 수 있음. // panle, groubbox ... 내부에 있는 control은 찾지 못함. Control GetControlByName(string Name) {     foreach (Control c in this.Controls)         if (c.Name == Name)             return c;     return null; } // form 의 모든 control을 찾을 수 있음. string name = "btnBit" + (i + 1).ToString("D2"); var tmpBtn = this.Controls.Find(name, true).FirstOrDefault(); if (tmpBtn != null) {     if (value == 1) tmpBtn.BackColor = Color.Lime;     else tmpBtn.BackColor = Color.Gray; }

C# - ARGB 색상

속성 A 이  Color  구조체의 알파 구성 요소 값을 가져옵니다. Alice Blue ARGB 값이  #FFF0F8FF 인 시스템 정의 색을 가져옵니다. Antique White ARGB 값이  #FFFAEBD7 인 시스템 정의 색을 가져옵니다. Aqua ARGB 값이  #FF00FFFF 인 시스템 정의 색을 가져옵니다. Aquamarine ARGB 값이  #FF7FFFD4 인 시스템 정의 색을 가져옵니다. Azure ARGB 값이  #FFF0FFFF 인 시스템 정의 색을 가져옵니다. B 이  Color  구조체의 파랑 구성 요소 값을 가져옵니다. Beige ARGB 값이  #FFF5F5DC 인 시스템 정의 색을 가져옵니다. Bisque ARGB 값이  #FFFFE4C4 인 시스템 정의 색을 가져옵니다. Black ARGB 값이  #FF000000 인 시스템 정의 색을 가져옵니다. Blanched Almond ARGB 값이  #FFFFEBCD 인 시스템 정의 색을 가져옵니다. Blue ARGB 값이  #FF0000FF 인 시스템 정의 색을 가져옵니다. Blue Violet ARGB 값이  #FF8A2BE2 인 시스템 정의 색을 가져옵니다. Brown ARGB 값이  #FFA52A2A 인 시스템 정의 색을 가져옵니다. Burly Wood ARGB 값이  #FFDEB887 인 시스템 정의 색을 가져옵니다. Cadet Blue ARGB 값이  #FF5F9EA0 인 시스템 정의 색을 가져옵니다. Chartreuse ARGB 값이  #FF7FFF00 인 시스템 정의 색을 가져옵니다. Chocolate ARGB 값이  #FFD2691E 인 시스템 정의 색을 가져옵니다. Coral ARGB ...