MFC에서 사용자 정의 메시지 생성과 처리, 데이터 전송 방법

MFC에서 사용자 정의 메시지 생성과 처리, 데이터 전송 방법 

사용자 정의 메시지 생성과 메시지 맵을 활용한 메시지 처리 방법

윈도우 사용자 정의 메시지 생성에서 다음과 같이 윈도우에서 정의된 것이 아닌 사용자가 사용할 메시지를 정의한다. WM_USER라는 윈도우 메시지에 임의로 중복되지 않도록 값을 사용자가 정의하는 것입니다. 100이라는 값을 이미 사용자 정의 메시지로 사용하고 있기 때문에 중복되지않는 값을 정하기 위해서 11을 더했습니다. 

#define WM_USER_ON_RECEIVE_SERVER_IBT    WM_USER + 100 + 11 ///< IBT BMS

윈도우 메시지 정의 코딩
윈도우 메시지 정의 위한 메시지 맵
BEGIN_MESSAGE_MAP(CDimonDlg, CDialogEx)과 END_MESSAGE_MAP()사이 블럭에 프로그램에서 사용하는 메시지가 정의되어 있습니다. 윈도우 메시지를 생성하면 자동으로 이곳에 메시지가 위치하게 되는데, 사용자 정의메시지도 또한 이곳에 사용자가 코딩을 해줘야 합니다. define문으로 정의한 사용자 정의 메시지와 윈도우의 메소드와 연결해줘야 합니다.  연결해주는 문장이 ON_MESSAGE(WM_USER_ON_RECEIVE_SERVER_IBT, OnReceiveData_IBT_Server) 메시지 정의입니다. 
  • 의미는 WM_USER_ON_RECEIVE_SERVER_IBT 사용자 정의 메시지를 클래스내의 메소스인 OnReceiveData_IBT_Server 메소드와 연결을 시킨다입니다. 즉, 윈도우에서 사용자가 정의한 윈도우 이벤트가 발생하면, 사용자 정의 메시지와 연결한 메소드로 이벤트가 들어오게 됩니다. 이 메소드에 이벤트를 받아 처리하는 코드를 추가하면, 원하는 내용을 처리할 수 있습니다.

통신 클래스에서 사용자 정의 메시지를 생성하여 데이터 전송하는 이유와 방법

사용자 정의 WM_USER_ON_RECEIVE_SERVER_IBT 메시지를 어디에선가는 생성하는 곳이 있어야 합니다. 다음 그림에서 처럼 다른 클래스에서 사용자 정의 메시지를 생성할 수 있습니다. 이쯤에서 의아해하는 부분이 있을 겁니다. 이유는 클래스와 클래스사이의 데이터 전송인데 굳이 윈도우 메시지 이벤트를 발생하여 데이터를 전송할 필요가 있는가? 입니다. 이에 대한 답은 일반적으로 데이터를 주고 받을 땐, 객체를 생성하여 하는 방법으로 하면 되고, 지금부터 설명하려하는 것은 통신 클래스와 데이터를 처리하는 데이터 클래스일 경우입니다. 통신 클래스에서는 실시간으로 계속 데이터를 수신할 것이고, 이 데이터를 수신하기 위해서는 스레드를 구동하여 데이터를 소켓 버퍼에서 수신하게 됩니다. 이 실시간이라는 것은 수초도 될 수 있고, 수 밀리초도 될 수 있습니다. 이처럼 데이터가 많이 수신되면, 메소드 콜방식으로 처리하게 되면 프로그램이 블록 현상이 발생하고, 데이터 처리 또한 느려지게 됩니다. 이런 현상이 있다는 것은 다년간 프로그램을 하고 release하였을 때, 발생했던 경험에서 나온 것입니다. 

사용자 정의 메시지
사용자 정의 메시지 이벤트 생성

따라서, 위 현상을 고려하여 윈도우 메시지 큐를 사용하여 구현하게되어  위의 코드를 사용했습니다. 코드 중에 PostMessage()를 상세히 설명하면 다음과 같습니다.

 MFC(Microsoft Foundation Class)의 PostMessage 함수 이해와 Windows API의 PostMessage 함수와의 유사성

MFC(Microsoft Foundation Class)에서 PostMessage는 Windows 메시지를 큐에 보내는 함수입니다. 이 함수는 비동기적으로 동작하며, 메시지 큐에 메시지를 추가한 후 즉시 반환됩니다.  PostMessage 함수는 두 개의 매개변수를 가지며, 첫 번째 매개변수는 메시지를 받을 윈도우 핸들이고, 두 번째 매개변수는 전달할 메시지입니다. 이 함수는 보통 다른 스레드에서 호출되며, 메시지 처리기 함수는 메시지 큐에서 메시지를 가져와 해당 메시지에 대한 처리를 수행합니다. 예를 들어, 대화 상자에서 버튼을 클릭하면 버튼 핸들과 클릭 이벤트를 포함하는 메시지가 생성됩니다. 이 메시지는 PostMessage 함수를 사용하여 메시지 큐에 전달됩니다. 메시지 큐에서 메시지가 처리되면 해당 버튼에 대한 처리기 함수가 호출되어 버튼 클릭에 대한 응답을 수행합니다. MFC에서 PostMessage 함수는 Windows API의 PostMessage 함수를 래핑한 것입니다. 따라서 MFC에서 사용되는 PostMessage 함수와 Windows API의 PostMessage 함수는 매우 유사합니다.

MFC에서 PostMessage와 SendMessage 함수의 차이점과 선택적 사용

MFC에서 PostMessage와 SendMessage는 모두 Windows 메시지를 보내는 함수입니다. 그러나 두 함수는 약간의 차이점이 있습니다. PostMessage는 메시지를 비동기적으로 보내며, 함수가 호출되고 메시지가 큐에 추가된 후 즉시 반환됩니다. 따라서 호출자는 메시지를 보낸 후 다른 작업을 수행할 수 있습니다. 메시지는 나중에 메시지 큐에서 처리됩니다. 반면에 SendMessage는 메시지를 동기적으로 보내며, 호출자가 메시지가 처리될 때까지 대기합니다. SendMessage 함수는 메시지 처리가 완료될 때까지 반환하지 않으므로, 호출자는 메시지 처리가 완료될 때까지 다른 작업을 수행할 수 없습니다. 따라서, SendMessage는 호출자의 작업을 차단하고 대기 시간이 긴 작업을 수행해야하는 경우에 적합합니다. 반면에, PostMessage는 호출자의 작업을 차단하지 않고 비동기적으로 작업을 수행해야하는 경우에 적합합니다. 또한, SendMessage는 반환값을 사용하여 메시지 처리 결과를 반환할 수 있지만, PostMessage는 반환값이 없으므로 메시지 처리 결과를 반환할 수 없습니다. 따라서, 호출자는 메시지 전송 방식과 작업 요구 사항에 따라 PostMessage 또는 SendMessage 함수를 선택해야합니다.

메시지 큐에서 데이터를 받아 처리하는 코드 구현

다시 본론으로 돌아와서, 메시지 큐에 있는 내용을 가져와 처리할 수 있도록 다음과 같이 구현을 하여야 합니다. 헤더파일과 구현파일에 아래와 같은 내용의 코드 구조를 작성합니다.

  • .cpp 구현 파일 : LRESULT CDimonDlg::OnReceiveData_IBT_Server(WPARAM wParam, LPARAM lParam)
  • .h 헤더 파일 : afx_msg LRESULT OnReceiveData_IBT_Server(WPARAM wParam, LPARAM lParam); 

내부에 데이터를 받아서 처리할 수 있는 코드를 삽입합니다.

비행기 위탁수하물에 USB 충전식 LED 조명 거울을 부칠 수 있는지에 대한 상세 분석

비행기 위탁수하물에 USB 충전식 LED 조명 거울을 부칠 수 있는지에 대한 상세 분석 항공기 여행 시 위탁수하물로 전자기기(특히 배터리 내장 제품)를 부칠 때는 각종 규정과 제한 사항을 준수해야 합니다. USB 충전식 LED 조명 거울의 위탁 여부는...