3、VS2005(c/c++)外壳扩展编程之windows右键菜单(3)

简介: 第三部分 SHELL Additional  一、编程中的一些关键点  1、 We implemented the IShellExtInit interface, which was how Explorer initialized our object.

第三部分 SHELL Additional 

一、编程中的一些关键点 

1We implemented the IShellExtInit interface, which was how Explorer initialized our object. There is another initialization interface used for some shell extensions, IPersistFile, and this is the one an infotip extension uses. IShellExtInit::Initialize() receives an IDataObject pointer with which it can enumerate all of the files that were selected. Extensions that can only ever operate on a single file use IPersistFile. Since the mouse can't hover over more than one object at a time, an infotip extension only works on one file at a time, so it uses IPersistFile. 

2AFX_MANAGE_STATE(AfxGetStaticModuleState()); // init MFC

The AFX_MANAGE_STATE macro is necessary for MFC to work properly. Because our DLL is being loaded by a non-MFC app, every exported function that uses MFC must initialize MFC manually. If you don't include that line, many MFC functions (mostly the ones related to resources) will break or have assertion failures.

3In order to have a dialog which has the XP theme enabled, it was necessary to set the following values in stdafx.h before any of the #includes:

#define VC_EXTRALEAN //necessary

#ifndef _WIN32_WINNT

#define _WIN32_WINNT 0x501

#endif

#define _ATL_APARTMENT_THREADED

#define ISOLATION_AWARE_ENABLED 1 //XP style awareness

4A shell extension is a COM DLL

5Note that DllRegisterServer() and DllUnregisterServer() are not called by Explorer, but by the installer. If you downloaded the source files instead of the installer, you will have to register the DLL yourself using the command line tool regsvr32. If you compile the source from within Visual C++, then regsvr32 runs as part as the build process.

6、整体而言,使用SHELL时流程基本如下:

In short, this is what happens: When the user right-clicks inside an Explorer window, Explorer calls CtxMenu's Initialize() function. At this point, the context menu isn't visible yet. Explorer then calls the QueryContextMenu() function to add the Select... item to the menu, and shows it. When the user moves over this menu item, Explorer obtains a description from GetCommandString(). Finally, when the user picks the Select... item, Explorer calls InvokeCommand().

The only place where we can figure out whether the user clicked on a file or on the background of the window is in Initialize().

http://www.codeproject.com/KB/shell/wildcardselect.aspx

http://www.allyoursoftware.com/

第四部分 相关的API

1GlobalLock Function

Locks a global memory object and returns a pointer to the first byte of the object's memory block.

2DragQueryFile Function

Retrieves the names of dropped files that result from a successful drag-and-drop operation.

http://msdn.microsoft.com/en-us/library/bb776408%28VS.85%29.aspx

3GetProcAddress Function

Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).

http://msdn.microsoft.com/en-us/library/ms683212%28VS.85%29.aspx

4InsertMenu Function

Inserts a new menu item into a menu, moving other items down the menu.

Note The InsertMenu function has been superseded by the InsertMenuItem function. You can still use InsertMenu, however, if you do not need any of the extended features of InsertMenuItem.

http://msdn.microsoft.com/en-us/library/ms647987%28VS.85%29.aspx

5SetMenuItemBitmaps Function

Associates the specified bitmap with a menu item. Whether the menu item is selected or clear, the system displays the appropriate bitmap next to the menu item.

http://msdn.microsoft.com/en-us/library/ms647998%28VS.85%29.aspx

6GetCurrentDirectory Function

Retrieves the current directory for the current process.

SetCurrentDirectory

7lstrcpyn Function

Copies a specified number of characters from a source string into a buffer.

Warning Do not use. Consider using StringCchCopy instead. See Remarks.

8CStdioFile::ReadString

Reads text data into a buffer, up to a limit of nMax1 characters, from the file associated with the CStdioFile object.

Reading is stopped by the first newline character. If, in that case, fewer than nMax1 characters have been read, a newline character is stored in the buffer. A null character ('\0') is appended in either case.

http://msdn.microsoft.com/en-us/library/x5t0zfyf%28VS.80%29.aspx

9FindFirstFile Function

Searches a directory for a file or subdirectory with a name that matches a specific name (or partial name if wildcards are used).

To specify additional attributes to use in a search, use the FindFirstFileEx function.

To perform this operation as a transacted operation, use the FindFirstFileTransacted function.

http://msdn.microsoft.com/en-us/library/aa364418%28VS.85%29.aspx

10SHGetPathFromIDList Function

Converts an item identifier list to a file system path.

http://msdn.microsoft.com/en-us/library/bb762194%28VS.85%29.aspx

11GetTopWindow Function

Examines the Z order of the child windows associated with the specified parent window and retrieves a handle to the child window at the top of the Z order.

http://msdn.microsoft.com/en-us/library/ms633514%28VS.85%29.aspx

12HIWORD Macro

Retrieves the high-order word from the specified 32-bit value.

http://msdn.microsoft.com/en-us/library/ms632657%28VS.85%29.aspx

13SHGetMalloc

Retrieves a pointer to the shell's IMalloc interface

12FindNextFile

Continues a file search from a previous call to the FindFirstFile or FindFirstFileEx function.

http://msdn.microsoft.com/en-us/library/aa364428%28VS.85%29.aspx

 

代码
 
  
1 void CShellExtentionToVirC::RecursiveObtainDirFiles(WCHAR * lpPath)
2 {
3 WCHAR szFind[MAX_PATH];
4 WCHAR szFile[MAX_PATH];
5 WIN32_FIND_DATA FindFileData;
6
7 wcscpy(szFind, lpPath);
8 wcscat(szFind, TEXT( " \\*.* " ));
9
10 HANDLE hFind = ::FindFirstFile((LPCWSTR)szFind, & FindFileData);
11   if (INVALID_HANDLE_VALUE == hFind)
12 return ;
13
14 while (TRUE)
15 {
16 if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
17 {
18 if (FindFileData.cFileName[ 0 ] != L ' . ' )
19 {
20 wcscpy(szFile, lpPath);
21 wcscat(szFile, TEXT( " \\ " ));
22 wcscat(szFile, FindFileData.cFileName);
23 RecursiveObtainDirFiles(szFile);
24 }
25 }
26 else
27 {
28 std::wcout << FindFileData.cFileName << std::endl;
29 }
30 if ( ! FindNextFile(hFind, & FindFileData))
31 break ;
32 }
33 FindClose(hFind);
34 }
35
36
37 HRESULT CShellExtentionToVirC::InvokeCommand(LPCMINVOKECOMMANDINFO pInfo)
38 {
39 // If lpVerb really points to a string, ignore this function call and bail out.
40 if ( 0 != HIWORD( pInfo -> lpVerb ))
41 return E_INVALIDARG;
42
43 // Check that lpVerb is one of our commands (0 or 1)
44
45 switch ( LOWORD( pInfo -> lpVerb ))
46 {
47 case 0 :
48 case 1 :
49 {
50 TCHAR szMsg[MAX_PATH + 32 ];
51 wsprintf( szMsg, _T( " Only a test " ));
52 MessageBox( pInfo -> hwnd, szMsg, _T( " VirCS " ),MB_ICONINFORMATION );
53
54 strCurrentDirectory = L " C:\\Intel\\Logs " ;
55 RecursiveObtainDirFiles(const_cast < WCHAR *> (strCurrentDirectory.data()));
56 return S_OK;
57 }
58 break ;
59
60 default :
61 return E_INVALIDARG;
62 break ;
63 }
64 }

参考

[1] http://www.codeproject.com/KB/shell/shellextguideindex.aspx

关 于Shell Extension,CodeProject讲解了更多,如drag and drop handler(用右键拖拽时显示的菜单)property sheet handler(在属性页中显示的菜单),icon handler(不同类型文件图标不同)等。

[2] 相关文档下载地址

http://download.csdn.net/source/2878021

[3] http://www.codeproject.com/KB/shell/wildcardselect.aspx

[4] http://msdn.microsoft.com/en-us/library/bb776426%28VS.85%29.aspx

[5] http://blog.csdn.net/luckyboy101/archive/2009/11/25/4866408.aspx

[6] http://www.programbbs.com/

[7] http://www.cnblogs.com/MaxWoods/archive/2010/06/23/1764036.html

[8] http://www.cnblogs.com/MaxWoods/archive/2010/06/23/1764034.html

[9] http://www.cnblogs.com/lemony/archive/2007/04/16/715833.html

[10] http://www.cnblogs.com/lemony/archive/2007/04/16/715833.html

[11] Dino Esposito's great book Visual C++ Windows Shell Programming (ISBN 1861001843)

目录
相关文章
|
17天前
|
C++
C++ 语言异常处理实战:在编程潮流中坚守稳定,开启代码可靠之旅
【8月更文挑战第22天】C++的异常处理机制是确保程序稳定的关键特性。它允许程序在遇到错误时优雅地响应而非直接崩溃。通过`throw`抛出异常,并用`catch`捕获处理,可使程序控制流跳转至错误处理代码。例如,在进行除法运算或文件读取时,若发生除数为零或文件无法打开等错误,则可通过抛出异常并在调用处捕获来妥善处理这些情况。恰当使用异常处理能显著提升程序的健壮性和维护性。
34 2
|
17天前
|
算法 C语言 C++
C++语言学习指南:从新手到高手,一文带你领略系统编程的巅峰技艺!
【8月更文挑战第22天】C++由Bjarne Stroustrup于1985年创立,凭借卓越性能与灵活性,在系统编程、游戏开发等领域占据重要地位。它继承了C语言的高效性,并引入面向对象编程,使代码更模块化易管理。C++支持基本语法如变量声明与控制结构;通过`iostream`库实现输入输出;利用类与对象实现面向对象编程;提供模板增强代码复用性;具备异常处理机制确保程序健壮性;C++11引入现代化特性简化编程;标准模板库(STL)支持高效编程;多线程支持利用多核优势。虽然学习曲线陡峭,但掌握后可开启高性能编程大门。随着新标准如C++20的发展,C++持续演进,提供更多开发可能性。
40 0
|
3月前
|
编译器 C++ 开发者
C++一分钟之-C++20新特性:模块化编程
【6月更文挑战第27天】C++20引入模块化编程,缓解`#include`带来的编译时间长和头文件管理难题。模块由接口(`.cppm`)和实现(`.cpp`)组成,使用`import`导入。常见问题包括兼容性、设计不当、暴露私有细节和编译器支持。避免这些问题需分阶段迁移、合理设计、明确接口和关注编译器更新。示例展示了模块定义和使用,提升代码组织和维护性。随着编译器支持加强,模块化将成为C++标准的关键特性。
127 3
|
3天前
|
存储 设计模式 编译器
C++(十三) 类的扩展
本文详细介绍了C++中类的各种扩展特性,包括类成员存储、`sizeof`操作符的应用、类成员函数的存储方式及其背后的`this`指针机制。此外,还探讨了`const`修饰符在成员变量和函数中的作用,以及如何通过`static`关键字实现类中的资源共享。文章还介绍了单例模式的设计思路,并讨论了指向类成员(数据成员和函数成员)的指针的使用方法。最后,还讲解了指向静态成员的指针的相关概念和应用示例。通过这些内容,帮助读者更好地理解和掌握C++面向对象编程的核心概念和技术细节。
|
8天前
|
Rust 安全 C++
系统编程的未来之战:Rust能否撼动C++的王座?
【8月更文挑战第31天】Rust与C++:现代系统编程的新选择。C++长期主导系统编程,但内存安全问题频发。Rust以安全性为核心,通过所有权和生命周期概念避免内存泄漏和野指针等问题。Rust在编译时确保内存安全,简化并发编程,其生态系统虽不及C++成熟,但发展迅速,为现代系统编程提供了新选择。未来有望看到更多Rust驱动的系统级应用。
25 1
|
7天前
|
图形学 C++ C#
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
18 0
|
7天前
|
数据库 Windows
超详细步骤解析:从零开始,手把手教你使用 Visual Studio 打造你的第一个 Windows Forms 应用程序,菜鸟也能轻松上手的编程入门指南来了!
【8月更文挑战第31天】创建你的第一个Windows Forms (WinForms) 应用程序是一个激动人心的过程,尤其适合编程新手。本指南将带你逐步完成一个简单WinForms 应用的开发。首先,在Visual Studio 中创建一个“Windows Forms App (.NET)”项目,命名为“我的第一个WinForms 应用”。接着,在空白窗体中添加一个按钮和一个标签控件,并设置按钮文本为“点击我”。然后,为按钮添加点击事件处理程序`button1_Click`,实现点击按钮后更新标签文本为“你好,你刚刚点击了按钮!”。
22 0
|
1月前
|
编译器 开发工具 C语言
解锁QtCreator跨界神技!Windows下轻松驾驭OpenCV动态库,让你的跨平台开发如虎添翼,秒变视觉编程大师!
【8月更文挑战第4天】QtCreator是一款强大的跨平台IDE,便于创建多平台应用。本教程教你如何在Windows环境下集成OpenCV库至Qt项目。首先,下载匹配MinGW的OpenCV预编译版并解压。接着,在QtCreator中新建或打开项目,并在.pro文件中添加OpenCV的头文件和库文件路径。确保编译器设置正确。随后编写测试代码,例如加载和显示图片,并进行编译运行。完成这些步骤后,你就能在QtCreator中利用OpenCV进行图像处理开发了。
77 6
|
2月前
|
人工智能 JavaScript 开发工具
C++中的AI编程助手添加
今天为大家推荐一款适配了 Viusal Studio(本文使用),VS Code(本文使用),JetBrains系列以及Vim等多种编译器环境的插件 Fitten Code,Fitten Code 是由非十大模型驱动的 AI 编程助手,它可以自动生成代码,提升开发效率,帮您调试 Bug,节省您的时间,另外还可以对话聊天,解决您编程碰到的问题。 Fitten Code免费且支持 80 多种语言:Python、C++、Javascript、Typescript、Java等。
73 8
|
17天前
|
存储 编译器 C++
打破C++的神秘面纱:一步步带你走进面向未来的编程世界!
【8月更文挑战第22天】C++是一门功能强大但学习曲线陡峭的语言,提供高性能与底层控制。本文通过实例介绍C++基础语法,包括程序结构、数据类型、控制结构和函数。从简单的“Hello, C++!”程序开始,逐步探索变量声明、数据类型、循环与条件判断,以及函数定义与调用。这些核心概念为理解和编写C++程序打下坚实基础,引导你进入C++编程的世界。
30 0
下一篇
DDNS