有关COM编程资料

转载:http://www.cnblogs.com/lzjsky/archive/2010/11/22/1884702.html

活动桌面引入一项新特性, 当你在某些特定对象上旋停鼠标时,工具提示将显示它们的描述

例如对TXT格式文件:

系统默认的:                                                            扩展之后的:

                               

第一步:新建一个ATL项目,输入工程名:TxtInfo,具体如下图:

第二步:点击next

第三步:应用类型选择动态库链接(DLL),同时勾选支持MFC,最后点击Finish。

第四步:新建一个ATL简单对象(英文版的VS为ATLSimple Object)

单击 Add,在第二页面中, 在Short Name编辑框中输入TxtInofShlExt,点击 Finish.

第五步:开始我们需要添加IPersistFile到CTxtInfoShlExt实现的接口列表中.打开 TxtInfoShlExt.h, 并添加如下代码:

 #include <comdef.h>
#include <shlobj.h>
class ATL_NO_VTABLE CTxtInfoShlExt :
public CComObjectRootEx,
public CComCoClass,
public IDispatchImpl,
public IPersistFile
{
BEGIN_COM_MAP(CTxtInfoShlExt)
COM_INTERFACE_ENTRY(ITxtInfoShlExt)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IPersistFile)
END_COM_MAP()

我们需要一个保存浏览器给出的文件名的变量:
protected:
// ITxtInfoShlExt

CString m_sFilename;

注意我们可以在任何地方使用 MFC 对象.如果你看一下 IpersistFile 的文档, 你会看到很多方法.
幸运的是, 对于Shell扩展, 我们只用实现Load(), 而忽略其它方法. 以下是 IPersistFile 方法的原型:

public:
// IPersistFile
STDMETHOD(GetClassID)(LPCLSID) { return E_NOTIMPL; }
STDMETHOD(IsDirty)() { return E_NOTIMPL; }
STDMETHOD(Load)(LPCOLESTR, DWORD);
STDMETHOD(Save)(LPCOLESTR, BOOL) { return E_NOTIMPL; } STDMETHOD(SaveCompleted)(LPCOLESTR) { return E_NOTIMPL; } STDMETHOD(GetCurFile)(LPOLESTR*) { return E_NOTIMPL; }

除开 Load() 外的方法都只返回 E_NOTIMPL 以表明我们没有实现它们.
更妙的是, Load() 方法也相当简单.
我们只需保存浏览器传给我们的文件名. 也就是当前鼠标在其上盘旋的文件.

HRESULT CTxtInfoShlExt::Load ( LPCOLESTR wszFilename, DWORD dwMode )
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); // init MFC
// 让CString 自动转化文件名为 ANSI 字符.
m_sFilename = wszFilename;
return S_OK;
}

请注意函数的第一行. 要让MFC正确地工作该行代码是必要的.
由于我们的 DLL 要被非MFC程序所调用, 任一个使用MFC的输出函数必须手动初始化
MFC.
如果你不写这行代码, 则许多MFC函数 (大多是与资源处理有关的函数) 将失败或出错.

文件名被保存在 m_sFilename 以备后用.
注意我利用了 CString 的赋值操作符的特性来转化字符串为ANSI格式
- 如果该 DLL以ANSI方式建立.

创建工具提示的文本

在浏览器调用了我们的 Load() 方法之后, 它接着调用
QueryInterface() 获取另一个接口: IQueryInfo. IQueryInfo 是个相当简单的接口,只有两个接口 (而其中也只有一个被真正使用). 打开 TxtInfoShlExt.h ,添加如下标红的代码:

class ATL_NO_VTABLE CTxtInfoShlExt :
public CComObjectRootEx,
public CComCoClass,
public IDispatchImpl,
public IPersistFile,
public IQueryInfo
{
BEGIN_COM_MAP(CTxtInfoShlExt)
COM_INTERFACE_ENTRY(ITxtInfoShlExt)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IPersistFile)
COM_INTERFACE_ENTRY(IQueryInfo)
END_COM_MAP()

然后添加 IQueryInfo 方法的实现:

// IQueryInfo
STDMETHOD(GetInfoFlags)(DWORD*) { return E_NOTIMPL; }
STDMETHOD(GetInfoTip)(DWORD, LPWSTR*);

GetInfoFlags() 方法当前并不使用, 所以我们只返回 E_NOTIMPL.
GetInfoTip()
让我们返回工具提示文本 字符串. 首先是开头繁琐的代码:

HRESULT CTxtInfoShlExt::GetInfoTip ( DWORD dwFlags, LPWSTR* ppwszTip )
{
AFX_MANAGE_STATE(AfxGetStaticModuleState()); // init MFC

LPMALLOC pMalloc;
CStdioFile file;
DWORD dwFileSize;
CString sFirstLine;
BOOL bReadLine;
CString sTooltip;
USES_CONVERSION;

接着,AFX_MANAGE_STATE首先被调用以初始化 MFC.
这是每个函数都该做的第一件事, 甚至应该在变量声明之前,因为MFC构造函数可能调用其它的 MFC 函数.

dwFlags 当前并不被使用. ppwszTip 是个 LPWSTR (Unicode 字符串指针) 变量的指针,我们要将其赋值为我们所分配的字符

串缓冲区的指针.(指向指针的指针)

首先, 我们试着打开文件读取. 由于我们在Load()中保存了文件名,现在就可以使用了.
if ( !file.Open ( m_sFilename , CFile::modeRead | CFile::shareDenyWrite )) return E_FAIL;

现在, 我们需要使用Shell的内存分配器分配一个缓冲, 我们通过SHGetMalloc()函数获取一个IMalloc接口:
if ( FAILED( SHGetMalloc ( &pMalloc ))) return E_FAIL;

关于Imalloc 稍后我有更多的要说. 下一步是取得文件大小并读取第一行:
// 取得文件大小.
dwFileSize = file.GetLength();

// 读取第一行.
bReadLine = file.ReadString ( sFirstLine );
bReadLine总是为真, 除非文件不可获取或长度为0.下一步是创建工具提示的第一部分:文件大小.
sTooltip.Format ( _T("File size: %lu"), dwFileSize );

现在, 我们读取第一行并添加到工具提示中.
if ( bReadLine )
{
sTooltip += _T("\n"); sTooltip += sFirstLine;
}

现在我们完成了工具提示, 我们要分配一个缓冲.在这我们将使用 Imalloc 接口.
由 SHGetMalloc() 返回的指针是一个Shell的Imalloc接口指针的拷贝.
我们用这个接口分配的任何内存都位于Shell的进程空间内, 所以Shell可以使用它.
更重要的是, Shell可以释放它. 所以我们所作的就是分配缓冲区,然后忘掉它.
Shell将在完成操作时释放该内存.

要认识到的一件事是我们返回给Shell的字符串必须是 Unicode 格式的.
这就是为什么下面的Alloc()中的计算要乘以 sizeof(wchar_t);
只分配lstrlen(sToolTip)长的内存只够一半所需的内存.

*ppwszTip=(LPWSTR)pMalloc->Alloc ((1 + lstrlen(sTooltip))*sizeof(wchar_t));
if (NULL == *ppwszTip)
{
pMalloc->Release();
return E_OUTOFMEMORY;
}
// 使用 Unicode 字符串拷贝函数将工具提示文本拷入缓冲区.
wcscpy ( *ppwszTip, T2COLE((LPCTSTR) sTooltip) );
//最后我们释放先前获取得 IMalloc 接口.
pMalloc->Release();
return S_OK;
}

用命令行注册COM :regsvr32 dll的绝对路径

注:必须以管理员运行cmd

卸载COM: regsvr32 /u dll的绝对路径

如果你的操作系统是64位的 编译的工程必须x64

如果你的操作系统是32位的 编译工程是Win32

第六步:编辑TxtInfoShlExt.rgs文件

方式一:

方式二:

源码:为文件对象弹出信息框的Shell扩展

参考源码:实例程序

参考资料:Windows Shell扩展编程完全指南.rar

Windows Shell编程之如何编写为文件对象弹出信息框的Shell扩展的更多相关文章

  1. java web 下载本地文件并弹出下载框

    window.open("/dept/download") jsp代码 @RequestMapping(value = "/download", method ...

  2. 【Java】数据库查询的数据直接以指定文件类型下载到本地(弹出下载框)

    欲实现的功能目标:当点击下图的导出数据文件时弹出文件下载框,默认csv格式,用户自定义下载的本地路径 遇到的问题: 1.项目之前做过一次下载,但是是使用了本地文件模板.用输入流读取文件模板,插入数据, ...

  3. CAD打开文件总是弹出要求选择字体怎么办

    CAD打开文件总是弹出要求选择字体怎么办1.在C:\Documents and Settings\下搜索acad.fmp文件,双击用记事本打开acad.fmp文件,在最后添加内容,上面几行本来就有,不 ...

  4. CEfSharp下载文件 弹出保存框,实现 IDownloadHandler 接口

    上节讲了如何将CefSharp集成到C#中,但集成后将web界面链接进ChromiumWebBrowser后,但web界面上下载附件的功能不好使咯. 百度了半天还是没搞定,只能去看官网的Excampl ...

  5. 使用CEfSharp之旅(3)下载文件 弹出保存框 IDownloadHandler

    原文:使用CEfSharp之旅(3)下载文件 弹出保存框 IDownloadHandler 版权声明:本文为博主原创文章,未经博主允许不得转载.可点击关注博主 ,不明白的进群191065815 我的群 ...

  6. Windows核心编程学习九:利用内核对象进行线程同步

    注:源码为学习<Windows核心编程>的一些尝试,非原创.若能有助于一二访客,幸甚. 1.程序框架 #include "Queue.h" #include <t ...

  7. VS2010/MFC编程(对话框:模态对话框及其弹出过程)

    讲讲什么是模态对话框和非模态对话框,以及模态对话框怎样弹出. 一.模态对话框和非模态对话框 Windows对话框分为两类:模态对话框和非模态对话框. 模态对话框是这样的对话框,当它弹出后,本应用程序其 ...

  8. QT 获取文件的路径、打开文件的弹出对话框

    1.打开获取文件夹路径的对话框 QString filePath = QFileDialog::getExistingDirectory(this, "请选择文件保存路径...", ...

  9. 解决Windows Server2008 R2中IE开网页时弹出阻止框(Windows Server2008网页无法打开的问题)

    相信使用Windows Server2008的朋友都遇到过这种情况,用IE打开网站时会弹出“Internet Explorer增强安全配置正在阻止来自下列网站的此应用程序中的内容”的对话框.如下图所示 ...

随机推荐

  1. 【linux系列】vmware12pro安装centos7

    安装参考:http://blog.csdn.net/guin_guo/article/details/49403889 安装完成之后ip还是不成功无法连接网络: 进入/etc/sysconfig/ne ...

  2. vue脚手架一

    一准备: 在F:/xampp/htdocs/文件夹下检查: 1,node -v; 2,npm -v; 3,淘宝镜像(选装): npm install -g cnpm --registry= https ...

  3. Dell、IBM服务器配置远程管理卡

    author: headsen  chen date: 2018-10-09 14:12:32 1,IBM的服务器: 需要在bios里边进行配置,具体配置如下: , 开机画面过完之后,按F1进入bio ...

  4. 在ScrollView嵌套GridView,使GridView不滚动

    <ScrollView>       ……   <LinearLayout> </LinearLayout>       ……</ScrollView> ...

  5. Mac - 苹果电脑mac系统释放硬盘空间方法汇总

    硬盘空间是大家最头痛的一个问题,大家在硬盘空间变小的时候怎么腾空间的呢?下面为大家分享7个mac系统释放空间的高级方法,大家赶紧来收了! mac系统释放硬盘空间方法: 方法一:删除Emacs--可以节 ...

  6. thinkphp---数据表更新字段开发模式可更新生产模式不能更新!

    这里认为是坑的主要原因:这个问题我调试了一天,才发现是缓存的问题. 问题原因:在做一thinkphp的项目,在后期要进行修改.修改的时候,数据表里面添加了两个字段,然后前台修改模板,将添加的字段提交上 ...

  7. Linux系统下 Supervisor 安装搭建(yum安装)

    安装Supervisor # 安装supervisor yum install supervisor # 打开supervisor的配置文件 vi /etc/supervisord.conf 将sup ...

  8. [NGINX] - 配置文件优化 - NGINX.CONF

    Nginx 本文主要针对公司的Nginx负载均衡配置进行解释,配置文件在最下方.因为公司没有使用PHP,所以NGINX里面并没有太多facgi模块相关优化    NGINX.CONF user   语 ...

  9. 自定义Realm解析

    自定义Realm解析---------------------------------------> /* * Copyright 2005-2013 shopxx.net. All right ...

  10. CodeForces 19D Points (线段树+set)

    D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...