为金山虚拟光驱扩展浏览器上下文菜单功能
http://tech.ddvip.com 2007年10月31日 社区交流
内容摘要:本文详述了如何为金山虚拟光驱软件进行浏览器上下文菜单扩展.通过扩展,你可以直接通过鼠标右击虚拟光驱盘符来插入或者弹出虚拟光盘文件,也可以通过右击虚拟光盘文件(*.ISO)来将它直接插入某个虚拟光盘内。
3)添加接口IshellExtInit和IcontextMenu的函数说明和实现代码。
4)定义一些程序内需要用到的一些类数据成员。
5)添加两个私有辅助函数。
最后类的完整说明代码如下:
// Extend.h: interface for the CExtend class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_EXTEND_H__CC9F0D8A_0948_4BAD_9179_148BC1CE6630__INCLUDED_)
#define AFX_EXTEND_H__CC9F0D8A_0948_4BAD_9179_148BC1CE6630__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "resource.h" // main symbols
#include <comdef.h>
#include <shlobj.h>
#include "KVDExtend.h"
class ATL_NO_VTABLE CExtend :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CExtend, &CLSID_KVDExtend>,
public IShellExtInit,
public IContextMenu
{
public:
CExtend() {}
virtual ~CExtend() {}
// 定义自注册脚本资源
DECLARE_REGISTRY_RESOURCEID(IDR_KVDEXTEND)
DECLARE_PROTECT_FINAL_CONSTRUCT()
// 接口映射表
BEGIN_COM_MAP(CExtend)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()
HRESULT FinalConstruct();
void FinalRelease();
public:
// IShellExtInit 接口
// 初始化Shell扩展
STDMETHOD(Initialize)(THIS_ LPCITEMIDLIST pidlFolder,
LPDATAOBJECT lpdobj, HKEY hkeyProgID);
// IContextMenu 接口
// 向上下文菜单添加自定义项目
STDMETHOD(QueryContextMenu)(THIS_
HMENU hmenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags);
// 当自定义菜单项被选中后执行该函数
STDMETHOD(InvokeCommand)(THIS_
LPCMINVOKECOMMANDINFO lpici);
// 当鼠标划过菜单项时,系统请求显示相关菜单命令的说明字符串
STDMETHOD(GetCommandString)(THIS_
UINT idCmd,
UINT uType,
UINT * pwReserved,
LPSTR pszName,
UINT cchMax);
private:
TCHAR m_strFileName[MAX_PATH]; // 保存当前选中的Shell对象路径
CHAR m_strISOFileName[MAX_PATH]; // 保存返回的ISO文件路径
enum KVDTYPE{ Empty, ISOFile, Driver }; // 当前选中对象的类型定义
KVDTYPE m_kt;
HMODULE m_hDll; // kscdrush.dll 模块的句柄
// kscdrush.dll 内部功能函数和结构的说明
struct _kvd_entry;
struct _kvd_func_table;
typedef struct _kvd_entry KVD_ENTRY;
typedef struct _kvd_func_table KVD_FUNC_TABLE;
typedef void (__stdcall* FUNC_ENTRY)(KVD_ENTRY** ppEntry);
struct _kvd_entry
{
KVD_FUNC_TABLE* pFuncTable;
DWORD dw1;
DWORD dw2;
};
typedef struct _kvd_buf
{
DWORD dwSize;
DWORD dw1; // 标志(1/0)
DWORD dw2;
char path[256]; // 返回文件名
DWORD dw3;
} KVD_BUF;
struct _kvd_func_table
{
void (__stdcall* func0)(KVD_ENTRY*);
void (__stdcall* Release)(KVD_ENTRY*);
void (__stdcall* func2)(KVD_ENTRY*);
void (__stdcall* func3)(KVD_ENTRY*);
void (__stdcall* func4)(KVD_ENTRY*);
void (__stdcall* func5)(KVD_ENTRY*);
HRESULT (__stdcall* AddDriver)(KVD_ENTRY*, DWORD);
HRESULT (__stdcall* func7)(KVD_ENTRY*, DWORD, DWORD);
HRESULT (__stdcall* func8)(KVD_ENTRY*, DWORD, DWORD);
HRESULT (__stdcall* func9)(KVD_ENTRY*, DWORD, DWORD, DWORD);
HRESULT (__stdcall* InsertDisk)(KVD_ENTRY*, const char*, const char*);
HRESULT (__stdcall* PopDisk)(KVD_ENTRY*, const char*);
HRESULT (__stdcall* IsKVD)(KVD_ENTRY*, const char*, DWORD*);
HRESULT (__stdcall* GetFileNameInDriver)(KVD_ENTRY*, const char*, KVD_BUF*);
void (__stdcall* func14)(KVD_ENTRY*);
void (__stdcall* func15)(KVD_ENTRY*);
};
// DLL 入口
KVD_ENTRY* m_pEntry;
private:
// 内部函数包装
BOOL IsKVD(LPCTSTR lpszDriver);
BOOL Succeed(HRESULT hr); // 判断函数返回是否成功
};
#endif // !defined(AFX_EXTEND_H__CC9F0D8A_0948_4BAD_9179_148BC1CE6630__INCLUDED_)
责编:豆豆技术应用