메뉴에서 프로젝트 - 클래스 마법사 - -Dlg클래스 선택 - 사용자 지정 메시지 추가로 추가하는 방법도 있다.
방법
먼저 사용자 지정 메시지를 정의한다.
#define MY_MSG1 (WM_USER + 1)
#define MY_MSG2 (WM_USER + 2)
Windows API에는 미리 정의된 메시지 상수가 많이 있지만, 애플리케이션의 필요에 따라 추가적인 사용자 지정 메시지를 정의할 수 있는데, 이때 WM_USER를 사용하여 사용자 지정 메시지의 베이스 값을 설정한다. WM_USER의 값은 0x0400으로 (WM_USER + n) 이런식으로 정의하면 다른 시스템 또는 프레임워크 메시지와 충돌하지 않도록 할 수 있다.
다음은 다이얼로그 헤더에 메시지 처리기를 추가한다.
afx_msg LRESULT MyMessageHandler(WPARAM wParam, LPARAM lParam);
다이얼로그 cpp 파일에서 메시지 맵에 메시지와 처리기를 연결시키고 처리기 함수를 구현한다.
BEGIN_MESSAGE_MAP(CRwrTesterDlg, CDialogEx)
// ...
ON_MESSAGE(MY_MSG, MyMessageHandler)
// ...
END_MESSAGE_MAP()
afx_msg LRESULT AppDlg::MyMessageHandler(WPARAM wParam, LPARAM lParam)
{
CString* pStr = (CString*)lParam;
m_listBox.InsertString(m_listBox.GetCount(), *pStr);
delete pStr;
return NULL;
}
어플리케이션에서 아래와 같이 메시지를 전송한다.
CString* pStr = new CString(_T("Hello World!"));
HWND hWnd = AfxGetApp()->m_pMainWnd->m_hWnd;
PostMessage(hWnd, MY_MSG, NULL, (LPARAM)pStr);
// 혹은 this->PostMessage(MY_MSG, NULL, (LPARAM)pStr);
PostMessage 방식을 썼기 때문에 메시지 처리기에서 데이터를 처리한 후 메모리를 해제할 수 있도록 신경써야 한다. 메시지를 보내는 쪽에서 new 로 메모리를 할당하고 처리기에서 delete로 메모리를 해제한다. 처리기에서는 값 멤버변수가 아니라 컨트롤을 직접 조작하기 때문에 데이터와 컨트롤을 동기화 하는 UpdateData는 호출하지 않았다.
WPARAM과 LPARAM
WPARAM과 LPARAM은 Windows 프로그래밍에서 메시지 처리시 사용되는 두 개의 데이터 형식이다.
1. WPARAM : Word Parameter의 약자로, 16비트 부호 없는 정수(unsigned short)이다. WPARAM은 일반적으로 메시지와 관련된 추가 정보를 전달하기 위해 사용된다. 예를 들면, 버튼 클릭과 같은 이벤트에서 어떤 버튼이 클릭되었는지를 식별하는 데 사용될 수 있다.
2. LPARAM : Long Parameter의 약자로, 32비트 부호 있는 정수(int)이다. LPARAM은 주로 메시지와 연결된 데이터나 포인터를 전달하는 데 사용된다. 예를 들어, 텍스트 입력 필드에서 텍스트를 전달하거나, 객체에 대한 포인터를 전달할 때 사용될 수 있다.
위 사례에서는 문자열 데이터에 대한 포인터를 전달하기에 LPARAM을 사용하였고 WPARAM은 NULL 값을 넘겼다.
SendMessage와 PostMessage
SendMessage와 PostMessage 함수는 위와 같이 사용자 정의 메시지를 트리거하기 위해 사용할 수 도 있고, 스레드간 메시지를 전달해야 할 경우 사용할 수 있다.
예를 들면 윈도우와 컨트롤에 접근하는 건 UI 스레드에서 독점적으로 해야 안전하므로 다른 스레드에서 UI 관련 작업이 필요하면 UI 스레드에 메시지를 보내(SendMessage, PostMessage) UI 스레드에서 처리하도록 할 수 있다.
SendMessage와 PostMessage의 차이
1. SendMessage : 메시지를 동기적으로 보낸다. 이 함수는 호출한 스레드에서 대상 윈도우의 메시지 처리기(윈도우 프로시저)를 직접 호출하고 메시지 처리가 완료된 후 결과를 반환한다. 즉., 메시지 처리가 완료될 때까지 호출 스레드는 블록될 수 있다.
2. PostMessage : 메시지를 비동기적으로 보낸다. 이 함수는 호출되자마자 메시지를 핸들의 메시지 큐에 삽입한 뒤 제어를 반환하며, 대상 윈도우의 메시지 처리기(윈도우 프로시저)는 나중에 이벤트 큐에서 메시지를 처리한다. 즉, 호출 스레드는 대기하지 않고 다른 작업을 수행할 수 있다.
- hWnd: 메시지를 수신할 대상 윈도우의 핸들.
- Msg: 보낼 메시지 ID.
- wParam과 lParam: 메시지와 관련된 추가 데이터.
'프로그래밍 > MFC (C++)' 카테고리의 다른 글
MFC ] 특정 컨트롤에 포커스 설정하기 (0) | 2023.11.06 |
---|---|
시스템 종료와 관련된 윈도우 메시지 WM_QUERYENDSESSION, WM_ENDSESSION (0) | 2023.11.02 |
MFC ] 리스트박스 스크롤 하단으로 내리는 법 (0) | 2023.09.15 |
MFC ] 다이얼로그 생성시 함수 호출 순서 (0) | 2023.09.15 |
MFC ] 멀티바이트 집합 사용시에도 현대적 UI 적용하기 (0) | 2023.09.15 |