以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 C/C++编程思想 』  (http://bbs.xml.org.cn/list.asp?boardid=61)
----  关于一个COM组件编写的问题,懂的高人进来帮帮小弟  (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=70042)


--  作者:dialoglife
--  发布时间:12/3/2008 10:33:00 AM

--  关于一个COM组件编写的问题,懂的高人进来帮帮小弟
我需要的是编程实现,因为我要在COM组件里传个数据到主程序,再相应的更改主程序的功能
所以像你们说的用注册表的方法都是行不通的
我试验了几天发现IContextMenu的接口本身就是对文件及文件夹的右键菜单操作,也就是说主要实现IContextMenu接口的重写
都可以对文件及文件夹的右键系统菜单进行添加,剩下的我们只要是对"HKEY_LOCAL_MACHINE\Software\CLASSES\Directory\shell"
或者"HKEY_CLASSES_ROOT\Folder"主键下的"Shell"主键上新建个名为主程序名的键,默认的值设为主程序的CLSDI的值,应该就可以了实现了
但是死活都写不进去,不知哪里出错,望高手指出(还有一个,算了,问题我在代码注释里给出),下面是我COM组件的主要代码:
Initialize(LPCITEMIDLIST pIDFolder,
LPDATAOBJECT  pDataObj,
HKEY          hRegKey)
{
//数据存储格式
//FORMATETC 结构由目标设备、数据的方位或视图以及存储介质指示符组成。
//OLE 不使用剪贴板格式,而使用 FORMATETC 数据结构。在需要数据格式信息的 OLE 函数和方法中,此结构被用作参数
FORMATETC fmt = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
//数据存储内存句柄(常用于IDataObject和IAdviseSink接口的数据传输操作)
//提供 STGMEDIUM 结构的托管定义
STGMEDIUM stg = {TYMED_HGLOBAL};
if (FAILED(pDataObj->GetData(&fmt, &stg)))
{
//如果获取数据内存句柄失败则返回E_INVALIDARG,
//返回E_INVALIDARG则Explorer不会再调用我们的Shell扩展接口
return E_INVALIDARG;
}
//获取实际数据内存句柄
HDROP hdrop = (HDROP)GlobalLock(stg.hGlobal);
if (NULL == hdrop)
{
return E_INVALIDARG;
}
//获取用户Drag/Drop的文件数目
int fileCount = ::DragQueryFile((HDROP)stg.hGlobal, 0xFFFFFFFF, NULL, 0);
if (fileCount != 1)
{
::ReleaseStgMedium(&stg);
}
memset(m_filePath, 0x0, MAX_PATH*sizeof(TCHAR));
//获取文件名称
::DragQueryFile((HDROP)stg.hGlobal, 0x0, m_filePath, MAX_PATH);
return S_OK;
}
QueryContextMenu(HMENU hmenu,
  UINT  indexMenu,
  UINT  idCmdFirst,
  UINT  idCmdLast,
  UINT  uFlags)
{
if (!(uFlags & CMF_DEFAULTONLY))
{
::InsertMenu(hmenu, indexMenu, MF_BYPOSITION,
idCmdFirst, _T("&Encrypt"));
//错误处理COM用宏MAKE_HRESULT代替
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(2));
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(2));
}
HRESULT CEncryptCom::GetCommandString(UINT  idCmd,
  UINT  uFlags,
  UINT *pwReserved,
  LPSTR pszName,
  UINT  cchMax)
{
USES_CONVERSION;

HRESULT hr = E_INVALIDARG;

LPCTSTR IDM_ENP_MNU_HLPTXT = _T("Encrypt Sucessful!");

if (uFlags & GCS_HELPTEXT)
{
switch (idCmd)
{
case 0:
{
if (uFlags & GCS_UNICODE)
{
//为UNICODE
lstrcpynW((LPWSTR)pszName, T2CW(IDM_ENP_MNU_HLPTXT), cchMax);
}else
{
//为ANSI
lstrcpynA(pszName, T2CA(IDM_ENP_MNU_HLPTXT), cchMax);
}
hr = S_OK;
}
break;
}
}
return hr;
}
InvokeCommand(LPCMINVOKECOMMANDINFO pici)
{
USES_CONVERSION;

int nFlag = HIWORD(pici->lpVerb);

//用户单击该菜单
int nMnuID = LOWORD(pici->lpVerb);

if (0 != nFlag)//非单击事件
{
return E_INVALIDARG;
}
switch (nMnuID)
{
case 0:
{
TCHAR szCmdLine[256];
memset(szCmdLine, 0x0, 256*sizeof(TCHAR));
wsprintf(szCmdLine, _T("file:\"%s\""), m_filePath);
MessageBox(NULL, "test1", "Caption", MB_OK);
return S_OK;
}
break;
}
return E_INVALIDARG;
}

下面是注册表的操作:
STDAPI DllRegisterServer(void)
{
    // registers object, typelib and all interfaces in typelib
if (0 == (GetVersion() & 0x80000000UL))
{

HKEY subhk;
unsigned char cstr[] = _T("{3436D648-15E6-42F8-B701-D7028D89C6C0}");
                //用CRegKey类的方法Create应该是可以的,但是我用了也不行
                  //所以我用这个,但是也不行,其中CEncrypt是要建的主键
::RegCreateKey(HKEY_CLASSES_ROOT, "HKEY_CLASSES_ROOT\\Folder\\Shellex\\ContextMenuHandlers", &subhk);
RegSetValueEx(subhk, "CEncrypt", NULL, REG_SZ, cstr, sizeof(cstr));
::RegCloseKey(subhk);
}
    return _Module.RegisterServer(TRUE);
}
STDAPI DllUnregisterServer(void)
{

if ( 0 == (GetVersion() & 0x80000000UL) )
{
        CRegKey reg;
        LONG    lRet;

        lRet = reg.Open ( HKEY_CLASSES_ROOT,
_T("HKEY_CLASSES_ROOT\\Folder\\Shellex\\ContextMenuHandlers\\CEncrypt"),
KEY_SET_VALUE );

        if ( ERROR_SUCCESS == lRet )
{
            lRet = reg.DeleteValue ( _T("{3436D648-15E6-42F8-B701-D7028D89C6C0}") );
}
}
    return _Module.UnregisterServer(TRUE);
}
还有一个我想问下:
ATL COM工程里的.rgs文件是否是系统自动生成的对注册表就行操作的代码
如果是的话,我们还要编写DllRegisterServer和DllUnregisterServer函数吗?
还一个,我们要对文件夹操作是否就是我说的那两个地方随便一个添加主键就OK?


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
17,691.410ms