views:

260

answers:

3

Hello all, Friends its really giving me a great head ache about the problem I am facing for the couple of days...Its simple...I want to communicate between two/more dialog boxes for example if there is a variable CString test..I want this test variable to be common for the dialogs/classes(considering each dialog having separate classes)...I tried lot methods, everything failed..atlast I tried this WM_COPYDATA method...even now, am not achieve what i wanted to do...

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();

}

Receiver class:

#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;
}

in the above I dont know what is the mistake I am doing but its not receiving the data from the CCopyDialog class...Please help me with this...

+2  A: 

Your CString may be in the struct, but the memory to store it is allocated on the heap. You have to go low-tech here: put a wchar (or char, or TCHAR depending upon your desires) array in the ShareMessage struct and copy the string contents to that array. In your receiver code, read the string out of the wchar array. Oh, and you have sent the address of YOUR struct, not the COPYDATASTRUCT, and sent it to yourself, not the other dialog. modify the SendMessage call like this:

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

Also, are you SURE the FindWindow call is working? That class name looks very suspicious to me. Better to use NULL, and rely on the window title. I have this vague memory that MFC dialogs have a fixed class name.

Your code should work then.

For example:

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;
   ...

I haven't tested that code, it's off the top of my head. I assumed wchar because you used the L modifier on your constant string.

Additionally, in your receiver code you have this line:

if (WM_COPYDATA != NULL)

which doesn't make sense. I assume you meant to test the received message number against the constant WM_COPYDATA.

Bob Moore
thnx for replyin Bob..I appreciate ur help..I tired that..Its still the same..the switch(pData->dwData) is still 0.do u know anythere methods...
kiddo
You have an error in the SendMessage call I didn't notice. I have edited my reply to show this.
Bob Moore
no Bob,its still the same error...Do u find any thing wrong in the window handle or in receiving the message...because in the Dialog1 class pData->dwData is still 0.more over the in the send message the hwnd(i.e HWND hwnd = FindWindow(L"Dialog1",L"Test")) says NULL...is that should be okay..
kiddo
hey Bob u know what!I just noticed that when the SendMessage is intiated it goes to the Dialog1 class..when it enters it doesnt match with the switch statement first and then tries 2nd time ..it seems it got the value..i could see that in the debugger but for some reason it says.."Unhandled exception at 0x00413429 in CopyData.exe: 0xC0000005: Access violation reading location 0x00000000." and just stays away from entering the statement...
kiddo
I noticed that you sent the message to yourself (m_hWnd), not the intended window (hWnd). Also, the FindWindow call is a little strange. MFC dialogs have a fixed class name (I think it's "#32770"). Better to use NULL for the class and just rely on the dialog title.
Bob Moore
Oh, I just read your earlier comment. No, if FindWindow returns NULL then nothing is going to work :-). You only thought it worked because you accidentally sent the message to m_hWnd. You really need to correct the parameters to FindWindow as I outlined above, and test the return value from that function before you do the SendMessage.
Bob Moore
If I dont mention the class name..it will not work..I did tested that..I think if we find out the cause of above exception..we can fix it..
kiddo
Note that the "class" name used in FindWindow is not the same as the "class" name of a C++ class. It refers to a different concept entirely, one that pre-dates C++. A window class is a "type" of window that Windows is told about when you register it. All the code for registering window classes is hidden in MFC.
Bob Moore
Oh I see...Is there any other fix..
kiddo
OK, so concentrate on fixing the FindWindow call. The class of an MFC dialog should be "#32770", so pass that as the class and the dialog title as the second parameter. Note that if this is an ANSI build you should use the string constants as is, if it's Unicode then you need the L modifier. I'm a bit worried about the way you specify all your strings as Unicode, but sometimes call ANSI api functions (like SendMessageA and MessageboxA). This seems very odd to me.
Bob Moore
I have to go to a meeting now, I'll check back in a while.
Bob Moore
I can try that now..but I have a small doubt..am able to pass the value to the Dialog1 class now...but somehow(i guess some memory problem)..it showing that access violation exception(that i mentioned earlier)..But what you are saying is, that, there should be some problem with FindWindow..if thats the case it shouldnt pass the value to the Dialog1 class itself...am i making sense..
kiddo
If you are receiving the WM_COPYDATA message in Dialog1, then let's proceed to look at the receive code. I'll post another answer, as this one is getting a little long-winded.
Bob Moore
okay Bob..that fine
kiddo
A: 

Further to my answer above, this is the receive code

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);
....

But there's another more basic question here... in an MFC application, overriding the WindowProc just to handle a basic message seems very odd.

Bob Moore
hm..tried it...problem in memcpy...jus giv ,me a min..i vl show the screen shot if possible
kiddo
bob..I just realized that its not sending the message...the condition (message == WN_COPYDATA) fails...I said that its able to send the data...but what I actually saw in the debugger is structure(which holds the value) of the CCopyDialogdlg but not the Dialog1 class structure..so like u said it should be the problem with FindWindow....
kiddo
I have to leave work now (to play golf). I'll try and pick this up again either later today, or Monday.
Bob Moore
Aaargh. I just looked back at your original code. At the point you call FindWindow, the window doesn't even exist, because you haven't called DoModal. No wonder FindWindow always fails. You can't find a window that doesn't exist yet !! A modal dialog exists for the duration of the DoModal call. You can't possibly get comms working with this app design. Dlg1 would have to become modeless. Then you could create it, send your message, and some later destroy it.
Bob Moore
oh Bob...I was working through that for along time..the above point you mentioned was really helpful..I was reading lot about this FindWindow...I atlast found a fix(woudnt happen without ur help,please check my answer..)..It was great that u assisted me with..You are very knowledgy..I would like to be in touch with Bob..my mail id is {[email protected]/[email protected]}..just send me a mail..v vl have a chat...hope u had a good time playin golf.bye
kiddo
A: 

I avoided to use WinProc..Instead of that I wrote a normal function(CopyData) in the class Dialog11..Created a modeless dialog in the class CCopyDialog1.. and called that function(CopyData)..It worked..Please check the below code...

//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;
}

Basically when compared to my previous code(code in my question)...theres lot of difference/mistakes..

1.In the sendmessage i passed the structure instead of COPYDATASTRUCT.. 2.Called FindWindow before calling the Dialog1 window.. 3.Used the function WinProc function to receive the message..which was very hard to make it work..then avoided that and used a normal function 4.Didnt pass a proper window handle... the above all are corrected by Bob Moore...credit goes to him....

kiddo