无论是IE中的“图片另存为”还是QQ图片工具条,保存图片的时候都需要选择路径,文件名,然后再按保存。如果是一两张图片这样保存自然无所谓,但是如果长期需要做图片收集还是自己DIY一个菜单吧。 如果你只是想了解用Delphi编写ActiveX或者IE 右键菜单的相关信息,注意每一步下面的Addition,那里有相关主题的更多信息。
正文: 这个菜单实现的功能是:浏览网页时在图片上单击右键,弹出菜单中比平时多一项“自动保存图片”,单击后自动将图片保存到C:\Images\下面,文件名为默认的文件名,如果遇到重名情况,自动在原文件名后添加几个随机生成的字母,然后自动保存。 实现方法简介: IE右键菜单项 ---------- 修改注册表,添加菜单入口 响应菜单 ---------- VBScript脚本调用ActiveX Object 主体:保存文件 ---------- Delphi ActiveX Library & Automation Object
Step by Step: 1.添加IE右键菜单项 开始菜单,运行,输入regedit,回车,依次展开 HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt 添加一个子键:自动保存图片&Z,修改默认值为:C:\Program Files\PicSaver\PicSaver.htm (这是稍后我们将要编写的脚本),在新建的子键下添加一个REG_DWORD类型的项Contexts,修改值为2。 关闭注册表以保存 此时,新打开的IE窗口在图片上单击右键,已经出现自动保存图片菜单。
Addition:一个子键对应一个菜单项,默认值对应单击菜单时需要激活的脚本文件,Contexts是一个可选项。设置为不同的值表示仅在特定内容上单击右键才会出现这个项目。 Context IE 6.0典型值: Context Value
--------------------------- Default 0x1 Images 0x2 Controls 0x4 Tables 0x8 Text selection 0x10 Anchor 0x20
添加菜单项更多信息参见MSDN:http://msdn2.microsoft.com/en-us/library/Aa753589.aspx
2.编写VBScript脚本 新建一个空文件,输入以下内容:
<script language="VBScript"> set srcEvent = external.menuArguments.event set img = external.menuArguments.document.elementFromPoint(srcEvent.clientX, srcEvent.clientY) set ps = CreateObject("PicSaver.AutoSave") call ps.SaveImage(img.href) set ps = nothing </script>
保存为C:\Program Files\PicSaver\PicSaver.htm
Addition: 这个脚本参考了FlashGet下载软件的脚本。其中external.menuArguments可以获得对应的页面内容, elementFromPoint方法返回一个object(事实上就是那个单击的图片),img.href属性取得object对应的URL地址。 PicSaver.AutoSave是下面将要编写的ActiveX (Automation Object),调用了对象的SaveImage方法。
脚本中使用HTML 的参考资料比较少,只有MSDN的内容
http://msdn2.microsoft.com/en-us/library/ms533050.aspx
这个信息是很全的,但是检索很不方便。 脚本中使用Automation Object的方法与使用Scripting.FileSystemObject的方法完全相同,创建对象,访问属性(properties)和方法(methods)都很简单。 Scripting.FileSystemObject是内置的处理文件的object,Scripting.FileSystemObject的使用方法见:http://msdn2.microsoft.com/en-us/library/6kxy1a51.aspx,一般的VBScript教程里面都有详细说明。
3.编写Automation Object: PicSaver.AutoSave 这是最重要的部分。网上范例用.Net来编写的比较多,本例中我使用Delphi来编写。 选择用Delphi而不用C++, .Net的原因是:我现在用的机器上没有Virtual Studio,只有Delphi 7。寒。 进入正题,先打开Delphi7,File->close all,工具栏,New Item,选择ActiveX->ActiveX Library,Save,Project name为PicSaver。 New Item,选择ActiveX->Automation Object,CoClass Name为AutoSave,其余项目保留默认值。 弹出PicSaver.tlb窗口(如果没有看到,View->Type Library可以打开这个窗口),Save,Unit name为AutoSave。 在左侧可以看到IAutoSave(接口),右键单击,选择New->Method,取名字为SaveImage,单击Parameters选项卡修改参数,Name:urlstr,Type:BSTR, 单击窗口上的Refresh Implementation。Save。 关闭PicSaver.tlb窗口,弹出代码编辑器。可以看到Delphi已经自动生成了刚才定义的方法: procedure SaveImage(const urlstr: WideString); safecall; 接下来是Coding,没有太多可说的,附上我的源代码。
<---------------------------------Delphi Code----------------------------------> unit AutoSave;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses ComObj, ActiveX, PicSaver_TLB, StdVcl;
type TAutoSave = class(TAutoObject, IAutoSave) protected procedure SaveImage(const urlstr: WideString); safecall;
end;
implementation
uses ComServ, UrlMon, SysUtils, Dialogs, StrUtils;
function DownloadFile(SourceFile, DestFile: string): Boolean; begin try Result := UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0, nil) = 0; except Result := False; end; end;
function rPos(const substr, str: AnsiString): Integer; begin Result := length(str) - pos(AnsiReverseString(substr), AnsiReverseString(str)) + 1; end;
function rename(filename: string): string; var i, p: integer; randomchar: char; name, ext: string; begin p := rpos('.', filename); name := copy(filename, 1, p - 1); ext := copy(filename, p + 1, length(filename) - p); result := name; for i := 1 to 5 do begin randomchar := Chr(random(300) mod 26 + 65); result := result + randomchar; end; result := result + '.' + ext; end;
procedure TAutoSave.SaveImage(const urlstr: WideString); const PATH = 'C:\Images'; var url, DestFile, name, rname: string; len, p: integer; begin url := urlstr; //parse file name and get destfile name len := length(url); p := rpos('/', url); name := copy(url, p + 1, len - p); rname := name; while fileexists(PATH + rname) do begin rname := rename(name); end; name := rname; DestFile := PATH + name;
if DownloadFile(url, DestFile) then begin //ShowMessage('保存成功!'); end else begin ShowMessage('!!!!保存不成功!!!!'); end; end;
initialization TAutoObjectFactory.Create(ComServer, TAutoSave, Class_AutoSave, ciMultiInstance, tmApartment); end.
<-----------------------------End of Delphi Code-------------------------------->
Save, Compile, Build。 菜单:Run->Register ActiveX Server,弹出注册成功的提示。 OK,整个工程完成。
Addition: Delphi作为一款强大的IDE早已被众多程序员肯定。但是这次是我使用Delphi的最糟糕的经历。 因为“编写一个VBScript脚本里可以调用的object”相关的文档太难找了,开始的时候我选择了COM Object,编写一点问题都没有。但是VBScript CreateObject之后返回值根本不包含对象的引用。然后看到网上有很多例子都是使用ActiveX Control(控件),但是Delphi里面都是需要VCL Component来转换或者创建Active Form来实现,但是我需要的功能不是一个可视组件,只是需要一个方法和接口。之后又看到一些软件使用了BHO(Browser Helper Object),那个可以在页面加载时就开始运行,获取事件响应。BHO 也不符合我的要求。COM+好像与服务有关系,没有考虑。剩下的就只有Automation Object了,试一下居然OK了。 还有值得注意的是字符串参数一定要选BSTR,不能用LPSTR。如果选LPSTR,脚本运行的时候会出错,提示不支持的对象类型。 结论:右键菜单脚本调用object在Delphi中一定要选择Automation Object
4.由于没有制作Setup安装程式,所以使用上需要注意: 确保C:\Images存在 Delphi 提示ActiveX DLL注册成功 脚本文件存在,位置与注册表对应项一致
|
请发表评论