• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 544
  • Last Modified:

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;

}

0
sarath83
Asked:
sarath83
  • 7
  • 6
1 Solution
 
martynjpearsonCommented:
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
0
 
sarath83Author Commented:
i am getting the error"memory cannot b read" when i send the message
0
 
martynjpearsonCommented:
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


0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
sarath83Author Commented:
is there any onther technique  available to do this
0
 
martynjpearsonCommented:
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
0
 
sarath83Author Commented:
Then hw to  retrieve the data in destination window. I wish to send using CString .
0
 
martynjpearsonCommented:
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
0
 
sarath83Author Commented:
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);
0
 
sarath83Author Commented:
please help me out hw to do this .i am trying this for a very long time.
0
 
sarath83Author Commented:
sii1.sCommand = CString((const char *)&pCopyDataStruct->lpData[sizeof(long) + sizeof(long)]);
for the above line i am getting error :

 C2036: 'void *' : unknown size
0
 
martynjpearsonCommented:
Firstly, on the receive side, my code needs a couple of changes :

   BYTE * pData = (BYTE *)pCopyDataStruct->lpData;
 SII sii;
    memcpy( &sii1.lsessionID, pData, sizeof(long) );
    memcpy( &sii1.lqueue, &pData[sizeof(long)], sizeof(long) );
    sii1.sCommand = CString((const char *)&pData[sizeof(long) + sizeof(long)]);

    return TRUE;

That should solve your C2036 error.

For sending the data, your code needs to be like this :

copy.dwData =500;
copy.cbData = lBufferLength;
copy.lpData = pBuffer;
lresult =pPdmm->SendMessage(WM_COPYDATA,(WPARAM)(HWND)m_hWnd,(LPARAM)(LPVOID)   &copy);


Martyn
0
 
sarath83Author Commented:
Mr.Martyn Thanku very much . its working . Can u plz suggets me which books to follow to learn VC++ . I am a beginner.
0
 
martynjpearsonCommented:
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
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now