Thread: Windows API - Controlling other windows

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    10

    Windows API - Controlling other windows

    Hello dearest fellow prorammers (if I may call myself one),

    I am trying to open a program with another program, using ShellExecute, this ShellExecute hands me a HINSTANCE of the started program. However I want to have the HWND of this program, I tried using functions such as:
    GetWindow();
    Handing it either my own hwnd, or the desktop hwnd, using all the possible GW_ flags, but the best I could get was shutting down windows when trying to send WM_CLOSE.

    Can anyone tell me a surefire way of getting the right HWND of the program I started, so I can use:
    PostMessage();
    To send it WM_ commands.
    (I need to fool a windows program into thinking its being used by a normal user, while my program provides all the input).

    Thankyou very much for all your attention!

  2. #2
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    You can use shellexecuteex to get the process handle, and then the pid, and then enumerate windows until you find yours.

    Code:
    	SHELLEXECUTEINFO eI = { 0 };	
    	DWORD pIdExec = 0, pTId = 0;
    	HWND hWnd;
    	
    	eI.cbSize       = sizeof(eI);           
    	eI.lpVerb       = "open";
    	eI.lpFile       = "iexplore";
    	eI.nShow        = SW_SHOW;	
    	eI.fMask		= SEE_MASK_NOCLOSEPROCESS;
        
    	if(ShellExecuteEx(&eI) != FALSE)
    	{
    		WaitForInputIdle(eI.hProcess, 5000);
    
    		hWnd = FindWindow(NULL, 0);
    		while(hWnd != NULL)
    		{
    			GetWindowThreadProcessId(hWnd, &pTId);
    			pIdExec = GetProcessId(eI.hProcess);
    
    			if(pTId == pIdExec)
    			{
    				// yrs
    			}
    			hWnd = GetWindow(hWnd, GW_HWNDNEXT);
    			
    		}
    	}

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    10
    Wow, thanks. I have spent almost two days circling on pages in the MSDN directory and browsing through tutorials and nothing even close to this usefullness came up. I'm going to try this later today.

    Thankyou ever so much!

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    10
    Humm,

    It keeps hanging on the:
    Code:
    pIdExec = GetProcessId(eI.hProcess);
    when either compiling or linking.
    I have checked the MSDN directory and it has a minimum requirement of Win XP SP1, since I am running Win XP SP2 I assumed that couldn't be the problem, however when compiling ti claims it is an uneclared function, which gets solved when I take the declaration from winbase.h and put it into my own header, but then the linker fails on "unresolved external" (of course). But this proves that the #ifdef check for the right winversion fails.

    Anyone have any ideas? I'm using Dev C++, latest (4.9.9.something?), with a very recently updated WinAPI package.

    Perhaps you could tell me what you use Tonto? (I tried borland 6 as well, but that one is getting old, so... not really a wonder it won't work there).

    Thanks!

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    #define WINVER 0x0510
    #define _WIN32_WINNT 0x0510
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Oct 2006
    Posts
    10

    Smile

    Okay, that was indeed at least a bit stupid of me!

    Thankyou for the help, It does not work as of yet, but I do think that I can manage the remaining problems myself, if not i'll be sure to post again. Exhausting testing made it quite clear that the windowhandle my program got and the actual one were quite different, but that must quite surely be a mistake in my putting the code into my program (was quite a tedious task with my current experimental program structure :-) )

    Thanks a bunch Tonto and CornedBee!

  7. #7
    Registered User
    Join Date
    Oct 2006
    Posts
    10
    Okay working now!
    Wierd little thing:
    The loop returns a positive match twice, and I used break on the first one (to save looping time), while the second one was the correct one, I find that a bit weird, is this known of this loop or did I just find yet another "great" Windows feature?

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Perhaps the process has opened two top-level windows?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    He should use EnumThreadWindows().
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Or at least EnumWindows instead of the GetWindow loop, as the docs of EnumWindows says. EnumThreadWindows might be tricky without a thread ID. And enumerating threads is complicated: it requires you to take a snapshot with the toolhelp32 library (CreateToolhelp32Snapshot()) and then iterate through the threads in the snapshot. Of course, any thread might actually die at any time, so once you reach a thread, you don't know whether it's still alive or anything.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    I mean using EnumThreadWindows() after getting the process id.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  12. #12
    Registered User Ktulu's Avatar
    Join Date
    Oct 2006
    Posts
    107
    Best way is CreateProcess, in a structure you will receive the ProcessId, call a EnumWindows procedure, get the ProcessId by every window with GetWindowThreadProcessId and check if the ProcessId is the same, if so, return and you have the window handle of the process that you have created .
    This parameter is reserved

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Use windows API functions in a GTK+ program?
    By Jake.c in forum Windows Programming
    Replies: 19
    Last Post: 01-23-2009, 06:40 AM
  2. What does this do (Windows API)?
    By EVOEx in forum Windows Programming
    Replies: 4
    Last Post: 12-19-2008, 10:48 AM
  3. Want to learn Windows API for Game Programming
    By George M. in forum Windows Programming
    Replies: 15
    Last Post: 09-28-2008, 10:26 AM
  4. Script errors - bool unrecognized and struct issues
    By ulillillia in forum Windows Programming
    Replies: 10
    Last Post: 12-18-2006, 04:44 AM
  5. I dont know Windows API...
    By vasanth in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 03-07-2004, 06:24 PM