PropertySheet外壳扩展AppWizard
本文旨在简化属性表外壳扩展的实现。它紧接我的第一篇文章 处理上下文菜单壳扩展和灵感 由Michael Dunn最优秀的系列教程 关于编写shell扩展。我强烈建议你们通读一下,以便更好地理解 下面。 这一次,我们将处理一个实现属性表外壳扩展的解决方案。我们会重复使用材料 在我的前一篇文章中找到,并添加了几行代码。所有这些都打包在一个整洁的PropertySheet外壳扩展中 AppWizard。 安装并运行向导 属性表外壳扩展向导包含在一个自包含的propsheetapp中。awx文件 需要复制到您的模板文件夹中。模板文件夹可以在主Microsoft Visual中找到 Studio安装文件夹,位于\通用\MSDev98\模板文件夹下。 使用File|New菜单项激活向导,该菜单项会触发一个New Projects对话框。 选择属性表外壳扩展项将出现以下向导对话框。这一步可以让 指定shell扩展要注册的文件类型,以及它的c++类名 将由向导生成。 巫师给了你什么? 该向导将生成一个与ATL/COM应用向导创建的项目类似的Visual Studio项目。 主要区别在于,项目已经包含了实现属性表骨架的类 外壳扩展。 回想一下Michael Dunn的教程,属性表外壳扩展是一个应该实现的COM对象 IShellExtInit和IShellPropSheetExt接口。向导生成的类 已经以头文件atlshellexh的形式提供了支持这些实现所需的所有内容 它与我上一篇文章中使用的相同,只是经过了更新,而且增加了几行代码 输出IShellPropSheetExt接口的实现。 向导生成的代码使用了ATL的WTL扩展。这些真的很方便 没有明显的理由不使用它们。这些扩展简化了对属性页本身和对话框的编程 控制。向导已经生成了初始的属性页类。它已经知道如何对WM_INITDIALOG作出反应 和PSM_APPLY消息。 让我们从一个示例开始 让我们尝试编写一个类似于本教程中描述的shell扩展。这可不那么容易 时间,因为属性表有点复杂,你必须自己做大部分工作。然而, 向导已经生成了实际创建和显示属性页的所有工作。 从上面的屏幕快照中可以注意到,我们选择将shell扩展挂钩到. txt文件,就像Michael的一样。 还要注意,在我们的示例中实现扩展的类名为CShellExt。 如果查看CShellExt中AddPages()方法的实现,就会发现 看到这些线: 隐藏,复制Code
STDMETHODIMP CShellExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
{
CSamplePropPage* m_pPage; m_pPage = new CSamplePropPage;
m_pPage->SetTitle(_T("Sample"));
m_pPage->SetFile(m_files[0]); HPROPSHEETPAGE hPage = m_pPage->Create();
if (!lpfnAddPage(hPage, lParam)) delete m_pPage;
return S_OK;
}
这段由向导生成的代码实际上创建了一个属性页的实例,并为它分配了一个假标题 根据您的项目名称。它还将第一个选定文件的名称传递给属性表,并调用 shell的回调函数,执行向属性表添加页面的操作。请注意这个属性 page类名是基于您的项目名合成的,在我们的例子中,项目是Sample,因此 CSamplePropPage类。 如果我们需要添加更多的页面,就像Michael在他的例子中所做的那样,那就是放置它们的地方。我不会做 我举个例子。只需对m_files数组和进行迭代就足够了 为每个属性页创建其他实例。 令人惊讶的是,属性页的WTL实现没有提供在其中设置小图标的方法 属性页选项卡。所以我们需要自己添加它。此外,我们希望文件名显示 也在选项卡中。需要作出的改变概述如下: 隐藏,复制Code
<FONT COLOR="red">#include </FONT><FONT COLOR="red">"shlwapi.h"</FONT>
...
STDMETHODIMP CShellExt::AddPages(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam)
{
CSamplePropPage* m_pPage;
m_pPage = new CSamplePropPage; <FONT COLOR="red">// Add a small icon (assuming a resource identifier IDI_ICON)</FONT><FONT
COLOR="red">
m_pPage->m_psp.pszIcon = MAKEINTRESOURCE(IDI_ICON);
m_pPage->m_psp.dwFlags |= PSP_USEICONID;</FONT> <FONT COLOR="red">// Use the file name as the title</FONT><FONT COLOR="red">
TCHAR szFile[_MAX_FNAME];
lstrcpy(szFile, m_files[</FONT><FONT COLOR="red">0</FONT><FONT COLOR="red">]);
::PathStripPath(szFile);</FONT> m_pPage->SetTitle(<FONT COLOR="red">szFile</FONT>);
m_pPage->SetFile(m_files[0]); HPROPSHEETPAGE hPage = m_pPage->Create();
if (!lpfnAddPage(hPage, lParam)) delete m_pPage;
return S_OK;
}
一定要添加shlwapi。将库设置为项目设置中的库列表。 现在我们已经建立并运行了属性表的基础知识,我们需要添加更多有趣的特性 CSamplePropPage类。我们将在对话框模板中添加五个日期和时间选择器控件 order用来显示各种日期和时间,以及额外的静态控件来显示完整的文件路径。 为了简化我们的工作,我们将使用SetCombinedDatetime()和GetCombinedDateTime() 帮助函数,分别从两个日期和时间选择器中设置和获取日期和时间部分 控制。这些函数的代码改编自Michael的项目: 隐藏,收缩,复制Code
void GetCombinedDateTime ( HWND hwnd, UINT idcDatePicker, UINT idcTimePicker,
FILETIME* pFiletime )
{
SYSTEMTIME st = {0}, stDate = {0}, stTime = {0};
FILETIME ftLocal; CDateTimePickerCtrl dtControl;
dtControl.Attach(::GetDlgItem(hwnd, idcDatePicker));
dtControl.GetSystemTime(&stDate); if (idcTimePicker != 0) {
dtControl.Attach(::GetDlgItem(hwnd, idcTimePicker));
dtControl.GetSystemTime(&stTime);
} st.wMonth = stDate.wMonth;
st.wDay = stDate.wDay;
st.wYear = stDate.wYear;
st.wHour = stTime.wHour;
st.wMinute = stTime.wMinute;
st.wSecond = stTime.wSecond; ::SystemTimeToFileTime (&st, &ftLocal);
::LocalFileTimeToFileTime (&ftLocal, pFiletime); dtControl.Detach();
}
隐藏,复制Code
void SetCombinedDateTime ( HWND hwnd, UINT idcDatePicker, UINT idcTimePicker,
const FILETIME* pFiletime )
{
SYSTEMTIME st;
FILETIME ftLocal; ::FileTimeToLocalFileTime (pFiletime, &ftLocal);
::FileTimeToSystemTime (&ftLocal, &st); CDateTimePickerCtrl dtControl;
dtControl.Attach(::GetDlgItem(hwnd, idcDatePicker));
dtControl.SetSystemTime(GDT_VALID, &st); if (idcTimePicker != 0) {
dtControl.Attach(::GetDlgItem(hwnd, idcTimePicker));
dtControl.SetSystemTime(GDT_VALID, &st);
} dtControl.Detach();
}
更新这些控件的代码是相当标准的WTL控件编程n OnInitDialog () 函数。这个函数是由向导生成的,所以这里是你需要添加的行: 隐藏,收缩,复制Code
LRESULT CSamplePropPage::OnInitDialog(HWND /*hWnd*/, LPARAM /*lParam*/)
{
// Display the full path
CStatic sPath;
sPath.Attach(::GetDlgItem(m_hWnd, IDC_FILE));
sPath.SetWindowText(m_file);
sPath.Detach(); // Get the file dates and times FILETIME creationTime;
FILETIME accessTime;
FILETIME modificationTime; HANDLE hFile; hFile = ::CreateFile(m_file, GENERIC_READ,
FILE_SHARE_READ, 0,
OPEN_EXISTING, 0, 0);
ATLASSERT(hFile != INVALID_HANDLE_VALUE); ::GetFileTime(hFile, &creationTime, &accessTime, &modificationTime);
::CloseHandle(hFile); // Display the creation/modification/access date and time SetCombinedDateTime(m_hWnd, IDC_CREATIONDATE, IDC_CREATIONTIME, &creationTime);
SetCombinedDateTime(m_hWnd, IDC_MODIFICATIONDATE, IDC_MODIFICATIONTIME, &modificationTime);
SetCombinedDateTime(m_hWnd, IDC_ACCESSDATE, 0, &accessTime); return 0L;
}
要启用Apply按钮,我们需要捕获日期和时间选择器控件发送的通知。 它们向属性表发送一个DTN_DATETIMECHANGE通知。我们只需要添加一个宏 我们的消息映射和类中相应的消息处理程序来完成任务。注意,因为我们是 在使用WTL时,我使用了_EX版本的消息映射宏来执行消息破解,但是你没有 如果您愿意,可以随时使用ATL提供的一个。 隐藏,复制Code
class CSamplePropPage : public CPropertyPageImpl<CSamplePropPage>
{
...
LRESULT OnDateTimeChanged(LPNMHDR lpnmhdr);
...
// Message map
public:
BEGIN_MSG_MAP_EX(CSamplePropPage)
CHAIN_MSG_MAP(CPropertyPageImpll<CSamplePropPage>)
MSG_WM_INITDIALOG(OnInitDialog)
<FONT COLOR="red">NOTIFY_RANGE_CODE_HANDLER_EX(IDC_CREATIONDATE, IDC_ACCESSDATE, DTN_DATETIMECHANGE, OnDateTimeChanged)</FONT>
END_MSG_MAP()
};
我假设日期和时间选择器控件的资源标识符是顺序的,因此我可以 使用范围处理程序将所有这些控件的通知路由到一个消息处理程序。实现 OnDateTimeChanged()函数很简单。只要启用Apply按钮… 隐藏,复制Code
LRESULT CSamplePropPage::OnDateTimeChanged(LPNMHDR /*lpnmhdr*/)
{
SetModified(TRUE);
return 0L;
}
点击Apply按钮将触发向导生成的OnApply()函数。 这是一个被覆盖的函数,每当用户点击OK或Apply按钮时就会调用它。我们需要申请 返回到文件的日期和时间修改。 隐藏,复制Code
BOOL CSamplePropPage::OnApply(void)
{
FILETIME creationTime;
FILETIME accessTime;
FILETIME modificationTime; // Get the new creation/modification/access date and time GetCombinedDateTime(m_hWnd, IDC_CREATIONDATE, IDC_CREATIONTIME, &creationTime);
GetCombinedDateTime(m_hWnd, IDC_MODIFICATIONDATE, IDC_MODIFICATIONTIME, &modificationTime);
GetCombinedDateTime(m_hWnd, IDC_ACCESSDATE, 0, &accessTime); // Set the file dates and times
HANDLE hFile; hFile = ::CreateFile(m_file, GENERIC_WRITE,
0, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
ATLASSERT(hFile != INVALID_HANDLE_VALUE); ::SetFileTime(hFile, &creationTime, &accessTime, &modificationTime);
::CloseHandle(hFile); return TRUE;
}
就是这样!这个项目现在完成了。 结论 如您所见,实现上下文菜单扩展现在更快更容易了。此外,你可以重复使用 在您自己的项目中提供了atlshellexh文件。这个文件,atlshellexh实现的 IShellExtInit接口在某种程度上也与实现上下文菜单Shell直接相关 我在上一篇文章中概述的扩展。 我希望这篇文章足够清楚。如果你有什么问题,请告诉我。 本文转载于:http://www.diyabc.com/frontweb/news30106.html
PropertySheet外壳扩展AppWizard的更多相关文章
- [翻译].NET Shell Extensions - Shell Context Menus---.net 外壳扩展-右键菜单
我自己的前言说明: 本文原作者为 Dave Kerr,原文链接为.NET Shell Extensions - Shell Context Menus:,我是在为了完成最新需求的时候查询资料的时 ...
- Delphi编写Shell扩展
用delphi创建一个外壳扩展(Shell Extension)程序的基本步骤如下: (1) 创建一个 ActiveX Library 工程,命名为“CloudUpload“(2) 创建一个新的自动化 ...
- windows的各种扩展名详解
Windows系统文件按照不同的格式和用途分很多种类,为便于管理和识别,在对文件命名时,是以扩展名加以区分的,即文件名格式为: 主文件名.扩展名.这样就可以根据文件的扩展名,判定文件的种类,从而知道其 ...
- 如何往IE工具条添加按钮(转载)
如何往IE工具条添加按钮 问题提出:金山词霸.网络蚂蚁等软件安装后会向IE的工具条添加自己的按钮.按下按钮后还会作出相应的动作,这种功能是如何实现的呢?读完本文,您也可以将自己应用程序的按钮添加到IE ...
- [No000098]SVN学习笔记5-分支,合并,属性,补丁,锁,分支图
行结束符和空白选项 在项目的生命周期中,有时可能会将行结束符由 CRLF 改为 LF,或者修改一段代码的缩进.不幸的是这样将会使大量的代码行被标记为已修改,尽管代码本身并没有被修改.这里列出的选项将会 ...
- 如何使用BHO定制你的Internet Explorer浏览器
原文出处:Browser Helper Objects: The Browser the Way You Want It一.简介 有时,你可能需要一个定制版本的浏览器.在这种情况下,你可以自由地把一些 ...
- atitit。wondows 右键菜单的管理与位置存储
atitit.wondows 右键菜单的管理与位置存储 原理 .这样的功能称为Windows外壳扩展(Shell Extensions) 1 常用右键菜单 atiContentMenu1 通用tool ...
- Delphi 的知识体系
第一部分 快速开发的基础 第1章 Delphi 5下的Windows编程 1 1.1 Delphi产品家族 1 1.2 Delphi是什么 3 1.2.1 可视化开 ...
- delphi公共函数 UMyPubFuncFroc--版权所有 (C) 2008 勇者工作室
{*******************************************************} { } { Delphi公用函数单元 } { } { 版权所有 (C) 2008 勇 ...
随机推荐
- 目标识别AI资料
朋友推荐的, 还有自己搜的. 入门可以看看. 网上资料应该不少, 一搜一大把, 简单记下地址. Review of Deep Learning Algorithms for Object Detect ...
- 利用阿里云服务器免费体验word press博客、个人网站
本文首发于我的个人博客:https://chens.life/create-wordpress-blog.html 前言 目前市面上有许许多多的虚拟云服务器ECS,例如阿里云.华为云.又拍云等等,他们 ...
- java初探(1)之秒杀的业务简单实现
前言 秒杀的业务场景广泛存在于电商当中,即有一个倒计时的时间限制,当倒计时为0时,秒杀开始,秒杀之后持续很小的一段时间,而且秒杀的商品很少,因此会有大量的顾客进行购买,会产生很大的并发量,从而创造技术 ...
- python之结合if条件判断和生成随机数的相关知识,完成石头剪刀布的游戏
程序开始,显示下面提示信息: 请输入:剪刀(0).石头(1).布(2): 用户输入数字0-2中的一个数字,与系统随机生成的数字比较后给出结果信息. 例如:输入0后,显示如下 你的输入为:剪刀(0) 随 ...
- RGB打水印在YUV图片上
一. 概述 将RGB图片打在YUV上需要注意的是, 字体之外应该透明, 否则背景也会被覆盖不好看, 所以RGB必须有透明度, 本测试格式为BMP ARGB8888(也即B是最低字节, A是最高字节 ...
- GaussDB(DWS)应用实战:对被视图引用的表进行DDL操作
摘要:GaussDB(DWS)是从Postgres演进过来的,像Postgres一样,如果表被视图引用的话,特定场景下,部分DDL操作是不能直接执行的. 背景说明 GaussDB(DWS)是从Post ...
- 如何使用dockerfile将jar包生成镜像
1.编写dockersfile FROM java:8 ADD SPRINGCLOUD.jar app.jar RUN bash -c ‘touch /app.jar’ ENTRYPOINT [&qu ...
- Oracle命令类别
Oracle命令类别: 数据操纵语言:DML: select; insert; delete; update; merge. 数据定义语言:DDL: create; alter; drop; trun ...
- Redis必须会的知识点
Nosql:非关系型数据库 分表分库 + 水平拆分 + mysql集群: 在Memcached的高速缓存,Mysql主从复制.读写分离的基础上,由于MyISAM使用表锁,高并发Mysql应用开始使用I ...
- Linux实战(16):Centos history命令进阶
因在使用history命令是发现历史命令不同步,没有时间戳,在查看历史操作的时候很不方便,特查询了相关文档,发现可通过系统自带的logger来记录跟踪,历史命令执行的用户,时间,登录IP. vim / ...