新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 C/C++编程思想 』 → 关于一个COM组件编写的问题,懂的高人进来帮帮小弟 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 4461 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 关于一个COM组件编写的问题,懂的高人进来帮帮小弟 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     dialoglife 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:1
      积分:52
      门派:XML.ORG.CN
      注册:2008/12/3

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给dialoglife发送一个短消息 把dialoglife加入好友 查看dialoglife的个人资料 搜索dialoglife在『 C/C++编程思想 』的所有贴子 引用回复这个贴子 回复这个贴子 查看dialoglife的博客楼主
    发贴心情 关于一个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?


       收藏   分享  
    顶(0)
      




    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/12/3 10:33:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/28 13:23:24

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    46.875ms