快捷搜索:

您的位置:澳门新葡4473网站 > 项目 > Creating Context Menu / 创建上下文菜单项 / VC++, Wind

Creating Context Menu / 创建上下文菜单项 / VC++, Wind

发布时间:2019-11-03 05:41编辑:项目浏览(174)

    创建上下文菜单项 

     

    1、新建一个ATL Project。

    图片 1

    2、建议将Project Property中Linker – General - “Register Output” 设为no,C/C++ - “Code Generation” - “Runtime Library” 设为 /MTd。

     图片 2

    图片 3

    3、在Solution Explorer中右键Add Class,选择ATL Simple Object。并在弹出的对话框中为该Class命名。

     图片 4

    图片 5

    4、添加完成后建议Build一下Project,MIDL compiler将根据 .idl文件生成IIDs and CLSIDs。

     图片 6

    5、(可选)在Solution Explorer中右键Add Resource导入图标资源。

     图片 7

    6、切换到新增Class的 .h文件中,使其继承接口IShellExtInit和IContextMenu。并在 .cpp文件中,参照MSDN给出实现。

     图片 8

    图片 9

    图片 10

    图片 11

    图片 12图片 13

     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)
    

    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 }
    

    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 }
    

    8、Build Project 后打开cmd.exe,通过regsvr32命令注册或解注册生成的 .dll文件。

     图片 14

    10、查看效果如下图所示。

     图片 15

     

    ——————————————————

    本文为本人原创,如需转载请注明出处。

    本文由澳门新葡4473网站发布于项目,转载请注明出处:Creating Context Menu / 创建上下文菜单项 / VC++, Wind

    关键词:

上一篇:笔记本(华硕UL80VT)软件超频setFSB

下一篇:没有了