继续学习MFC——有关外壳图标处理过程

找了一本《MFC技术内幕》的书,英文名MFC Black Book,老美Al Williams写的,很早以前写的啦。不管怎样,让我来学习吧。

 

从最后一章,哦,是附录A学起吧。

附录A有关外壳图标处理过程

 

Windows的外壳设计者让我们能够通过注册表、COM对象来扩展外壳,知道这一点,我们才能决定是否通过一个外壳来实现我们的某种需求。

 

下表列出外壳扩展的种类:(我喜欢表格)

名称

描述

接口

Icon

为文件类型提供动态图标

IExtractIcon,IPersistFile

Context Menu

添加上下文菜单或拖放菜单

IContextMenu,IShellExtInit

Property Sheet

添加定制的属性页

IShellPropSheetExt,IShellExtInit

Copy Hook

管理文件操作

ICopyHook

Drop Target

当对象被拖放至其它对象时交互

IDropTarget,IPersistFile

Data Object

为拖放或拷贝粘贴提供数据对象

IDataObject,IPersistFile

Quick View

Quick Vierwer 解析文件

IFileViewer,IPersistFile

Briefcase Reconcile

把某文件的多个版本合并为一个文件

IReconcilableObject, IPersistFile

 

说起来这好像不是MFC的范畴的东西。以前曾经用ATL做过文件管理器的一个扩展,实在是很麻烦。不过学习要坚持下去啦~~~

 

接下来是关于COM,MFC对COM支持的一些小节,其中MFC用来实现COM接口的方式值得关注一下。为了支持多个接口,MFC使用嵌套(Nested)类的方式,缺省的名称开头为X,让我们到MFC源代码中去找一个例子:

class COleDataSource : public CCmdTarget

{

// Interface Maps   这里删减掉了其它构造、属性、实现等部分

public:

     BEGIN_INTERFACE_PART(DataObject, IDataObject)

         INIT_INTERFACE_PART(COleDataSource, DataObject)

         STDMETHOD(GetData)(LPFORMATETC, LPSTGMEDIUM);

          // 此处删减掉 IDataObject 其它多个接口函数的定义部分

     END_INTERFACE_PART(DataObject)

     DECLARE_INTERFACE_MAP()

};

代码中绿色的几个宏就是用嵌套类的方式来实现IDataObject接口,具体宏的定义如下:

#define BEGIN_INTERFACE_PART(localClass, baseClass) /

     class X##localClass : public baseClass /

     { /

     public: /

         STDMETHOD_(ULONG, AddRef)(); /

         STDMETHOD_(ULONG, Release)(); /

         STDMETHOD(QueryInterface)(REFIID iid, LPVOID* ppvObj); /

 

#define END_INTERFACE_PART(localClass) /

     } m_x##localClass; /

     friend class X##localClass; /

 

也就是说在COleDataSource类中定义展开的样子大致如下:

     class XDataObject : public IDataObject

     {

     public:

         STDMETHOD_(ULONG, AddRef)();

          // 删减了其它接口定义 . . .

     } m_xDataObject;           // 同时产生一个实例

     friend class XDataObject;  // 定义为友类,好让嵌套类访问父类的私有、保护成员

 

如果有多个接口实现,就会定义多个这样的嵌套类和实例。下面再简单看看实现的代码:

STDMETHODIMP_(ULONG) COleDataSource::XDataObject::AddRef()

{

     // 这个宏产生 COleDataSource* pThis 的值,使用 pThis 可以访问嵌套父类

     METHOD_PROLOGUE_EX_(COleDataSource, DataObject)

     return pThis->ExternalAddRef();  // AddRef, Release 等被委托给父类(CCmdTarget)实现

}

 

至此,MFC怎样实现COM应该大致理解了。

书上说用AppWizard可以创建一个MFC COM对象,不过在VC7(.NET)中好像不太好使了。

 

 

下面总算详细介绍图标处理过程了。从表里面可以看到我们的COM对象需要实现两个接口IPersistFile 和IExtractIcon。

 

提示:如果仅仅使用一个静态图标,则只需要更改注册表DefaultIcon键就可以了,例如到HKCR下面随便找到几个:

.col/DefaultIcon = C:/WINDOWS/hh.exe,0

.nsc/DefaultIcon = dxmasf.dll,-502

 

对于基于一些文件属性或其他动态条件而更改图标,才需要用到这种复杂的方法,例如:

l        显示不同类型的账目文件。

l        网络文件图标。当网络连通正常时显示为绿色,当网络断开时显示为红色。

l        等等。。。

 

下表给出IPersistFile接口在此应用中需要实现的接口函数及其意义:

函数

描述

GetClassID

不要求,返回E_NOTIMPL。

IsDirty

不要求,返回E_NOTIMPL。

Load

外壳给该函数传递一个文件名;把UNICODE文件名转换为ANSI并保存起来。

Save

不要求,返回E_NOTIMPL。

SaveCompleted

不要求,返回E_NOTIMPL。

GetCurFile

不要求,返回E_NOTIMPL。

 

IExtractIcon接口:

函数

描述

GetIconLocation

获取包含图标的文件名和图标在该文件中的索引。

Extract

返回图标句柄。

注:这两个函数实现一个就可以。

 

书中给出了一个例子,表明怎么用CIconHandler来实现为 .VIZ文件实现自定义Icon, 也就是要实现上面所说的IPersistFile, IExtractIcon接口,我找了半天,也没看到GetIconLocation, Extract两个函数的实现,作者忘掉了吗??

 

 

最后最最关键的是要知道仅仅写了代码编译了是没有用的,还要:

1、将你的COM组件注册到系统中。不注册外壳程序找不到的哦。

2、在注册表添加如下键值:

[HKCR/.VIZ] = "VIZFile"

[HKCR/VIZFile] = "Vxxx Dxxx File Description"

[HKCR/VIZFile/Shellex/IconHandler] = "{The handlers CLSID GUID}"

[HKCR/VIZFile/DefaultIcon] = "%1"

 

 

注:到MSDN的User Interface Design And Development/Windows Shell/SDK/Windows Shell/Shell Programmer’s Guide可以找到更多的信息。

 

还有啊,现在要是实现的话,建议用ATL,不要用复杂的MFC,我笔记这些仅仅是为了学习哦。 :)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值