FindWindow and Data Copy Problem
Hi,
I want to exchange data between two MFC applications.So
I created two MFc application and I have a problem with
FindWindow() function to proceed with data copy.
In one appication I have following code to register the class in InitInstance()
LPCTSTR lpszUniqueClass = _T("ASANKATEST");
WNDCLASS wndcls;
memset(&wndcls, 0, sizeof(WNDCLASS));
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hIcon = LoadIcon(IDR_MAINFRAME); //
wndcls.hCursor = LoadCursor( IDC_ARROW );
wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = lpszUniqueClass;
// Register new class and exit if it fails
if(!AfxRegisterClass(&wndcls)) {
TRACE("Class Registration Failed\n");
MessageBox(NULL, L"Class Registration Failed", NULL, NULL);
}else{
MessageBox(NULL, L"Class Registration Successfull", NULL, NULL);
}
Then after in another MFC application which is dialog based i have called
HWND hWindow = ::FindWindow(lpszUniqueClass,NULL);
if(hWindow == NULL){
AfxMessageBox(L" NOT found Application");
}
It says that class registration is successful but FindWindow is not working.Can any one help please..
Asanka
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
23-Jun-08
dwData is DWORD i.e. 32 bits, so it is not possible to use a GUID (because a
GUID is 128 bits) here.
But it could be possible to put a GUID as header bytes for
COPYDATASTRUCT.lpData .
Giovanni
Previous Posts In This Thread:
On Monday, June 16, 2008 10:39 AM
Anders Eriksson wrote:
WM_COPYDATA between two applications
Hello,
I'm running VC++ 2005.
I have two program and want to exchange some data, a string, between them.
In the sender program I have this function:
BOOL CFSGClientDlg::SendCommand(CString command)
{
COPYDATASTRUCT cds;
LRESULT rc;
TCHAR *buf;
buf = new TCHAR[MAX_COPY_LENGTH];
memset(buf,'\0',MAX_COPY_LENGTH);
_tcscpy_s(buf,MAX_COPY_LENGTH,sOrderno.GetBuffer());
sOrderno.ReleaseBuffer();
cds.dwData = 0;
cds.cbData = sOrderno.GetLength()+1;
cds.lpData = (void*)buf;
rc = m_pSCMLaserCWnd->SendMessage(WM_COPYDATA,
(WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(),
(LPARAM)&cds);
if (rc ==NULL)
{
DWORD errcode = GetLastError();
return false;
} // if (rc==NULL)
return true;
}
And in the receiver program I have this:
BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
CString sData=(TCHAR*)(pCopyDataStruct->lpData);
..... doing stuff with sData...
return CFrameWnd::OnCopyData(pWnd, pCopyDataStruct);
}
I can see that the string I send is OK, but when I get to the receiving
part I get a couple of characters correkt and then just rubbish...
What have I done wrong?
// Anders
--
English is not my first, or second, language
so anything strange, or insulting, is due to
the translation.
Please correct me so I may improve my English!
On Monday, June 16, 2008 10:51 AM
AliR \(VC++ MVP\) wrote:
Do both of your applications have the same unicode settings?
Do both of your applications have the same unicode settings?
should this line:
be:
AliR.
On Monday, June 16, 2008 11:02 AM
Anders Eriksson wrote:
Re: WM_COPYDATA between two applications
On Mon, 16 Jun 2008 09:51:36 -0500, AliR (VC++ MVP) wrote:
Hello AliR,
Yes both applications has the same unicode settings and I have changed to
the above but I still get rubbish.
The string that I send is "test4" and the string I receive is "tes??????????????????"
I think is has something to do with me using unicode but I can't figure out
what I have done wrong?
// Anders
--
English is not my first, or second, language
so anything strange, or insulting, is due to
the translation.
Please correct me so I may improve my English!
On Monday, June 16, 2008 11:16 AM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
it is:
cds.cbData = sOrderno.GetLength() * sizeof(TCHAR);
(scale * by sizeof(TCHAR))
Giovanni
On Monday, June 16, 2008 11:21 AM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
"Anders Eriksson" <andis59@gmail.com> ha scritto nel messaggio
news:1s37n3yj1am4g.dlg@ostling.com...
Pass input string by reference:
BOOL CFSGClientDlg::SendCommand(const CString & command)
Do:
memset( buf, 0, MAX_COPY_LENGTH * sizeof( TCHAR ) );
or
ZeroMemory( buf, MAX_COPY_LENGTH * sizeof( TCHAR ) );
No need of GetBuffer here; try this:
_tcscpy_s(buf, MAX_COPY_LENGTH, sOrderno );
That should be OK (there's implicit LPCTSTR conversion operator defined for
CString).
The above should be:
cds.cbData = (sOrderno.GetLength()+1) * sizeof(TCHAR);
Giovanni
On Monday, June 16, 2008 11:30 AM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
"Giovanni Dicanio" <giovanni.dicanio@invalid.com> ha scritto nel messaggio
news:Owbh6T8zIHA.3920@TK2MSFTNGP02.phx.gbl...
BTW: why do you allocate a fixed size "big" buffer (using MAX_COPY_LENGTH) ?
You may consider not wasting memory, and just allocate required bytes:
// Number of TCHAR's, including NUL end-of-string (+1)
int tcharCount = command.GetLength() + 1;
// Allocate buffer to store them
TCHAR * buf = new TCHAR[ tcharCount ];
// Copy from original string
StringCchCopy( buf, tcharCount, command );
...
cds.cbData = tcharCount * sizeof(TCHAR);
Moreover, note that someone must delete[] the buffer allocated new[]. Else,
you will have memory leaks.
HTH,
Giovanni
On Monday, June 16, 2008 11:37 AM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
"AliR (VC++ MVP)" <AliR@online.nospam> ha scritto nel messaggio
news:z5v5k.5263$N87.121@nlpi068.nbdc.sbc.com...
I believe AliR meant * sizeof(TCHAR) (not + ).
However, there is also the need to transmit NUL (0 end-of-string).
So (...GetLength() + 1) * sizeof(TCHAR) should be used.
Giovanni
On Monday, June 16, 2008 11:47 AM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
Not related to your problem, but I think worth correcting:
.....
The function returns BOOL, so you should use TRUE and FALSE instead of
'true' and 'false' (which are fine for 'bool').
Giovanni
On Monday, June 16, 2008 12:16 PM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
"Anders Eriksson" <andis59@gmail.com> ha scritto nel messaggio
news:1s37n3yj1am4g.dlg@ostling.com...
I did a small MFC test using a dialog-based app, and developed this routine
for sending (it works for me in Unicode builds with VS2008):
<code>
BOOL CDataSenderDlg::SendCommand( const CString & command )
{
// Number of TCHAR's, including terminating NUL
int charCount = command.GetLength() + 1;
// Dynamically allocate buffer for string
TCHAR * buf = new TCHAR[ charCount ];
// Copy source string to destination buffer
_tcscpy_s( buf, charCount, command );
// Prepare structure for WM_COPYDATA
COPYDATASTRUCT copyData;
copyData.dwData = /* some ID code here... */;
copyData.cbData = charCount * sizeof(TCHAR);
copyData.lpData = (void * )buf;
// Send message
BOOL processed = (BOOL) m_pWndReceiver->SendMessage(
WM_COPYDATA,
reinterpret_cast<WPARAM>( this->GetSafeHwnd() ),
reinterpret_cast<LPARAM>( ©Data )
);
// Cleanup allocated buffer
delete[] buf;
buf = NULL;
if ( !processed )
{
// ... do something for error here
return FALSE;
}
// All right
return TRUE;
}
</code>
HTH,
Giovanni
On Monday, June 16, 2008 2:51 PM
AliR \(VC++ MVP\) wrote:
Re: WM_COPYDATA between two applications
Hi Giovanni,
Thanks for correcting my mistake. :)
AliR.
On Monday, June 16, 2008 3:19 PM
Karsten Schulz wrote:
Hi Anders,u cant copy data from one process to another.
Hi Anders,
u cant copy data from one process to another. Inprocess
u can handel WM_COPYDATA so:
void CBitmapView::SendCopyData(CLICKEVENT Event,CPoint pt /*=CPoint(0,0)*/)
{
if(!m_pParentWnd || !m_pParentWnd->m_hWnd)
return;
CCrossFocus *pHair = m_gdiobj.GetFocus();
int id=-1;
if(pHair)
{
pt = pHair->GetFocus();
id = pHair->GetId();
}
m_vclick.PosX = pt.x;
m_vclick.PosY = pt.y;
m_vclick.FocusId = id;
m_vclick.PixelUnit = m_gdiobj.GetPixelUnits();
m_vclick.Event = Event;
m_pParentWnd->SendMessage(WM_COPYDATA,(WPARAM)(HWND) m_hWnd,(LPARAM)
(LPVOID) &m_MyCDS);
}
"Anders Eriksson" <andis59@gmail.com> schrieb im Newsbeitrag
news:1s37n3yj1am4g.dlg@ostling.com...
On Monday, June 16, 2008 3:22 PM
Karsten Schulz wrote:
Hi Anders,u cant copy data from one process to another.
Hi Anders,
u cant copy data from one process to another. Inprocess
u can handel WM_COPYDATA so:
typedef struct ViewClick
{
int PosX;
int PosY;
int FocusId;
double PixelUnit;
CLICKEVENT Event;
}VIEWCLICK;
void CBitmapView::SendCopyData(CLICKEVENT Event,CPoint pt /*=CPoint(0,0)*/)
{
if(!m_pParentWnd || !m_pParentWnd->m_hWnd)
return;
CCrossFocus *pHair = m_gdiobj.GetFocus();
int id=-1;
if(pHair)
{
pt = pHair->GetFocus();
id = pHair->GetId();
}
m_vclick.PosX = pt.x;
m_vclick.PosY = pt.y;
m_vclick.FocusId = id;
m_vclick.PixelUnit = m_gdiobj.GetPixelUnits();
m_vclick.Event = Event;
m_pParentWnd->SendMessage(WM_COPYDATA,(WPARAM)(HWND) m_hWnd,(LPARAM)
(LPVOID) &m_MyCDS);
}
After send data u can handle it in your Dialog :
BOOL CCamInspectTestDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT*
pCopyDataStruct)
{
VIEWCLICK *pVclk=0;
if(pCopyDataStruct->dwData == VIEWCLICKMSG)
if(pCopyDataStruct->cbData == sizeof(VIEWCLICK))
if((pVclk = (VIEWCLICK *)pCopyDataStruct->lpData))
{
double cal(pVclk->PixelUnit);
CString str; str.Format("X(%0.4f):Y(%0.4f) Cal(%0.4f) Id(%d) Evt(%d)",
pVclk->PosX*cal,pVclk->PosY*cal,cal,pVclk->FocusId,pVclk->Event);
SetWindowText(str);
}
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}
"Anders Eriksson" <andis59@gmail.com> schrieb im Newsbeitrag
news:1s37n3yj1am4g.dlg@ostling.com...
On Monday, June 16, 2008 5:46 PM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
"AliR (VC++ MVP)" <AliR@online.nospam> ha scritto nel messaggio
This kind of typos can happen to everyone when we do not use the compiler to
build the code.
Giovanni
On Monday, June 16, 2008 8:31 PM
David Ching wrote:
Re: WM_COPYDATA between two applications
I am sorry, but this is not true. WM_COPYDATA marshalls the data across
process boundaries. That is in fact why it exists!
-- David
On Tuesday, June 17, 2008 1:04 AM
Anders Eriksson wrote:
Re: WM_COPYDATA between two applications
On Mon, 16 Jun 2008 16:39:40 +0200, Anders Eriksson wrote:
Thank you all for your answers! A special Thank You to mr Giovanni Dicanio
that took the time to explain in detail!
// Anders
--
English is not my first, or second, language
so anything strange, or insulting, is due to
the translation.
Please correct me so I may improve my English!
On Tuesday, June 17, 2008 3:39 AM
Karsten Schulz wrote:
Re: WM_COPYDATA between two applications
ok nice, but code works.
On Tuesday, June 17, 2008 10:30 AM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
You're welcome Anders.
BTW: "Giovanni" works better than "Mr. Giovanni Dicanio" ;-)
Giovanni
On Wednesday, June 18, 2008 5:12 PM
Tom Serface wrote:
Re: WM_COPYDATA between two applications
Or there is always "G" :o)
Tom
On Wednesday, June 18, 2008 6:23 PM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
Yes :-)
G
On Sunday, June 22, 2008 8:56 PM
Joseph M. Newcomer wrote:
Actually, I would not use 'new'. I would doCByteArray buf;buf.
Actually, I would not use 'new'. I would do
CByteArray buf;
buf.SetSize( (command.GetLength() + 1) * sizeof(TCHAR));
and do
cds.cbData = buf.GetSize();
and
cds.lpData = buf.GetData();
so there would be no need to remember to do the delete at all.
In addition, I have been seriously done in by irresponsible programmers who did a
SendMessage(HWND_BROADCAST, WM_COPYDATA, ...)
so I now put a GUID as the first 128 bits of the message and double-check it; see my essay
on WM_COPYDATA.
joe
On Mon, 16 Jun 2008 17:30:06 +0200, "Giovanni Dicanio" <giovanni.dicanio@invalid.com>
wrote:
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
On Monday, June 23, 2008 4:17 AM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
"Joseph M. Newcomer" <newcomer@flounder.com> ha scritto nel messaggio
news:5vst54dfklnsarqdgjil3g910ufrmrkg4e@4ax.com...
I agree with you about using a container class.
I would use std::vector< BYTE >.
I used 'new' just to keep the code as near as possible to original OP's
version.
I do agree with you.
In fact in code I posted I wrote "some ID code here ..." (and GUID you
suggested is an excellent option, of course).
<code>
.....
// Prepare structure for WM_COPYDATA
COPYDATASTRUCT copyData;
copyData.dwData = /* some ID code here... */;
.....
</code>
Giovanni
On Monday, June 23, 2008 4:34 AM
Giovanni Dicanio wrote:
Re: WM_COPYDATA between two applications
dwData is DWORD i.e. 32 bits, so it is not possible to use a GUID (because a
GUID is 128 bits) here.
But it could be possible to put a GUID as header bytes for
COPYDATASTRUCT.lpData .
Giovanni
Submitted via EggHeadCafe - Software Developer Portal of Choice
Adding WCF Service References
http://www.eggheadcafe.com/tutorials/aspnet/a1647f10-9aa4-4b0c-bbd9-dfa51a9fab8e/adding-wcf-service-refere.aspx