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
Solved

AOL-specific problems with IHTMLDocument2.get_URL( ) calls (returns local AOL html file rather than web url)

Posted on 2006-07-06
8
906 Views
Last Modified: 2008-01-09
Dear Beloved Geniuses,

As part of a software package that needs to identify running browser instances and their document URL's, I have written some additional code to accommodate special circumstances present in IE browsers running under the AOL application.  This is necessary because my original code does not "see" those browser instances - AOL apparently sets some sort of flag that suppresses their IE instances from registering as a browser, which messes up my original method of retrieving browser instances using ShellWindows method calls.

The "specialty code" I've written to accommodate AOL uses the following algorithm:

1) Find top level windows that belong to the process "waol.exe" -
  a) EnumWindows( )
  b) for each top level window, GetWindowThreadProcessId( ), EnumProcessModules( ), and GetModuleFileNameEx( ) to check whether each window is owned by "waol.exe".
2) For each top-level window owned by waol.exe, use EnumChildWindows( ) and EnumChildWindowsEx( ) to find windows of the class "Shell DocObject View", then beneath that class, the child window of class "Internet Explorer_Server".
3) Having found such windows, I use their handles to attempt to retrieve the URL that the browser control is pointing at, using GetLocUrlFromHwnd (shown at the end of this posting)

The difficulty I'm having is this: while my enum code correctly identifies the browser control(s), and fetches a pointer to the IHTMLDocument2 interface, my call to get_URL( ) returns the following address:

"file:///C:/Documents and Settings/All Users/Application Data/AOL/C_America Online 9.0/ShopAssist/Apps/core/main.html"

rather than the URL of the page the browser is displaying.  I am pretty certain that things in my code are mostly correct, because I have checked the HWND for the browser control against results shown in Spy++, and the handle is dead-on, and my code has also not thrown a single exception, nor has it returned any errors.  Oh, and I have also gone to the trouble of "reaching farther down", by calling get_LocationUrl( ) from the IWebBrowser2 interface (retrieved from IHTMLDocument2 through calls made via IServiceProvider.)

One other special circumstance that may come to bear: ultimately, the consumer of this information is a Windows Service I have written - but this should not cause any grief, because the service obtains the URL information from a hidden helper application running in the logged-in user's security context by requesting said info through a .NET remoting call to the hidden application.  (i.e. the functionality I've described lives in the helper app, not in the service.)  Also, the code that DOES work (gets URLS for non-AOL browser instances) also lives in this helper app, so I'm pretty sure this has nothing to do with desktop/shell interaction problems.

Can someone help with this puzzle?  (By the way, I have also included the code within the aforementioned html disk file below, just in case that might provide part of the solution, or at least an indication of WHY I'm getting this local file address rather than a web address.)

Many thanks,

Skyline

The code:

#define qtseterr(a) {bErr = true; szErr = String::Copy(a);}

bool GetLocUrlfromHwnd(HWND hwndIn, String*& szRet)
{
   bool bRetval = false;
   System::String* szErr;
   bool bErr = false;
   try
   {
      IHTMLDocument2* pDoc;
      HMODULE hLib = LoadLibrary("OLEACC.DLL");
      if (NULL != hLib)
      {
         //grab proc address for ObjectFromLresult()
          typedef HRESULT (STDAPICALLTYPE *LPFNOBJECTFROMLRESULT)(LRESULT lResult, REFIID riid, WPARAM wParam, void** ppvObject);
         LPFNOBJECTFROMLRESULT pfObjFromLResult;
         pfObjFromLResult = (LPFNOBJECTFROMLRESULT) ::GetProcAddress(hLib, "ObjectFromLresult");
         if (pfObjFromLResult != NULL)
         {
            //call OFLR
            LRESULT lRes;
            UINT uiMsg = RegisterWindowMessage("WM_HTML_GETOBJECT");
            ::SendMessageTimeout(hwndIn, uiMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes);
            HRESULT hr;
            hr = (*pfObjFromLResult)(lRes, IID_IHTMLDocument2, 0, (void**)&pDoc);
            if (SUCCEEDED(hr))
            {
               //now have document interface pointer, go get the doc's URL
               BSTR bstrFeaster;
               hr = pDoc->get_URL(&bstrFeaster);
               if (SUCCEEDED(hr))
               {
                  bRetval = true;
                  szRet = String::Copy(bstrFeaster);
               }
            }//if success get doc object from LRES
            else
               qtseterr(S"get doc object failed")
         }//if success get proc address from loaded DLL
         else
            qtseterr(S"get proc address failed")
         FreeLibrary(hLib);
      }//if hLib not null (successful DLL load)
      else
         qtseterr(S"loadlibrary failed")
   }
   catch(Exception* ex)
   {
      qtseterr(String::Concat(S"Exception caught in GetLocUrlFromHwnd: ", ex->get_Message()))
   }
   if (bErr)
   {
      szRet = szErr;
   }
   return bRetval;
}//GetLocUrlFromHwnd

The HTML file:

<HTML>
<HEAD>
<TITLE>main page - sink & dispatch events and contains app iframes</TITLE>
<SCRIPT src="js/core.js"></SCRIPT>
<SCRIPT>
function createAppFrame(appName)
{
      var appUrl = "../" + appName + "/bs.html"
      var tagStr = "<iframe name='" + appName + "' src='" + appUrl + "' width=0 height=0></iframe>";
      document.writeln(tagStr);
}
</SCRIPT>
</HEAD>

<BODY topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" marginwidth="0" marginheight="0">
      <iframe name="ui" src="about:blank" width="100%" height="100%" frameborder="0" marginheight="0" marginwidth="0" scrolling="no"></iframe>

<SCRIPT>
for (var i=0; i< g_appObjArray.length; i++)
{
      createAppFrame(g_appObjArray[i].AppName);
}
</SCRIPT>
</BODY>      
</HTML>

There is also a javascript file that goes with this - I will post as a comment if someone needs it.  Anyone with a recent version of AOL can find the file (core.js) along the same path I mention for the above html file.
0
Comment
Question by:skyline_blvd
  • 4
  • 2
8 Comments
 

Author Comment

by:skyline_blvd
ID: 17053081
Addendum by author to paragraph 5 (mentions IWebBrowser2 etc.): the calls to IWebBrowser2.get_LocationUrl( ) result in the same bad results (main.html rather than the "real" url.)
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 17054650
What if your code is 100% correct?   What if waol.exe writes and displays that file (based upon the actual content of the page it is currently browsing, with perhaps a tweek here or there)?

The first thing I'd do is examine the HTML text of that main.html page.  Perhaps it contains an IFrame or something and there might be a way to obtain from *that* the "real" URL that waol.Exe is displaying.
0
 

Author Comment

by:skyline_blvd
ID: 17055749
Good point - I've examined that possibility, but am rather out of my element with respect to such things, Dan.  I felt rather like a guy stuck by the side of the road looking dumbly under the hood of my broken-down car - am not at ALL conversant in HTML, scripting, etc.   Which is the main reason I posted.  (If you can figure out what to do with that HTML, my friend, you get the points :)  In retrospect, perhaps this question belongs in a different category (Web Development, possibly?) - is there a way I can accomplish that move?

By the way, I will be traveling for the next week, so please, no one take offense if I fail to post/resolve points for a day or two; will not always be able to check this site frequently.  Thanks!
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 49

Expert Comment

by:DanRollins
ID: 17061624
You know the URL and it is a local file and you know its location on your hard disk.  So the first thing to do is use the Windows Explorer to find that file and then to open it in Notepad.  Copy it and give it an extension of .TXT then double-click the resulting file.
0
 

Author Comment

by:skyline_blvd
ID: 17109276
Thanks Dan - I knew how to view the source code of a page already ;) but I do appreciate the extra help lol!

So sorry for delaying so long, I have just returned from vacation with the family.  I'll be mucking around in that mystery file, as suggested, to see if I can find a way to dig further for IFrames (whatever that is) or other objects that may reveal the true URL being displayed.
0
 

Author Comment

by:skyline_blvd
ID: 17115210
I have found my bug-a-boo, thankfully - the short version of the story is that one of my trusted minions made an undocumented change to the collection to which the url(s) were being added that was causing only the last url added to be retained - in this case, the effect was that I was seeing only the listing for the (apparently hidden) browser window that utilises the aforementioned AOL html file.  So the bug in the derivative collection class was the culprit, making it *appear* that the code I've posted is not working when in fact it is.

I will be closing this issue now - hopefully its presence in the E-E database will prove helpful to folks who wish to fiddle with AOL-hosted browser windows!  Thanks to any and all who spent time on this!

Skyline
0
 
LVL 1

Accepted Solution

by:
GhostMod earned 0 total points
ID: 17185302
Closed, 500 points refunded.

GhostMod
Community Support Moderator
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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

Suggested Solutions

Title # Comments Views Activity
Safearray problem c++ 4 88
Need to convert MSDEV 6.0 to Dev Studio 2010 5 31
linker section missing in visual studio 1 93
Parsing HTML in C# 10 153
The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
In Easy String Encryption Using CryptoAPI in C++ (http://www.experts-exchange.com/viewArticle.jsp?aid=1193) I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

829 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