关于com组件调用的问题,我想获取鼠标点击某个文件或者同时选择多个文件的文件名 看了网上一些资料 IShellExtInit这个接口可以做到   
下面这是一个atl工程部分源码
class ATL_NO_VTABLE CSimpleShlExt : 
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CSimpleShlExt, &CLSID_SimpleShlExt>,
public ISimpleShlExt,
public IShellExtInit//这是自己添加的
{
public:
CSimpleShlExt(){}
DECLARE_REGISTRY_RESOURCEID(IDR_SIMPLESHLEXT)
DECLARE_NOT_AGGREGATABLE(CSimpleShlExt)
DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CSimpleShlExt)
COM_INTERFACE_ENTRY(ISimpleShlExt)
COM_INTERFACE_ENTRY(IShellExtInit)//这是自己添加的
END_COM_MAP()// ISimpleShlExt
protected: 
TCHAR m_szFile [MAX_PATH]; 
public: 
// IShellExtInit 
 LPCSTR getFileName;
STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pdtobj, HKEY hProgID); 
STDMETHOD(get_str)(LPCSTR a,LPCSTR *b);//为了测试用的 自己定义了一个get_str方法 

};然后在cpp定义文件中 实现
HRESULT CSimpleShlExt::Initialize ( LPCITEMIDLIST pidlFolder, LPDATAOBJECT pdtobj, HKEY hProgID )
{
....
....
            for( UINT uIndex = 0; uIndex < uCount; uIndex++ ) 
            {
                TCHAR szFileName[MAX_PATH] = { 0 };
                //获取文件名
                ::DragQueryFile(hDrop, uIndex, szFileName, (sizeof(szFileName) / sizeof(TCHAR)) - 1);
                //szFileName为文件(夹)名
            }
}
szFileName这是获取的文件夹名 现在的问题是 我怎么得到这个文件夹名呢?
我新建了个win32 Console Application 对这个com组件进行调用 
下面是调用过程
#include "Debug/demo_SimpleExt.h"
#include "Debug/demo_SimpleExt_i.c"int main()
{
   ::CoInitialize(NULL);
   HRESULT hr;
   ISimpleShlExt* pIntf=NULL;
   hr = CoCreateInstance(CLSID_SimpleShlExt, NULL, CLSCTX_SERVER , IID_ISimpleShlExt, (void **)& pIntf);
   if(SUCCEEDED(hr))
   {
     LPCSTR lp;
   pIntf->get_str("aaaa",&lp);
     cout<<lp<<endl;
   pIntf->Release();
   }
   ::CoUninitialize();
}
得出的结果是可以输出aaaa的 说明调用组件是成功了 但是我不知道如何得到com组件中szFileName这个文件名的值   这个问题困扰我很久了 请教下大家

解决方案 »

  1.   

    添加事件,触发事件
    http://www.bianceng.cn/Programming/VC_NET/200912/13252.htm
      

  2.   

    鼠标点击某个文件, 弹出shellmenu, 是系统调用你的IShellExtInit组件, 又不是你的控制台程序调用.
    不明白你想在哪个程序里获得文件信息?
      

  3.   

    4楼的兄弟 你说的DragQueryFile是对的 是可以获得 那是atl工程里可以获取到了
     for( UINT uIndex = 0; uIndex < uCount; uIndex++ )  
      {
      TCHAR szFileName[MAX_PATH] = { 0 };
      //获取文件名
      ::DragQueryFile(hDrop, uIndex, szFileName, (sizeof(szFileName) / sizeof(TCHAR)) - 1);
    //szFileName为文件(夹)名
      }
    但是比如我新建一个工程 我得调用它呢 我不知道如何获得这个文件名 关键是这个
      

  4.   

    你应该是不知道在什么时候调用获取文件名!
    这得看你要实现的功能!
    如:在用鼠标拖动文件到对话框时,或鼠标点击右键弹出菜单-做shell扩展的时候!
    如果在任何时候都获取,可能就需要用到HOOK了(乱想的)....
      

  5.   

    就是我们普通的选择文件 比如鼠标点击了一个文件或者鼠标全选了一些文件或者鼠标利用shift一个个选择间隔的文件 当鼠标出现这些动作时 我就获得这些文件名szFileName 但是现在问题是szFileName 在atl工程里是有的 我就不知道怎么在另一个工程去获得它 
      

  6.   

    那你可以把TCHAR m_szFile [MAX_PATH]; 
    在dll做成全局共享的,
    #pragma data_seg( "Shared ")
    TCHAR g_szFile [MAX_PATH]={0};//成员变量改为全局共享变量
    .....CSimpleShlExt::get_str(..)//不管CSimpleShlExt有多少实例,都能得到
    {
    return g_szFile;
    } 当任何工程调用这个dll的时候,szFileName的值就能得到了
    不过你需要处理szFileName的同步问题
      

  7.   

    #pragma   data_seg( "Shared ") 
    TCHAR g_szFile [MAX_PATH]={0};
    #pragma   data_seg() #pragma   comment(linker,   "/Section:Shared,rws ")
      

  8.   

    你好!newerC!atl工程中 好像只能这样的形式定义 
    STDMETHODIMP CSimpleShlExt::GetLastDragFile(BSTR *a)
    {
    // TODO: Add your implementation code here
    *a=m_sFile;
    return S_OK;
    }
    好像不能直接您返回g_szFile  我也不知道对不对 如有错误 还请你指点
    CSimpleShlExt::get_str(..)//不管CSimpleShlExt有多少实例,都能得到
    {
    return g_szFile;
    }我在想:这是我进行调用com组件的方法  ::CoInitialize(NULL);
      HRESULT hr;
      ISimpleShlExt* pIntf=NULL;
      hr = CoCreateInstance(CLSID_SimpleShlExt, NULL, CLSCTX_SERVER , IID_ISimpleShlExt, (void **)& pIntf);
      if(SUCCEEDED(hr))
      {
       LPCSTR lp;
            pIntf->get_str("aaaa",&lp);
       cout<<lp<<endl;
            pIntf->Release();
      }
      ::CoUninitialize(); 我在想 这里程序在运行的过程中 压根应该就没运行CSimpleShlExt::Initialize 虚函数吧 如果运行的 我应该就能得到这函数当中szFileName的值了 然后这个值在传给其他变量 我应该就可以得到了 现在问题应该就是为什么Initialize没有运行的起来?
      

  9.   

    CSimpleShlExt::Initialize是由操作系统调的
    (a) 在某文件上右键 ,操作系统调用你的CSimpleShlExt::Initialize(前提是你的shell组件能正常工作)
    Initialize被调用后,获取文件名, 全局的g_szFile被赋值(一定要是全局的,共享的变量)(b) 启动你的测试程序
    当执行到CoCreateInstance....
    CSimpleShlExt所在的dll被加载到你的测试程序空间
    由于g_szFile是全局共享的,在共享数据段中,所以你的测试程序可以从该dll中获取(a)中获取的路径名称(3)你自己搞了个接口
    STDMETHOD(get_str)(LPCSTR a,LPCSTR *b) 这是很不规范
    而且你一会用TCHAR, 一会用LPCSTR, 这很乱的
    假设你的工程是unicode.
    //////正规的写法
    STDMETHOD(get_str)(BSTR *pbStrOut)
    {
      if(g_szFile[0])
     {
       *pbStrOut = ::SysAllocString(g_szFile); //g_szFile为 wchar_t[]类型
       return S_OK;
     }
     return E_FAIL;
    }
      

  10.   

    你好!newerC!
    在某文件上右键 ,操作系统调用你的CSimpleShlExt::Initialize?我直接选择用鼠标选择或者利用ctrl或者shift键选择可以获取选择的文件名么 如果一定要右键才能获取那就没有意义了呢