Search

'PostThreadMessage()'에 해당되는 글 1건

  1. 2016.03.24 윈도우간 통신 SendMessage() 와 PostMessage(), PostThreadMessage()
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

MSDN 번역


■ 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, 0, 0, 0)) {

    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)

■ 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, 0, 0, 0)) {

    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)