// Copyright Pavel Zolnikov, 2002 // // BandObject - implements generic Band Object functionality. // http://www.codeproject.com/KB/shell/dotnetbandobjects.aspx using System; using System.Windows.Forms; using System.Runtime.InteropServices; using SHDocVw; using System.Reflection; using System.Diagnostics; using System.Drawing; using System.ComponentModel; using Microsoft.Win32; namespace BandObjectLib { /// /// Implements generic Band Object functionality. /// /// /// [Guid("YOURGUID-GOES-HERE-YOUR-GUIDGOESHERE")] /// [BandObject("Hello World Bar", BandObjectStyle.Horizontal | BandObjectStyle.ExplorerToolbar , HelpText = "Shows bar that says hello.")] /// public class HelloWorldBar : BandObject /// { /*...*/ } /// public class BandObject : UserControl, IObjectWithSite, IDeskBand, IDockingWindow, IOleWindow, IInputObject { /// /// Reference to the host explorer. /// protected WebBrowserClass Explorer; protected IInputObjectSite BandObjectSite; /// /// This event is fired after reference to hosting explorer is retreived and stored in Explorer property. /// public event EventHandler ExplorerAttached; public BandObject() { InitializeComponent(); } private void InitializeComponent() { // // ExplorerBar // this.Name = "BandObject"; } /// /// Title of band object. Displayed at the left or on top of the band object. /// [Browsable(true)] [DefaultValue("")] public String Title { get { return _title; } set { _title = value; } }String _title; /// /// Minimum size of the band object. Default value of -1 sets no minimum constraint. /// [Browsable(true)] [DefaultValue(typeof(Size), "-1,-1")] public Size MinSize { get { return _minSize; } set { _minSize = value; } }Size _minSize = new Size(-1, -1); /// /// Maximum size of the band object. Default value of -1 sets no maximum constraint. /// [Browsable(true)] [DefaultValue(typeof(Size), "-1,-1")] public Size MaxSize { get { return _maxSize; } set { _maxSize = value; } }Size _maxSize = new Size(-1, -1); /// /// Says that band object's size must be multiple of this size. Defauilt value of -1 does not set this constraint. /// [Browsable(true)] [DefaultValue(typeof(Size), "-1,-1")] public Size IntegralSize { get { return _integralSize; } set { _integralSize = value; } }Size _integralSize = new Size(-1, -1); public virtual void GetBandInfo( UInt32 dwBandID, UInt32 dwViewMode, ref DESKBANDINFO dbi) { dbi.wszTitle = this.Title; dbi.ptActual.X = this.Size.Width; dbi.ptActual.Y = this.Size.Height; dbi.ptMaxSize.X = this.MaxSize.Width; dbi.ptMaxSize.Y = this.MaxSize.Height; dbi.ptMinSize.X = this.MinSize.Width; dbi.ptMinSize.Y = this.MinSize.Height; dbi.ptIntegral.X = this.IntegralSize.Width; dbi.ptIntegral.Y = this.IntegralSize.Height; dbi.dwModeFlags = DBIM.TITLE | DBIM.ACTUAL | DBIM.MAXSIZE | DBIM.MINSIZE | DBIM.INTEGRAL; } /// /// Called by explorer when band object needs to be showed or hidden. /// /// public virtual void ShowDW(bool fShow) { if (fShow) Show(); else Hide(); } /// /// Called by explorer when window is about to close. /// public virtual void CloseDW(UInt32 dwReserved) { Dispose(true); } /// /// Not used. /// public virtual void ResizeBorderDW(IntPtr prcBorder, Object punkToolbarSite, bool fReserved) { } public virtual void GetWindow(out System.IntPtr phwnd) { phwnd = Handle; } public virtual void ContextSensitiveHelp(bool fEnterMode) { } public virtual void SetSite(Object pUnkSite) { if (BandObjectSite != null) Marshal.ReleaseComObject(BandObjectSite); if (Explorer != null) { Marshal.ReleaseComObject(Explorer); Explorer = null; } BandObjectSite = (IInputObjectSite)pUnkSite; if (BandObjectSite != null) { //pUnkSite is a pointer to object that implements IOleWindowSite or something similar //we need to get access to the top level object - explorer itself //to allows this explorer objects also implement IServiceProvider interface //(don't mix it with System.IServiceProvider!) //we get this interface and ask it to find WebBrowserApp _IServiceProvider sp = BandObjectSite as _IServiceProvider; Guid guid = ExplorerGUIDs.IID_IWebBrowserApp; Guid riid = ExplorerGUIDs.IID_IUnknown; try { object w; sp.QueryService( ref guid, ref riid, out w); //once we have interface to the COM object we can create RCW from it Explorer = (WebBrowserClass)Marshal.CreateWrapperOfType( w as IWebBrowser, typeof(WebBrowserClass) ); OnExplorerAttached(EventArgs.Empty); } catch (COMException) { //we anticipate this exception in case our object instantiated //as a Desk Band. There is no web browser service available. } } } public virtual void GetSite(ref Guid riid, out Object ppvSite) { ppvSite = BandObjectSite; } /// /// Called explorer when focus has to be chenged. /// public virtual void UIActivateIO(Int32 fActivate, ref MSG Msg) { if (fActivate != 0) { Control ctrl = GetNextControl(this, true);//first if (ModifierKeys == Keys.Shift) ctrl = GetNextControl(ctrl, false);//last if (ctrl != null) ctrl.Select(); this.Focus(); } } public virtual Int32 HasFocusIO() { return this.ContainsFocus ? 0 : 1; //S_OK : S_FALSE; } /// /// Called by explorer to process keyboard events. Undersatands Tab and F6. /// /// /// S_OK if message was processed, S_FALSE otherwise. public virtual Int32 TranslateAcceleratorIO(ref MSG msg) { if (msg.message == 0x100)//WM_KEYDOWN if (msg.wParam == (uint)Keys.Tab || msg.wParam == (uint)Keys.F6)//keys used by explorer to navigate from control to control if (SelectNextControl( ActiveControl, ModifierKeys == Keys.Shift ? false : true, true, true, false) ) return 0;//S_OK return 1;//S_FALSE } /// /// Override this method to handle ExplorerAttached event. /// /// protected virtual void OnExplorerAttached(EventArgs ea) { if (ExplorerAttached != null) ExplorerAttached(this, ea); } /// /// Notifies explorer of focus change. /// protected override void OnGotFocus(System.EventArgs e) { base.OnGotFocus(e); BandObjectSite.OnFocusChangeIS(this as IInputObject, 1); } /// /// Notifies explorer of focus change. /// protected override void OnLostFocus(System.EventArgs e) { base.OnLostFocus(e); if (ActiveControl == null) BandObjectSite.OnFocusChangeIS(this as IInputObject, 0); } /// /// Called when derived class is registered as a COM server. /// [ComRegisterFunctionAttribute] public static void Register(Type t) { string guid = t.GUID.ToString("B"); RegistryKey rkClass = Registry.ClassesRoot.CreateSubKey(@"CLSID\" + guid); RegistryKey rkCat = rkClass.CreateSubKey("Implemented Categories"); BandObjectAttribute[] boa = (BandObjectAttribute[])t.GetCustomAttributes( typeof(BandObjectAttribute), false); string name = t.Name; string help = t.Name; BandObjectStyle style = 0; if (boa.Length == 1) { if (boa[0].Name != null) name = boa[0].Name; if (boa[0].HelpText != null) help = boa[0].HelpText; style = boa[0].Style; } rkClass.SetValue(null, name); rkClass.SetValue("MenuText", name); rkClass.SetValue("HelpText", help); if (0 != (style & BandObjectStyle.Vertical)) rkCat.CreateSubKey("{00021493-0000-0000-C000-000000000046}"); else if (rkCat.OpenSubKey("{00021493-0000-0000-C000-000000000046}") != null) rkCat.DeleteSubKey("{00021493-0000-0000-C000-000000000046}"); if (0 != (style & BandObjectStyle.Horizontal)) rkCat.CreateSubKey("{00021494-0000-0000-C000-000000000046}"); else if (rkCat.OpenSubKey("{00021494-0000-0000-C000-000000000046}") != null) rkCat.DeleteSubKey("{00021494-0000-0000-C000-000000000046}"); if (0 != (style & BandObjectStyle.TaskbarToolBar)) rkCat.CreateSubKey("{00021492-0000-0000-C000-000000000046}"); else if (rkCat.OpenSubKey("{00021492-0000-0000-C000-000000000046}") != null) rkCat.DeleteSubKey("{00021492-0000-0000-C000-000000000046}"); if (0 != (style & BandObjectStyle.ExplorerToolbar)) Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").SetValue(guid, name); if (0 != (style & BandObjectStyle.ExplorerBar)) Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Explorer Bars").CreateSubKey(guid); else if (Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Explorer Bars").OpenSubKey(guid) != null) Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Explorer Bars").DeleteSubKey(guid); } /// /// Called when derived class is unregistered as a COM server. /// [ComUnregisterFunctionAttribute] public static void Unregister(Type t) { string guid = t.GUID.ToString("B"); BandObjectAttribute[] boa = (BandObjectAttribute[])t.GetCustomAttributes( typeof(BandObjectAttribute), false); BandObjectStyle style = 0; if (boa.Length == 1) style = boa[0].Style; if (0 != (style & BandObjectStyle.ExplorerToolbar)) Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Internet Explorer\Toolbar").DeleteValue(guid, false); Registry.ClassesRoot.CreateSubKey(@"CLSID").DeleteSubKeyTree(guid); } } }