Проблема в Связи между двумя диалоговыми окнами через WM_COPYDATA? - PullRequest
1 голос
/ 05 марта 2010

Друзья, это действительно доставляет мне сильную головную боль по поводу проблемы, с которой я сталкиваюсь в течение пары дней ... Это просто ... Я хочу общаться между двумя / более диалоговыми окнами, например, если есть переменная CString test ... Я хочу, чтобы эта тестовая переменная была общей для диалогов / классов (учитывая, что у каждого диалога есть отдельные классы) ... Я пробовал много методов, все не удалось .. Наконец я попробовал этот метод 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 ]

2 голосов
/ 05 марта 2010

Ваша CString может быть в структуре, но память для ее хранения выделена в куче. Здесь вы должны перейти на низкую технологию: поместите массив wchar (или char, или TCHAR в зависимости от ваших желаний) в структуру ShareMessage и скопируйте содержимое строки в этот массив. В коде вашего получателя прочитайте строку из массива 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.

0 голосов
/ 06 марта 2010

Я избегал использовать WinProc. Вместо этого я написал обычную функцию (CopyData) в классе Dialog11..Создал немодальный диалог в классе 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. Вызвал FindWindow перед вызовом окна Dialog1. 3. Использовал функцию WinProc для получения сообщения .. что было очень трудно заставить его работать .. затем избежал этого и использовал обычную функцию 4. Не передавайте правильную ручку окна ... все вышеперечисленное исправлено Бобом Муром ... кредит ему достается ...

0 голосов
/ 05 марта 2010

В дополнение к моему ответу выше, это код получения

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 просто для обработки основного сообщения кажется очень странным.

...