Solved

Window Handlers

Posted on 2000-04-13
9
389 Views
Last Modified: 2013-12-03
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.
0
Comment
Question by:VoidHawk
  • 4
  • 3
  • 2
9 Comments
 
LVL 12

Expert Comment

by:pjknibbs
Comment Utility
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
 
LVL 12

Accepted Solution

by:
pjknibbs earned 180 total points
Comment Utility
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
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
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
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
.. and IsWindowVisible(window)...
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:VoidHawk
Comment Utility
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
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
>> 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
 
LVL 12

Expert Comment

by:pjknibbs
Comment Utility
(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
 

Author Comment

by:VoidHawk
Comment Utility
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
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

zlib is a free compression library (a DLL) on which the popular gzip utility is built.  In this article, we'll see how to use the zlib functions to compress and decompress data in memory; that is, without needing to use a temporary file.  We'll be c…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now