Delphi编写Shell扩展
用delphi创建一个外壳扩展(Shell Extension)程序的基本步骤如下:
(1) 创建一个 ActiveX Library 工程,命名为“CloudUpload“
(2) 创建一个新的自动化对象(Automation Object)。 命名为“ TCloudUploadContext ”
TCloudUploadContext 类必须实现两个接口即:IShellExtInit 和 IContextMenu,
这样就可以在Windows Explorer 中集成该上下文菜单(Context Menu)。
{ IShellExtInit Methods }
{ Initialize the context menu if a files was selected}
function IShellExtInit.Initialize = ShellExtInitialize;
function ShellExtInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HResult; stdcall;
{ IContextMenu Methods }
{ Initializes the context menu and it decides which items appear in it,
based on the flags you pass }
function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,
uFlags: UINT): HResult; stdcall;
{ Execute the command, which will be the upload to Amazon or Azure}
function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;
{ Set help string on the Explorer status bar when the menu item is selected }
function GetCommandString(idCmd: UINT_PTR; uFlags: UINT; pwReserved: PUINT;
pszName: LPSTR; cchMax: UINT): HResult; stdcall;
ShellExtInitialize 定义了是否在 Windows Explorer 中显示上下文菜单(Context Menu)。
在该例子中,上下文菜单(Context Menu)仅当一个文件被选中的时候才显示出来,否则不会显示。
在一文件被选中时, FFileName 变量将接收该文件的文件名。
function TCloudUploadContextMenu.ShellExtInitialize(pidlFolder: PItemIDList;
lpdobj: IDataObject; hKeyProgID: HKEY): HResult;
var
DataFormat: TFormatEtc;
StrgMedium: TStgMedium;
Buffer: array [0 .. MAX_PATH] of Char;
begin
Result := E_FAIL;
{ Check if an object was defined }
if lpdobj = nil then
Exit;
{ Prepare to get information about the object }
DataFormat.cfFormat := CF_HDROP;
DataFormat.ptd := nil;
DataFormat.dwAspect := DVASPECT_CONTENT;
DataFormat.lindex := -1;
DataFormat.tymed := TYMED_HGLOBAL;
if lpdobj.GetData(DataFormat, StrgMedium) <> S_OK then
Exit;
{ The implementation now support only one file }
if DragQueryFile(StrgMedium.hGlobal, $FFFFFFFF, nil, 0) = 1 then
begin
SetLength(FFileName, MAX_PATH);
DragQueryFile(StrgMedium.hGlobal, 0, @Buffer, SizeOf(Buffer));
FFileName := Buffer;
Result := NOERROR;
end
else
begin
// Don't show the Menu if more then one file was selected
FFileName := EmptyStr;
Result := E_FAIL;
end;
{ http://msdn.microsoft.com/en-us/library/ms693491(v=vs.85).aspx }
ReleaseStgMedium(StrgMedium);
end;
在上下文件菜单句柄(context menu handler)在IShellExtInit接口中被初始化之后,
Windows系统使用 IContextMenu 接口去调用(call)上下文件菜单句柄中的其他方法。
在这种情形下,它将调用(call) QueryContextMenu, GetCommandString 和 InvokeCommand。
上下文件菜单选项(包括 Amazon S3 和 Microsoft Azure )将通过 QueryContextMenu 方法被创建。
function TCloudUploadContextMenu.QueryContextMenu(Menu: HMENU;
indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult;
var
CloudMenuItem: TMenuItemInfo;
MenuCaption: String;
SubMenu: HMENU;
uId: UINT;
begin
{ only adding one menu CloudMenuItem, so generate the result code accordingly }
Result := MakeResult(SEVERITY_SUCCESS, 0, 3);
{ store the menu CloudMenuItem index }
FMenuItemIndex := indexMenu;
{ specify what the menu says, depending on where it was spawned }
if (uFlags = CMF_NORMAL) then // from the desktop
MenuCaption := 'Send file from Desktop to the Cloud'
else if (uFlags and CMF_VERBSONLY) = CMF_VERBSONLY then // from a shortcut
MenuCaption := 'Send file from Shourtcut to the Cloud'
else if (uFlags and CMF_EXPLORE) = CMF_EXPLORE then // from explorer
MenuCaption := 'Send file from Explorer to the Cloud'
else
{ fail for any other value }
Result := E_FAIL;
if Result <> E_FAIL then
begin
SubMenu := CreatePopupMenu;
uId := idCmdFirst;
InsertMenu(SubMenu, AmazonIndex, MF_BYPOSITION, uId, TClouds[AmazonIndex]);
Inc(uId);
InsertMenu(SubMenu, AzureIndex, MF_BYPOSITION, uId, TClouds[AzureIndex]);
FillChar(CloudMenuItem, SizeOf(TMenuItemInfo), #0);
CloudMenuItem.cbSize := SizeOf(TMenuItemInfo);
CloudMenuItem.fMask := MIIM_SUBMENU or MIIM_STRING or MIIM_ID;
CloudMenuItem.fType := MFT_STRING;
CloudMenuItem.wID := FMenuItemIndex;
CloudMenuItem.hSubMenu := SubMenu;
CloudMenuItem.dwTypeData := PWideChar(MenuCaption);
CloudMenuItem.cch := Length(MenuCaption);
InsertMenuItem(Menu, indexMenu, True, CloudMenuItem);
end;
end;
在 Windows Explorer 中你用鼠标滑过该云菜单项(Cloud menu items )时会在状态栏中显示出瞬时帮助(提示)信息。 这个提示信息定义并在GetCommandString 方法中实现。
function TCloudUploadContextMenu.GetCommandString(idCmd: UINT_PTR; uFlags: UINT;
pwReserved: PUINT; pszName: LPSTR; cchMax: UINT): HResult;
begin
Result := E_INVALIDARG;
{ Set help string on the Explorer status bar when the menu item is selected }
if (idCmd in [AmazonIndex, AzureIndex]) and (uFlags = GCS_HELPTEXT) then
begin
StrLCopy(PWideChar(pszName), PWideChar('Copy the selected file to ' +
TClouds[idCmd]), cchMax);
Result := NOERROR;
end;
end;
当用户点击了一个云菜单项(Cloud menu items)中某一项时,InvokeCommand 方法将被调用(call)并且启动一个上传被选中的文件到目标云(Cloud)上的进程。
这样,我们就已经有了该文件名,基于 lpici 这个参数,我们能够分辨用户点击了哪个菜单项。
function TCloudUploadContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
var
Item: Word;
begin
Result := E_FAIL;
if HiWord(Integer(lpici.lpVerb)) <> 0 then
Exit;
{ if the index matches the index for the menu, show the cloud options }
Item := LoWord(Integer(lpici.lpVerb));
if Item in [AmazonIndex, AzureIndex] then
begin
try
Upload(lpici.HWND, Item, FFileName);
except
on E: Exception do
MessageBox(lpici.hwnd, PWideChar(E.Message), 'Cloud Upload', MB_ICONERROR);
end;
Result := NOERROR;
end;
end;
为确保当 CloudUpload 被加载时,该 COM对象(COM object)被创建,有必要创建一个类工厂的一个实例,特别是要创建一个该外壳扩展对象(the shell extension object)的一个实例,该工厂实例将在 initialization代码段中被创建。
initialization
TCloudUploadObjectFactory.Create(ComServer, TCloudUploadContextMenu, CLASS_CloudUploadContextMenu, ciMultiInstance, tmApartment);
end.
由于该类工厂将负责注册或反注册该DLL,当你使用 regsvr32.exe 的时候,ApproveShellExtension 和 UpdateRegistry 两个方法将被调用(invoked)。
注册 CloudUpload 外壳扩展应用
以管理员身份运行cmd
注册命令:
regsvr32 <PATH WHERE IS LOCATED THE DLL>CloudUpload.dll
反注册命令:
regsvr32 <PATH WHERE IS LOCATED THE DLL>CloudUpload.dll /u
原文地址:http://www.andreanolanusse.com/en/shell-extension-for-windows-32-bit-and-64-bit-with-delphi-xe2/
Delphi编写Shell扩展的更多相关文章
- 利用Delphi编写IE扩展
就是如何使IE扩展组件可以响应事件. 在自己的程序中使用过WebBrowser控件的朋友都知道,WebBrowser控件定义了诸如BeforeNavigate.DownloadComplete ...
- 启动VNC Shell扩展
下载source files - 18.3 Kb Introduction 我们使用RealVNC来远程控制我们的网络中的pc机,VNC是一个伟大的产品,但如果不记住计算机名称,它可以是乏味的,在网络 ...
- Windows Shell编程之如何编写为文件对象弹出信息框的Shell扩展
有关COM编程资料 转载:http://www.cnblogs.com/lzjsky/archive/2010/11/22/1884702.html 活动桌面引入一项新特性, 当你在某些特定对象上旋停 ...
- Linux下高效编写Shell——shell特殊字符汇总
Linux下无论如何都是要用到shell命令的,在Shell的实际使用中,有编程经验的很容易上手,但稍微有难度的是shell里面的那些个符号,各种特殊的符号在我们编写Shell脚本的时候如果能够用的好 ...
- 利用Delphi编写Socket通信程序
一.Delphi与Socket 计算机网络是由一系列网络通信协议组成的,其中的核心协议是传输层的TCP/IP和UDP协议.TCP是面向连接的,通信双方保持一条通路,好比目前的电话线,使用telnet登 ...
- python编写shell脚本详细讲解
python编写shell脚本详细讲解 那,python可以做shell脚本吗? 首先介绍一个函数: os.system(command) 这个函数可以调用shell运行命令行command并且返回它 ...
- 使用golang 编写postgresql 扩展
postgresql 的扩展可以帮助我们做好多强大的事情,支持的开发语言有lua.perl.java.js.c 社区有人开发了一个可以基于golang开发pg 扩展的项目,使用起来很方便,同时为我 ...
- 编写Postgres扩展之五:代码组织和版本控制
原文:http://big-elephants.com/2015-11/writing-postgres-extensions-part-v/ 编译:Tacey Wong 在关于编写Postgres扩 ...
- 编写Postgres扩展之四:测试
原文:http://big-elephants.com/2015-11/writing-postgres-extensions-part-iv/ 编译:http://big-elephants.com ...
随机推荐
- Tomcat 环境部署网站. 帆软平台部署.
主要内容. 需要使用Tomcat 部署 帆软报表平台(以下简称报表平台). 报表平台可以集成到网站, 也可独立部署. 此处是独立部署.即通过 网址:域名 独立访问这个报表平台. -- 技术要点 Tom ...
- 基于pyQt5开发的股价显示器(原创)
#/usr/bin/env python # -*- coding: utf-8 -*- ''' @author="livermorium116" 为了绕开公司内网而开发的 股票实 ...
- better-scroll高度问题
better-scroll无法滚动主要2方面原因,1)层级关系.2)高度问题
- 用excel批量生成insert语句
excel表格中有A.B.C三列数据,分别对应TableName的UserId.UserName.UserPwd三个字段.如下图所示 在excel的D2的位置,也就是A.B.C列的后面一列,添加下面公 ...
- Java第一次上机实验源代码
小学生计算题: package 第一次上机实验_; import java.util.*; public class 小学计算题 { public static void main(String[] ...
- Java8 list根据对象某个属性去重
1. 添加方法: import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import j ...
- Spring中BeanFactory与ApplicationContext的区别
BeanFactory:Bean工厂接口,是访问Spring Bean容器的根接口,基本Bean视图客户端.从其名称上即可看出其功能,即实现Spring Bean容器的读取. ApplicationC ...
- 【Jmeter自学】Jmeter实战-web程序(六)
1.确认测试被测对象 **网站 windows环境 2.需求: 并发登录性能测试 3.场景设置: 1s增加2个线程,运行2000次 分别查看20,,60并发下的表现 4.监控 成功率 响应时间 标准差 ...
- SAP系统中ASCS、ERS、PAS、AAS
SAP系统中ASCS.ERS.PAS.AAS是什么: ASCS:ABAP Central services instance (Message server) PAS: Primary applica ...
- 21纯 CSS 创作文本滑动特效的 UI 界面
原文地址:https://segmentfault.com/a/1190000014842868 简化版地址:https://scrimba.com/c/cgaZLh6 感想:笨蛋,想不出自己的东西. ...