CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Mar 2007
    Posts
    210

    getting WindowHandle from CreateProcess

    Hi,

    I'm having a small problem using Create process. I'm trying to run an external program using createProcess(). This is working fine and the program (i'm testing it using calc) is loading ok. Now i want to get hold of the window handle (HWND__*) of the new process in this case calc.

    I've tried the following code however it crashes out. Can anyone tell me whats going wrong with the code or another method to retrieve this handle?

    Code:
    STARTUPINFO siStartInfo;
    PROCESS_INFORMATION piProcessInfo;
    
    GetStartupInfo(&siStartInfo);
    CreateProcess(NULL, "Calc", NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,&piProcessInfo);
    		
    AppHook = FindProgWindow("Calculator");
    FindProgWindow("prog name"); is a methos i have in a DLL. this is simply

    Code:
    DllExport HWND__* WINAPI FindProgWindow(CString progName)
    {
    	return FindWindow(NULL, progName);
    }
    The program breaks out with the message

    User breakpoint called from code at 0x7c901230

    I have also tried replacing FindProgWindow("Calculator"); with FindWindow(NULL, "Calculator"); and this just returns 0.

    Any Ideas?
    thanks Matt.

  2. #2
    Join Date
    Feb 2002
    Posts
    4,640

    Re: getting WindowHandle from CreateProcess

    Well:

    http://msdn.microsoft.com/library/de...findwindow.asp

    What does "GetLastError" return when FindWindow returns 0?

    Viggy

  3. #3
    Join Date
    Mar 2007
    Posts
    210

    Re: getting WindowHandle from CreateProcess

    Hi,

    Thanks for the reply i've worked the problem out with using findWindow(). I simply needed to use the sleep(70) to wait until the program has loaded before i try and hook into.

    It now adds my button to the calculator but is still causing problems as clicking it does nothing and it is not refreshing the button if another window is moved over it. I know the hooks are being created as neither are returning zero.

    (These are events i have had working before as at first i had it as an Win32 application, however as i now don't want the form to appear i have rewritten it as a console application.)

    Can anyone help?

    Matt.

  4. #4
    Join Date
    Mar 2007
    Posts
    210

    Re: getting WindowHandle from CreateProcess

    Delving deeper the problem seems to be with my getMessage() command as once i have loaded the program added my button and hooked into it i then want to poll the program until WM_QUIT is retrieved, once this happens i can unhook and exit.

    heres the code can anyone see what im doing wrong?

    Code:
    	while( GetMessage(NULL,ThisHook,0,0) )
    	{
    	//do nothing until =0 and wm_quit is called
    	}
    
    	return 0;

  5. #5
    Join Date
    Dec 2003
    Location
    Spain
    Posts
    52

    Re: getting WindowHandle from CreateProcess

    I think there was a command named GetHandleFromPid in FBSL, a basic language

  6. #6
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,244

    Re: getting WindowHandle from CreateProcess

    1. Quote Originally Posted by flynny1st
      I simply needed to use the sleep(70) to wait until the program has loaded before i try and hook into.
      Are you sure that sleeping 70ms is always enough (could be too much as well)?
      Safer, once you have called CreateProcess and yo've got the handle to that process, you can use WaitForInputIdle to wait until that process has finished its initialization.
    2. Quote Originally Posted by flynny1st
      Code:
      FindWindow(NULL, progName);
      Generally, the worst idea is to find a window given its text.
      Better, in case of calc application you can use its main window class name ("SciCalc") or, better than better, once you have called CreateProcess and you've got the ID of main thread, you can use EnumThreadWindows

    Here is a complete example:
    Code:
    HWND hWndCalc = NULL;
    
    BOOL CALLBACK EnumThreadWndProc(HWND hWnd, LPARAM lParam)
    {
       hWndCalc = hWnd; // got the calc main window...
       // ... start hooking or whatever, then...
       return FALSE; // ...stop enum
    }
    // ...
       STARTUPINFO siStartInfo = {0};
       PROCESS_INFORMATION piProcessInfo = {0};
    
       CreateProcessA(NULL, "Calc", 
                          NULL, NULL, FALSE, 0, NULL, NULL,
                          &siStartInfo,&piProcessInfo);
    
       if(0 == WaitForInputIdle(piProcessInfo.hProcess, 5000))
       {
          EnumThreadWindows(piProcessInfo.dwThreadId, 
                                EnumThreadWndProc, NULL);
       }
       else
       {
          MessageBoxA(NULL, "Could not start calculator",
                            "Error", MB_OK|MB_ICONERROR);
       }
    // ...
    Last edited by ovidiucucu; April 23rd, 2007 at 07:03 PM.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  7. #7
    Join Date
    Mar 2002
    Location
    St. Petersburg, Florida, USA
    Posts
    12,125

    Re: getting WindowHandle from CreateProcess

    I wholeheartedly support the use of EnumThreadWindows. It has proven (to me) that it is the most reliable, and typically the most performant. I have had some issues during stress testing on Win-2000 Advanced Server, if I have over about 700 main windows open (and am nearly at resource exhaustion). But I have never found this to be a real world scenario.
    TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
    2008, 2009,2010
    In theory, there is no difference between theory and practice; in practice there is.

    * Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions
    * How NOT to post a question here
    * Of course you read this carefully before you posted
    * Need homework help? Read this first

  8. #8
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,244

    Re: getting WindowHandle from CreateProcess

    Quote Originally Posted by TheCPUWizard
    But I have never found this to be a real world scenario.
    I put that just for real life scenarios in that real world programmers tend to search for window caption texts.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  9. #9
    Join Date
    Mar 2007
    Posts
    210

    Re: getting WindowHandle from CreateProcess

    ok, ovidiucucu i've followed what you said and i'm adding the callback function to my program.

    However is it possible to add a callback function to a console application? or will i have to add it to my dll?

    the code i have at the moment will is

    Code:
    int main(int argc, char* argv[])
    {
    ...
    	STARTUPINFO siStartInfo = {0};
        PROCESS_INFORMATION piProcessInfo = {0};
    
    	GetStartupInfo(&siStartInfo);
    	CreateProcess(NULL, "Calc", NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,&piProcessInfo);
    
    	if(WaitForInputIdle(piProcessInfo.hProcess, 5000) == 0)
    	{
    		EnumThreadWindows(piProcessInfo.dwThreadId, EnumThreadWndProc, NULL);
    	}
    	else
    	{
    		MessageBoxA(NULL, "Could not start calculator","Error", MB_OK|MB_ICONERROR);
    	}
    }
    
    BOOL CALLBACK EnumThreadWndProc(HWND hWnd, LPARAM lParam)
    {
    	AppHook = hWnd; // got the calc main window   
    	AppHInstance = FindWindowHInstance(AppHook);
    	AppProcessID = FindWindowProcess(AppHook);
    
    	ButtonHook = CreateButton(220, 63, 45, 30, AppHook, AppHInstance, NULL);
    	ButtonHInstance = FindWindowHInstance(ButtonHook);
    	ButtonProcessID = FindWindowProcess(ButtonHook);
    
    	if(AppProcessID != 0) 
    	{
    		MouseHook = InstallMouseLauncher(NULL, ButtonProcessID, ButtonHook);
    		EventsHook = InstallEventsLauncher(ButtonHInstance, ButtonProcessID, ButtonHook, ThisHook);
    
    		sprintf(hook, "MouseHook %d, Events %d", MouseHook, EventsHook);
    		MessageBox(NULL,hook,NULL,0);
    	}	
    
    
    	return FALSE; // ...stop enum
    }
    however it compiling with this gives the following errors.

    error C2065: 'EnumThreadWndProc' : undeclared identifier
    error C2373: 'EnumThreadWndProc' : redefinition; different type modifiers

    any ideas? thanks for the help.

    Matt

  10. #10
    Join Date
    Mar 2007
    Posts
    210

    Re: getting WindowHandle from CreateProcess

    Hi,

    Ok i've pulled the callback method into my dll and its now working fine.

    thanks for the help.

    Matt.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured