IPC를 할 때 다양한 방법이 있지만 WM_COPYDATA를 사용한 윈도우Q에 SendMessage를 보내는 방식이 있다.
간단하고 쉬워서 많이 사용을 한다.
WM_COPYDATA를 이용해서 C#, MFC 등 다른 개발 언어로 통신을 하는 경우도 많다.
이번에 C# <-> MFC 프로그램간에 SendMessage를 보내는데 잘 안되는 문제가 발생했다.
C#에서 RunExecute로 MFC 프로그램을 실행하고 C# 앱의 ProcessID를 전달받아 MFC에서는 ProcessID로 핸들을 찾고 다시 SendMessage를 보내는 방식이다.
MFC에서 아래와 같은 방식으로 핸들을 구했다.
//Get Device Manage HWND HWND m_hwndDeviceMan = NULL; HWND m_tHwnd = NULL; DWORD dwProcessID = _ttoi(m_strProcessName);//m_strProcessName: ProcessID string do { m_tHwnd = FindWindowEx (NULL, m_tHwnd, NULL, NULL); DWORD dwPID = 0; GetWindowThreadProcessId (m_tHwnd, &dwPID); if (dwPID == dwProcessID) { m_hwndDeviceMan = m_tHwnd; break; } } while (m_tHwnd != NULL); |
위와 같이 처리를 했는데 찾은 Hwnd로 SendMessage를 보냈는데 C#에서 WM_COPYDATA로 받지는 못하는 것이다.
원인을 확인해 보니 찾은 윈도우 핸들이 최상위 윈도우 핸들이 아니고 하위 윈도우 핸들이었던 것이다.
ProcessID를 가지고 Window Handle을 찾을 때 그 Handle이 어떤 윈도우의 핸들인지 정확하게 알아야 한다.
아니면 최소한 Main Window handle을 찾아야 한다.
그래서 검색을 해서 찾은 방식이 아래와 같은 방식이다.
struct handle_data { unsigned long process_id; HWND window_handle; }; BOOL is_main_window(HWND handle) { return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle); } BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam) { handle_data& data = *(handle_data*)lParam; unsigned long process_id = 0; GetWindowThreadProcessId(handle, &process_id); if (data.process_id != process_id || !is_main_window(handle)) return TRUE; data.window_handle = handle; return FALSE; } HWND find_main_window(unsigned long process_id) { handle_data data; data.process_id = process_id; data.window_handle = 0; EnumWindows(enum_windows_callback, (LPARAM)&data); return data.window_handle; } |
DWORD dwProcessID = _ttoi(m_strProcessName); HWND m_hwndDeviceMan = find_main_window(dwProcessID); |
위와 같은 방식으로 Window Handle을 찾아서 사용을 하니 문제가 해결이 되었다.
이런 문제로 ProcessID를 전달하는 것보다는 Window Handle을 전달해서 바로 SendMessage를 보낼 수 있도록 하는 것이 좋을 것 같다.
'C++' 카테고리의 다른 글
ConvertBSTRToString 함수 메모리 누수 문제 (0) | 2023.09.14 |
---|---|
safearray 값을 SafeArrayAccessData 이용해서 읽어 오는 방법 (0) | 2023.09.07 |
std::map에서 char array를 key로 사용하기 (0) | 2021.04.08 |
memcmp 바이트 Array 비교를 할 때 사용 (0) | 2021.03.31 |
pointer new, delete, 지역 pointer 변수 오류 (0) | 2017.03.28 |