通过WM_COPYDATA在两个对话框之间进行通信时出现问题?

时间:2010-03-05 08:35:51

标签: mfc wm-copydata

朋友真的给了我一个很好的头脑疼痛我几天面临的问题...它很简单......我想在两个/多个对话框之间进行通信,例如,如果有一个变量CString测试..我希望这个测试变量对于对话框/类是常见的(考虑到每个对话框都有单独的类)...我尝试了很多方法,一切都失败了.atlast我尝试了这个WM_COPYDATA方法......即使现在,我也没有实现我想做什么......

Sender Class:

#define ORGININFO 1

typedef struct ShareMessage
{
    CString mydata;
    int myValue;
}MYDATA;

void CCopyDataDlg::OnBnClickedOk()
{
    // TODO: Add your control notification handler code here
    MYDATA myData;
    COPYDATASTRUCT cData;

    myData.mydata.SetString(L"Rakesh");

    cData.dwData = ORGININFO;
    cData.cbData = sizeof(myData);
    cData.lpData = &myData;

    HWND hwnd  = (HWND)FindWindow(L"Dialog1",L"Test");



    SendMessageA(m_hWnd,WM_COPYDATA,(WPARAM)hwnd,(LPARAM)(LPVOID)&myData);


    Dialog1 dlg;
    dlg.DoModal();

}

接收者类:

#define iMessage 1

typedef struct MyDatas
{
    CString myData;
    int myint;
}DATA;
PCOPYDATASTRUCT pData;


LRESULT Dialog1::WindowProc(UINT message,WPARAM wParam,LPARAM lparam)
{

    if(WM_COPYDATA != NULL)
        pData = (PCOPYDATASTRUCT)lparam;
        switch(pData->dwData)
        {
        case iMessage:
            MessageBoxA((HWND)AfxGetInstanceHandle(),(LPCSTR)(LPCTSTR)((DATA*)(pData->lpData))->myData,(LPCSTR)L"Test",MB_OK);

        }
    return 0;
}

在上面我不知道我在做什么错,但它没有从CCopyDialog类接收数据......请帮我这个......

3 个答案:

答案 0 :(得分:2)

你的CString可能在struct中,但是存储它的内存是在堆上分配的。你必须在这里使用低技术:在ShareMessage结构中放置一个wchar(或char,或TCHAR,具体取决于你的欲望)数组,并将字符串内容复制到该数组。在接收器代码中,从wchar数组中读取字符串。哦,你已经发送了你的结构的地址,而不是COPYDATASTRUCT,并将它发送给你自己,而不是其他对话框。像这样修改SendMessage调用:

SendMessage (hWnd,WM_COPYDATA,(WPARAM)hwnd,(LPARAM)(LPVOID)&cData);

另外,你确定FindWindow呼叫正在工作吗?那个班级名字对我来说非常可疑。最好使用NULL,并依赖窗口标题。我有这种模糊的记忆,MFC对话框有一个固定的类名。

您的代码应该可以使用。

例如:

typedef struct ShareMessage
{
    wchar szMyString [100];
    int myValue;
}MYDATA;

void CCopyDataDlg::OnBnClickedOk()
{
   MYDATA myData;
   COPYDATASTRUCT cData;
   ZeroMemory (&myData, sizeof(myData);

   wcscpy (myData.szMyString, (L"Rakesh"));

   cData.dwData = ORGININFO;
   cData.cbData = sizeof(myData);
   cData.lpData = &myData;
   ...

我还没有测试过这个代码,这是我的头脑。我假设wchar,因为你在常量字符串上使用了L修饰符。

此外,在您的接收器代码中,您有这一行:

if (WM_COPYDATA != NULL)

这没有意义。我假设您打算根据常量WM_COPYDATA测试收到的消息编号。

答案 1 :(得分:0)

继上面的答案之后,这是接收代码

LRESULT Dialog1::WindowProc(UINT message,WPARAM wParam,LPARAM lparam)
{
   CString csPassedString;
   PCOPYDATASTRUCT pData;
   MYDATA myStuff;

   if (message == WM_COPYDATA)
   {
      pData = (PCOPYDATASTRUCT)lparam;
      if (pData)
      {
         memcpy (&myStuff, pData->lpData, sizeof(myData));
         csPassedString = myStuff.szMyString;
         switch(pData->dwData)
         {
           case iMessage:
              MessageBox (csPassedString,
                          L"Test",
                          MB_OK);
....

但是这里还有另一个更基本的问题......在MFC应用程序中,覆盖WindowProc只是为了处理基本消息似乎很奇怪。

答案 2 :(得分:0)

我避免使用WinProc ..而不是我在类Dialog11中编写了一个普通函数(CopyData)。在类CCopyDialog1中处理了一个无模式对话框..并调用了该函数(CopyData)..它工作..请检查以下代码......

//CCopyDialog Class(sender)
void CCopyDataDlg::OnBnClickedOk()
{
    // TODO: Add your control notification handler code here
    Dialog1* dialog1 = new Dialog1();
    dialog1->Create(IDD_DIALOG1,0);
    dialog1->ShowWindow(SW_SHOW);
    ZeroMemory(&myData,sizeof(myData));
    wcscpy(myData.mydata,(L"Rakesh"));

    cData.dwData = ORGININFO;
    cData.cbData = sizeof(myData);
    cData.lpData = &myData;

       HWND rs = ::FindWindow(NULL,L"Rakesh");

    dialog1->CopyData(WM_COPYDATA,(WPARAM)rs,(LPARAM)&cData);


}


Dialog1 class(receiver)
LRESULT Dialog1::CopyData(UINT message,WPARAM wParam,LPARAM lparam)
{
    if(message == WM_COPYDATA)
    {
        pData = (PCOPYDATASTRUCT)lparam;
        wchar_t tes[50];
        memcpy(tes,((DATA*)(pData->lpData))->myData,sizeof(DATA));

    }
    else
    {
        return FALSE;
    }

    return 0;
}

基本上与我之前的代码(我的问题中的代码)相比......有很多差异/错误..

1.在sendmessage中,我通过了结构而不是COPYDATASTRUCT .. 2.在调用Dialog1窗口之前调用FindWindow .. 3.使用函数WinProc函数来接收消息..这很难使它工作..然后避免使用正常的函数 4.Didnt通过一个合适的窗口把手...... 以上所有都由鲍勃摩尔纠正...信用归他......