Internet Explorer 8 URL fetch code works on XP, does not work on Win7

Here is a snap of the code:

                         WndChild := FindWindowEX(WndChild, 0, 'Internet Explorer_Server', NIL);
                         if WndChild <> 0 then
                         begin
                              {$IFDEF DEBUG}op('explorer_server'){$ENDIF};
                              if GetIEFromHWnd(WndChild, IE) then
                              begin
                                   {$IFDEF DEBUG}if assigned(IE) then op('got IE!') else op('iE error');{$ENDIF};
                                   if assigned(IE) then
                                   begin
                                        s :=  IE.Get_LocationURL;
                                        {$IFDEF DEBUG}op('url: '+s){$ENDIF};
                                        if Pos(':',s) > 0 then
                                        begin
                                             Browsers.Add('Microsoft IE');
                                             Names.Add(title);
                                             Paths.Add(s);
                                             Handles.Add(IntToStr(WinHandle));
                                        end;
                                        Result := True;
                                   end;
                              end;
                         end;
                  end;

the variable IE is <> NIL on WinXP, but is NIL on Windows 7 (both have Internet Explorer 8).

here is an example project, with precompiled executable (and a debug output to a memo field):

http://thomasreimann.com/test/IeTest.rar

500 points, because of the urgency.
ThomasReimannAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
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.

Emmanuel PASQUIERFreelance Project ManagerCommented:
probably the window has another name in Seven. You have to determine which is it, and look for both
const
 IEServer_XP = 'Internet Explorer_Server';
 IEServer_Seven = '????';

WndChild := FindWindowEX(WndChild, 0, IEServer_XP, NIL);
if WndChild <> 0 
 then WndChild := FindWindowEX(WndChild, 0, IEServer_Seven, NIL);
if WndChild <> 0 then
 begin
  ...
 end;

Open in new window

0
Emmanuel PASQUIERFreelance Project ManagerCommented:
I might add : you can get this information with Spy++, among other tools. I don't have Seven, unfortunately, so I can't help  you more than that
0
ThomasReimannAuthor Commented:
The names are the same, since WndChild > 0 also in Windows 7.

I should have posted more code, but all the code is in the RAR file I've provided.

This code is problematic:

        Res := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);
        if Res = S_OK then
        begin
           {$IFDEF DEBUG}op('GetIEFromHWND got object'){$ENDIF};
           Result := True;
           if assigned(pDoc) and assigned(pDoc.parentWindow) then
              (pDoc.parentWindow as IServiceprovider).QueryService(IWebbrowserApp, IWebbrowser2, IE);
        end

------

 Res = S_OK is True on both XP and Win7, but

           if assigned(pDoc) and assigned(pDoc.parentWindow) then
              (pDoc.parentWindow as IServiceprovider).QueryService(IWebbrowserApp, IWebbrowser2,

works on XP, but does not work on 7. IE is <> NIL on XP, but is NIL on 7.
0
Bootstrap 4: Exploring New Features

Learn how to use and navigate the new features included in Bootstrap 4, the most popular HTML, CSS, and JavaScript framework for developing responsive, mobile-first websites.

ThomasReimannAuthor Commented:
p.s.

pDoc is <> NIL on both XP and Win7.
0
ThomasReimannAuthor Commented:
I've just discovered that it works on Windows 7 32 bit, but does not work on Windows 7 64bit.
0
Eddie ShipmanAll-around developerCommented:
Instead of doing it like that, why not use one of the other tried and true methods,
DDE and DOM.

Now, I'm not sure if the DDE method will work in Win7, but give it a shot.
i KNOW, that the DOM method will get the URL of the active tab.

// below uses DDE
procedure TForm1.GetCurrentURL (var URL, Title : string);
var
  DDEClient : TDDEClientConv;
  s : string;
begin
  s := '';
  try
    DDEClient := TDDEClientConv.Create(self);
    with DDEClient do
      begin
      if SetLink('IExplore','WWW_GetWindowInfo') then
        s := RequestData('0xFFFFFFFF,sURL,sTitle')
    if s <> '' then
      begin
      delete(s,1,1);
      URL := copy(s,1,pos('","',s)-1);
      delete(s,1,pos('","',s)+2);
      Title := copy(s,1,pos('"',s) - 1);
      end;
    exit;
  except
    MessageDlg('URL attempt failed!',mtError,[mbOK],0);
    end;
end;

// Below uses the DOM
function GetIEURL: String;
var
  ShellWindow: IShellWindows;
  WB: IWebbrowser2;
  spDisp: IDispatch;
  IDoc1: IHTMLDocument2;
  Document: Variant;
  k: Integer;
begin
  Result := '';
  ShellWindow := CoShellWindows.Create;
  // get the running instance of Internet Explorer
  for k := 0 to ShellWindow.Count do
  begin
    spDisp := ShellWindow.Item(k);
    if spDisp = nil then Continue;
    // QueryInterface determines if an interface can be used with an object
    spDisp.QueryInterface(iWebBrowser2, WB);
    if WB <> nil then
    begin
      WB.Document.QueryInterface(IHTMLDocument2, iDoc1);
      if iDoc1 <> nil then
      begin
        WB := ShellWindow.Item(k) as IWebbrowser2;
        Document := WB.Document;
        Result := Document.Location;
      end; { idoc <> nil }
    end; { wb <> nil }
  end; { for k }
end;

Open in new window

0
Eddie ShipmanAll-around developerCommented:
If I may ask, why are you using API calls to do that, anyway?
0
ThomasReimannAuthor Commented:
Eddie, my application needs to get URLs from all tabs, not only the active tab, so I can't use DDE or COM. Also DDE cuts the URL length to 255 chars, so it's not really usable.
0
ThomasReimannAuthor Commented:
I did mean DOM by writing COM.
0
Eddie ShipmanAll-around developerCommented:
The code you posted does no such thing, either. Besides, the address bar is SHARED between all the tabs and shows the URL of ONLY the active tab.

What you have to do is get the Document Object for each tab and get it's location like using the DOM. I will see if I can find some code to do that.
0
ThomasReimannAuthor Commented:
The code in my application makes several FindWindowEx(), basically it goes line this:

IEFrame -> Frame Tab -> TabWindowClass -> Shell DocObject View -> Internet Explorer_Server.

Then it uses if GetIEFromHWnd() from the example project I've attached to get the IE object from the handle.

After this you get the URL as IE.Get_LocationURL.

You can do it for every tab in a IE window.

But GetIEFromHWnd(), which is included in the example project, fails on 64bit systems.
0
Eddie ShipmanAll-around developerCommented:
If I'm not mistaken, the ShellWindows "array" has each tab as a separate instance of IE.

Just like this code will return the URL for each tab in a memo in IE7 on XP(SP3)
Try it and see if it works for you.


uses ...,ShDocVW, MSHTML;

procedure TForm1.Button1Click(Sender: TObject);
var
  ShellWindow: IShellWindows;
  WB: IWebbrowser2;
  spDisp: IDispatch;
  IDoc1: IHTMLDocument2;
  k: Integer;
begin
  ShellWindow := CoShellWindows.Create;
  // get the running instance of Internet Explorer
  for k := 0 to ShellWindow.Count do
  begin
    spDisp := ShellWindow.Item(k);
    if spDisp = nil then Continue;
    // QueryInterface determines if an interface can be used with an object
    spDisp.QueryInterface(iWebBrowser2, WB);
    if WB <> nil then
    begin
      WB.Document.QueryInterface(IHTMLDocument2, iDoc1);
      if iDoc1 <> nil then
      begin
        // Result := Result + iDoc1
        WB := ShellWindow.Item(k) as IWebbrowser2;
        Memo1.Lines.Add(WB.LocationURL);
      end; { idoc <> nil }
    end; { wb <> nil }
  end; { for k }
end;

Open in new window

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
Eddie ShipmanAll-around developerCommented:
This line in my code:
WB := ShellWindow.Item(k) as IWebbrowser2;

Does essentially the same thing as it also returns an instance of IWebBrowser2 and using the LocationURL property is the same as calling Get_LocationURL.

I can test this on Win7 and IE8 in about 10 minutes and let you know the result.

I don't have a 64-bit system to test.
0
Eddie ShipmanAll-around developerCommented:
Well, it didn't take 10 minutes and it worked on Win7 with IE8, it returned ALL URLS in ALL tabs.

Give it a go and let me know.
0
ThomasReimannAuthor Commented:
It's almost done, meaning it works, but how can I determinate which of the URLs comes from the active tab?
0
Eddie ShipmanAll-around developerCommented:
Let me work on it to see. I'll post more in a couple of hours.
0
Eddie ShipmanAll-around developerCommented:
I have not been able to find out how to tell which is active, however, I'll keep trying.
0
ThomasReimannAuthor Commented:
Eddie, I'll accept your solution within 24 hours. I wanted just to ask if you could provide something similar for Firefox (DDE is no a solution here, because of 255 char limit and also only one tab). The Firefox solution would mean another 500 points of course.
0
Eddie ShipmanAll-around developerCommented:
Well, Firefox is a different ball of wax. I have never been able to get anything from it as the majority of it's API is NOT exposed to COM or any external efforts, as far as I have found.

I will continue to search for the answer to your first question and also try to foind out about FF.
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
Web Browsers

From novice to tech pro — start learning today.