VS2008.Net 制作IE8 工具条

一、IE8工具条和VS2008.Net

       IE8上的工具条叫做ToolBand,制作这种扩展这里依靠Windows.Net技术,不用.Net用ATL C++也可以,这样发布时就不需要.Net安装包。.Net支持C++\CLIC#等编程,这里选用C#比较方便。.Net就像一个容器,容器里面的“组件”之间可以无障碍的访问。IE的一个工具条(可能是dll的形式)就是一个组件,只要这个组件注册到这册表(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InternetExplorer\Toolbar)中,那么当IE启动时,就会加载这个工具条。

二、制作IE8工具条模板组件

       当然,IE工具条组件必须遵守一定的规格,也就是说自己写的IE工具条应当继承自IEToolBand提供的模板组件,这个组件在.Net的仓库里,把这个组件组合上其他的浏览器组件,就可以做成更完整工具栏的模板组件。CodeProject上的PavelZolnikov已经做好了这个组件,叫做BandObject,下载他的源码,编译时使用管理员权限运行VS,把工程属性里的SigningSignthe assmebly打勾,选择好签名文件,这样以使用组件的强名称,最后把生成的BandObjectLib.dll注册到.NetGAC(就像一个组件仓库),工程会拷贝.NetInterop.SHDocVw.dll到工程的输出文件夹下,它是一个副本,把他也注册到GAC中,注册方法是使用GAC实用工具,gacutil/if ***.dll 注册,以后可以用gacutil/uf ***.dll 注销。

三、制作自定义IE8工具条

       制作好BandObjectLib.dll后,在工程内先引用注册好的BandObjectLib.dll,写自己的工具栏类继承自BandObject,一些格式可以参考BandOnjectLib源码附带的例子,然后添加自己的控件和事件响应。

       不过,这个BandObjectLib.dllIE83Bug,一是工具条的位置出现在了右上角的菜单栏里,二是工具条不是背景透明的,三是里面的文本输入控件textbox不能响应退格键。幸运的是这3bug,已经被解决了,原文1原文2

        对于Bug1:需要修改BandObjectLib的源码,引用原文1

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

Openthe ComInterop.cs file from the BandObjectLib project andadd the following structure.

DBIMF Structure

/// <summary>
/// A set of flags that define the mode of operation for the band object.     
/// </summary>
[Flags]
public enum DBIMF : int
{
    //The band is normal in all respects. The other mode flags modify this flag.
    NORMAL = 0x0001,
    //Windows XP and later
    FIXED = 0x0002,
    FIXEDBMP = 0x0004,
    //The height of the band object can be changed. The ptIntegral member defines 
    //the step value by which the band object can be resized. 
    VARIABLEHEIGHT = 0x0008,
    //Windows XP and later:
    UNDELETEABLE = 0x0010,
    //The band object is displayed with a sunken appearance. 
    DEBOSSED = 0x0020,
    //The band will be displayed with the background color specified in crBkgnd. 
    BKCOLOR = 0x0040,
    //Windows XP and later:
    USECHEVRON = 0x0080,
    BREAK = 0x0100,
    ADDTOFRONT = 0x0200,
    TOPALIGN = 0x0400,
    NOGRIPPER = 0x0800,
    ALWAYSGRIPPER = 0x1000,
    NOMARGINS = 0x2000,
}

Nowyou need to locate the DESKBANDINFO structure in the same file andchange the type of its dwModeFlags data field from DBIM to the newlyadded structure type DBIMF. Also change the type of the dwMask fieldto DBIM. You should wind up with the following revised structure.

DESKBANDINFO Structure

[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
public struct DESKBANDINFO
{
    public DBIM  dwMask;
    public Point ptMinSize;
    public Point ptMaxSize;
    public Point ptIntegral;
    public Point ptActual;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=255)]
    public String    wszTitle;
    public DBIMF dwModeFlags;
    public Int32 crBkgnd;
};

Ifyou want to learn more then take a look on MSDN on howthe DESKBANDINFO structureshould be implemented. The last change you need to make is in theGetBandInfo(…) method of the BandObject class which is located inthe BandObject.cs File. Assign the following value to the dwModeFlagsfield of the dbi structure in this method:

GetBandInfo(…)method

public virtual void GetBandInfo(
    UInt32 dwBandID,
    UInt32 dwViewMode,
    ref DESKBANDINFO dbi)
{
      //... preceded by other code ...

      dbi.dwModeFlags = DBIMF.BREAK;
}

Itwould be handy if you could change the value of the dwModeFlags atdesign time through a property of the BandObject class using theproperty grid. However the property grid treats this property as anenumeration and thus you can only select a single field from thedrop-down list. So you need to implement your own TypeConvertor whichhelps you edit bit field properties. Implementing this is beyond thescope of this article, but if you are interested in doing this then Irecommend the BitFlags Type Convertor article written by Serge Gorbenko. Thesources accompagnying this article already contain this typeconvertor and the BandObject class exposes a property called ViewModewhich you can use to tweak the behaviour of the toolbar.

Nowthat the BandObjectLib library has been fixed it is time to rebuildthe entire solution. Afterwards you have to reregister theBandObjectLib and SampleToolbar assemblies for the GAC in order forthe changes to become visible.

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

       对于Bug2:重载自己这个子类的绘制背景函数,这个方法也可以实现处理控件的背景透明,即继承某个控件,然后用下面的方法重载背景绘制函数。

------------------------------------------------------------------------------------------------------------------------------------------------------------------

[DllImport("uxtheme", ExactSpelling = true)] 
public extern static Int32 DrawThemeParentBackground(IntPtr hWnd, IntPtr hdc, ref Rectangle pRect); 
 
protected override void OnPaintBackground(PaintEventArgs e) 

    if (this.BackColor == Color.Transparent) 
    { 
        IntPtr hdc = e.Graphics.GetHdc(); 
        Rectangle rec = new Rectangle(e.ClipRectangle.Left, 
                                      e.ClipRectangle.Top, e.ClipRectangle.Width, e.ClipRectangle.Height); 
        DrawThemeParentBackground(this.Handle, hdc, ref rec); 
        e.Graphics.ReleaseHdc(hdc); 
    } 
    else 
    { 
        base.OnPaintBackground(e); 
    } 

------------------------------------------------------------------------------------------------------------------------------------------------------------------

        对于Bug3:如果在自己继承自BandObject的工具栏中使用了textbox,那么需要添加下面的方法到类中。

------------------------------------------------------------------------------------------------------------------------------------------------------------------

[DllImport("user32.dll")] 
public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, UInt32 wParam, Int32 lParam); 
[DllImport("user32.dll")] 
public static extern int TranslateMessage(ref MSG lpMsg); 
[DllImport("user32", EntryPoint = "DispatchMessage")] 
static extern bool DispatchMessage(ref MSG msg); 
 
public override int TranslateAcceleratorIO(ref MSG msg) 

    //const int WM_CHAR = 0x0102; 
    TranslateMessage(ref msg); 
    DispatchMessage(ref msg); 
 
    return 0

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

       然后在类的构造函数中,InitializeComponent();之后,设置这个textbox的焦点事件响应函数

------------------------------------------------------------------------------------------------------------------------------------------------------------------------

textBox1.GotFocus += new EventHandler(txtSearch_GotFocus); 
textBox1.Focus(); 

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

四、制作自定义的控件

 

五、制作安装程序

       安装程序实现这个工具栏组件依赖文件安装和自动注册。这里略去了.Net的依赖问题。

       这里的安装分两部分,一个是工具栏组件注册到注册表,一个是发布一个可执行的安装文件。

       下面实现工具栏组件的注册。BandObject里已经实现了注册和注销的函数,他们将注册注册表,实现IE的自动加载,剩下的就是在这个自定义工具栏组件在安装过程中的调用这些函数的问题了。首先,在这个工程中添加“新项”,即一个安装项(InstallerClass),修改源码,重写InstallUninstall函数,例如:

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Configuration.Install; 
using System.Text; 
using System.ComponentModel; 
using System.Runtime.InteropServices; 
 
namespace 
工具栏组件名称空间

    [RunInstaller(
true)] 
    
public partial class Register : Installer 
    { 
        
public Register() 
        { 
            InitializeComponent(); 
        } 
 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)] 
        
public override void Install(System.Collections.IDictionary stateSaver) 
        { 
            base.Install(stateSaver); 
            
//
注册注册表 
            RegistrationServices reg = 
new RegistrationServices(); 
            
if (!reg.RegisterAssembly( 
                        
this.GetType().Assembly, 
                        AssemblyRegistrationFlags.SetCodeBase) 
               ) 
            { 
                
throw new Exception("Install error :Can not register your DLL to IE"); 
            } 
        } 
 
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)] 
        
public override void Uninstall(System.Collections.IDictionary savedState) 
        { 
            base.Uninstall(savedState); 
 
            RegistrationServices reg = 
new RegistrationServices(); 
            
//
移除注册表内容 
            
if (!reg.UnregisterAssembly(this.GetType().Assembly)) 
            { 
                
throw new InstallException("Uninstall error : Failed to unregister the toolbar for COM"); 
            } 
        } 
    } 

 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------

       这样,只要在下面的安装工程中指定costomaction中的Installuninstall后,就可以自动调用注册函数了。

       接下来,制作安装程序。添加一个安装工程(SetupProject),在文件视图中,添加这个工具栏组件到“ApplicationFolder”,而不是GACFolder,属性里选则vsdraCOM为注册类型,同时,他的一些依赖组件会自动添加,这里右键点击ieframe.dll选择exclude将它排除。

切换到"CustomActions"视图,在InstallUninstall项里添加刚才添加文件时添加的那个组件,意思是安装和删除这个组件是要调用它的安装和卸载函数,这样就实现了注册函数的调用了。

六、最后的一句话

      生成了安装文件就测试吧,当然要先装好.NetIE8的浏览器工具栏制作的大概过程就是这样啦,中间遇到的问题只有自己去解决了!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值