Re: How to use SetWindowLong outside my aplication?

Posted by maxwell on April 16, 2006

In Reply to How to use SetWindowLong outside my aplication? posted by haivan lovrevic on April 05, 2006

: When I use GetWindowLong(comhandle,GWL_WNDPROC) on some component that's on my aplication, it gives me what I need. Also, when I use:
: SetWindowLong(comhandle,GWL_WNDPROC,LongInt(@NewWindowProc)), where comhandle is the handler of some component on my aplication, I get NewWindowProc to receive messages sent to that component.
: But, if comhandle is the handler of some component on any other aplication (IE, Notepad...) GetWindowLong(comhandle,GWL_WNDPROC) returns 0, and SetWindowLong(comhandle,GWL_WNDPROC,LongInt(@NewWindowProc)) does not work.
: My question is how can I intercept messages sent TO and FROM some component in some other aplication if I have it's handler (example IE ComboBox. I get it's handler by using FindWindowEx()).

If you have the handle of a control, even in another running application, you can do several things with it, such as send a WM_GETTEXT message to get its text.

But to obtain the handle, you need to know the exact order of the controls that are parents to the desired control.

Example: using Delphi to get the current URL (web address) from an Internet Explorer window:

procedure TForm1.Button1Click(Sender: TObject);
  hIEMain, hIEToolbar, hIEAddressBar, hIEComboBox: THandle;
  Buffer: array[0..255] of Char;
  // 1. Class name of main IE window is called 'IEFrame'
  hIEMain := FindWindow('IEFrame', Buffer);   

  // 2. Use FindWindowEx several times for getting 
  //    handle of the combobox with the URL
  if hIEMain > 0 then begin
    hIEToolbar := FindWindowEx(hIE, 0, 'WorkerW', nil);
    hIEAddressBar := FindWindowEx(hIEToolbar, 0, 'ReBarWindow32', nil);
    hIEComboBox := FindWindowEx(hIEAddressBar, 0, 'ComboBoxEx32', nil);

    // 3. Read text of the combobox into buffer
    SendMessage(hIEComboBox, WM_GETTEXT, 255, integer(@Buffer));

    // 4. Do something with text, for example:
    Label1.Caption := Buffer;
    ShowMesage('Error: Internet Explorer window not found');

Careful: FindWindow, as used in step 1, retrieves the handle to the top-level window. In the example, you will get the handle of the last activated IE window. What if you want the URLs of all the IE windows?

That's a bit more complicated:

1. Get the handle of each IE window ("enumerate" the IE windows), with the function EnumWindows in combination with a "callback" function.
2. For each IE window handle, get the handle of the URL ComboBox.
3. Get the text of the URL ComboBox.
4. Store the URL somewhere in a list, for example in a ListBox.

Note: a very good free tool for finding the hierarchy of controls Windows application, is called "WinDowse". Run the tool, place the mouse cursor on any window, and WinDowse shows all parameters of that window.

Related Articles and Replies