问题描述
- Visual C++ 中利用WM_COPYDATA进程通信
-
在MFC进程利用通信时,怎么在利用发送消息的窗口类指针pWnd在接收消息后回复一个响应。
具体想法如下:
BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
if (pCopyDataStruct != NULL)
{
LPCTSTR pszText = (LPCTSTR)(pCopyDataStruct->lpData);
DWORD dwLength = (DWORD)(pCopyDataStruct->cbData);
CString mystr;
memcpy(mystr.GetBuffer(dwLength / sizeof(TCHAR)), pszText, dwLength);
mystr.ReleaseBuffer();
::SendMessage(pWnd->m_hWnd, WM_COPYDATA, (WPARAM)(AfxGetApp()->m_pMainWnd), (LPARAM)pmyDataStruct);
}
return CFrameWnd::OnCopyData(pWnd, pCopyDataStruct);
}
但是通过pWnd->m_hWnd并不能成功发送数据,求教指点
pmyDataStruct是测试用的返回过去的信息,已经赋值
解决方案
下断点
LPCTSTR pszText = (LPCTSTR)(pCopyDataStruct->lpData);
DWORD dwLength = (DWORD)(pCopyDataStruct->cbData);
这里能获取到么
然后下面的
pWnd->m_hWnd
这个句柄有效么?
解决方案二:
这个能获取到,接收消息没问题,mystr能正确接收到那边的输入,给出回应时那边收不到消息
解决方案三:
用spy++监视下对方程序,拦截wm_copydata消息。
看看对方收消息有没有问题。
解决方案四:
在该段程序内测试时用
HWND revhwnd = ::FindWindow(NULL, _T("XXXXXXX"));
HWND mywnd = pWnd->m_hWnd;
对应的值分别是 ![图片说明](http://img.ask.csdn.net/upload/201505/01/1430443566_725822.png)
然后测试这两句代码时
::SendMessage(pWnd->m_hWnd, WM_COPYDATA, (WPARAM)(AfxGetApp()->m_pMainWnd), (LPARAM)pCopyDataStruct);
::SendMessage(revhwnd, WM_COPYDATA, (WPARAM)(AfxGetApp()->m_pMainWnd), (LPARAM)pCopyDataStruct);
下面的回应能收到
两个进程分别有各自的用户环境(虚实地址变换不同),WM_COPYDATA应该是通过系统调用映射地址实现的,这里的pWnd应该不是对应的发送方窗口句柄,但是确实唯一标识了发送方的句柄,是不是需要通过系统函数来转换下,求大神解答
解决方案五:
SendMessage是阻塞模式,你收到WM_COPYDATA消息后,接受放又发送sendmessage回来,这样会阻塞,。你第二个只能用PostMessage异步方式
解决方案六:
你的WM_COPYDATA消息的那个结构体是怎么定义的?
MSDN上的例子代码,前面是发送端,后面那一段是接收端:
// ************ 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.
// ************ 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;
解决方案七:
你的WM_COPYDATA消息的那个结构体是怎么定义的?
MSDN上的例子代码,前面是发送端,后面那一段是接收端:
// ************ 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.
// ************ 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;