Explorer文件菜单添加

这是一个用来添加Explorer文件右键菜单的小工具,支持插件,这样就能减少在COM上打转的时间,将时间真正放到功能的实现上。

如下图显示的菜单,其中打开cmd是用插件加入的。

 

系统提一个头文件和lib文件,按照这个实现这些即可在菜单中添加命令。

简单的接口定义文件

 

#pragma  once
#include 
< Windows.h >

#define  MAX_DESCRIPTION_SIZE 256

// 一个菜单所需要的所有基本数据,这是系统会提供的一个接口,在需要相关数据的时候从这里获取
class  IMenuObjectData
{
public :
    
enum  FileType {
        File 
=   0x1 ,
        Directory 
=   0x2 ,
        None 
=   0x0
    };
    
virtual  HWND GetHwnd()  =   0 ; // 取得explorer窗口句柄
     virtual  UINT GetFileCount()  =   0 ; // 取得在弹出菜单时选中的文件个数
     virtual   const  TCHAR *  GetFileName( int  index)  =   0 ; // 文件名及类型
     virtual  FileType GetFileType( int  index)  =   0 ;
    
virtual  BOOL IsInExplorer()  =   0 ; // 是否在Explorer右边窗口弹出(即非左边的数状目录)
};

// 这是插件需要实现的接口
class  IMenuControl
{
public :
    
virtual   ~ IMenuControl()  =   0  {}
    
virtual   void  SetMenuObjectData(IMenuObjectData * =   0 ; // 一开始
     virtual  UINT GetMenuCount()  =   0 ; // 告诉系统你将要几个命令菜单项(Explorer的右键菜单)
     virtual  UINT InitMenu(HMENU hMenu, UINT uIndex, UINT uID)  =   0 ; // 初始化这个菜单
     virtual  UINT GetSubMenuCount()  =   0 ; // 告诉系统你将要几个子菜单(扩展工具的子菜单)
     virtual  UINT InitSubMenu(HMENU hMenu, UINT uIndex, UINT uID)  =   0 ; // 返回增加了菜单之后的index
     virtual  BOOL Invoke(UINT uID)  =   0 ; // 命令被调用
     virtual  BOOL GetCmdDescription(UINT uID, TCHAR *  pszDesc)  =   0 ; // 需要被显示命令的tip
};

// IMenuControl* 
typedef IMenuControl *  (__stdcall *  fnGetMenuControl)( void ); // 从插件中取得IMenuControl接口的方法
typedef  void  (__stdcall *  fnReleaseMenuControl)(IMenuControl * ); // 告诉插件释放这个接口

void  RegisterMenuControl(fnGetMenuControl, fnReleaseMenuControl); // 插件将自己的这两个函数注册给系统

注释中已经很详细的说明了使用方法,下面是打开cmd这个菜单的插件的实现样例。

 

//  CmdTools.cpp : Defines the entry point for the DLL application.
//

#include 
" stdafx.h "
#include 
" ../ExternTools/ExternToolsDef.h "
#include 
< string >

using   namespace  std;
class  CMyMenuControl :  public  IMenuControl
{
public :
    CMyMenuControl() : m_pMenuData(
0 ), m_uID( 0 ) {}
    
virtual   void  SetMenuObjectData(IMenuObjectData *  pMenuData) { m_pMenuData  =  pMenuData; }
    
virtual  UINT GetMenuCount() {  return   0 ; }
    
virtual  UINT InitMenu(HMENU hMenu, UINT uIndex, UINT uID) {  return   0 ; }
    
virtual  UINT GetSubMenuCount();
    
virtual  UINT InitSubMenu(HMENU hMenu, UINT uIndex, UINT uID);
    
virtual  BOOL Invoke(UINT uID);
    
virtual  BOOL GetCmdDescription(UINT uID, TCHAR *  pszDesc);
private :
    IMenuObjectData
*  m_pMenuData;
    UINT m_uID;
};

IMenuControl
*  __stdcall GetMenuControl()
{
    
return   new  CMyMenuControl();
}

void  __stdcall ReleaseMenuControl(IMenuControl *  pControl)
{
    delete pControl;
}

BOOL APIENTRY DllMain( HANDLE hModule, 
                      DWORD  ul_reason_for_call, 
                      LPVOID lpReserved
                      )
{
    
if (ul_reason_for_call  ==  DLL_PROCESS_ATTACH)
    {
        RegisterMenuControl(GetMenuControl, ReleaseMenuControl);
    }
    
return  TRUE;
}

UINT CMyMenuControl::GetSubMenuCount()
{
    
return   1 ;
}
UINT CMyMenuControl::InitSubMenu(HMENU hMenu, UINT uIndex, UINT uID)
{
    m_uID 
=  uID;
    InsertMenu(hMenu, uIndex, MF_STRING 
|  MF_BYPOSITION, uID,  " 打开cmd(&C) " );
    
return  uIndex  +   1 ;
}
BOOL CMyMenuControl::Invoke(UINT uID)
{
    
if (uID  ==  m_uID)
    {
        
if (m_pMenuData)
        {
            std::
string  str(m_pMenuData -> GetFileName( 0 ));
            
if (m_pMenuData -> IsInExplorer())
            {
                
string ::size_type pos  =  str.find_last_of( ' / ' );
                
if (pos  !=   string ::npos)
                {
                    str 
=  str.substr( 0 , pos);
                    
if (str.size()  <   3 ) str  +=   " / " ;
                }
            }
            STARTUPINFO si;
            si.cb 
=   sizeof (si);
            GetStartupInfo(
& si);
            PROCESS_INFORMATION pi;
            
if (::CreateProcess( 0 " cmd.exe " 0 0 , FALSE,  0 0 , str.c_str(),  & si,  & pi))
            {
                ::CloseHandle(pi.hThread);
                ::CloseHandle(pi.hProcess);
            }
        }
        
return  TRUE;
    }
    
return  FALSE;
}

BOOL CMyMenuControl::GetCmdDescription(UINT uID, TCHAR
*  pszDesc)
{
    
if (uID  ==  m_uID)
    {
        
static  TCHAR szDesc[]  =   " 当前目录下打开命令提示符 " ;
        memcpy(pszDesc, szDesc, 
sizeof (szDesc));
        
return  TRUE;
    }
    
return  FALSE;
}

将插件放在注册表中

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE/SOFTWARE/ExternTools/dlls]
"cmdtool"="E://Develop//CmdTools//Debug//CmdTools.dll"

这样就可以了。

不知道怎么上载源文件,有兴趣的可以Email给我,共同研究

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值