본문 바로가기

programming/MFC

SendMessage & PostMessage


1. SendMessage() 와 PostMessage() 함수의 공통점
 
    두 함수는 모두 해당 윈도우에 메세지를 발생시키기 위하여 사용되고, 함수의 리턴 타입과 매개 변수는
    타입과 용도가 모두 같습니다. 두 함수의 원형은 아래와 같습니다 .
 
    LRESULT SendMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ); 
    LRESULT PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 );
 
 
    1.1 함수의 매개 변수에 대한 설명
 
        1.1.1 message
 
            발생시키고자 하는 메세지를 unsigned int 타입으로 명시합니다.
 
 
        1.1.2 wParam
 
            메세지에 대한 부가적인 정보를 WPARAM 타입으로 명시합니다. 기본적으로 0값을 가집니다.
 
 
        1.1.3 lParam
 
            메세지에 대한 부가적인 정보를 LPARAM 타입으로 명시합니다. 기본적으로 0값을 가집니다.
 
 
    1.2 함수의 반환값
 
        메세지를 처리한 후의 결과를 반환합니다. 발생한 메세지에 의해 수행되는 루틴은 루틴에 대한
        결과를 반환할 수 있고, 반환한 결과 값은 이 함수의 반환값이 됩니다.
 
 
2. SendMessage() 와 PostMessage() 함수의 차이점
 
    두 함수는 다른 처리 과정을 거쳐 메세지를 발생시키는 동일한 기능을 수행합니다. 
 
    SendMessage() 함수는 윈도우 프로시저를 직접 호출합니다. SendMessage() 함수에 의해
    발생한 메세지는 윈도우 프로시저가 호출된 시점에서 바로 처리하게 되고, 해당 메세지가 처리되기
    전까지는 다음 루틴을 수행하지 못합니다. 즉, 윈도우 프로시저가 메세지를 처리하기 전까지
    SendMessage() 함수는 반환하지 못합니다. 이것은 일반적인 함수 호출과 동일하게 작동한다고
    생각하시면 됩니다.
 
    반면에 PostMessage() 함수가 발생시키는 메세지는 메세지 큐에 들어가게 됩니다. 윈도우에서
    발생하는 일반적인 메세지들과 마찬가지로 해당 메세지는 GetMessage()PeekMessage()
    함수에 의해 처리되기 때문에 PostMessage() 함수를 호출 한 후의 루틴들을 모두 수행한 후
    메세지가 처리됩니다.
 
    즉, PostMessage() 가 어떤 루틴의 앞부분에 호출되더라도 그 루틴이 종료된 후 GetMessage()
    함수에 의해 발생한 메세지가 처리되는 것입니다.
 
    아래의 코드는 SendMessage() 와 PostMessage() 함수의 동작 차이를 나타낸 예 입니다.
 
    // "SendMessage 버튼"을 누른 경우 수행하는 함수 
    void CExamMessageDlg::OnSendBtn()
    {
        m_message_list.AddString("");
        m_message_list.AddString("SendMessage 호출 전");
        // SendMessage() 호출
        SendMessage(1000);
        m_message_list.AddString("SendMessage 호출 후");
    }
 
    // "PostMessage 버튼"을 누른 경우 수행하는 함수
    void CExamMessageDlg::OnPostBtn()
    {
        m_message_list.AddString("");
        m_message_list.AddString("PostMessage 호출 전");
        // PostMessage() 호출
        PostMessage(1001);
        m_message_list.AddString("PostMessage 호출 후");
    }
 
    // 발생한 메세지를 처리해주는 윈도우 프로시저
    LRESULT CExamMessageDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    {
        // SendMessage() 에 의해 발생한 메세지(1000)
        if(message == 1000){
            m_message_list.AddString("SendMessage가 호출되었습니다.");
        // PostMessage() 에 의해 발생한 메세지(1000)
        } else if(message == 1001){
            m_message_list.AddString("PostMessage 가 호출되었습니다.");
        }
        return CDialog::DefWindowProc(message, wParam, lParam);
    }
 
    위의 코드는 두 개의 버튼을 누르면 각각 SendMessage() 와 PostMessage() 함수를 호출하는
    프로그램의 주요 부분입니다. 두 함수가 호출되면 모두 DefWindowProc() 에서 메세지가 처리되게
    됩니다.
 
    아래의 그림과 같이 "SendMessage 버튼"을 눌러 OnSendBtn() 함수가 호출되면 리스트 박스에
    공백이 먼저 삽입되고, "SendMessage 호출 전" 이 삽입된 후 SendMessage() 함수가 호출됩니다.
    이때  SendMessage() 함수는 DefWindowPoc 을 바로 호출하여 1000 메세지에 해당하는 처리 즉,
    "SendMessage 가 호출되었습니다." 가 수행되고, OnSendBtn() 함수로 돌아가서 "SendMessage
     호출 후" 를 삽입하게 됩니다.
 
    "PostMessage 버튼"을 눌러 OnPostBtn() 함수가 호출되는 경우에는 리스트 박스에 공백이 삽입되고
    "PostMessage 호출 전" 이 삽입된 후, PostMessage() 함수에 의해 1001 메세지가 메세지 큐에 들어
    가고 나서, "PostMessage 호출 후" 를 삽입합니다. 그리고 OnPostBtn() 함수의 수행이 종료된 후
    GetMessage() 함수에 의해 해석된 메세지가 DefWindowPoc 에서 처리되어 "PostMessage가 호출
    되었습니다." 가 리스트 박스에 삽입되게 됩니다.
 
   

((맨날 헷갈리고, 까먹어 ㅡ,,ㅡ; ))