티스토리 뷰
API IPC - 메시지
정보를 교환할 수 있는 가장 간단한 방법이며 가장 빠른 방법이다.
두 프로세스가 서로 윈도우 핸들만 알고 있다면 약속된 메시지를 wParam, lParam 을 통해 정보를 교환할 수 있다. 메시지는 메모리를 거치지 않고 OS에 의해 직접 전달되므로 주소 공간이 격리되어 있더라도 잘 전달된다.
정수같이 비교적 크기가 작은 정보를 전달할때만 사용할 수 있다. 정보라기 보다 어떤 사실을 통보하기 위한 목적으로 사용할 수 있다. 예로 지금 종료하라던가, 새로 데이터를 읽어라든가 등등의 명령 정도는 이 방법으로 쉽게 전달할 수 있다.
그러나 문자열이나 구조체 같은 큰 데이터는 전달 할 수 없다. 왜냐하면 메시지와 함께 전달되는 wParam, lParam은 둘 다 더해봐야 불과 8바이트에 불과하기 때문이다. 또, 이 파라미터로 포인터를 전달한다 해도 Win32환경에서는 프로세스간 메모리 공간이 격리되어 있으므로 같은 번지라도 두 프로세스가 참조하는 메모리가서로 다른 다르다.
메시지 보낼 프로젝트는 Win32Project3 이고, 메시지 받을 프로젝트는 Win32Project1 으로 했다.
하나의 워크스페이스에 2개의 프로젝트를 만든 경우 솔루션 속성에서 아래 그림처럼 설정을 해야 한다.
만약, 메시지 받을 프로젝트 이름(윈도우 창 제목)이 다른 경우 아래 코드 9행에서 메시지 받을 윈도우 제목으로 바꿔야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
#define WM_IPC WM_USER+1
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR* pMsg = L"마우스 왼쪽 버튼을 누르면 다른 프로세스로 메시지를 보냅니다.";
HWND hWnd1 = NULL;
switch (message)
{
case WM_LBUTTONDOWN:
hWnd1 = FindWindow(NULL, L"Win32Project1"); // 윈도우 제목으로 핸들 얻음
if (hWnd1 != NULL)
SendMessage(hWnd1, WM_IPC, (WPARAM)1234, (LPARAM)0);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 여기에 hdc를 사용하는 그리기 코드를 추가합니다.
TextOut(hdc, 10, 50, pMsg, lstrlen(pMsg));
EndPaint(hWnd, &ps);
}
break;
...
} |
cs |
Win32Project1 프로젝트 소스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 |
#define WM_IPC WM_USER+1
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
TCHAR* pMsg = L"다른 프로그램으로 부터 메시지를 전달 받는다.";
TCHAR str[128];
static int n = 90;
switch (message)
{
case WM_IPC:
hdc = GetDC(hWnd);
wsprintf(str, L"%d를 받았습니다.", wParam);
TextOut(hdc, 10, n=(n+12+5), str, lstrlen(str));
ReleaseDC(hWnd, hdc);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 여기에 hdc를 사용하는 그리기 코드를 추가합니다.
TextOut(hdc, 10, 50, pMsg, lstrlen(pMsg));
EndPaint(hWnd, &ps);
}
break;
...
} |
cs |