Interface
tool
IEGUID Unit
IEGUID is a small unit that makes it
easier to work with the webbrowser component.
When you start Delphi-programming with the
Webbrowser component, you will soon find that many important
header-files still are not converted to Delphi. So if you for
instance need the service identifier SID_STopLevelBrowser
you will not find it declared in the Delphi source-files. You
will have to search in the c++ headerfiles available from
MS-site. There you will find SID_SToplLevelBrowser in shlguid.h:
DEFINE_GUID(SID_STopLevelBrowser,
0x4C96BE40L, 0x915C, 0x11CF, 0x99, 0xD3, 0x00, 0xAA, 0x00, 0x4A,
0xE8, 0x37);
So now you have to translate it to Delphi
SID_STopLevelBrowser : TGUID =
'{4C96BE40-915C-11CF-99D3-00AA004AE837}';
before you can continue, unless you already have
forgotten why you needed it in the first place.
You can use the function CreateGuidList i IEGuid.pas to
collect GUIDs from headerfiles and from registered interfaces in
your registry database.
If you have downloaded IE 5.5
and Win2000 header-files it collects between 4000 and 5000
GUID's and place them in a textfile in the following
format:
IWebbrowserApp={0002DF05-0000-0000-C000-000000000046}
The GUID-list is not only useful for having easy
access to the declarations. It is also useful if you have an
interface and you don't know what other interfaces you can
obtain. Just call queryinterface with all the GUIDs in the list,
and see if for which of them S_OK is returned.
Follow these steps to create your GUID-list:
1) Download IE
5.5 Header-files.
2) Download Windows
2000 Header-files.
Dont use old header-files. Even if you run IE4
on WIN95.
3) Copy all the .h-files into a temporary directory (e.g. C:\headers).
4) Call CreateGuidList-function
in IEGuid.pas:
function CreateIEGuid('C:\headers',
'C:\MyGuidList.txt') : Integer;
First parameter is the directory where your header-files are
placed. The second parameter the output file. The function
returns the number of GUID's collected.
Note that this raw Guid-list contains all kind
of identifiers: Service identifiers (SID_) , class identifier (CLSID_),
interface identifiers (IID_) etc. It also contains identical
Guids with different names, since e.g.:
SID_SHLinkFrame = IID_IHLinkFrame = IHLinkFrame
I have included at quick function
CreateIEList that selects the GUIDs must interesting when
working with the webbrowser. In the following demos the
output-file of this function (ielist.txt) is used.
procedure TForm1.Button1Click(Sender: TObject);
begin
Showmessage('GUID's found: '+inttoStr(CreateIEGuid('c:\headers','c:\guidlist.txt')));
Showmessage('Sorted GUID's: '+inttoStr(CreateIEList('c:\guidlist.txt','c:\ieguidlist.txt')));
end;
|
Hunting Interfaces
You probably know that you can use
QueryInterface to obtain certain interfaces on Webbrowser1 or
Webbrowser1.Application or Webbrowser1.Document. But it is not
easy to get a clear picture of what kind of interfaces you can
obtain.
The Guid-list is helpful here. Place a
memo-field and a button on a form and add IEGuid.pas in the
uses-section. MyGuids.Create(NameofYourGuidList) loads your
guid-list and place them in two stringlists: MyGuids.Names and
MyGuids.Guids. The first list contains the name of the
identifier and the latter the guid-string. So to create a list
of interfaces you can query for on Webbrowser1.Application you
just have to add this code:
uses shdocvw (or
shdocvw_tlb), IEGuid;
var
MyGuids: TIEGuid;
procedure TForm1.Button1Click(Sender: TObject);
var
Counter: Integer;
i: IUnknown;
wb: Twebbrowser;
begin
WB := Twebbrowser.Create(self);
MyGuids.GetInterfaces(wb.Application, memo1.lines);
WB.free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
MyGuids := TIEGuid.Create('C:\IEGuidList.txt');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
MyGuids.Free;
end;
|
If you use IE 5.5 and the IEList.txt (created with CreateIEList),
your memo1 will show the following interfaces:
IConnectionPointContainer
IDataObject
IDispatch
IExternalConnection
IHlinkFrame
IInternetSecurityMgrSite
IObjectSafety
IOleCommandTarget
IOleControl
IOleInPlaceActiveObject
IOleInPlaceObject
IOleObject
IOleWindow
IPersist
IPersistHistory
IPersistPropertyBag
IPersistStorage
IPersistStream
IPersistStreamInit
IProvideClassInfo
IProvideClassInfo2
IServiceProvider
ITargetFrame
ITargetFrame2
ITargetNotify
IUnknown
IUrlHistoryNotify
IViewObject
IViewObject2
IWebBrowser
IWebBrowser2
IWebBrowserApp
|
Of course you can do the same on all other
interfaces. Remember to load a document in the webbrowser before
trying to query on Webbrowser1.document.
You now have a list of interfaces you can get
from Webbrowser1.Application. If you want a Serviceprovider you
can use:
MyServiceProvider:=Webbrowser1.Application
as IServiceprovider;
or
MyServiceProvider:=IServiceprovider(Webbrowser1.Application);
or
Webbrowser1.Application.QueryInterface(IServiceprovider,
MyServiceProvider);
You can also use the IEGuid to search
interfaces that can be obtained using
IServiceprovider(Webbrowser.Application).QueryService. In the
following sample we use the IEguid to get some information
about the the service-group SID_STopLevelBrowser:
procedure TForm1.Button2Click(Sender: TObject);
var
wb: Twebbrowser;
begin
WB := Twebbrowser.Create(self);
MyGuids.GetServices(wb.Application,'SID_STOPLEVELBROWSER', memo1.lines);
WB.free;
end;
|
This time the result looks like this:
IAdviseSink
IDropTarget
IInputObjectSite
IInternetSecurityMgrSite
IOleCommandTarget
IOleContainer
IOleInPlaceUIWindow
IOleWindow
IPersistHistory
IProfferService
IServiceProvider
IShellBrowser
IUnknown
IUrlHistoryStg
IVersionHost
|
Leave second parameter empty if you want
a list for services, where rsid is equal to iid (e.g.
QueryService(IHtmlwindow2, IHtmlWindow2, unk):
MyGuids.GetServices(wb.Application,'', memo1.lines);
It is now easy to find the right interface and
call the methods you want. If you need to call IHtmlWindow2s
method Confirm to show a dialogbox it only is a
few lines of code away:
1. QueryInterface Webbrowser1.Application for ServiceProvider.
2. Queryservice for IHTMLWindow2.
3. Call IHtmlWindow2.confirm.
or using typecasting:
var
IHW: IHtmlwindow2;
begin
(Embeddedwb1.Application as IServiceprovider).QueryService(IhtmlWindow2,IhtmlWindow2,
IHW);
IHW.confirm('This is a dialogbox!');
end;
|
Microsoft website includes documentation for many of the
interfaces and their methods, but since many header-files not
yet are converted to Delphi you might need to convert them
yourself.
First search the Delphi-Jedi Projects WINAPI library to see if
it already has been converted by someone else. Or download these
excellent tutorials on converting C++ header-files to Delphi:
Project
JEDI Conversion Tutorial
Dr Bob's header conversion articles
Outgoing
Interfaces
On Webbrowser1.Application we could query for
IConnectionPointContainer so we can also use the guidlist to get
a list of outgoing interfaces as well:
procedure TForm1.Button2Click(Sender: TObject);
var
wb: Twebbrowser;
begin
WB := Twebbrowser.Create(self);
MyGuids.GetConnectionpoints(wb.Application,memo1.lines, TRUE);
WB.free;
end;
|
The result is perhaps not a big surprise:
DWebBrowserEvents2
DWebBrowserEvents
IPropertyNotifySink
|
and on Webbrowser.Document:
IPropertyNotifySink
HTMLDocumentEvents
HTMLDocumentEvents2
ITridentEventSink
IDispatch
|
Use your own
implementations
To study what goes on behind the scene when the
webbrowser is running, you can use the guidlist in the
OnQueryService eventhandler in EmbeddedWB:
function
TForm1.EmbeddedWB1QueryService(const rsid, iid: TGUID;
out Obj: IUnknown): HRESULT;
begin
Memo1.Lines.Add(MyGuids.NameFromGuid(rsid)+' - '+MyGuids.NameFromGuid(iid));
Result:=E_NOINTERFACE;
end;
|
The result output may look like this:
ITargetFrame2 -
{9216E421-2BF5-11D0-82B4-00A0C90C29C5}
SID_STopWindow - ISearchContext
ITargetFrame2 - IUnknown
SID_STopLevelBrowser - IOleCommandTarget
SID_STopLevelBrowser -
{DFEED31E-78ED-11D2-86BA-00C04F8EEA99}
SID_STopLevelBrowser - IServiceProvider
SID_STopLevelBrowser - IServiceProvider
IMimeInfo - IMimeInfo
SID_STopLevelBrowser - IOleCommandTarget
{639447BD-B2D3-44B9-9FB0-510F23CB45E4} -
{639447BD-B2D3-44B9-9FB0-510F23CB45E4}
SID_STopLevelBrowser - IOleWindow
ITargetFrame2 - IUnknown
SID_STopLevelBrowser - IOleCommandTarget
SID_STopLevelBrowser - IUrlHistoryStg
IOleUndoManager - IOleUndoManager
IInternetSecurityManager - IInternetSecurityManager
SID_STopLevelBrowser - IServiceProvider
HTMLFrameBase - HTMLFrameBase
{AD7F6C62-F6BD-11D2-959B-006097C553C8} - IUnknown
{6D12FE80-7911-11CF-9534-0000C05BAE0B} - IUnknown
IElementBehaviorFactory - IElementBehaviorFactory
{371EA634-DC5C-11D1-BA57-00C04FC2040E} - IVersionHost
IInternetProtocol - IInternetProtocol
ITargetFrame2 - IUnknown
SID_STopLevelBrowser - IServiceProvider
SID_STopLevelBrowser - IOleCommandTarget
SID_STopLevelBrowser - IUrlHistoryStg
SID_STopLevelBrowser - IShellBrowser
IActiveScriptSite - IOleCommandTarget
SID_GetCaller - IServiceProvider
SID_STopLevelBrowser - IOleCommandTarget
SID_SEditCommandTarget - IOleCommandTarget
SID_STopLevelBrowser - IShellBrowser
SID_SEditCommandTarget - IOleCommandTarget
ITargetFrame2 - IUnknown
SID_SEditCommandTarget - IOleCommandTarget
IHTMLEditHost - IHTMLEditHost
|
Here you also have a chance to hand the
webbrowser your own version of the interface it is asking for.
For more info see the included IEGuid Demo.
Enjoy!
Created and maintained by
Per Lindsų Larsen
Last Update: October 15, 2000
|