Still got problems with WM_COPYDATA message ! 
Author Message
 Still got problems with WM_COPYDATA message !

I have 2 MFC applikations and I would like to tell the one applikation what
to do from the other.

I have found out that it is possible to send data from one applikation to
another with the WM_COPYDATA message, but I can't get the SendMessage to
work. I have made my sendmessage function this way:

void CMainFrame::OnSendmessage()
{
 COPYDATASTRUCT CPDATA;

 CPDATA.dwData=9;
  CWnd *pWnd=CWnd::FindWindow("App1MainWnd",NULL);
 if (pWnd)
  pWnd->SendMessage(WM_COPYDATA,(WPARAM)m_hWnd,(LPARAM) &CPDATA); //never
comes here ???

Quote:
}

But pWnd is never TRUE, so FindWindow can't the applikation "App1MainWnd" I
have registered this way:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
 WNDCLASS MyReceiverClass;
 MyReceiverClass.lpszClassName="App1MainWnd";
 //RegisterClass(&MyReceiverClass);
 AfxRegisterClass(&MyReceiverClass);
 return CMDIFrameWnd::PreCreateWindow(cs);

Quote:
}

What AM I doing Wrong ???

Thomas



Mon, 15 Jan 2001 03:00:00 GMT  
 Still got problems with WM_COPYDATA message !
You can't get a pointer to a CWnd of a window running in a different
process.
Use PostMessage(). Don't specify a target window handle - let your app do
the filtering.
        Niki Estner


Mon, 15 Jan 2001 03:00:00 GMT  
 Still got problems with WM_COPYDATA message !
In the MFC documentation it is written that WM_COPYDATA message is to be
send with SendMessage and not PostMessage !!

But I have tried anyway, and got the following warning in my debug window:

Warning: No message line prompt for ID 0x80004

Thomas
----------------------------------------------------------------------------
--------------------------------------


Quote:
>You can't get a pointer to a CWnd of a window running in a different
>process.
>Use PostMessage(). Don't specify a target window handle - let your app do
>the filtering.
> Niki Estner



Mon, 15 Jan 2001 03:00:00 GMT  
 Still got problems with WM_COPYDATA message !
I've just tried using FindWindow but using the Window title to identify the
window and it worked ok.
Both apps were MFC Dialog Based Apps.

APPLICATION 2
void CApp2Dlg::OnButton1()
{
 // TODO: Add your control notification handler code here
 CWnd *pWnd=CWnd::FindWindow(NULL,"app1");

    COPYDATASTRUCT copyData;

    char *pData=new char[20];

    copyData.dwData=77;
    copyData.cbData=20 * sizeof(char);
    copyData.lpData=pData;

    int
i=pWnd->SendMessage(WM_COPYDATA,(WPARAM)GetSafeHwnd(),(LPARAM)&copyData);

    delete[]pData;

Quote:
}

APPLICATION 1
BOOL CApp1Dlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
 // TODO: Add your message handler code here and/or call default
 AfxMessageBox("WM_COPYDATA");
 return CDialog::OnCopyData(pWnd, pCopyDataStruct);

Quote:
}

If you don't actually send any data it does not appear to work
e.g
pWnd->SendMessage(WM_COPYDATA,(WPARAM)GetSafeHwnd(),NULL);
Quote:

>I have 2 MFC applikations and I would like to tell the one applikation what
>to do from the other.

>I have found out that it is possible to send data from one applikation to
>another with the WM_COPYDATA message, but I can't get the SendMessage to
>work. I have made my sendmessage function this way:

>void CMainFrame::OnSendmessage()
>{
> COPYDATASTRUCT CPDATA;

> CPDATA.dwData=9;
>  CWnd *pWnd=CWnd::FindWindow("App1MainWnd",NULL);
> if (pWnd)
>  pWnd->SendMessage(WM_COPYDATA,(WPARAM)m_hWnd,(LPARAM) &CPDATA); //never
>comes here ???

>}
>But pWnd is never TRUE, so FindWindow can't the applikation "App1MainWnd" I
>have registered this way:

>BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
>{
> WNDCLASS MyReceiverClass;
> MyReceiverClass.lpszClassName="App1MainWnd";
> //RegisterClass(&MyReceiverClass);
> AfxRegisterClass(&MyReceiverClass);
> return CMDIFrameWnd::PreCreateWindow(cs);
>}

>What AM I doing Wrong ???

>Thomas



Mon, 15 Jan 2001 03:00:00 GMT  
 Still got problems with WM_COPYDATA message !
I've just looked at the code you posted and it would appear that although
you regsitered the Window class you did not modify the CREATESTRUCT passed
into PreCreateWindow so that when the window is created it has your new
Window class.

i.e

cs.lpszClass="App1MainWnd";

If you do not do this the Window will be created wit the default Window
Class.

Quote:

>I have 2 MFC applikations and I would like to tell the one applikation what
>to do from the other.

>I have found out that it is possible to send data from one applikation to
>another with the WM_COPYDATA message, but I can't get the SendMessage to
>work. I have made my sendmessage function this way:

>void CMainFrame::OnSendmessage()
>{
> COPYDATASTRUCT CPDATA;

> CPDATA.dwData=9;
>  CWnd *pWnd=CWnd::FindWindow("App1MainWnd",NULL);
> if (pWnd)
>  pWnd->SendMessage(WM_COPYDATA,(WPARAM)m_hWnd,(LPARAM) &CPDATA); //never
>comes here ???

>}
>But pWnd is never TRUE, so FindWindow can't the applikation "App1MainWnd" I
>have registered this way:

>BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
>{
> WNDCLASS MyReceiverClass;
> MyReceiverClass.lpszClassName="App1MainWnd";
> //RegisterClass(&MyReceiverClass);
> AfxRegisterClass(&MyReceiverClass);
> return CMDIFrameWnd::PreCreateWindow(cs);
>}

>What AM I doing Wrong ???

>Thomas



Mon, 15 Jan 2001 03:00:00 GMT  
 Still got problems with WM_COPYDATA message !
One quick way to fix your problem is to register your class from inside the
InitInstance method in your app:

BOOL CMyApp::InitInstance()
{
 AfxEnableControlContainer();

 // Standard initialization
 // If you are not using these features and wish to reduce the size
 //  of your final executable, you should remove from the following
 //  the specific initialization routines you do not need.

#ifdef _AFXDLL
 Enable3dControls();   // Call this when using MFC in a shared DLL
#else
 Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif

///////////////////////////////////////////////////////////////////////////////

    // Add this code!

///////////////////////////////////////////////////////////////////////////////

    WNDCLASS MyReceiverClass;
    memset(&MyReceiverClass, NULL, sizeof(WNDCLASS));   // start with NULL
defaults

    // common initialization
    MyReceiverClass.lpfnWndProc = DefWindowProc;
    MyReceiverClass.hInstance = m_hInstance;
    MyReceiverClass.hCursor = NULL;
    MyReceiverClass.hIcon = LoadIcon(IDR_MAINFRAME);
    MyReceiverClass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
    MyReceiverClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
    MyReceiverClass.lpszMenuName = MAKEINTRESOURCE(IDR_MAINFRAME);
    MyReceiverClass.lpszClassName="App1MainWnd";

    AfxRegisterClass(&MyReceiverClass);

    .
    .
    .

Quote:
}

Now change your MainFrame object to look like this:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{

    // Set the window class name
    cs.lpszClass = "App1MainWnd";

     return CMDIFrameWnd::PreCreateWindow(cs);

Quote:
}

Try these two changes and see if your code works...

Chris Copenhaver

Quote:

> I have 2 MFC applikations and I would like to tell the one applikation what
> to do from the other.

> I have found out that it is possible to send data from one applikation to
> another with the WM_COPYDATA message, but I can't get the SendMessage to
> work. I have made my sendmessage function this way:

> void CMainFrame::OnSendmessage()
> {
>  COPYDATASTRUCT CPDATA;

>  CPDATA.dwData=9;
>   CWnd *pWnd=CWnd::FindWindow("App1MainWnd",NULL);
>  if (pWnd)
>   pWnd->SendMessage(WM_COPYDATA,(WPARAM)m_hWnd,(LPARAM) &CPDATA); //never
> comes here ???

> }
> But pWnd is never TRUE, so FindWindow can't the applikation "App1MainWnd" I
> have registered this way:

> BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
> {
>  WNDCLASS MyReceiverClass;
>  MyReceiverClass.lpszClassName="App1MainWnd";
>  //RegisterClass(&MyReceiverClass);
>  AfxRegisterClass(&MyReceiverClass);
>  return CMDIFrameWnd::PreCreateWindow(cs);
> }

> What AM I doing Wrong ???

> Thomas



Mon, 15 Jan 2001 03:00:00 GMT  
 Still got problems with WM_COPYDATA message !

Quote:

> You can't get a pointer to a CWnd of a window running in a different
> process.
> Use PostMessage(). Don't specify a target window handle - let your app do
> the filtering.
>         Niki Estner

Sorry Niki, but this is incorrect.  One point of this thread is how to
do just that.

   CWnd* p = CWnd::FindWindow(winclassname, m_hWnd, ....)

does it, if you know the winclassname.



Mon, 15 Jan 2001 03:00:00 GMT  
 Still got problems with WM_COPYDATA message !
The first question is,are you really finding the right instance of
your application?  I've had such ill luck using window classes that on
the whole I avoid this method, but if you use it, it is always a good
idea to use GUIGEN to create a guaranteed-unique window name, such as
        "App1MainWnd-{5037D2A0-2994-11d2-8868-00AA00080A1D}"

btw, pWnd will NEVER be "TRUE", since "TRUE" is the literal constant
value 1. The correct test is
        if(pWnd != NULL)

However, I think the problem is in the code where you call
AfxRegisterClass. The name you give is for a "receiver class" which is
not the class being created, and I don't see where you are
initializing any other members of the WNDCLASS structure. So there is
a chance the AfxRegisterClass would fail because of bogus data in the
WNDCLASS, and having registered the receiver class, you need to create
instances of it (by the time PreCreateWindow is called, the name of
the class that is being created is already determined). Hence your
receiver class window, if it exists at all (you don't show any
instances being created), is a child window, and FindWindow only
enumerates top-level windows. So either you have no instances of this
class, or they are all all child windows.

What I do to find a window I want is as follows:

Create a .h file containing the declaration
#define UWM_FIND_WINDOW_MSG =
"UWM_FIND_WINDOW-{5037D2A1-2994-11d2-8868-00AA00080A1D}"

Note the use of GUIDGEN to get a unique suffix string, which
guarantees that nobody, anywhere, can ever replicate your choice of
message string.

In both the client app (the one searching for the window) and server
app (the one with the window you want), add this declaration:

        static WORD UWM_FIND_WINDOW =  
                ::RegisterWindowMessage(UWM_FIND_WINDOW_MSG);

In the server app, add the following
        ON_REGISTERED_MESSAGE(UWM_FIND_WINDOW, OnFindWindow)

        LRESULT CMainFrame::OnFindWindow(WPARAM, LPARAM)
           {
             return (LRESULT)m_hWnd;
                 }

In the client app, add the following:

        CMyClientMainFrame::OnCreate(...)
            {
             PostMessage(UWM_LOCATE_TARGET);
            }

(This represents a bias I have about not doing too much during the
actual window creation.  UWM_LOCATE_TARGET is a user-defined message
local to your client app, which my choice is to always use a
registered window message; I no longer believe in WM_USER+n for
anything because I've been done in by too many controls that use
WM_USER+n for their own purposes)

In the client app:
        LRESULT CMyClientMainFrame::OnLocateTarget(WPARAM, LPARAM)
            {
             target = NULL;
             ::EnumWindows(findApplication, (LPARAM)this);
             // ... if target is non-NULL, it is the handle of the
             // destination
            }

// Declare this function as 'static'!!!!!!
BOOL CALLBACK CRCONInterfaceDlg::findApplication(HWND hWnd, LPARAM
lParam)
    {
     CMyClientMainFrame* self = (CMyClientMainFrame *)lParam;
     return self->finder(hWnd, UWM_QUERY_RCON, self->hClient);
    }

BOOL CMyClientMainFrame::finder(HWND hWnd)
    {
     HWNDh = (HWND)::SendMessage(hWnd, UWM_FIND_WINDW, 0, 0);

     if(h == NULL)
        return TRUE;  // not our window, continue search

     target = hWnd;
     return FALSE; // no more searching required
    }

While a bit more elaborate than FindWindow, I find it more reliable. I
do not consider the window class name a  decent or valid
representative of the thing I am looking for, since it encodes
"secret" information and introduces a hidden dependency. I've been
done in by this too often to want to take advantage of it any longer.

The code may seem a bit tedious, but I've written it only once, and it
migrates to all my client/server-style applications (I currently have
one with three components). A variant of this theme is that the
SendMessage includes the window handle of the sending window as wParam
or lParam, so the recipient can find the window to send stuff back to
by storing the wParam or lParam value itself.
                                joe



Quote:
>I have 2 MFC applikations and I would like to tell the one applikation what
>to do from the other.

>I have found out that it is possible to send data from one applikation to
>another with the WM_COPYDATA message, but I can't get the SendMessage to
>work. I have made my sendmessage function this way:

>void CMainFrame::OnSendmessage()
>{
> COPYDATASTRUCT CPDATA;

> CPDATA.dwData=9;
>  CWnd *pWnd=CWnd::FindWindow("App1MainWnd",NULL);
> if (pWnd)
>  pWnd->SendMessage(WM_COPYDATA,(WPARAM)m_hWnd,(LPARAM) &CPDATA); //never
>comes here ???

>}
>But pWnd is never TRUE, so FindWindow can't the applikation "App1MainWnd" I
>have registered this way:

>BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
>{
> WNDCLASS MyReceiverClass;
> MyReceiverClass.lpszClassName="App1MainWnd";
> //RegisterClass(&MyReceiverClass);
> AfxRegisterClass(&MyReceiverClass);
> return CMDIFrameWnd::PreCreateWindow(cs);
>}

>What AM I doing Wrong ???

>Thomas

Joseph M. Newcomer

http://www3.pgh.net/~newcomer


Thu, 18 Jan 2001 03:00:00 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Problem in sending WM_COPYDATA message

2. Marshaling problem using WM_COPYDATA and byte[]

3. WM_COPYDATA Problems (urgent) ...

4. Problem getting ctrl+x message

5. Problem with WM_COPYDATA

6. I am having problem sending WM_COPYDATA message to a 16bit app.

7. Gets a more detail error message

8. Getting error message while calling a method of the ATL object from ASP

9. Not getting enough messages

10. Not getting the message, ActiveX control in ATL dialog

11. Getting Mouse position when a message happens

12. Getting a dialog to receive WM_CHAR messages.

 

 
Powered by phpBB® Forum Software