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 勇 ...
随机推荐
- Unity中接收服务器消息并广播事件的实现
最近接触的项目,是一个棋牌游戏,棋牌游戏需要在前端进行一些操作,然后向服务器发送数据包,在服务器接收到客户端的数据后,会在服务端进行一系列的判断之后,然后发送给客户端一个返回数据,客户端接收到这个返回 ...
- 【jmespath】—4. 进阶 Flatten Projections
这里要怎么翻呢?扁平投影? 一.Flatten Projections 1. 核心1 这个可以暂时忽略,一个重要的核心是:对于列表/对象投影,在投影中创建投影时,原始文档的结构将保留. 说人话就是,比 ...
- P1020 导弹拦截(nlogn求最长不下降子序列)
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- Codeforces1250C Trip to Saint Petersburg 线段树
题意 有个人要去圣彼得堡旅游,在圣彼得堡每天要花\(k\)块钱,然后在圣彼得堡有\(n\)个兼职工作\(l_i,r_i,p_i\),如果这个人在\(l_i\)到\(r_i\)这个时间段都在圣彼得堡,那 ...
- MyBatis的逆向工程、Example类
public void testFindUserByName(){ //通过criteria构造查询条件 UserExample userExample = new UserExample(); us ...
- composer browse 查看包的存储库和主页
composer browse 用于打开或查看包的存储库和主页 1. 使用示例 browse 命令官方手册:https://getcomposer.org/doc/03-cli.md#browse-h ...
- Java审计之XSS篇
Java审计之XSS篇 0x00 前言 继续 学习一波Java审计的XSS漏洞的产生过程和代码. 0x01 Java 中XSS漏洞代码分析 xss原理 xss产生过程: 后台未对用户输入进行检查或过滤 ...
- Golang多线程简单斗地主
多线程,通道,读写锁(单写多读),随机(洗牌),是本文涉及的主要知识点. 先看一下做出来的效果,因为是实验程序,跟真实的斗地主还是有差距,理解万岁! [发牌员]:洗牌咯. 刷刷刷... [发牌员]:牌 ...
- Vant IndexBar 在小程序中的简单使用
这篇文章是老王的朋友超超提供的,上午已经更新到原创微信公众号「软件老王」,链接,欢迎各位朋友关注老王的原创公号! 先看下最终效果图,主要是渲染一个A - Z 的 通讯录.同样的,如果你要做的是城市列表 ...
- Vue环境搭建、创建与启动、案例
vue环境搭建 """ 1) 安装node 官网下载安装包,傻瓜式安装:https://nodejs.org/zh-cn/ 2) 安装cnpm npm install - ...