网站导航免费论文 原创论文 论文搜索 原创论文 网学软件 学术大家 资料中心 会员中心 问题解答 原创论文 论文素材 设计下载 最新论文 下载排行 论文上传 在线投稿 联系我们
返回网学首页
网学联系
最新论文 推荐专题 热门论文 素材专题
当前位置: 网学 > 编程文档 > VC++ > 正文
VC++ 外壳扩展编程之windows右键菜单
来源:Http://myeducs.cn 联系QQ:点击这里给我发消息 作者: 用户投稿 来源: 网络 发布时间: 12/10/15
下载{$ArticleTitle}原创论文样式
的组件不继承其他外部已有接口,那么这样的COM组件实现起来则非常简单,它和编写普通类代码没有任何不一样的地方,只需要使用 ATL 接口的 Method 和Property 增/删向导即可实现。
    显然我们的组件要继承 Shell 的扩展接口,并且还得实现所有继承的 Shell 接口,所以我们就不能完全依赖 ATL 的"自动化"了,这里需要我们自己写代码来实现该接口。首先我们通过 AT L向导新增一个简单接口 SimpleShlExt,如下图1.5,图1.6 和 图1.7 所示操作过程:

图 1.5


图 1.6

图 1.7

然后一切默认即可,这样ATL就为我们生成了一个组件框架,我们以下的讨论都基于此框架。
 

2.添加代码

图1.8 组件类继承关系

图1.8 中红色方框是我们自己要实现的 Shell 扩展接口,它不是向导自动生成代码,需要我们手工输入。

    我们从该框架中可以获得很多好处,首先通过 ATL 的模板类 CcomCoClass 我们就可以省去反复再三的 QueryInterface 接口的实现,而我们只需要绑定组件和接口的映射关系(如下图1.9 所示)以及实现所继承接口的全部虚函数即可,以及组件的注册等它基本上都为我们做好了一切,好处大家就慢慢体会吧。下面我们首先介绍继承的各接口和其虚成员函数的作用,它们的声明包含在头文件中,首先头文件你必须包含进来:

图1.9 建立组件和接口的映射关系

图1.9 红色方框为 IShellExtInit 和 IContextMenu 接口和组件的接口映射关系,它不是向导自动生成代码,需要我们手工输入。

IShellExtInit接口:IShellExtInit 接口为 Shell 扩展编程必须要实现的接口。该接口主要用来初始化 Shell 扩展处理器(表一所列的处理器),它仅有一个虚成员函数Initialize,用户所有的 Shell 扩展初始化动作都由该函数完成。该函数的原型如下:

HRESULT Initialize(
    LPCITEMIDLIST pidlFolder,
LPDATAOBJECT lpdobj,
HKEY hkeyProgID
);

    在 Initialize 函数中,我们要做的事情就是获取用户鼠标右键点击的文件名称,但是有可能用户选择了多个文件,这里为了简单起见我们仅获取文件列表中的第一个文件。在这里我们得补充一点内容:当用户在一个拥有 WS_EX_ACCEPTFILES 风格的窗体中Drag/Drop 文件时这些文件名会以同一种格式存储,而且文件完整路径的获取也都以DragQueryFile API函数来实现。但是 DragQueryFile 需要传入一个 HDROP 句柄,该句柄即为 Drag/Drop 文件名称列表数据句柄(开始存放数据的内存区域首指针)。而 HDROP 句柄的可以通过接口 " DATAOBJECT lpdobj" 的成员函数" GetData" 来获取。以下为获取第一个 Drag/Drop 文件的完整文件路径的具体代码:

//数据存储格式
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };

//数据存储内存句柄(常用于IDataObject和IAdviseSink接口的数据传输操作)
STGMEDIUM stg = { TYMED_HGLOBAL };

if(FAILED(pDataObj->GetData(&fmt, &stg)))
{
     //如果获取数据内存句柄失败则返回E_INVALIDARG,
     //返回E_INVALIDARG则Explorer不会再调用我们的Shell扩展接口
     return E_INVALIDARG;
}

//获取实际数据内存句柄
HDROP hDrop = (HDROP)GlobalLock(stg.hGlobal);
if(NULL==hDrop)
{
     //在COM程序中养成良好的检错习惯是很重要的!!!
     return E_INVALIDARG;
}
//获取用户Drag/Drop的文件数目
int nDropCount = ::DragQueryFile((HDROP)stg.hGlobal,
0xFFFFFFFF, NULL, 0);

//本示例程序仅获取第一个Drag/Drop文件完整路径
//以下注释代码为获取所有文件完整路径的实现代码:
//for(int i = 0; i < nDropCount; ++i){
     //循环获取每个Drag/Drop文件的完整文件名
     //::DragQueryFile((HDROP)stg.hGlobal, i, m_pzDropFile, MAX_PATH);
//}

//如果用户Drag/Drop的文件数目不为一个则不予处理
if(1==nDropCount)
{
     //pzDropFile为组件类内部的private变量
     //它用来保存用户Drag/Drop的文件完整文件名
     memset(m_pzDropFile, 0x0, MAX_PATH*sizeof(TCHAR));
     ::DragQueryFile((HDROP)stg.hGlobal, 0, m_pzDropFile, MAX_PATH);
}

//释放内存句柄
::ReleaseStgMedium(&mdmSTG);

网学推荐

免费论文

原创论文

浏览:
设为首页 | 加入收藏 | 论文首页 | 论文专题 | 设计下载 | 网学软件 | 论文模板 | 论文资源 | 程序设计 | 关于网学 | 站内搜索 | 网学留言 | 友情链接 | 资料中心
版权所有 QQ:3710167 邮箱:3710167@qq.com 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2015 myeducs.Cn www.myeducs.Cn All Rights Reserved
湘ICP备09003080号