关于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这个文件名的值 这个问题困扰我很久了 请教下大家
下面这是一个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这个文件名的值 这个问题困扰我很久了 请教下大家
解决方案 »
- 网络封包抓取的疑惑?
- 有关图像编程的为题
- 调用DLL后,主程序可以退出,进程管理器中显示的进程名为*.dll,请问怎么实现呢?
- WINDOWS.H already included. MFC apps must not #include <windows.h>
- MSDN连接问题
- 我需要在dll或者com中根据对应的协议动态生成一个链表框架...请教!!!
- vc调用sqlserver2000存储过程能获得返回值吗?在线等
- 我要哭了:CListCtrl怎么不支持动态CRuntimeClass->CreateObject()
- 请教SDI程序 菜单快捷键无效的问题。
- 一个关于链表的问题
- VC++2005 写出应用程序中,哪个函数(或消息) 相当于析构函数?
- VS2008中使用工业仪表控件Iocomp的问题!!!
http://www.bianceng.cn/Programming/VC_NET/200912/13252.htm
不明白你想在哪个程序里获得文件信息?
for( UINT uIndex = 0; uIndex < uCount; uIndex++ )
{
TCHAR szFileName[MAX_PATH] = { 0 };
//获取文件名
::DragQueryFile(hDrop, uIndex, szFileName, (sizeof(szFileName) / sizeof(TCHAR)) - 1);
//szFileName为文件(夹)名
}
但是比如我新建一个工程 我得调用它呢 我不知道如何获得这个文件名 关键是这个
这得看你要实现的功能!
如:在用鼠标拖动文件到对话框时,或鼠标点击右键弹出菜单-做shell扩展的时候!
如果在任何时候都获取,可能就需要用到HOOK了(乱想的)....
在dll做成全局共享的,
#pragma data_seg( "Shared ")
TCHAR g_szFile [MAX_PATH]={0};//成员变量改为全局共享变量
.....CSimpleShlExt::get_str(..)//不管CSimpleShlExt有多少实例,都能得到
{
return g_szFile;
} 当任何工程调用这个dll的时候,szFileName的值就能得到了
不过你需要处理szFileName的同步问题
TCHAR g_szFile [MAX_PATH]={0};
#pragma data_seg() #pragma comment(linker, "/Section:Shared,rws ")
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没有运行的起来?
(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;
}
在某文件上右键 ,操作系统调用你的CSimpleShlExt::Initialize?我直接选择用鼠标选择或者利用ctrl或者shift键选择可以获取选择的文件名么 如果一定要右键才能获取那就没有意义了呢