Window Handlers

Due to a lack of reference material on my behalf, I'm having difficulty in implementing the following:

I wish to execute an installed application, say an instance of MS Internet Explorer, and return the window handle of the browser window it opens so that I may retrieve its coordinates, send commands such as maximise, setfocus, set the window size, retrieve the title bar contents, etc.

Additionally (or if the above is not possible) I want to be able to return the handles of all top level windows belonging to a running process eg "iexplore.exe". I've attempted using EnumWindows in conjunction with EnumWindowsProc, searching for handles based in title contents. I know its not the best solution, but I'd like to know where I went wrong since I always get stuck in an infinite loop. The code is as follows:

What I tried to do here is append the title of each window to a message box's contents. If it weren't for the counter to forcibly stop the process, it would simply loop infinately through the titles of each window over and over again.

I'm using Borland C++ Builder 5.

//--------------------------------------

TForm1 *Form1;

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
      char text[200];
      GetWindowText(hwnd,text,200);
      Form1->Memo1->Lines->Add(text);
      Form1->counter++;
      if (Form1->counter == 1000) return FALSE;
      return TRUE;
};

//--------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{

      HWND hwnd;
      LPARAM lParam = 0;

    Form1->counter = 0;

      while(EnumWindows((WNDENUMPROC)EnumWindowsProc, lParam))
      {
            EnumWindowsProc(hwnd,lParam);
      }

}
//--------------------------------------


I would greatly appreciate code examples.
VoidHawkAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

pjknibbsCommented:
The reason you're getting an infinite loop is because you appear to have misunderstood how EnumWindows() works. EnumWindows() does all the calling of EnumWindowsProc() for you, and it only returns FALSE if it encounters an error. Therefore, what your WHILE loop above will do is: firstly enumerate all the windows on the system via EnumWindows(). EnumWindows() will almost certainly succeed, so you then call EnumWindowsProc() with a garbage window handle (since you never assign anything to hWnd). It then goes round the loop again, enumerating the windows again.

*All* the windows EnumXXX functions work this way, which is why you pass them the address of the enumeration procedure in the first place!
0
pjknibbsCommented:
As for getting the window handle to the new process, I'm assuming you're starting this process using a call to CreateProcess(). The last parameter to this function is a pointer to a PROCESS_INFORMATION structure which looks like this:

typedef struct _PROCESS_INFORMATION {
    HANDLE hProcess;
    HANDLE hThread;
    DWORD dwProcessId;
    DWORD dwThreadId;
} PROCESS_INFORMATION;

You can limit your window enumeration to just the application you've launched by using EnumThreadWindows() with the thread handle from this structure.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MadshiCommented:
pjknibbs is completely right. Just one addition: If you've enumerated all windows of that main thread, the question is still: Which one is (or are) the main window(s)?
Main windows (that is windows that are visible as buttons in the taskbar) don't have a parent window nor an owner window. Also they must be visible and must not have the WS_EX_TOOLWINDOW style bit set in the extended window style. (APIs GetWindow(window, GW_OWNER), GetParent(window), GetWindowLong(window, GWL_EXSTYLE))

Regards, Madshi.
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

MadshiCommented:
.. and IsWindowVisible(window)...
0
VoidHawkAuthor Commented:
Thanks very much for that - It really clears things up. I was using a code example written by someone else for EnumWindows. I have altered it to the following.

//--------------------------------------

TForm1 *Form1;

bool EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
      char text[200];
      GetWindowText(hwnd,text,200);
      Form1->Memo1->Lines->Add(text);
      return TRUE;
};

//--------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
      EnumWindows((WNDENUMPROC) EnumWindowsProc,NULL);
}
//--------------------------------------

Just for clarification, Why must I use (WDENUMPROC) in EnumWindows? And why won't it work without the brackets?

As for CreateProcess(), I was looking at ShellExecute() which only returned the application's instance handle.

One last thing, as I asked in my initial question, is it possible to go through all of the active processes and return the window handles from a process of a particular name without knowing its process ID? eg. search for all instances of iexplore.exe and return its top level window handles?

Oh to be able to afford a decent reference book. (Student budget)
0
MadshiCommented:
>> Just for clarification, Why must I use (WDENUMPROC) in EnumWindows? And why won't it work without the brackets?

Well, I'm using (and loving) Delphi, there are no such syntax mysteriums...  :-)

>> As for CreateProcess(), I was looking at ShellExecute() which only returned the application's instance handle.

You can't do anything with the instance handle. Neither can you do something (that helps you with finding the windows) with the process handle that you can get from ShellExecuteEx. So CreateProcess is the way to go here.

>> is it possible to go through all of the active processes and return the window handles from a process of a particular name without knowing its process ID? eg. search for all instances of iexplore.exe and return its top level window handles?

I told you how to find the top level windows from the PID. So the only part missing is: How to get the PID of all running iexplore.exe instances? That's quite ugly. It's different under win9x and winNT. Under win9x you have to use the toolhelp functions, under winNT the library "psApi.dll" (which you have to distribute with your app).

Regards, Madshi.
0
pjknibbsCommented:
(WNDENUMPROC) is just there to keep your compiler happy. It tells it that yes, the function you are supplying *is* of the correct form for an EnumWindows() callback even if the compiler doesn't think it is. You could avoid using this if you declared EnumWindowsProc() *exactly* as it is in the header files rather than the documentation, but who has time to search the headers when a cast is quicker?

As for searching for all instances of a running application, Madshi's right--it's different under Win9x and NT, and it's probably not something you want to get into unless you enjoy grubbing around in the guts of Windows.
0
VoidHawkAuthor Commented:
Thanks a lot for that. I think I'm just going to have to dig deep and get myself a decent reference book or two.

Id love to be able to throw a few well earned points Madshi's way, but unfortunately I you only get to designate one recipient. I think I'll throw that into the suggestions box.
0
MadshiCommented:
No problem for me...  :-)

Yes, please do that suggestion. A lot of people have suggested that already, but nothing changed yet. But the more people say something the better are our chances that we'll see a point splitting feature soon.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.