通过WTL自定义CShellFileDialog对话框,即实现IFileDialogControlEvents接口和处理IFileDialogCustomize接口

本文详细介绍了如何在WTL中使用CShellFileDialog及其派生类实现文件对话框的自定义,包括自定义事件处理和界面定制。通过CShellFileOpenDialogCustomize和CShellFileSaveDialogCustomize实例,展示了如何添加控件和处理编码选择,以及创建自定义事件响应。

一、简单介绍一下WTL的CShellFileDialog对话框

1、在WTL中用于实现CShellFileDialog模板有

class CShellFileDialogImpl<T>;        //基于IFileDialogEvents接口的基础模板,主要封装相关事件,是CShellFileOpenDialogImpl和CShellFileSaveDialogImpl的基础
class CShellFileOpenDialogImpl<T>;    //基于IFileOpenDialog接口的基础模板,IFileOpenDialog是IFileDialog的派送类,MFC中是使用IFileDialog作为成员变量的,而后通过传入的参数,实际实例化IFileOpenDialog或者IFileSaveDialog
class CShellFileOpenDialog;           //基于IFileOpenDialog接口的基础模板的实现类
class CShellFileSaveDialogImpl<T>;    //基于IFileSaveDialog接口的基础模板,IFileSaveDialog是IFileDialog的派送类,MFC中是使用IFileDialog作为成员变量的,而后通过传入的参数,实际实例化IFileOpenDialog或者IFileSaveDialog
class CShellFileSaveDialog;           //基于IFileSaveDialog接口的基础模板的实现类

CShellFileDialogImpl<T>已经实现了所有IFileDialogEvents接口,并通过_Advise和_Unadvise来实现对事件的绑定和实际调用
CShellFileOpenDialogImpl<T>是CShellFileDialogImpl<T>派送类,并对集成了IFileOpenDialog接口应用的简单封装,主要完成了构造函数的初始化,其实际功能需要通过GetPtr函数返回的IFileOpenDialog指针来完成
CShellFileOpenDialog则是CShellFileOpenDialogImpl<T>模板的实例,其中_Advise和_Unadvise函数被刻意置空,也就是默认没有实现对自定义事件的实现功能

2、自定义事件处理
要对自定义事件进行处理,就需要自己对CShellFileOpenDialogImpl<T>模板派送一个实例,添加对应的处理函数,但不能添加_Advise和_Unadvise函数,而是让其继承CShellFileDialogImpl< T >中的相关函数用于绑定事件处理

class MyShellFileOpenDialog : public CShellFileOpenDialogImpl<CShellFileOpenDialog>
{
public:
	MyShellFileOpenDialog(LPCWSTR lpszFileName = NULL, 
	                     DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST, 
	                     LPCWSTR lpszDefExt = NULL, 
	                     const COMDLG_FILTERSPEC* arrFilterSpec = NULL, 
	                     UINT uFilterSpecCount = 0U) : CShellFileOpenDialogImpl<MyShellFileOpenDialog>(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount)
	{ }

	virtual ~MyShellFileOpenDialog()
	{ }
    //删除原CShellFileOpenDialog中的_Advise和_Unadvise即可以绑定事件
	//void _Advise(DWORD& /*dwCookie*/){ }

	//void _Unadvise(DWORD /*dwCookie*/){ }
    HRESULT OnFileOk()//添加处理函数
	{
        MessageBox(....);
		return S_OK;
	}
};

二、实现界面的自定义(IFileDialogCustomize)以及实现自定义事件处理(IFileDialogControlEvents)

1、IFileDialogControlEvents接口是系统自动从实现了IFileDialogEvents接口的对象中调取,不需要用户另外配置或绑定的

class CShellFileOpenDialogCustomizeImpl : public IFileDialogEvents, public IFileDialogControlEvents;
//或者利用WTL已经实现CShellFileDialogImpl,则我们只需要再实现IFileDialogControlEvents
template <class T>
class CShellFileDialogCustomizeImpl : public IFileDialogControlEvents< T >;
template <class T>
class CShellFileOpenDialogCustomizeImpl : public WTL::CShellFileDialogImpl< T >, public CShellFileDialogCustomizeImpl< T >

2、IFileDialogCustomize接口,此接口是用于添加控件,实现界面及控件自定义的关键,这个接口可直接从IFileOpenDialog接口中获取

ATL::CComPtr<IFileOpenDialog> m_spFileDlg;
ATL::CComPtr<IFileDialogCustomize> m_spFileDlgCust;

HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileOpenDialog);
hRet = m_spFileDlg->QueryInterface(IID_PPV_ARGS(&m_spFileDlgCust));

完成后,只需要调用m_spFileDlgCust(IFileDialogCustomize)中的相关函数的调用,即可完成对对话框的添加控件的任务

保存对话框也是类似,只是接口由IFileOpenDialog变成了IFileSaveDialog

三、全部实现代码如下:

#ifndef _FILEDIALOGCUSTOMIZE_H_
#define _FILEDIALOGCUSTOMIZE_H_

#include <atlwin.h>
#include <atldlgs.h>

namespace WTL {
	template <class T>
	class ATL_NO_VTABLE CShellFileDialogCustomizeImpl : public IFileDialogControlEvents {
	public:
	// Implementation - IUnknown interface
		STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
		{
			if(ppvObject == NULL)
				return E_POINTER;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值