Link to home
Start Free TrialLog in
Avatar of sarath83
sarath83

asked on

WM_COPYDATA need to correct errors.any one help me

I have used a structure and the following code . i am getting error access violation when message is sent to destination window. i am not able find were the error lies. plz any one help  me .
typedef struct tagSII{
      long lsessionID;
      long lqueue;
                CString  sCommand;
}SII ;
//Sending window
CWnd *pPdmm;

LRESULT lresult;
COPYDATASTRUCT copy;
HANDLE hWnd(this);

SII sii;       
      
  pPdmm = CWnd::FindWindow(NULL,"di");
 if(pPdmm == NULL){
  MessageBox("Would not find",NULL,MB_OK);
 }
else{
      sii.lsessionID = 4;
      sii.lqueue     = 5;
      sii.sCommand ="ab";
            
      copy.dwData =500;
      copy.cbData = sizeof(sii);
      copy.lpData = &sii;
lresult =pPdmm->SendMessage(WM_COPYDATA,(WPARAM)(HWND)m_hWnd,(LPARAM)(LPVOID)   &copy);
            
      }

      if ( lresult== TRUE)
            MessageBox("posted",NULL,MB_OK);
      else
            MessageBox("Failed",NULL,MB_OK);

//Receiving window

BOOL CDiDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
      if( pCopyDataStruct->cbData == sizeof(SII ) )
            {
                  SII sii1;
                  SII sii2;
            memcpy( &sii1, pCopyDataStruct->lpData, sizeof( SII ) );
           sii2.lsessionID=sii1.lsessionID;
             sii2.lqueue    =sii1.lqueue;
              sii2.sCommand      =sii2.sCommand;
         
             MessageBox(sii1.sCommand);
             return TRUE;
            }
 return FALSE;

}

Avatar of martynjpearson
martynjpearson

I'm not sure about the validity of doing the line

memcpy( &sii1, pCopyDataStruct->lpData, sizeof( SII ) );

This is all very well when copying basic data, but I'm fairly certain that this will not set up the CString correctly. You would be better off to do a cast instead, like this :

SII * pSII = (SII *)pCopyDataStruct->lpData
sii1.sCommand = pSII->sCommand; etc

Hope this helps
Martyn
Avatar of sarath83

ASKER

i am getting the error"memory cannot b read" when i send the message
I've had a look at the documentation for WM_COPYDATA, and came across the line :

"The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data. "

What this means is that your SII struct can't contain pointers to local memory, and I would imagine that it is the CString that is causing the problem. Instead, you could have a character buffer in SII instead of a CString, or you'd have to dynamically allocate a chunk of memory to hold your SII members and the string, and then copy the data into it for sending.

So, something like this :

long lBufferLength = sizeof(long) + sizeof(long) + sCommand.GetLength() + 1
BYTE * pBuffer = new BYTE(lBufferLength);

memcpy(pBuffer, &sii.lsessionID, sizeof(long));
memcpy(pBuffer, &sii.lqueue, sizeof(long));
strcpy((char *)&pBuffer[sizeof(long) + sizeof(long)], sCommand);

Then send pBuffer as the data.

All the best
Martyn


is there any onther technique  available to do this
When you set up the COPYDATASTRUCT structure, you pass it a pointer to some data. It doesn't matter what the data is, but it cannot include pointers to other data. So, in other words, all the data you want to be copied has to be within that structure - with no pointers to any other data.

So, one approach is the one that I have suggested above, where you allocate a buffer, place your data into it and send it. Another approach could be to replace your CString with a fixed length character array in SII. However, this is less flexible as the number of charcters you send is fixed, and of course there will always be an upper limit. If you are always sending the same number of characters, this is fine, but what if you could send anywhere between 1 and 64,000 characters - you wouldn't want to have an array of 64,000 chars as that would mean that you are copying 64k EVERY time - even if you are really only sending one character.

Martyn
Then hw to  retrieve the data in destination window. I wish to send using CString .
Assuming when sending the data, you have built up a buffer containing the longs, and the characters of the string, you can do the following to put your data back together :

BOOL CDiDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
    SII sii;
    memcpy( &sii1.lsessionID, pCopyDataStruct->lpData, sizeof(long) );
    memcpy( &sii1.lsessionID, pCopyDataStruct->lpData, sizeof(long) );
    sii1.sCommand = CString((const char *)&pCopyDataStruct->lpData[sizeof(long) + sizeof(long)]);

    return TRUE;
}


Martyn
Can I use this lines to send data

                                copy.dwData =500;
            copy.cbData = sizeof(pBuffer);
            copy.lpData = &pBuffer;
            lresult =pPdmm->SendMessage(WM_COPYDATA,(WPARAM)(HWND)m_hWnd,(LPARAM) &pBuffer);
please help me out hw to do this .i am trying this for a very long time.
sii1.sCommand = CString((const char *)&pCopyDataStruct->lpData[sizeof(long) + sizeof(long)]);
for the above line i am getting error :

 C2036: 'void *' : unknown size
ASKER CERTIFIED SOLUTION
Avatar of martynjpearson
martynjpearson

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Mr.Martyn Thanku very much . its working . Can u plz suggets me which books to follow to learn VC++ . I am a beginner.
No problems - glad it's working now!

With regards to books, that's a tricky one, as the ones that I learnt from are probably no longer in print!! I learnt C and C++ at university, and then when I started programming for Windows (using Visual C++ 4.0 on Windows 95!!!) I had a book published by Sams, called Essential Visual C++ 4.0. This was quite good in that it covered all the basics, like dialogs, documents etc, and then went on to cover the basics of graphics using brushes, pens etc.

In the past, I have found the Wrox books to be of consistently high quality - check out www.wrox.com - and they generally do books that are aimed at a particular level, such as beginner, intermediate, expert etc.

All the best!
Martyn