Click here to Skip to main content
Click here to Skip to main content

Sending a message to the Main Frame Window of Another Application, given only the Process Handle

, 8 Dec 1999
Rate this:
Please Sign up or sign in to vote.
Explains how to send a message between windows when you only have the Process handle
<!-- Article Starts -->

In order to send a message to another process, it is necessary to know the handle of the receiving window. However, if that process is created using CreateProcess or opened using OpenProcess, only the handles of the process and of it's main thread are known.

It is normally possible to find the window, if the title is known, simply by enumerating all windows and searching for the right window. When the name is unknown however, it is a little more complex to get its handle.

In order to find that handle it is, however, possible to scan all top-level windows and compare each window process Id with the Id received from the CreateProcess or the OpenProcess function. Please take note that not all Windows messages can be sent between processes. It is why use WM_COPYDATA is recommended.

Finally, remember that the message will need to be sent to the Main Frame. If it is intended for a child window ( a CView-derived class, for example ), it should be sent to the Main Frame, and then redirected in the target application.

In a private communication with a Senior Support Engineer at Microsoft, it has been noted that there is no guarantee that a process has any windows at all. It is also possible that a process has more than one window. Even if you get the correct window, it must know about and be able to handle the message being sent. A window always has a process, but a process can have zero to any number of windows, so there is no way to make a correlation between a process and a particular window.

I personally recommand a lot of care when using this method. However, this technique is working well in my projects, and I now use it for all inter-process communication. Furthermore, since I have included my code in several different projects, I have found only two problems with this code:

  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; 
    	} 
    }
    

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Martin-Pierre Frenette
Web Developer
Canada Canada
No Biography provided

Comments and Discussions

 
GeneralMy vote of 1 PinmemberRavindran Shanmugam12-Jul-10 8:36 
Generalmight help: similar business solution PingroupSymfund10-Oct-09 14:34 
Questionblock messages from other applications ?? [modified] Pinmemberkob-kob24-May-09 6:06 
QuestionHow HWND_BROADCAST Works? PinmemberEsonix22-Feb-07 0:56 
GeneralFacing problem while getting Handle of an Application PinmemberRaj241128-Mar-06 23:06 
GeneralRe: Facing problem while getting Handle of an Application Pinmembertor sen3-Apr-06 22:30 
GeneralRe: Facing problem while getting Handle of an Application PinmemberRaj24114-Apr-06 0:41 
GeneralThank you Pinmembertsurutsuru18-Apr-05 6:14 
Questionhow to use it Pinmemberroel the reds2-Nov-04 20:16 
GeneralGive me some example of inter process communication using call back function Pinmemberumer shabbir25-Aug-04 20:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141030.1 | Last Updated 9 Dec 1999
Article Copyright 1999 by Martin-Pierre Frenette
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid