创造上下文菜单项
创建上下文菜单项
制造图标标记 Handlers
(续)
创制图标标记 Handlers
(续)
【澳门金沙国际】始建上下文菜单项,成立图标标记。
1、新建一个ATL Project。
1、新建一个ATL Project。
1、新建一个ATL Project。
1、新建一个ATL Project。
2、建议将Project Property中Linker – General – “Register Output”
设为no,C/C++ – “Code Generation” – “Runtime Library” 设为 /MTd。
2、建议将Project Property中Linker – General – “Register Output”
设为no,C/C++ – “Code Generation” – “Runtime Library” 设为 /MTd。
2、建议将 Project Property 中 Linker –
General – “Register Output” 设为 no,C/C++ – “Code Generation” –
“Runtime Library” 设为 /MTd。
2、建议将 Project Property 中 Linker –
General – “Register Output” 设为 no,C/C++ – “Code Generation” –
“Runtime Library” 设为 /MTd。
3、在Solution Explorer中右键Add Class,接纳ATL Simple
Object。并在弹出的对话框中为该Class命名。
3、在Solution Explorer中右键Add Class,接纳ATL Simple
Object。并在弹出的对话框中为该Class命名。
3、在 Solution Explorer 中右键 Add
Class,选用 ATL Simple Object。并在弹出的对话框中为该 Class
命名。
3、在 Solution Explorer 中右键 Add
Class,选拔 ATL Simple Object。并在弹出的对话框中为该 Class
命名。
4、添加达成后指出Build一下Project,MIDL compiler将基于 .idl文件生成IIDs
and CLSIDs。
4、添加完毕后提出Build一下Project,MIDL compiler将根据 .idl文件生成IIDs
and CLSIDs。
4、添加已毕后提议 Build 一下
Project,MIDL compiler 将依照 .idl 文件生成 IIDs and CLSIDs。
4、添加完毕后提出 Build 一下
Project,MIDL compiler 将按照 .idl 文件生成 IIDs and CLSIDs。
5、(可选)在Solution Explorer中右键Add Resource导入图标资源。
5、(可选)在Solution Explorer中右键Add Resource导入图标资源。
5、切换来新增 Class 的 .h
文件中,使其接二连三接口 IShellIconOverlayIdentifier。
5、切换来新增 Class 的 .h
文件中,使其后续接口 IShellIconOverlayIdentifier。
6、切换来新增Class的
.h文件中,使其继承接口IShellExtInit和IContextMenu。并在
.cpp文件中,参照MSDN给出完结。
6、切换来新增Class的
.h文件中,使其继承接口IShellExtInit和IContextMenu。并在
.cpp文件中,参照MSDN给出达成。
1 // MyOverlay.h : Declaration of the CMyOverlay
2
3 #pragma once
4 #include "resource.h" // main symbols
5
6
7
8 #include "Example_i.h"
9 #include <ShlObj.h>
10
11
12
13 #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
14 #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
15 #endif
16
17 using namespace ATL;
18
19
20 // CMyOverlay
21
22 class ATL_NO_VTABLE CMyOverlay :
23 public CComObjectRootEx<CComSingleThreadModel>,
24 public CComCoClass<CMyOverlay, &CLSID_MyOverlay>,
25 public IDispatchImpl<IMyOverlay, &IID_IMyOverlay, &LIBID_ExampleLib,
26 /*wMajor =*/ 1, /*wMinor =*/ 0>,
27 public IShellIconOverlayIdentifier
28 {
29 public:
30 CMyOverlay()
31 {
32 }
33
34 DECLARE_REGISTRY_RESOURCEID(IDR_MYOVERLAY)
35
36
37 BEGIN_COM_MAP(CMyOverlay)
38 COM_INTERFACE_ENTRY(IMyOverlay)
39 COM_INTERFACE_ENTRY(IDispatch)
40 COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier)
41 END_COM_MAP()
42
43
44
45 DECLARE_PROTECT_FINAL_CONSTRUCT()
46
47
48 HRESULT FinalConstruct()
49 {
50 return S_OK;
51 }
52
53 void FinalRelease()
54 {
55 }
56
57 public:
58 STDMETHOD(IsMemberOf)(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib);
59 STDMETHOD(GetOverlayInfo)(THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile,
60 int cchMax, _Out_ int * pIndex, _Out_ DWORD * pdwFlags);
61 STDMETHOD(GetPriority)(THIS_ _Out_ int * pIPriority);
62
63 };
64
65 OBJECT_ENTRY_AUTO(__uuidof(MyOverlay), CMyOverlay)
1 // MyOverlay.h : Declaration of the CMyOverlay
2
3 #pragma once
4 #include "resource.h" // main symbols
5
6
7
8 #include "Example_i.h"
9 #include <ShlObj.h>
10
11
12
13 #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
14 #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
15 #endif
16
17 using namespace ATL;
18
19
20 // CMyOverlay
21
22 class ATL_NO_VTABLE CMyOverlay :
23 public CComObjectRootEx<CComSingleThreadModel>,
24 public CComCoClass<CMyOverlay, &CLSID_MyOverlay>,
25 public IDispatchImpl<IMyOverlay, &IID_IMyOverlay, &LIBID_ExampleLib,
26 /*wMajor =*/ 1, /*wMinor =*/ 0>,
27 public IShellIconOverlayIdentifier
28 {
29 public:
30 CMyOverlay()
31 {
32 }
33
34 DECLARE_REGISTRY_RESOURCEID(IDR_MYOVERLAY)
35
36
37 BEGIN_COM_MAP(CMyOverlay)
38 COM_INTERFACE_ENTRY(IMyOverlay)
39 COM_INTERFACE_ENTRY(IDispatch)
40 COM_INTERFACE_ENTRY(IShellIconOverlayIdentifier)
41 END_COM_MAP()
42
43
44
45 DECLARE_PROTECT_FINAL_CONSTRUCT()
46
47
48 HRESULT FinalConstruct()
49 {
50 return S_OK;
51 }
52
53 void FinalRelease()
54 {
55 }
56
57 public:
58 STDMETHOD(IsMemberOf)(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib);
59 STDMETHOD(GetOverlayInfo)(THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile,
60 int cchMax, _Out_ int * pIndex, _Out_ DWORD * pdwFlags);
61 STDMETHOD(GetPriority)(THIS_ _Out_ int * pIPriority);
62
63 };
64
65 OBJECT_ENTRY_AUTO(__uuidof(MyOverlay), CMyOverlay)
MyOverlay.h
MyOverlay.h
1 // MyContextMenu.h : Declaration of the CMyContextMenu
2
3 #pragma once
4 #include "resource.h" // main symbols
5
6
7
8 #include "ContextMenuExample_i.h"
9 #include <Shlobj.h>
10
11
12
13 #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
14 #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
15 #endif
16
17 using namespace ATL;
18
19
20 // CMyContextMenu
21
22 class ATL_NO_VTABLE CMyContextMenu :
23 public CComObjectRootEx<CComSingleThreadModel>,
24 public CComCoClass<CMyContextMenu, &CLSID_MyContextMenu>,
25 public IDispatchImpl<IMyContextMenu, &IID_IMyContextMenu,
26 &LIBID_ContextMenuExampleLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
27 public IShellExtInit,
28 public IContextMenu
29 {
30 public:
31 CMyContextMenu()
32 {
33 }
34
35 DECLARE_REGISTRY_RESOURCEID(IDR_MYCONTEXTMENU)
36
37
38 BEGIN_COM_MAP(CMyContextMenu)
39 COM_INTERFACE_ENTRY(IMyContextMenu)
40 COM_INTERFACE_ENTRY(IDispatch)
41 COM_INTERFACE_ENTRY(IShellExtInit)
42 COM_INTERFACE_ENTRY(IContextMenu)
43 END_COM_MAP()
44
45
46
47 DECLARE_PROTECT_FINAL_CONSTRUCT()
48
49 HRESULT FinalConstruct();
50
51 void FinalRelease();
52
53 public:
54 // IShellExtInit Method
55 HRESULT STDMETHODCALLTYPE Initialize(
56 _In_opt_ PCIDLIST_ABSOLUTE pidlFolder,
57 _In_opt_ IDataObject *pdtobj,
58 _In_opt_ HKEY hkeyProgID);
59
60 // IContextMenu Method
61 HRESULT STDMETHODCALLTYPE QueryContextMenu(
62 _In_ HMENU hmenu,
63 _In_ UINT indexMenu,
64 _In_ UINT idCmdFirst,
65 _In_ UINT idCmdLast,
66 _In_ UINT uFlags);
67
68 HRESULT STDMETHODCALLTYPE InvokeCommand(
69 _In_ CMINVOKECOMMANDINFO *pici);
70
71 HRESULT STDMETHODCALLTYPE GetCommandString(
72 _In_ UINT_PTR idCmd,
73 _In_ UINT uType,
74 _Reserved_ UINT *pReserved,
75 _Out_writes_bytes_((uType & GCS_UNICODE) ? (cchMax * sizeof(wchar_t)) : cchMax) _When_(!(uType & (GCS_VALIDATEA | GCS_VALIDATEW)), _Null_terminated_) CHAR *pszName,
76 _In_ UINT cchMax);
77
78 private:
79 HBITMAP MenuIcon1;
80 HBITMAP MenuIcon2;
81 HBITMAP MenuIcon3;
82 HBITMAP MenuIcon4;
83
84
85 };
86
87 OBJECT_ENTRY_AUTO(__uuidof(MyContextMenu), CMyContextMenu)
1 // MyContextMenu.h : Declaration of the CMyContextMenu
2
3 #pragma once
4 #include "resource.h" // main symbols
5
6
7
8 #include "ContextMenuExample_i.h"
9 #include <Shlobj.h>
10
11
12
13 #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
14 #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
15 #endif
16
17 using namespace ATL;
18
19
20 // CMyContextMenu
21
22 class ATL_NO_VTABLE CMyContextMenu :
23 public CComObjectRootEx<CComSingleThreadModel>,
24 public CComCoClass<CMyContextMenu, &CLSID_MyContextMenu>,
25 public IDispatchImpl<IMyContextMenu, &IID_IMyContextMenu,
26 &LIBID_ContextMenuExampleLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
27 public IShellExtInit,
28 public IContextMenu
29 {
30 public:
31 CMyContextMenu()
32 {
33 }
34
35 DECLARE_REGISTRY_RESOURCEID(IDR_MYCONTEXTMENU)
36
37
38 BEGIN_COM_MAP(CMyContextMenu)
39 COM_INTERFACE_ENTRY(IMyContextMenu)
40 COM_INTERFACE_ENTRY(IDispatch)
41 COM_INTERFACE_ENTRY(IShellExtInit)
42 COM_INTERFACE_ENTRY(IContextMenu)
43 END_COM_MAP()
44
45
46
47 DECLARE_PROTECT_FINAL_CONSTRUCT()
48
49 HRESULT FinalConstruct();
50
51 void FinalRelease();
52
53 public:
54 // IShellExtInit Method
55 HRESULT STDMETHODCALLTYPE Initialize(
56 _In_opt_ PCIDLIST_ABSOLUTE pidlFolder,
57 _In_opt_ IDataObject *pdtobj,
58 _In_opt_ HKEY hkeyProgID);
59
60 // IContextMenu Method
61 HRESULT STDMETHODCALLTYPE QueryContextMenu(
62 _In_ HMENU hmenu,
63 _In_ UINT indexMenu,
64 _In_ UINT idCmdFirst,
65 _In_ UINT idCmdLast,
66 _In_ UINT uFlags);
67
68 HRESULT STDMETHODCALLTYPE InvokeCommand(
69 _In_ CMINVOKECOMMANDINFO *pici);
70
71 HRESULT STDMETHODCALLTYPE GetCommandString(
72 _In_ UINT_PTR idCmd,
73 _In_ UINT uType,
74 _Reserved_ UINT *pReserved,
75 _Out_writes_bytes_((uType & GCS_UNICODE) ? (cchMax * sizeof(wchar_t)) : cchMax) _When_(!(uType & (GCS_VALIDATEA | GCS_VALIDATEW)), _Null_terminated_) CHAR *pszName,
76 _In_ UINT cchMax);
77
78 private:
79 HBITMAP MenuIcon1;
80 HBITMAP MenuIcon2;
81 HBITMAP MenuIcon3;
82 HBITMAP MenuIcon4;
83
84
85 };
86
87 OBJECT_ENTRY_AUTO(__uuidof(MyContextMenu), CMyContextMenu)
6、根据 MSDN 实现该 Class。
6、根据 MSDN 实现该 Class。
MyContextMenu.h
MyContextMenu.h
1 // MyContextMenu.cpp : Implementation of CMyContextMenu
2
3 #include "stdafx.h"
4 #include "MyContextMenu.h"
5
6
7 // CMyContextMenu
8
9 HRESULT CMyContextMenu::FinalConstruct()
10 {
11 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance();
12 MenuIcon1 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
13 MenuIcon2 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP2));
14 MenuIcon3 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP3));
15 MenuIcon4 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP4));
16
17 return S_OK;
18 }
19
20 void CMyContextMenu::FinalRelease()
21 {
22 if (MenuIcon1 != NULL)
23 {
24 DeleteObject(MenuIcon1);
25 }
26 if (MenuIcon2 != NULL)
27 {
28 DeleteObject(MenuIcon2);
29 }
30 if (MenuIcon3 != NULL)
31 {
32 DeleteObject(MenuIcon3);
33 }
34 if (MenuIcon4 != NULL)
35 {
36 DeleteObject(MenuIcon4);
37 }
38 }
39
40 HRESULT CMyContextMenu::Initialize(
41 _In_opt_ PCIDLIST_ABSOLUTE pidlFolder,
42 _In_opt_ IDataObject *pdtobj,
43 _In_opt_ HKEY hkeyProgID) {
44 HRESULT hr;
45 UINT nFileCount;
46
47 FORMATETC fmt =
48 {
49 CF_HDROP,
50 NULL,
51 DVASPECT_CONTENT,
52 -1,
53 TYMED_HGLOBAL
54 };
55
56 STGMEDIUM sm =
57 {
58 TYMED_HGLOBAL
59 };
60
61 hr = pdtobj->GetData(&fmt, &sm);
62
63 if (FAILED(hr))
64 {
65 return hr;
66 }
67
68 // query quantity of selected files
69 nFileCount = DragQueryFile((HDROP)sm.hGlobal, 0xFFFFFFFF, NULL, 0);
70
71 if (nFileCount == 1) // deal with only one file
72 {
73 // analyze selected file
74
75 }
76 else
77 {
78 hr = E_INVALIDARG;
79 }
80
81 ReleaseStgMedium(&sm);
82
83 return hr;
84 }
85
86 // IContextMenu Method
87 HRESULT CMyContextMenu::QueryContextMenu(
88 _In_ HMENU hmenu,
89 _In_ UINT indexMenu,
90 _In_ UINT idCmdFirst,
91 _In_ UINT idCmdLast,
92 _In_ UINT uFlags) {
93
94 UINT uCmdID = idCmdFirst;
95 LPCWSTR text1 = TEXT("新增层叠菜单项1");
96 LPCWSTR text2 = TEXT("新增菜单项2");
97 LPCWSTR text3 = TEXT("新增菜单项3");
98 LPCWSTR text4 = TEXT("新增菜单项4");
99 // do nothing when flag includes CMF_DEFAULTONLY.
100 if (uFlags & CMF_DEFAULTONLY)
101 {
102 return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
103 }
104 InsertMenu(hmenu, indexMenu, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
105 indexMenu++;
106 HMENU hSubMenu = CreateMenu();
107 if (hSubMenu)
108 {
109 InsertMenu(hSubMenu, 0, MF_STRING | MF_BYPOSITION, uCmdID++, text2);
110 SetMenuItemBitmaps(hSubMenu, 0, MF_BYPOSITION, MenuIcon2, MenuIcon2);
111 InsertMenu(hSubMenu, 1, MF_STRING | MF_BYPOSITION, uCmdID++, text3);
112 SetMenuItemBitmaps(hSubMenu, 1, MF_BYPOSITION, MenuIcon3, MenuIcon3);
113 InsertMenu(hSubMenu, 2, MF_STRING | MF_BYPOSITION, uCmdID++, text4);
114 SetMenuItemBitmaps(hSubMenu, 2, MF_BYPOSITION, MenuIcon4, MenuIcon4);
115 // InsertMenu(hSubMenu, 3, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);//插入分隔线
116 }
117 InsertMenu(hmenu, indexMenu, MF_STRING | MF_POPUP | MF_BYPOSITION, (UINT_PTR)hSubMenu, text1);
118 SetMenuItemBitmaps(hmenu, indexMenu, MF_BYPOSITION, MenuIcon1, MenuIcon1);
119 indexMenu++;
120 InsertMenu(hmenu, indexMenu, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
121 indexMenu++;
122
123 // inform the explorer how many menu item we have added
124 return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, uCmdID - idCmdFirst);
125 }
126
127 HRESULT CMyContextMenu::InvokeCommand(
128 _In_ CMINVOKECOMMANDINFO *pici) {
129 if (0 != HIWORD(pici->lpVerb))
130 return E_INVALIDARG;
131 // get index of added menu item
132 switch (LOWORD(pici->lpVerb))
133 {
134 case 0:
135 {
136 // 执行新增菜单项2触发的操作
137 STARTUPINFO si = { sizeof(si) };
138 PROCESS_INFORMATION pi;
139 TCHAR szCommandLine[] = TEXT("notepad");
140 BOOL bCreateRet = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
141
142 break;
143 }
144 case 1:
145 {
146 // 执行新增菜单项3触发的操作
147 STARTUPINFO si = { sizeof(si) };
148 PROCESS_INFORMATION pi;
149 TCHAR szCommandLine[] = TEXT("write");
150 BOOL bCreateRet = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
151
152 break;
153 }
154 case 2:
155 {
156 // 执行新增菜单项4触发的操作
157 STARTUPINFO si = { sizeof(si) };
158 PROCESS_INFORMATION pi;
159 TCHAR szCommandLine[] = TEXT("cmd");
160 BOOL bCreateRet = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
161
162 break;
163 }
164 default:
165 {
166 return E_INVALIDARG;
167 break;
168 }
169 }
170 return S_OK;
171 }
172
173 HRESULT CMyContextMenu::GetCommandString(
174 _In_ UINT_PTR idCmd,
175 _In_ UINT uType,
176 _Reserved_ UINT *pReserved,
177 _Out_writes_bytes_((uType & GCS_UNICODE) ? (cchMax * sizeof(wchar_t)) : cchMax) _When_(!(uType & (GCS_VALIDATEA | GCS_VALIDATEW)), _Null_terminated_) CHAR *pszName,
178 _In_ UINT cchMax) {
179 USES_CONVERSION;
180 LPCTSTR szPrompt;
181 // copy help info to cache when explorer ask
182 if (uType & GCS_HELPTEXT)
183 {
184 switch (idCmd)
185 {
186 case 0:
187 szPrompt = _T("新增菜单项2说明文字");
188 break;
189 case 1:
190 szPrompt = _T("新增菜单项3说明文字");
191 break;
192 case 2:
193 szPrompt = _T("新增菜单项4说明文字");
194 break;
195 default:
196 //ATLASSERT(0); // should never get here
197 return E_INVALIDARG;
198 break;
199 }
200 if (uType & GCS_UNICODE)
201 {
202 lstrcpynW((LPWSTR)pszName, T2CW(szPrompt), cchMax);
203 }
204 else
205 {
206 lstrcpynA(pszName, T2CA(szPrompt), cchMax);
207 }
208 return S_OK;
209 }
210 return E_INVALIDARG;
211 }
1 // MyContextMenu.cpp : Implementation of CMyContextMenu
2
3 #include "stdafx.h"
4 #include "MyContextMenu.h"
5
6
7 // CMyContextMenu
8
9 HRESULT CMyContextMenu::FinalConstruct()
10 {
11 HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance();
12 MenuIcon1 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
13 MenuIcon2 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP2));
14 MenuIcon3 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP3));
15 MenuIcon4 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP4));
16
17 return S_OK;
18 }
19
20 void CMyContextMenu::FinalRelease()
21 {
22 if (MenuIcon1 != NULL)
23 {
24 DeleteObject(MenuIcon1);
25 }
26 if (MenuIcon2 != NULL)
27 {
28 DeleteObject(MenuIcon2);
29 }
30 if (MenuIcon3 != NULL)
31 {
32 DeleteObject(MenuIcon3);
33 }
34 if (MenuIcon4 != NULL)
35 {
36 DeleteObject(MenuIcon4);
37 }
38 }
39
40 HRESULT CMyContextMenu::Initialize(
41 _In_opt_ PCIDLIST_ABSOLUTE pidlFolder,
42 _In_opt_ IDataObject *pdtobj,
43 _In_opt_ HKEY hkeyProgID) {
44 HRESULT hr;
45 UINT nFileCount;
46
47 FORMATETC fmt =
48 {
49 CF_HDROP,
50 NULL,
51 DVASPECT_CONTENT,
52 -1,
53 TYMED_HGLOBAL
54 };
55
56 STGMEDIUM sm =
57 {
58 TYMED_HGLOBAL
59 };
60
61 hr = pdtobj->GetData(&fmt, &sm);
62
63 if (FAILED(hr))
64 {
65 return hr;
66 }
67
68 // query quantity of selected files
69 nFileCount = DragQueryFile((HDROP)sm.hGlobal, 0xFFFFFFFF, NULL, 0);
70
71 if (nFileCount == 1) // deal with only one file
72 {
73 // analyze selected file
74
75 }
76 else
77 {
78 hr = E_INVALIDARG;
79 }
80
81 ReleaseStgMedium(&sm);
82
83 return hr;
84 }
85
86 // IContextMenu Method
87 HRESULT CMyContextMenu::QueryContextMenu(
88 _In_ HMENU hmenu,
89 _In_ UINT indexMenu,
90 _In_ UINT idCmdFirst,
91 _In_ UINT idCmdLast,
92 _In_ UINT uFlags) {
93
94 UINT uCmdID = idCmdFirst;
95 LPCWSTR text1 = TEXT("新增层叠菜单项1");
96 LPCWSTR text2 = TEXT("新增菜单项2");
97 LPCWSTR text3 = TEXT("新增菜单项3");
98 LPCWSTR text4 = TEXT("新增菜单项4");
99 // do nothing when flag includes CMF_DEFAULTONLY.
100 if (uFlags & CMF_DEFAULTONLY)
101 {
102 return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
103 }
104 InsertMenu(hmenu, indexMenu, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
105 indexMenu++;
106 HMENU hSubMenu = CreateMenu();
107 if (hSubMenu)
108 {
109 InsertMenu(hSubMenu, 0, MF_STRING | MF_BYPOSITION, uCmdID++, text2);
110 SetMenuItemBitmaps(hSubMenu, 0, MF_BYPOSITION, MenuIcon2, MenuIcon2);
111 InsertMenu(hSubMenu, 1, MF_STRING | MF_BYPOSITION, uCmdID++, text3);
112 SetMenuItemBitmaps(hSubMenu, 1, MF_BYPOSITION, MenuIcon3, MenuIcon3);
113 InsertMenu(hSubMenu, 2, MF_STRING | MF_BYPOSITION, uCmdID++, text4);
114 SetMenuItemBitmaps(hSubMenu, 2, MF_BYPOSITION, MenuIcon4, MenuIcon4);
115 // InsertMenu(hSubMenu, 3, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);//插入分隔线
116 }
117 InsertMenu(hmenu, indexMenu, MF_STRING | MF_POPUP | MF_BYPOSITION, (UINT_PTR)hSubMenu, text1);
118 SetMenuItemBitmaps(hmenu, indexMenu, MF_BYPOSITION, MenuIcon1, MenuIcon1);
119 indexMenu++;
120 InsertMenu(hmenu, indexMenu, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
121 indexMenu++;
122
123 // inform the explorer how many menu item we have added
124 return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, uCmdID - idCmdFirst);
125 }
126
127 HRESULT CMyContextMenu::InvokeCommand(
128 _In_ CMINVOKECOMMANDINFO *pici) {
129 if (0 != HIWORD(pici->lpVerb))
130 return E_INVALIDARG;
131 // get index of added menu item
132 switch (LOWORD(pici->lpVerb))
133 {
134 case 0:
135 {
136 // 执行新增菜单项2触发的操作
137 STARTUPINFO si = { sizeof(si) };
138 PROCESS_INFORMATION pi;
139 TCHAR szCommandLine[] = TEXT("notepad");
140 BOOL bCreateRet = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
141
142 break;
143 }
144 case 1:
145 {
146 // 执行新增菜单项3触发的操作
147 STARTUPINFO si = { sizeof(si) };
148 PROCESS_INFORMATION pi;
149 TCHAR szCommandLine[] = TEXT("write");
150 BOOL bCreateRet = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
151
152 break;
153 }
154 case 2:
155 {
156 // 执行新增菜单项4触发的操作
157 STARTUPINFO si = { sizeof(si) };
158 PROCESS_INFORMATION pi;
159 TCHAR szCommandLine[] = TEXT("cmd");
160 BOOL bCreateRet = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
161
162 break;
163 }
164 default:
165 {
166 return E_INVALIDARG;
167 break;
168 }
169 }
170 return S_OK;
171 }
172
173 HRESULT CMyContextMenu::GetCommandString(
174 _In_ UINT_PTR idCmd,
175 _In_ UINT uType,
176 _Reserved_ UINT *pReserved,
177 _Out_writes_bytes_((uType & GCS_UNICODE) ? (cchMax * sizeof(wchar_t)) : cchMax) _When_(!(uType & (GCS_VALIDATEA | GCS_VALIDATEW)), _Null_terminated_) CHAR *pszName,
178 _In_ UINT cchMax) {
179 USES_CONVERSION;
180 LPCTSTR szPrompt;
181 // copy help info to cache when explorer ask
182 if (uType & GCS_HELPTEXT)
183 {
184 switch (idCmd)
185 {
186 case 0:
187 szPrompt = _T("新增菜单项2说明文字");
188 break;
189 case 1:
190 szPrompt = _T("新增菜单项3说明文字");
191 break;
192 case 2:
193 szPrompt = _T("新增菜单项4说明文字");
194 break;
195 default:
196 //ATLASSERT(0); // should never get here
197 return E_INVALIDARG;
198 break;
199 }
200 if (uType & GCS_UNICODE)
201 {
202 lstrcpynW((LPWSTR)pszName, T2CW(szPrompt), cchMax);
203 }
204 else
205 {
206 lstrcpynA(pszName, T2CA(szPrompt), cchMax);
207 }
208 return S_OK;
209 }
210 return E_INVALIDARG;
211 }
7、在 .rgs文件中添加注册表音信,确保各GUID与 .idl文件中的一致。
7、在 .rgs文件中添加注册表新闻,确保各GUID与 .idl文件中的一致。
1 HKCR
2 {
3 NoRemove CLSID
4 {
5 ForceRemove {9C50C98F-E1FF-41CF-BD54-E9A3BBDDDEF8} = s 'MyContextMenu Class'
6 {
7 ForceRemove Programmable
8 InprocServer32 = s '%MODULE%'
9 {
10 val ThreadingModel = s 'Apartment'
11 }
12 TypeLib = s '{EB1C2F43-315D-4D8F-9A2A-70E67BE888E2}'
13 Version = s '1.0'
14 }
15 }
16
17 NoRemove *
18 {
19 NoRemove ShellEx
20 {
21 NoRemove ContextMenuHandlers
22 {
23 ForceRemove MyContextMenu = s '{9C50C98F-E1FF-41CF-BD54-E9A3BBDDDEF8}'
24 }
25 }
26 }
27 }
1 HKCR
2 {
3 NoRemove CLSID
4 {
5 ForceRemove {9C50C98F-E1FF-41CF-BD54-E9A3BBDDDEF8} = s 'MyContextMenu Class'
6 {
7 ForceRemove Programmable
8 InprocServer32 = s '%MODULE%'
9 {
10 val ThreadingModel = s 'Apartment'
11 }
12 TypeLib = s '{EB1C2F43-315D-4D8F-9A2A-70E67BE888E2}'
13 Version = s '1.0'
14 }
15 }
16
17 NoRemove *
18 {
19 NoRemove ShellEx
20 {
21 NoRemove ContextMenuHandlers
22 {
23 ForceRemove MyContextMenu = s '{9C50C98F-E1FF-41CF-BD54-E9A3BBDDDEF8}'
24 }
25 }
26 }
27 }
8、Build Project 后打开cmd.exe,通过regsvr32发令注册或解注册生成的
.dll文件。
8、Build Project 后打开cmd.exe,通过regsvr32指令注册或解注册生成的
.dll文件。
1 // MyOverlay.cpp : Implementation of CMyOverlay
2
3 #include "stdafx.h"
4 #include "MyOverlay.h"
5 #include <WinBase.h>
6 #pragma comment(lib, "Kernel32.lib")
7
8 // CMyOverlay
9
10 STDMETHODIMP CMyOverlay::IsMemberOf(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib)
11 {
12 if (_tcscmp(pwszPath, L"test") == 0)
13 {
14 return S_OK;
15 }
16 else
17 {
18 return S_FALSE;
19 }
20 }
21
22 STDMETHODIMP CMyOverlay::GetOverlayInfo(
23 THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile,
24 int cchMax,
25 _Out_ int * pIndex,
26 _Out_ DWORD * pdwFlags)
27 {
28
29 GetModuleFileNameW(_AtlBaseModule.GetModuleInstance(), pwszIconFile, cchMax);
30
31 *pIndex = 0;
32
33 *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
34
35 return S_OK;
36 }
37
38 STDMETHODIMP CMyOverlay::GetPriority(THIS_ _Out_ int * pIPriority)
39 {
40 *pIPriority = 0;
41
42 return S_OK;
43 }
1 // MyOverlay.cpp : Implementation of CMyOverlay
2
3 #include "stdafx.h"
4 #include "MyOverlay.h"
5 #include <WinBase.h>
6 #pragma comment(lib, "Kernel32.lib")
7
8 // CMyOverlay
9
10 STDMETHODIMP CMyOverlay::IsMemberOf(THIS_ _In_ PCWSTR pwszPath, DWORD dwAttrib)
11 {
12 if (_tcscmp(pwszPath, L"test") == 0)
13 {
14 return S_OK;
15 }
16 else
17 {
18 return S_FALSE;
19 }
20 }
21
22 STDMETHODIMP CMyOverlay::GetOverlayInfo(
23 THIS_ _Out_writes_(cchMax) PWSTR pwszIconFile,
24 int cchMax,
25 _Out_ int * pIndex,
26 _Out_ DWORD * pdwFlags)
27 {
28
29 GetModuleFileNameW(_AtlBaseModule.GetModuleInstance(), pwszIconFile, cchMax);
30
31 *pIndex = 0;
32
33 *pdwFlags = ISIOI_ICONFILE | ISIOI_ICONINDEX;
34
35 return S_OK;
36 }
37
38 STDMETHODIMP CMyOverlay::GetPriority(THIS_ _Out_ int * pIPriority)
39 {
40 *pIPriority = 0;
41
42 return S_OK;
43 }
澳门金沙国际,10、查看效果如下图所示。
10、查看效果如下图所示。
MyOverlay.cpp
MyOverlay.cpp
7、在 .rgs 文件中添加注册表新闻,确保各
GUID 与 .idl 文件中的一致。
7、在 .rgs 文件中添加注册表音信,确保各
GUID 与 .idl 文件中的一致。
1 HKCR
2 {
3 NoRemove CLSID
4 {
5 ForceRemove {29913677-1662-46C5-8645-16F84DA6F438} = s 'MyOverlay Class'
6 {
7 ForceRemove Programmable
8 InprocServer32 = s '%MODULE%'
9 {
10 val ThreadingModel = s 'Apartment'
11 }
12 TypeLib = s '{942F4DBB-4667-4767-A35B-52F32F623C63}'
13 Version = s '1.0'
14 }
15 }
16 }
17
18 HKLM
19 {
20 NoRemove SOFTWARE
21 {
22 NoRemove Microsoft
23 {
24 NoRemove Windows
25 {
26 NoRemove CurrentVersion
27 {
28 NoRemove Explorer
29 {
30 NoRemove ShellIconOverlayIdentifiers
31 {
32 ForceRemove ' MyOverlay' = s '{29913677-1662-46C5-8645-16F84DA6F438}'
33 {
34 }
35 }
36 }
37 }
38 }
39 }
40 }
41 }
1 HKCR
2 {
3 NoRemove CLSID
4 {
5 ForceRemove {29913677-1662-46C5-8645-16F84DA6F438} = s 'MyOverlay Class'
6 {
7 ForceRemove Programmable
8 InprocServer32 = s '%MODULE%'
9 {
10 val ThreadingModel = s 'Apartment'
11 }
12 TypeLib = s '{942F4DBB-4667-4767-A35B-52F32F623C63}'
13 Version = s '1.0'
14 }
15 }
16 }
17
18 HKLM
19 {
20 NoRemove SOFTWARE
21 {
22 NoRemove Microsoft
23 {
24 NoRemove Windows
25 {
26 NoRemove CurrentVersion
27 {
28 NoRemove Explorer
29 {
30 NoRemove ShellIconOverlayIdentifiers
31 {
32 ForceRemove ' MyOverlay' = s '{29913677-1662-46C5-8645-16F84DA6F438}'
33 {
34 }
35 }
36 }
37 }
38 }
39 }
40 }
41 }
——————————————————
——————————————————
8、Build Project 后透过 cmd.exe
注册或解注册生成的 .dll 文件。重启 explorer.exe 后生效。
8、Build Project 后通过 cmd.exe
注册或解注册生成的 .dll 文件。重启 explorer.exe 后生效。
正文为本人原创,如需转载请表明出处。
本文为自身原创,如需转发请注脚出处。
9、由于 slots
数量有限,检查在注册表中丰裕的子项是或不是在有效限制内(方今为前15个)。按下Win+R键,通过运行对话框打开regedit.exe,按HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers的顺序依次展开或直接Ctrl+F查找到MyOverlay项。可利用在.rgs文件中的子项名称前添加空格的点子将其地点提前。
9、由于 slots
数量有限,检查在注册表中丰盛的子项是还是不是在使得限制内(近来为前15个)。按下Win+R键,通过运行对话框打开regedit.exe,按HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers的依次依次展开或直接Ctrl+F查找到MyOverlay项。可利用在.rgs文件中的子项名称前添加空格的章程将其地点提前。
10、查看效果如下图所示。
10、查看效果如下图所示。
参考网址:
参考网址:
—————————————————————————————————————
—————————————————————————————————————
本文为自家原创,如需转载请表明出处。
正文为自我原创,如需转发请注脚出处。