📄 ie异步可插入协议扩展(摘自哈巴狗的小窝).txt
字号:
procedure TForm1.Button1Click(Sender: TObject);var Strings:TEncryptStrings;begin if not OpenDialog1.Execute then Exit; Strings:=TEncryptStrings.Create; try Memo1.Lines.LoadFromFile(OpenDialog1.FileName); Strings.Text:=Memo1.Text; Strings.SaveToFile(OpenDialog1.FileName); Memo2.Lines.LoadFromFile(OpenDialog1.FileName); finally Strings.Free; end;end; procedure TForm1.Button2Click(Sender: TObject);var Strings:TDecryptStrings;begin if not OpenDialog1.Execute then Exit; Strings:=TDecryptStrings.Create; try Memo1.Lines.LoadFromFile(OpenDialog1.FileName); Strings.LoadFromFile(OpenDialog1.FileName); Memo2.Lines.Text:=Strings.Text; finally Strings.Free; end;end;
界面如下:
注册扩展
完成了扩展协议后,只剩下注册扩展了,要想注册扩展,需要在注册表的HKEY_CLASSES_ROOT\PROTOCOLS\Handler\下添加EBook关键字,然后在该关键字下添加名为CLSID的字段,设定其值为扩展的Guid,下面是用于注册的类工厂:
type TIEEncryptAPPFactory = class(TComObjectFactory) public procedure UpdateRegistry(Register: Boolean); override; end; { TIEEncryptAPPFactory } procedure TIEEncryptAPPFactory.UpdateRegistry(Register: Boolean);begin inherited; if Register then CreateRegKeyValue(HKEY_CLASSES_ROOT, 'PROTOCOLS\Handler\EBook', 'CLSID', GuidToString(ClassID)) else DeleteRegKeyValue(HKEY_CLASSES_ROOT, 'PROTOCOLS\Handler\EBook', 'CLSID');end; initialization TIEEncryptAPPFactory.Create(ComServer, TIEEncryptAPP, Class_IEEncryptAPP, 'IEEncryptAPP', '', ciMultiInstance, tmApartment);end.
最后,将本书光盘中的ebook.htm文件放到c:根目录下,注册扩展后,启动IE,输入ebook://c:\ebook.htm,然后在弹出的密码框中输入hubdog,IE就会显示解密后的电子小说,界面示意如下:
临时注册扩展
上面的注册方法可以称为持久注册的方法,一旦注册就总是生效,。IE还提供临时注册的方法,只要编写一个BHO扩展,在BHO加载时,调用TemporyRegister方法进行注册,在IE退出时调用:
var
Factory:IClassFactory;
procedure TemporaryRegister;
begin
CoGetClassObject(Class_IEEncryptAPP, CLSCTX_SERVER, nil, IClassFactory, Factory);
CoInternetGetSession(0, InternetSession, 0);
InternetSession.RegisterNameSpace(Factory, Class_IEEncryptAPP, 'EBook', 0, nil, 0);
end;
procedure UnRegister;
begin
InternetSession.UnregisterNameSpace(Factory, 'EBook');
end;
这样的好处是,在程序运行时,可以随时解除对扩展协议的支持,而前面的永久注册法必须在解除注册后,重新启动IE才行。缺点是必须通过一个BHO来实现临时注册。
其它的APP
除了上面的协议扩展外,IE还支持NameSpace Handler以及Mime-Handler两种APP扩展。其中NameSpace扩展是对特定名字空间进行处理的协议扩展,比如如果我们注册一个对名字空间<hubdog>,则当IE处理http://hubdog.csdn.net、mailto:hubdog@263.net的URL 时,一旦遇到hubdog名字空间,就会调用我们的NameSpace Handler进行处理,而不管URL是基于http协议的还是ftp等其它协议的都进行处理。从实现的角度来看,NameSpace的实现方法和前面的协议扩展几乎一样,除了注册时要填写的注册表项内容不同而已。
而Mime协议扩展处理的主要是对一些特殊的媒体资源如图片,声音文件进行处理,比如下表是IE默认支持的一些媒体形式。
text/richtext
text/html
audio/x-aiff
audio/basic
audio/wav
image/gif
image/jpeg
…
如果那天哪天你发明一种新的音乐形式,比如扩展名为.sy,就可以注册一个Mime扩展对 .sy文件处理,让IE播放相应的声音。
Mime扩展除了需要支持IInternetProtocol接口外,还必须实现IInternetProtocolSink接口,接口定义如下:
IInternetProtocolSink = interface ['{79eac9e5-baf9-11ce-8c82-00aa004ba90b}'] function Switch(const ProtocolData: TProtocolData): HResult; stdcall; function ReportProgress(ulStatusCode: ULONG; szStatusText: LPCWSTR): HResult; stdcall; function ReportData(grfBSCF: DWORD; ulProgress, ulProgressMax: ULONG): HResult; stdcall; function ReportResult(hrResult: HResult; dwError: DWORD; szResult: LPCWSTR): HResult; stdcall; end;
数据通讯方式上来看,Mime扩展同一般的协议扩展差别比较大,通讯的流程是这样的:
1. 首先,IE会在遇到相应资源下载请求时,调用扩展的Start方法来启动下载过程。
2. 然后IE会调用扩展的ReportProgress方法,告知扩展被下载的数据保存的缓存文件名称。
3. 当IE下载完原始数据后,会调用扩展的ReportData方法通知扩展准备对原始数据进行加工处理。
4. 这时,扩展需要调用IE提供的IInternetProtocol接口的Read方法来获得原始数据。
5. 对原始数据处理后,扩展要调用IE的IInternetProtocolSink接口的ReportData方法通知IE数据处理完毕。
6. 最后,IE调用扩展的Read方法获得处理后的数据。
可以看出来同一般协议扩展的纯主动向IE返回数据的方式不同,Mime的数据通讯方式即有被动的接收IE获取的原始数据,也有将处理后的数据返回IE的主动通讯方式。
由于本质上来看,Mime同一般的APP的实现相差不多,所以这里我将不再浪费篇幅来给出Mime扩展的实现实例了。
总结
IE早已经不再是一个单纯意义的Web浏览程序了,通过对IE支持的协议扩充,我们可以将IE变成一个网络开发平台,可以将IE的功能无限延伸。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -