Last updated: 29 September 1996 -- satona
This document describes two interfaces we've introduced in the IE 3.0 (Internet Explorer 3.0) to share the "Internet Toolbar" implementation between two browser frames, IE 3.0 (a stand-alone web browser) and IE 4.0 (the windows shell). Although I describe this interface in this particular context, there is nothing specific to this particular application or implementation in these interfaces.
Notes: IE 3.0 hosted only one toolbar, but IE 4.0 is going to host more than one (including the tree pane). The (private) interfaces we've introduced in IE 3.0 is not efficient for it. It requires to allocate a site for each toolbar. To avoid that inefficiency, we are changing the interface. All the member function calls to IDockingWindowSite takes an additiona parameter punkOuter, which identifies the toolbar. All the changes are marked in italic fonts.
When the browser frame is created, it CoCreateInstance an instance of the "Internet Toolbar" and attach it the frame window. The browser frame implements the IDockingWindowSite interface and the toolbar implements the IDockingWindow interface. Those interfaces are used only for layout negotiation and accelerators and actual navigation commands (that's what this particular toolbar does) is sent via the OLE automation interface (IWebBrowserApp in this particular case).
The idea is very similar to the toolbar layout negotiation between in-place active object and in-place frame, but uses different set of interfaces which are specific to the negotiation between the frame and the toolbar that is not provided by the active object.
In IE 4.0, we added another interface, IDockingWindowFrame, which provides a way to add or remove toolbars programatically. Both the WebBar and the DesktopChannel (a vertical toolbar with channel change UI buttons) will use this mechanism.
In addition to the standard "Internet Toolbar", ISVs (or ICPs) can add any toolbars (any COM objects which supports IDockingWindow interface) to browser windows (including browser window OCs, sub-frames in frame sets and the desktop window) programatically. It will be done by (1) obtaining the IDockingWindowFrame inteface via IServiceProvider::QueryService (sid = SID_SShellBrowser for the immediate parent or SID_STopLevelBrowser for the top-level browser), (2) then calling AddToolbar member with a COM object, which supports IDockingWindow interface. Member functions of IDockingWindowFrame are described below:
This interface is implemented by a frame window object, which typically implements the IOleInPlaceUIWindow as well It inherits IOleWindow, and it has four additional member functions, GetBorderST, RequestBorderSpaceST, SetBorderSpaceST and OnFocusChange. These member functions are always called by one of associated toolbars.
This interface is implemented by a toolbar object, which displays some tools within the border space of the frame window, with which it is associated. This interface also inherits IOleWindow. It has six additional member functions, SetToolbarSite, ShowST, CloseST, ResizeBorderST, TranslateAcceleratorST and HasFocus.
TranslateAcceleratorST and HasFocus might need some improvement if we are going to use these interfaces widely.
Not calling TranslateAcceleratorST at all when it does not have the input focus simplifies the issue but there is a restriction. There might be some cases where a toolbar wants to process a certain set of accelerators even though it does not have the input focus (of course, we need to worry about conflicts -- that's a general problem with multiple UI components).
We found a case where the browser frame needs to be notified when its toolbar (of one of its toolbars) gets the input focus (to redirect OLECMDID_CUT/COPY/PASET commands via IOleCommandTarget -- see another document "DocObject: Edit Menu command dispatching" for further discussion). We probably needs to add OnSetFocus member for IDockingWindowSite for this particular purpose.
IE 4.0 frame (the shell explorer) will probably support multiple toolbars (the tree pane will be added as a toolbar). To implement it under the current interfaces, the frame needs to have a IDockingWindowSite for each toolbar, which is not efficient. We can avoid it by adding a parameter to its member functions, which identifies the toolbar. It can be an object pointer or a DWORD identifier (which will be set by the frame via SetOwner).
//========================================================================== // IDockingWindowSite/IDockingWindow interfaces // // These interfaces allows us (or ISVs) to install/update external Internet // Toolbar for IE and the shell. The frame will simply get the CLSID from // registry (to be defined) and CoCreateInstance it. // //========================================================================== #undef INTERFACE #define INTERFACE IDockingWindowSite DECLARE_INTERFACE_(IDockingWindowSite, IOleWindow) { // *** IUnknown methods *** STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; STDMETHOD_(ULONG,AddRef) (THIS) PURE; STDMETHOD_(ULONG,Release) (THIS) PURE; // *** IOleWindow methods *** STDMETHOD(GetWindow) (THIS_ HWND * lphwnd) PURE; STDMETHOD(ContextSensitiveHelp) (THIS_ BOOL fEnterMode) PURE; // *** IDockingWindowSite methods *** STDMETHOD(GetBorderST) (THIS_ IUnkown* punkSrc, LPRECT prcBorder) PURE; STDMETHOD(RequestBorderSpaceST) (THIS_ IUnkown* punkSrc, LPCBORDERWIDTHS pbw) PURE; STDMETHOD(SetBorderSpaceST) (THIS_ IUnkown* punkSrc, LPCBORDERWIDTHS pbw) PURE; STDMETHOD(OnFocusChangeST) (THIS_ IUnknown* punkSrc, BOOL fSetFocus) PURE; };
#undef INTERFACE #define INTERFACE IDockingWindowFrame DECLARE_INTERFACE_(IDockingWindowFrame, IOleWindow) { // *** IUnknown methods *** STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; STDMETHOD_(ULONG,AddRef) (THIS) PURE; STDMETHOD_(ULONG,Release) (THIS) PURE; // *** IOleWindow methods *** STDMETHOD(GetWindow) (THIS_ HWND * lphwnd) PURE; STDMETHOD(ContextSensitiveHelp) (THIS_ BOOL fEnterMode) PURE; // *** IDockingWindowFrame methods *** STDMETHOD(AddToolbar) (THIS_ IUnkown* punkSrc, DWORD dwReserved) PURE; STDMETHOD(RemoveToolbar) (THIS_ IUnkown* punkSrc) PURE; };
#undef INTERFACE #define INTERFACE IDockingWindow DECLARE_INTERFACE_(IDockingWindow, IOleWindow) { // *** IUnknown methods *** STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID * ppvObj) PURE; STDMETHOD_(ULONG,AddRef) (THIS) PURE; STDMETHOD_(ULONG,Release) (THIS) PURE; // *** IOleWindow methods *** STDMETHOD(GetWindow) (THIS_ HWND * lphwnd) PURE; STDMETHOD(ContextSensitiveHelp) (THIS_ BOOL fEnterMode) PURE; // *** IDockingWindow methods *** STDMETHOD(SetToolbarSite) (THIS_ IUnknown* punkSite) PURE; STDMETHOD(ShowST) (THIS_ BOOL fShow) PURE; STDMETHOD(CloseST) (THIS_ DWORD dwReserved) PURE; STDMETHOD(ResizeBorderST) (THIS_ LPCRECT prcBorder, IUnknown* punkToolbarSite, BOOL fReserved) PURE; STDMETHOD(TranslateAcceleratorST) (THIS_ LPMSG lpmsg) PURE; STDMETHOD(HasFocus) (THIS) PURE; };