PostThreadMessage()를 이용한 쓰레드에 메세지 전송
● 알아두어야 할 사항
1. 윈도우 OS시스템에서는 자동적으로(GetMessage()호출시?) 메세지 큐를 각각 쓰레드마다 생성한다.
2. Posted Message를 위한 메세지 큐의 크기는 Windows 2000이나 XP인경우
10000이다. (최소 값: 4000) 이 값은 아래 윈도우즈 레지스트리에
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Windows/
USERPostMessageLimit
정의 한다.
3. PostThreadMessage()로 보내어지는 메세지는 윈도우와 관련이 없다.
● 결론
1. 간단한 메세지만 전송받아 처리 하는 쓰레드인 경우는 큐만든다고 삽질하지 말자.
2. 기본에 충실하자.
3. 옛날에 삽질한게 억울하다.
// --------------------------------------------------------------------------
// 예제
// --------------------------------------------------------------------------
CAppModule _Module;
DWORD WINAPI BackgroundThread (LPVOID param)
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
ATLTRACE (_T("hwnd = %x \r\n"), msg.hwnd );
ATLTRACE (_T("message = %x \r\n"), msg.message );
ATLTRACE (_T("wParam = %x \r\n"), msg.wParam );
ATLTRACE (_T("lParam = %x \r\n"), msg.lParam );
ATLTRACE (_T("time = %d \r\n"), msg.time );
ATLTRACE (_T("pt = %d %d \r\n"), msg.pt.x, msg.pt.y);
ATLTRACE (_T("\r\n"));
Sleep (1000);
while (::PeekMessage (&msg, NULL, WM_USER, WM_USER+5, PM_REMOVE));
}
ATLTRACE (_T("BackgroundThread(): End \r\n"));
return msg.wParam;
}
int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWNORMAL)
{
CMessageLoop theLoop;
_Module.AddMessageLoop(&theLoop);
CMainFrame wndMain;
DWORD dwThreadId = 0;
HANDLE hThread = CreateThread (NULL, 0, BackgroundThread, NULL, 0, &dwThreadId);
wndMain.m_ThreadId = dwThreadId;
if(wndMain.CreateEx() == NULL)
{
ATLTRACE(_T("Main window creation failed!\n"));
return 0;
}
wndMain.ShowWindow(nCmdShow);
int nRet = theLoop.Run();
_Module.RemoveMessageLoop();
WaitForSingleObject (hThread, INFINITE);
CloseHandle (hThread);
return nRet;
}
// --------------------------------------------------------------------------
LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
...
SetTimer (1, 10);
return 0;
}
LRESULT CMainFrame::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
bHandled = FALSE;
KillTimer (1);
PostThreadMessage (m_ThreadId, WM_QUIT, 0, 0);
return 0;
}
LRESULT CMainFrame::OnTimer (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
static int i = 0;
PostThreadMessage (m_ThreadId, WM_USER+(++i%5), 1, 2);
return 0;
}
// --------------------------------------------------------------------------
// 출력결과
// --------------------------------------------------------------------------
hwnd = 0
message = 403
wParam = 1
lParam = 2
time = 73702525
pt = 0 0
hwnd = 0
message = 400
wParam = 1
lParam = 2
time = 73703559
pt = 0 0
hwnd = 0
message = 400
wParam = 1
lParam = 2
time = 73704571
pt = 0 0
hwnd = 0
message = 403
wParam = 1
lParam = 2
time = 73705596
pt = 0 0
hwnd = 0
message = 403
wParam = 1
lParam = 2
time = 73706642
pt = 0 0
hwnd = 0
message = 400
wParam = 1
lParam = 2
time = 73707702
pt = 0 0
hwnd = 0
message = 403
wParam = 1
lParam = 2
time = 73708749
pt = 0 0
hwnd = 0
message = 400
wParam = 1
lParam = 2
time = 73709776
pt = 0 0
CMessageLoop::Run - exiting
BackgroundThread(): End
'BackgroundThread' (0x8706cf42) 스레드가 0 (0x0) 코드에서 끝났습니다.
모듈 언로드: commctrl.dll
모듈 언로드: oleaut32.dll
모듈 언로드: ole32.dll
모듈 언로드: rpcrt4.dll
모듈 언로드: lpcrt.dll
'[6702ec62] Test.exe' 프로그램이 1 (0x1) 코드에서 끝났습니다.