January 28, 2013

Internet Explorer Automation Part 1


Internet Explorer can be automated just like Word or Excel. Most automation is done using IWebBrowser2 interface. Getting hand on a IWebBrowser interface is easy. It is enough to call CreateComObject, passing the Internet Explorer ID. This will create a new instance of Internet Explorer:

FWebBrowser := CreateComObject(CLASS_InternetExplorer) as IWebBrowser2;

Once the instance is created (A new IE window will open), we can call for example the Navigate method to load a page:


FWebBrowser.Navigate('http://www.overbyte.be', EmptyParam,
                     EmptyParam, EmptyParam, EmptyParam);

Sometimes, we do not need a new Internet Explorer Window but access an existing window to automate some processing on that window.

There exists several ways of finding an existing Internet Explorer window. One of the easiest is to use the Windows Explorer API. There is a bunch of interfaces to work with Windows Explorer. IShellWindows handle a collection of Explorer windows and this is exactly what we need. We will iterate thru all the windows and locate the Internet Explorer. Since there can be several IE opened windows, we will use the URL to find the one we are looking for.

Here is the code:

function GetIERunningInstanceByUrl(const Url : String): IWebBrowser2;
var
    ShWindows : IShellWindows;
    I         : Integer;
begin
    ShWindows := CoShellWindows.Create;
    for I := 0 to ShWindows.Count - 1 do begin
        Result := ShWindows.Item(I) as IWebBrowser2;
        if Assigned(Result) then begin
            if SameText(GetClassName(Result.HWND), 'IEFrame') then begin
                if SameText(Url, Result.LocationURL) then
                    Exit;
            end;
        end;
    end;
    // Not found
    Result := nil;
end;


GetClassName is a simple wrapper around Windows API to make it easier to use with Delphi:

function GetClassName(Hndl : HWND) : String;
var
    L : Integer;
begin
    SetLength(Result, MAX_PATH * SizeOf(Char));
    L := WinApi.Windows.GetClassName(Hndl, PChar(Result), Length(Result));
    SetLength(Result, L);
end;


Share this article if you like it!


http://francois-piette.blogspot.com/2013/01/internet-explorer-automation-part-1.html

See aldo the second part:
    http://francois-piette.blogspot.be/2013/01/internet-explorer-automation-part-2.html

3 comments:

Thomas (Hamburg) said...

GetClassName() returns an Integer, but SameText() needs two strings as arguments, so the call failes.

François Piette said...

GetClassName is a wrapper around Windows API to make it easy to call from Delphi. Forgot to show the code, sorry. Here it is:


function GetClassName(Hndl : HWND) : String;
var
L : Integer;
begin
SetLength(Result, MAX_PATH * SizeOf(Char));
L := WinApi.Windows.GetClassName(Hndl, PChar(Result), Length(Result));
SetLength(Result, L);
end;

deepak said...

Why does the code not use the following hierarchy to get HNWD of the target TAB?

IEFrame
Frame Tab
TabWindowClass
Shell DocObject View
Internet Explorer_Server