博客日历
2025年01月 | ||||||
一 | 二 | 三 | 四 | 五 | 六 | 七 |
30 | 31 | 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | 1 | 2 |
存档
2024年03月 04月 05月 2021年
01月 02月 11月 12月 2020年
02月 03月 04月 05月 06月 07月
09月 2018年
09月 2017年
01月 02月 07月 2016年
01月 04月 07月 08月 11月 12月
2015年
01月 02月 03月 05月 09月 10月
11月 2014年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2013年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2012年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2011年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2010年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2009年
03月 04月 05月 06月 07月 08月
09月 10月 11月 12月
COM.6 Windows Shell扩展(在右键菜单显示“显示或者隐藏扩展名”)
1.Windows Shell扩展简介
Windows Shell扩展是实现了指定接口的COM组件。
当用户在Explorer中点击右键时,Explorer会在[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\Background\shellex\ContextMenuHandlers\XXXXX]下查找实现了IShellExtInit,IContextMenu接口的COM组件(根据CLSID)。也就是说要在右键菜单上添加一项,需要实现的接口是:IShellExtInit,IContextMenu。
本例的添加的注册表信息是:
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\Background\shellex\ContextMenuHandlers\ShowHideExtName]
@="{96BABF4F-7C38-4885-B407-3800F461669B}"
注:添加此注册信息可以在DllRegisterServer中实现,删除注册信息在DllUnregisterServer中实现。
2.实现右键菜单显示“显示或者隐藏扩展名”功能
显示或者隐藏扩展名是如下位置的注册表来决定的。
LPCTSTR lpHideFileExtSubKey=_T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced");
LPCTSTR lpHideFileExtKey=_T("HideFileExt");
在IShellExtInit的Initialize中检测当前状态是显示还是隐藏扩展名:
DWORD dwValue=-1;
GetRegValue(HKEY_CURRENT_USER,lpHideFileExtSubKey,lpHideFileExtKey,dwValue);
m_bHideExtName=(dwValue==1?TRUE:FALSE);
在IContextMenu的QueryContextMenu中添加菜单:
CMenu menu;
menu.Attach(hMenu);
menu.InsertMenu(indexMenu,MF_BYPOSITION,idCmdFirst,m_bHideExtName?_T("显示扩展名(&S)"):_T("隐藏扩展名(&H)"));
menu.Detach();
在InvokeCommand中处理菜单事件:
WriteRegKey(HKEY_CURRENT_USER,lpHideFileExtSubKey,lpHideFileExtKey,m_bHideExtName?0:1);
HWND hWnd=GetForegroundWindow();
RefreshWindow(hWnd);
刷新窗口是实现方法(模拟用户的鼠标和键盘操作):
void RefreshWindow(HWND hWnd)
{
//F5使已选择的图标去掉选中状态
keybd_event(VK_F5, 0, 0, 0);
Sleep(10);
keybd_event(VK_F5, 0, KEYEVENTF_KEYUP, 0);
//Shift+F10显示右键菜单
keybd_event(VK_LSHIFT, 0, 0, 0);
keybd_event(VK_F10, 0, 0, 0);
Sleep(10);
keybd_event(VK_F10, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_LSHIFT, 0, KEYEVENTF_KEYUP, 0);
//E执行刷新
keybd_event('E', 0, 0, 0);
Sleep(10);
keybd_event('E', 0, KEYEVENTF_KEYUP, 0);
}
具体实现可参考源码。
备注:
a.编译时如果提示找不到关联的GUID,则参见:http://support.microsoft.com/?id=192561
(定义预处理器符号 _ATL_NO_UUIDOF)
b.让Explorer在独立的进程中启动新窗口,以便于调试(可以尽量避免dll被占用的问题)。
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
"DesktopProcess"=dword:00000001
c.参考书籍
《Windows Shell 扩展编程完全指南.chm》
《Windows Shell 编程指南与实例.pdf》
《Visual C++ Windows Shell Programming.pdf》
源码:点击下载ShowExtName.zip
注意,64位系统需要自己编译一个64位的版本。
以上程序在Windows XP(32bit),Windows 7 SP1(32bit),Windows Server 2008 R2(64bit) 测试通过。
上一篇: CeGCC编译的DLL在Windows Mobile6.1等系统中无法加载
下一篇: COM.0 一些COM函数的使用示例
分类:Win32/C++ 查看次数:7404 发布时间:2011/11/1 11:14:00