본문 바로가기
VisualStudio.C++.C#/코딩팁,함수활용,단편

WM_COPYDATA . OnCopyData . CWnd * pWnd . WPARAM

by 리치굿맨 2020. 8. 31.
 

개요

 
2개의 프로세스 사이에 SendMessage 함수로 메시지 송/수신과 동시에 구조체자료형 COPYDATASTRUCT 를 전송가능한 것.
 
즉 메시지 송신측에서 SendMessage 함수인자를 아래처럼 호출하면 HWND 에 해당하는 다른 프로세스에서 COPYDATASTRUCT 로 정의된 데이터 myCDS 를 수신가능하다.
 
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

dwData
Type: ULONG_PTR
The data to be passed to the receiving application.
cbData
Type: DWORD
The size, in bytes, of the data pointed to by the lpData member.
lpData
Type: PVOID
The data to be passed to the receiving application. This member can be NULL.
 
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()  로 해당값 확보가능함. 

 

 

 

 

 

 

 

 

 

 

코드 예.

 
 

Using Data Copy

 
The following example demonstrates how to send information between two applications using the WM_COPYDATA message.
The sending application displays a dialog box to the user which requests certain information. The application packages the information into a private data structure, includes a pointer to the structure in the COPYDATASTRUCT structure, and sends the information to the receiving application using the WM_COPYDATA message. The receiving application has a hidden window with the class name Disp32Class.
 
Copy
// ************ 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 );
The receiving application has a hidden window which receives the information from WM_COPYDATA and displays it to the user.
 
Copy
// ************ 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;

Related topics

Reference
FindWindow
 
 
 
   

 

연관 

 

 

메타트레이더. WM_COPYDATA

///// 메타트레이더 에서 WM_COPYDATA SendMessage 예 #property strict #define WM_COPYDATA 0x004A #define INFO 0x01 #define FindWindow FindWindowW #define SendMessage SendMessageW struct Copydatastruct..

igotit.tistory.com

 

 


첫 등록 : 2017.03.28

최종 수정 : 2022.02.15

단축 주소 : https://igotit.tistory.com/1312

 


 

 

댓글0


   
현물 |선물 인버스 |선물 USDT     현물 | 선물 USDT |봇제작툴/카피트레이딩     현물 |선물 인버스 |선물 USDT     선물 인버스 |선물 USDT