개요
SendMessage (HWND, WM_COPYDATA, 0,(LPARAM)&myCDS); // 메시지 전송.
myCDS 로 전송하기 위한 간단한 예.
typedef struct {
int a;
int b;
} MySTData;
MySTData my_stdata; // 이 구조체를 COPYDATASTRUCT 의 lpData 로 송신하고자한다.
COPYDATASTRUCT myCDS; // COPYDATASTRUCT 형의 구조체 변수 선언.
myCDS.dwData = 1; // 통상 여러 타입의 데이터를 lpData 로 전송할때 타입 식별자 용도로 사용함.
myCDS.lpData = &my_stdata;
myCDS.cbData = sizeof(my_stdata); // lpData 로 전송하는 데이터의 바이트 사이즈 지정한다.
주의사항
구조체 멤버 제한사항.
WM_COPYDATA 로 전송할 구조체의 멤버에 CString 포함 포인터 를 멤버로 갖는 구조체를 WM_COPYDATA 로 전송하는 것은 무의미. 즉, 다른 프로세스는 이곳의 프로세스와는 다른 메모리 영역을 갖는데 , 이곳의 메모리 주소를 보내봤자 상대방 프로세스는 이곳의 메모리 주소는 접근 불가하므로 의도한 데이터 송신 불가. 구조체 멤버에 문자열을 보내려면 CString 아닌 TCHAR m_tchar[100] 식으로 정의해서 송신해야함.
COPYDATASTRUCT
- dwData 에만 데이터 할당하고 송신하려는 경우에도 멤버 lpData, cbData 로 전송할 데이터가 없고 값설정하지 않은 상태에서는 정상적으로 SendMessage 실행되지 못하고 통신 실패한다. 아래처럼 명시적으로 lpData, cbData 에 값설정해야 정상적으로 SendMessage 실행된다.
COPYDATASTRUCT myCDS;
myCDS.dwData = 999999;
myCDS.lpData = NULL;
myCDS.cbData = 0;
구조체 COPYDATASTRUCT |
|
구조체 COPYDATASTRUCT 타입정의는 아래와 같다.
typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData; DWORD cbData; PVOID lpData; } COPYDATASTRUCT, *PCOPYDATASTRUCT; Members
from :
|
|
WM_COPYDATA 메시지 수신측 메시지 핸들러 추가 방법. |
|
WM_COPYDATA 메시지를 수신하려는 쪽의 클래스 에 클래스 위저드 이용하여 간단 추가 가능하다.
예 : 클래스 위저드(ctrl+shift+x) 실행하여, 메시지 수신할 클래스 CCySingleStrategy1_UITDlg 의 Messages 부분에서 WM_COPYDATA 선택하여 버튼 Add Handler 클릭한다.
위 처리에 의하여 클래스에 자동 코드 생성된다. (아래그림)
|
|
OnCopyData 의 인자 CWnd * pWnd 상세
메시지 수신측의 이벤트 핸들러 OnCopyData 의 첫번째 인자인 CWnd* pWnd 는 메시지 송신한 측의 CWnd* 이다.
그럼 pWnd->GwtSafeHwnd() (주의 : pWnd->m_hWnd 로 접근하지 말것 프로그램 뒤진다.) 함수 반환값은 메시지 송신한 것의 윈도우 핸들이 기록되어있을 것이라 여겨지지만, 전혀 아니다.
pWnd->GetSafeHwnd() 로 확보되는 값은 메시지 송신한 곳에서 SendMessage 함수 호출시 3번째 인자 WPARAM 의 값이 기록되어있다.
만일, 아래처럼 WPARAM 에 0을 기록했다면 수신한 측에서 pWnd->GetSafeHwnd() 값은 0이 기록되어있다.
SendMessage (HWND, WM_COPYDATA, 0,(LPARAM)&myCDS); // 메시지 전송.
송신측에서 아래 코드 처럼 WPARAM 에 자신의 윈도우핸들을 기록하여 송신했다면
SendMessage (HWND, WM_COPYDATA, (WPARAM)this->GetSafeHwnd(),(LPARAM)&myCDS);
수신한 측에서도 송신한 윈도우의 핸들값을 pWnd->GetSafeHwnd() 로 얻을 수 있지만 송신한 측에서 윈도우 핸들을 기록하지 않고 다른 데이터를 기록했다면 수신한 측에서의 pWnd->GetSafeHwnd() 에는 윈도우 핸들이 아닌 송신시 기록한 WPARAM 값이 기록되어있다.
따라서, 결론적으로 숙지하고 있어야 할 사항.
SendMessage( , WM_COPYDATA, WPARAM, LPARAM ) 호출시 WPARAM 값으로 송신측의 윈도우 핸들이 아닌 다른 임의 값을 기록 가능하며, 수신한측에서 pWnd->GetSafeHwnd() 로 해당값 확보가능함.
코드예
- 코드 출처 : f https://msdn.microsoft.com/en-us/library/ms649009(v=vs.85).aspx
다음 예제에서는 WM_COPYDATA 메시지를 사용하여 두 애플리케이션 간에 정보를 보내는 방법을 보여 줍니다.
보내는 애플리케이션은 특정 정보를 요청하는 사용자에게 대화 상자를 표시합니다. 애플리케이션은 정보를 프라이빗 데이터 구조로 패키징하고 COPYDATASTRUCT 구조체의 구조에 대한 포인터를 포함하고 WM_COPYDATA 메시지를 사용하여 수신 애플리케이션에 정보를 보냅니다. 수신 애플리케이션에는 클래스 이름이 Disp32Class인 숨겨진 창이 있습니다
// ************ Globals ************
//
#define MYDISPLAY 1
typedef struct tagMYREC
{
char s1[80];
char s2[80];
DWORD n;
} MYREC;
COPYDATASTRUCT MyCDS;
MYREC MyRec;
HRESULT hResult;
BOOL CALLBACK InfoDlgProc( HWND, UINT, WPARAM, LPARAM );
// ************ Code fragment ****************
// Get data from user. InfoDlgProc stores the information in MyRec.
//
DialogBox( ghInstance, "InfoDlg", hWnd, (DLGPROC) InfoDlgProc );
//
// Copy data into structure to be passed via WM_COPYDATA.
// Also, we assume that truncation of the data is acceptable.
//
hResult = StringCbCopy( MyRec.s1, sizeof(MyRec.s1), szFirstName );
if (hResult != S_OK)
return False;
hResult = StringCbCopy( MyRec.s2, sizeof(MyRec.s2), szLastName );
if (hResult != S_OK)
return False;
MyRec.n = nAge;
//
// Fill the COPYDATA structure
//
MyCDS.dwData = MYPRINT; // function identifier
MyCDS.cbData = sizeof( MyRec ); // size of data
MyCDS.lpData = &MyRec; // data structure
//
// Call function, passing data in &MyCDS
//
hwDispatch = FindWindow( "Disp32Class", "Hidden Window" );
if( hwDispatch != NULL )
SendMessage( hwDispatch,
WM_COPYDATA,
(WPARAM)(HWND) hWnd,
(LPARAM) (LPVOID) &MyCDS );
else
MessageBox( hWnd, "Can't send WM_COPYDATA", "MyApp", MB_OK );
수신 애플리케이션에는 WM_COPYDATA 정보를 수신하고 사용자에게 표시하는 숨겨진 창이 있습니다.
// ************ Globals ************
//
#define MYDISPLAY 1
typedef struct tagMYREC
{
char s1[80];
char s2[80];
DWORD n;
} MYREC;
PCOPYDATASTRUCT pMyCDS;
void WINAPI MyDisplay( LPSTR, LPSTR, DWORD );
//
// ************ Code fragment ****************
//
case WM_COPYDATA:
pMyCDS = (PCOPYDATASTRUCT) lParam;
switch( pMyCDS->dwData )
{
case MYDISPLAY:
MyDisplay( (LPSTR) ((MYREC *)(pMyCDS->lpData))->s1,
(LPSTR) ((MYREC *)(pMyCDS->lpData))->s2,
(DWORD) ((MYREC *)(pMyCDS->lpData))->n );
}
break;
연관
첫 등록 : 2017.03.28
최종 수정 : 2024.05.30
단축 주소 : https://igotit.tistory.com/1312
'VisualStudio.C++.C# > 코딩팁,함수활용,단편' 카테고리의 다른 글
win API . FindWindow , FindWindowEx (0) | 2020.09.05 |
---|---|
MFC.대화상자. x버튼 그레이처리 (1) | 2020.08.31 |
Critical Section (크리티컬 섹션) (0) | 2020.05.13 |
jsoncpp. Json::Value , Json::Reader, Json::CharReader, Json::CharReaderBuilder (0) | 2020.05.12 |
libcurl. curl_easy_perform. perform a blocking file transfer (0) | 2020.05.05 |
댓글