==================================================================================================
파일 매핑(Memory Mapped IO)으로 두 프로세스가 메모리를 공유하는 방법
참고 : 윈도우즈 API 정복
-----------------------------------------------------------------------------------------------
[실행화면]
: MemShare1에서 키보드 입력을 하는 경우 MemShare2의 에디트 윈도우에도 같이 입력된다.
: MemShare2에서 키보드 입력을 하는 경우 MemShare1의 에디트 윈도우에도 같이 입력된다.
-----------------------------------------------------------------------------------------------
[소스코드]
/* MemShare1.cpp */
#include <windows.h>
#include <windowsx.h> // 메시지 크래커 사용을 위해 추가
#define ID_EDIT 100 // 에디트 윈도우의 Menu ID 값
#define MAXSHAREMEMORY 1024 // 최대 메모리 공유 사이즈
// 윈도우 프로시저 프로토 타입
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// 메시지 크랙커 정의 함수 프로토 타입
BOOL MemShare1_OnCreate(HWND, LPCREATESTRUCT);
void MemShare1_OnCommand(HWND, int, HWND, UINT);
void MemShare1_OnPaint(HWND);
void MemShare1_OnDestroy(HWND);
UINT UserMessage; // 사용자 정의 메시지
HWND hEdit; // 에디트 윈도우
HANDLE hFMap; // 파일 연결 오브젝트 변수
TCHAR *PtrlnFile; // 메모리에 매핑의 시작번지를 나타내는 포인터 변수
// 윈도우 메인
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nShowCmd)
{
HWND hwnd;
MSG msg;
WNDCLASS wndclass = {0};
static TCHAR WinMainClassName[] = TEXT("MemShare1");
wndclass.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_3DFACE);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = WinMainClassName;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndclass);
hwnd = CreateWindow (
WinMainClassName,
WinMainClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
(HMENU) NULL,
hInstance,
NULL
);
ShowWindow(hwnd, nShowCmd);
// 메시지 루프
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
// 윈도우 프로시저 구현
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch (iMessage) // 메시지 크랙커
{
HANDLE_MSG(hwnd, WM_CREATE, MemShare1_OnCreate);
HANDLE_MSG(hwnd, WM_COMMAND, MemShare1_OnCommand);
HANDLE_MSG(hwnd, WM_PAINT, MemShare1_OnPaint);
HANDLE_MSG(hwnd, WM_DESTROY, MemShare1_OnDestroy);
}
if(iMessage == UserMessage) // 사용자 정의 메시지
SetWindowText(hEdit, PtrlnFile);
return (DefWindowProc(hwnd, iMessage, wParam, lParam));
}
// 메시지 크랙커 정의 함수 구현
BOOL MemShare1_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
MoveWindow(hwnd, 80, 200, 400, 350, TRUE);
hEdit = CreateWindow(
TEXT("edit"),
NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE,
10, 10, 500, 200,
hwnd,
(HMENU) ID_EDIT,
GetModuleHandle(0),
NULL
);
// 사용자 정의 메시지 등록!
UserMessage = RegisterWindowMessage(TEXT("WM_SYNCSHAREMEMORY"));
// 파일 연결 오브젝트 생성!
hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
MAXSHAREMEMORY, "MEMORYSHAREMAPPING");
// 파일뷰를 메모리에 매핑!
PtrlnFile = (TCHAR *) MapViewOfFile(hFMap, FILE_MAP_ALL_ACCESS, 0, 0,
MAXSHAREMEMORY);
return TRUE;
}
void MemShare1_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id) // LOWORD(wParam)
{
case ID_EDIT :
switch(codeNotify) // HIWORD(wParam)
{
case EN_CHANGE :
{
HWND hTarget;
GetWindowText(hEdit, PtrlnFile, MAXSHAREMEMORY);
hTarget = FindWindow(NULL, TEXT("MemShare2")); // 찾을 윈도우
if(hTarget)
SendMessage(hTarget, UserMessage, 0, 0);
}
break;
}
}
}
void MemShare1_OnPaint(HWND hwnd)
{
PAINTSTRUCT ps;
TCHAR *Message = TEXT("메모리 공유 테스트");
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 10, 220, Message, lstrlen(Message));
EndPaint(hwnd, &ps);
}
void MemShare1_OnDestroy(HWND hwnd)
{
// Memory Mapped File 관련 자원 해제
UnmapViewOfFile(PtrlnFile);
CloseHandle(hFMap);
PostQuitMessage(0);
}
-----------------------------------------------------------------------------------------------
/* MemShare2.cpp */
#include <windows.h>
#include <windowsx.h> // 메시지 크래커 사용을 위해 추가
#define ID_EDIT 100 // 에디트 윈도우의 Menu ID 값
#define MAXSHAREMEMORY 1024 // 최대 메모리 공유 사이즈
// 윈도우 프로시저 프로토 타입
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
// 메시지 크랙커 정의 함수 프로토 타입
BOOL MemShare2_OnCreate(HWND, LPCREATESTRUCT);
void MemShare2_OnCommand(HWND, int, HWND, UINT);
void MemShare2_OnPaint(HWND);
void MemShare2_OnDestroy(HWND);
UINT UserMessage; // 사용자 정의 메시지
HWND hEdit; // 에디트 윈도우
HANDLE hFMap; // 파일 연결 오브젝트 변수
TCHAR *PtrlnFile; // 메모리에 매핑의 시작번지를 나타내는 포인터 변수
// 윈도우 메인
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
int nShowCmd)
{
HWND hwnd;
MSG msg;
WNDCLASS wndclass = {0};
static TCHAR WinMainClassName[] = TEXT("MemShare2");
wndclass.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_3DFACE);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = WinMainClassName;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndclass);
hwnd = CreateWindow (
WinMainClassName,
WinMainClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
(HMENU) NULL,
hInstance,
NULL
);
ShowWindow(hwnd, nShowCmd);
// 메시지 루프
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
// 윈도우 프로시저 구현
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch (iMessage) // 메시지 크랙커
{
HANDLE_MSG(hwnd, WM_CREATE, MemShare2_OnCreate);
HANDLE_MSG(hwnd, WM_COMMAND, MemShare2_OnCommand);
HANDLE_MSG(hwnd, WM_PAINT, MemShare2_OnPaint);
HANDLE_MSG(hwnd, WM_DESTROY, MemShare2_OnDestroy);
}
if(iMessage == UserMessage) // 사용자 정의 메시지
SetWindowText(hEdit, PtrlnFile);
return (DefWindowProc(hwnd, iMessage, wParam, lParam));
}
// 메시지 크랙커 정의 함수 구현
BOOL MemShare2_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
MoveWindow(hwnd, 500, 200, 400, 350, TRUE);
hEdit = CreateWindow(
TEXT("edit"),
NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE,
10, 10, 500, 200,
hwnd,
(HMENU) ID_EDIT,
GetModuleHandle(0),
NULL
);
// 사용자 정의 메시지 등록!
UserMessage = RegisterWindowMessage(TEXT("WM_SYNCSHAREMEMORY"));
// 파일 연결 오브젝트 생성!
hFMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
MAXSHAREMEMORY, "MEMORYSHAREMAPPING");
// 파일뷰를 메모리에 매핑!
PtrlnFile = (TCHAR *) MapViewOfFile(hFMap, FILE_MAP_ALL_ACCESS, 0, 0,
MAXSHAREMEMORY);
return TRUE;
}
void MemShare2_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id) // LOWORD(wParam)
{
case ID_EDIT :
switch(codeNotify) // HIWORD(wParam)
{
case EN_CHANGE :
{
HWND hTarget;
GetWindowText(hEdit, PtrlnFile, MAXSHAREMEMORY);
hTarget = FindWindow(NULL, TEXT("MemShare1")); // 찾을 윈도우
if(hTarget)
SendMessage(hTarget, UserMessage, 0, 0);
}
break;
}
}
}
void MemShare2_OnPaint(HWND hwnd)
{
PAINTSTRUCT ps;
TCHAR *Message = TEXT("메모리 공유 테스트");
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 10, 220, Message, lstrlen(Message));
EndPaint(hwnd, &ps);
}
void MemShare2_OnDestroy(HWND hwnd)
{
// Memory Mapped File 관련 자원 해제
UnmapViewOfFile(PtrlnFile);
CloseHandle(hFMap);
PostQuitMessage(0);
}
==================================================================================================
'IT_Programming > MFC · API' 카테고리의 다른 글
[API] WIN32 API에서 ODBC (오라클,MS-SQL,MDB) 사용하기 - CQuery Class (0) | 2009.08.09 |
---|---|
[API] 더블 버퍼링 스크롤바 테스트! (0) | 2009.08.04 |
[펌] 유니코드를 위한 Win API | MFC 프로그래밍 (0) | 2009.07.31 |
[API] 슈퍼 클래싱 (Super Classing) (0) | 2009.07.29 |
[API] 서브 클래싱( SUB CLASSING ) (0) | 2009.07.29 |