- 中查找“文件飞跃提示扩展”更多相关内容
- 中查找“文件飞跃提示扩展”更多相关内容
- ·上一篇文章:外壳搜索扩展
- ·下一篇文章:外壳拖放控制扩展
文件飞跃提示扩展
实现这个扩展必须编写一个实现IPersistFile和IQueryInfo接口(除了标准的Iunknown接口外)进程内的COM Server。IPersistFile接口使当前文件名可以被传递到COM对象,而IQueryInfo则把对应文件的信息反馈回外壳,然后外壳负责显示信息。这实际上是一个非常简单的过程,但奇怪的是甚至在最新的Windows SDK里也没有记载。
下面是建立一个基本的Infotip扩展的详细步骤。这个扩展可以获取mp3歌曲文件的ID3-Tag中的信息,并显示出来。首先,创建一个新的ActiveX library (File New ActiveXActive Library)并添加IPersistFile和IQueryInfo接口,得到下列文件:
Define a new type as below:
TInfoTip = class(TComObject, IQueryInfo, IPersistFile)
private
fName : string;
protected
{ IQueryInfo }
function GetInfoTip(dwFlags: DWORD; var ppwszTip: PWideChar): HResult; stdcall;
function GetInfoFlags(out pdwFlags: DWORD): HResult; stdcall;
{ IPersistFile }
function IsDirty: HResult; stdcall;
function Load(pszFileName: POleStr; dwMode: Longint): HResult; stdcall;
function Save(pszFileName: POleStr; fRemember: BOOL): HResult; stdcall;
function SaveCompleted(pszFileName: POleStr): HResult; stdcall;
function GetCurFile(out pszFileName: POleStr): HResult; stdcall;
function GetClassID(out classID: TCLSID): HResult; stdcall;
end;
implementation
uses ComServ;
对于这个扩展,IPersistFile唯一重要的方法是Load,至于IpersistFile其他的方法只要返回E_NOTIMPL就可以了,所以IpersistFile的其他方法都实现为类似下面的方法:
function TInfoTip.Save(pszFileName: POleStr; fRemember: BOOL): HResult;
begin
Result := E_NOTIMPL;
end;
当外壳调用IPersistFile.Load,它会传递文件名作为pszFileName的参数给COM对象,这时要把文件名保存起来,因为后面要用到它(注意的是pszFileName的类型是PoleStr,实际上等同于类型 PWideChar)。下面是对文件名进行保存:
function TInfoTip.Load(pszFileName: POleStr; dwMode: Integer): HResult;
begin
WideCharToStrVar(pszFileName, fName);
Result := S_OK;
end;
同样IQueryInfo接口的.GetInfoFlags方法不被外壳调用,所以也只需要返回E_NOTIMPL就可以了。整个扩展的核心部分是IQueryInfo.GetInfoTip方法。 DwFlags参数没有被外壳调用,所以可以忽略它,而ppwszTip参数就是用来返回想要显示的信息 (是一个 UNICODE 字符串)。要注意的是,必须为它分配内存,然而释放内存则是由外壳来负责。Delphi里有一个非常有用的函数StringTooleStr,这个函数接受一个Pascal类型的字符串参数,分配必须的内存,然后把它转化成PWideChar。
过程的核心部分是获得mp3文件中的Id3-tag信息。一个MP3文件包含有一个ID3-Tag头,它用来提供艺术家、标题、专辑、出版年和歌曲流派等信息。这个头总是128字节长并位于MP3文件末尾。ID3-Tag 结构是这样的:
type
TID3Tag = packed record // 128 字节
TAGID: array[0..2] of char; // 3 字节: 必须是TAG
Title: array[0..29] of char; // 30 字节: 歌曲标题
Artist: array[0..29] of char; // 30 字节: 演唱歌曲的艺术家
Album: array[0..29] of char; // 30 字节: 歌曲专辑
Year: array[0..3] of char; // 4 字节: 出版年
Comment: array[0..29] of char; // 30 字节: 评论
Genre: byte; // 1 字节: 种类标识
end;
我们要做的就是读取fName文件,跳到倒数第128个字节,读取ID3-Tag信息,并将其格式化成字符串。下面就是实现的IQueryInfo.GetInfoTip方法,注意这里我们要返回S_Ok的结果。
function TInfoTip.GetInfoTip(dwFlags: DWORD; var ppwszTip: PWideChar): HResult;
var
id3tag: Tid3tag;
mp3file: Tfilestream;
s:string;
begin
mp3file:=Tfilestream.create(fName,fmOpenRead);
try
mp3file.position:=mp3file.size-128; // 跳到id3-tag
mp3file.Read(id3tag,SizeOf(id3tag));
s:=' 标题:'+id3tag.title+#10#13+ ‘艺术家:
'+id3tag.artist+#10#13+
' Album: '+id3tag.album+#10#13+ 年份:
'+id3tag.year+#10#13+ 注释:
'+id3tag.comment+#10#13+ 风格-ID:
'+inttostr(id3tag.genre);
finally
mp3file.free;
end;
ppwszTip := StringToOleStr(s);
Result := S_OK;
end;
最后就是注册COM Server使之同文件相关联,我们要重载COM类工厂对象的UpdateReigistry 方法来添加额外的注册表项。
下面是我们要在注册表中添加的表项:
HKEY_CLASSES_ROOT
\.txt
\ShellEx
\{00021500-0000-0000-C000-000000000046}
{00021500-0000-0000-C000-000000000046}是IqueryInfo接口的GUID,我们不能改变它,最后点菜单 (Run Register ActiveX Server.)来注册它。
很重要的是一旦提示信息被显示出来,动态连接库就被装入内存,这时就无法重新编译或UnRegister库了。要想重新编译,必须用任务管理器关闭explore.exe。
注意:要想在Windows NT和Windows 2000下正常工作,外壳扩展必须注册为管理员同意权限。很多开发者会疏忽这一点,因为大多数情况下他们是以管理员的权限登录的系统。对于Win 9X则不需要设定这一项。
下面就是要添加的注册表项
HKEY_LOCAL_MACHINE
\SOFTWARE
\Microsoft
\Windows
\CurrentVersion
\Shell Extensions
\Approved
在这个键下添加扩展的类标示符(CLSID)及描述信息。
下面是最后实现的注册代码:
procedure TCXFileInfoFactory.UpdateRegistry(Register: Boolean);
var
ClassID: string;
begin
if Register then begin
inherited UpdateRegistry(Register);
ClassID := GUIDToString(Class_CXFileInfo);
CreateRegKey('.mp3\ShellEx\{00021500-0000-0000-C000-000000000046}', '', Classid);
with TRegistry.Create do
begin
try
RootKey:=HKEY_LOCAL_MACHINE;
OpenKey('\SOFTWARE\Classes\.mp3\ShellEx\
{00021500-0000-0000-C000-000000000046}',True);
WriteString('',ClassID);
finally
CloseKey;
Free;
end;
end;
end
else begin
//winnt approve registry not installed
DeleteRegKey('.mp3\ShellEx\{00021500-0000-0000-C000-000000000046}');
with TRegistry.Create do
begin
try
RootKey:=HKEY_LOCAL_MACHINE;
图2.4
DeleteKey('\SOFTWARE\Classes\.mp3\ShellEx\{00021500-0000-0000-C000-000000000046}');
finally
CloseKey;
Free;
end;
end;
inherited UpdateRegistry(Register);
end;
end;
好了,现在让我们来试验一下它的效果吧。扩展运行后的示意如图2.4所示。
Tags:
作者:佚名评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论