1. The Process must have finished it’s initialization. This can be verified with the following call made before the call to SendMessage :
    WaitForInputIdle( ProcessInfo.hProcess, INFINITE );
  2. The Process must be receiving its messages. In order to go around this problem, I place my calls to SendMessageToProcess in a while loop, which waits to the receiving application to send back a WM_COPYDATA message confirming reception.

To add a function that send a message to a Process, perfoms the steps listed bellow. NOTE: These steps assume that the name of the CWinApp-derived object is CMyWinApp.

  1. Add the Following members to the declaration of CMyWinApp in MYWINAPP.H:
    public:
    	void SendMessageToProcess(LPPROCESS_INFORMATION lpProcessInformation, 
    	                          UINT Msg, WPARAM wParam, LPARAM lParam);
    protected:
    	static BOOL CALLBACK EnumWindowCallBack(HWND hwnd, LPARAM lParam);
    
  2. Define the CMyWinApp::SendMessageToProcess function.
    void CMyWinApp:: SendMessageToProcess(LPPROCESS_INFORMATION lpProcessInformation, 
                                          UINT Msg, WPARAM wParam, LPARAM lParam)
    {
    	FINDWINDOWHANDLESTRUCT fwhs;
    	fwhs.ProcessInfo = lpProcessInformation;
    	fwhs.hWndFound  = NULL;
    
    	EnumWindows ( EnumWindowCallBack, (LPARAM)&fwhs ) ;
    
    	SendMessage ( fwhs.hWndFound, Msg, wParam, lParam );
    }
    
  3. Define the CMyWinApp::EnumWindowCallBack function.
    BOOL CALLBACK CMyWinApp::EnumWindowCallBack(HWND hwnd, LPARAM lParam) 
    { 
    	FINDWINDOWHANDLESTRUCT * pfwhs = (FINDWINDOWHANDLESTRUCT * )lParam; 
    	DWORD ProcessId; 
    	CString Title; 
    	GetWindowThreadProcessId ( hwnd, &ProcessId ); 
    
    	// note: In order to make sure we have the MainFrame, verify that the title 
    	// has Zero-Length. Under Windows 98, sometimes the Client Window ( which doesn't 
    	// have a title ) is enumerated before the MainFrame 
    
    	CWnd::FromHandle( hwnd )->GetWindowText(Title);
    	if ( ProcessId  == pfwhs->ProcessInfo->dwProcessId && Title.GetLength() != 0) 
    	{ 
    		pfwhs->hWndFound = hwnd; 
    		return false; 
    	} 
    	else 
    	{ 
    		// Keep enumerating 
    		return true; 
    	} 
    }
Advertisements