[Win API] WindowProc의 스레드와 TCP연결
WindowProc은 메시지(창 크기변환, 클릭 등 사용자와의 상호작용)를 받았을 때 호출되는 함수이다. 이 메시지는 반복문으로 계속 호출되는데 게임에서 프레임 호출과는 다르다. 그냥 OS에서 어플리케이션 메시지 큐에서 대기하고 있는 메시지들이다. 그리고 하나의 스레드에서 돌아간다.
여기서 주의할 점은 하나의 스레드에서 돌아가기 때문에 WindowProc에서 진행되는 코드는 굉장히 빨리 끝나야한다. 예를들어 이 함수에서 TCP를 연동하고 서버가 반응하길 기다린다면 그것이 끝날 때 까지 창이 멈춰버릴 것이다. 따라서 멀티스레딩으로 따로 처리해줘야한다.
내 코드 예시를 한번보자.
case WM_KEYDOWN: { //winporc안의 코드
if (wParam == 'A') {
// 작업 시작
//std::thread(DoWorkAndRepaint, hwnd).detach();
DoWorkAndRepaint(hwnd);
}
}
void DoWorkAndRepaint(HWND hwnd)
{
openServer();
g_isProcessing = true;
// 다시 WM_PAINT 요청
InvalidateRect(hwnd, nullptr, false);
}
이렇게 하면 winproc가 하나의 스레드인데, 서버를 열고 클라이언트의 답을 받을때까지 윈도우 창이 먹통이 되어버린다. 클라이언트의 연결이 될 때까지 기다려야하기 때문이다. 그런데,
case WM_KEYDOWN: {
if (wParam == 'A') {
// 작업 시작
std::thread(DoWorkAndRepaint, hwnd).detach();
//DoWorkAndRepaint(hwnd);
}
}
이렇게 다른 스레드에서 실행시켜보았다.
클라이언트 기다리면서 윈도우창을 클릭해도 먹통이 되지않고 움직일 수 있었다.
재미로 내 로컬에서 서버를 켜고, 클라이언트도 연동해서 적용해봤다.
TCP/IP에 대한 좀 더 자세한 내용은 다음 블로그에 있다
https://pdy0930.tistory.com/102
reference
https://learn.microsoft.com/en-us/windows/win32/learnwin32/writing-the-window-procedure
https://learn.microsoft.com/ko-kr/windows/win32/gdi/redrawing-the-entire-client-area