[Tip] WM_COPYDATA 메시지로 프로그램간에 데이터 주고받는 방법

트랙백 주소 : http://www.tipssoft.com/bulletin/tb.php/FAQ/319

팁스소프트에서 제공하는 프로그래밍과 관련된 자료나 정보들을 무단으로 복제하거나 게재하는 행위는
상호간의 신뢰를 무너뜨리는 행위이며, 법적인 문제를 야기할 수 있으므로 각별한 주의를 당부드립니다.

* 팁스소프트 저작권 정책 보기 – http://www.tipssoft.com/bulletin/tb.php/FAQ/637

이 자료들은 팁스소프트에서 제공하는 [ 알짜배기 ] 프로그램을 이용하면 더 편리하게 볼수 있습니다.

* 알짜배기 프로그램 받기 – http://www.tipssoft.com/bulletin/tb.php/QnA/8406

WM_COPYDATA 메시지는 프로세스와 프로세스간에 데이터를 주고 받을 수 있도록 제공하는 메시지입니다.
WM_COPYDATA 메시지를 이용하여 프로그램간에 데이터를 주고 받는 방법에 대해서 알아보겠습니다.

‘TestCopyDataSend’ 가 데이터를 보내고, ‘TestCopyDataReceive’가 데이터를 받는 쪽이라 가정합니다.

========================== TestCopyDataSendDlg ==========================

1. 데이터를 보내는 프로세스에서의 활용 방법

// 만약 프로세스간의 데이터 전송이 여러 클래스에서 빈번하게 발생된다면 아래의 함수를
// 전역함수로 선언한 후 사용한다. (전역함수로 가정)

// stdafx.cpp 파일 내부에 아래의 함수를 추가한다.
// << 매개변수 설명 >>
// HWND parm_wnd : WM_COPYDATA 메시지를 통해 데이터를 받을 대상이 되는 프로세스의 메인 윈도우 핸들
// HWND parm_this_wnd : 현재 메시지를 보내는 자신의 윈도우 핸들
// int parm_message_type : 현재 WM_COPYDATA 메시지를 통해 보내는 데이터의 종류를 구별하는 헤더
// char *parm_data : 전송하고자 하는 데이터의 메모리 시작위치

// int parm_size : 전송하고자 하는 데이터의 사이즈
int TW_SendDataMessage(HWND parm_wnd, HWND parm_this_wnd, int parm_message_type,
char *parm_data, int parm_size)
{
int return_value = 0;
char *p_buffer = NULL;

// 데이터를 받을 윈도우가 있고, 전송하고자 하는 데이터의 사이즈가 있다면
if(parm_wnd != NULL){
if(parm_size){
// parm_size 만큼의 동적 메모리를 생성한다.
// 프로세스와 프로세스간에 데이터를 주고 받을 때는 heap 메모리 영역에 활당한다.
p_buffer = (char *)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, parm_size);

// 생성된 동적 메모리에 전송하고자 하는 데이터를 복사한다.
// parm_size만큼 parm_data의 내용을 생성된 동적 메모리인 p_buffer에 복사한다.
if(p_buffer != NULL) memcpy(p_buffer, parm_data, parm_size);
}

// WM_COPYDATA 메시지 정보를 위한 구조체에 해당 정보를 설정한다.
COPYDATASTRUCT tip;

// 보내는 데이터의 종류를 구별하게끔 하는 헤더를 저장한다.
tip.dwData = parm_message_type;
// 보내는 데이터의 사이즈를 저장한다.
tip.cbData = parm_size;
// 보내는 데이터의 메모리상 시작위치 저장한다.
tip.lpData = p_buffer;

// WM_COPYDATA 메시지를 대상이 되는 parm_wnd 윈도우에 전송한다.
// 이때 동기화의 문제로 인해 PostMessage()함수가 아닌 SendMessage()함수만을 사용해야 한다.
if(IsWindow(parm_wnd)) return_value = ::SendMessage(parm_wnd, WM_COPYDATA,
(WPARAM)parm_this_wnd, (LPARAM)&tip);

// WM_COPYDATA메세지를 받은 윈도우에서 처리가 다 되었다면, 동적메모리를 해제한다.
if(p_buffer != NULL) ::HeapFree(::GetProcessHeap(), 0, p_buffer);
}

return return_value;
}

// stdafx.h 파일에 아래의 코드를 추가한다.
extern int TW_SendDataMessage(HWND parm_wnd, HWND parm_this_wnd, int parm_message_type,
char *parm_data, int parm_size);

// test_data 배열에 저장된 문자열을 다른 프로세서(윈도우 이름(캡션) “TestCopyDataReceive”)에 전송한다고 가정.
#define MM_TEST_DATA 20000

char test_data[64] = {0};
strcpy(test_data, “안녕하세요. 팁스소프트입니다.”);

// 윈도우 캡션명으로 찾는다.
// FindWindow(윈도우 클래스명, 윈도우 이름(캡션명))
HWND dest_wnd = ::FindWindow(NULL, “TestCopyDataReceive”);

int result = TW_SendDataMessage(dest_wnd, this->m_hWnd, MM_TEST_DATA, test_data,

sizeof(test_data));

if(!result) MessageBox(“성공!”);
else MessageBox(“실패!”);

========================== TestCopyDataReceiveDlg ==========================

2. 데이터를 받는 프로세스에서의 활용 방법

// ClassWizard를 이용해서 WM_COPYDATA 메시지를 등록하고 해당 메시지 핸들러에 아래의 코드를 추가한다.
// (예로 MFC의 VIEW-DOCUMMENT 구조를 사용중이라면 CMainFrame 클래스에 발생 시키면 된다.)
#define MM_TEST_DATA 20000

BOOL CTestCopyDataReceiveDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
switch(pCopyDataStruct->dwData){
case MM_TEST_DATA:
{
CString str;
char *p_data = (char *)pCopyDataStruct->lpData;
str = p_data;
MessageBox(str);
}
break;
}

return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}

<< 실행화면 >>