Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Window Handlers

Posted on 2000-04-13
9
Medium Priority
?
414 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
9 Comments
 
LVL 12

Expert Comment

by:pjknibbs
ID: 2714938
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 720 total points
ID: 2714954
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
ID: 2714980
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
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 
LVL 20

Expert Comment

by:Madshi
ID: 2714985
.. and IsWindowVisible(window)...
0
 

Author Comment

by:VoidHawk
ID: 2720582
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
ID: 2720598
>> 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
ID: 2721801
(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
ID: 2721937
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
ID: 2721955
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
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…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…

650 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