com组件已知函数名和参数名 如何获取参数的类型

尘归笑夕 2023-11-27 14:07:24

com组件已知函数名和参数名  如何获取参数的类型

...全文
313 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
尘归笑夕 2023-11-29
  • 打赏
  • 举报
回复

在已知com组件的函数名并获取到参数的FuncDesc后,可以通过FuncDesc->lprgelemdescParam[i].tdesc去逐层获取到参数的类型。
例如int类型在lprgelemdescParam中会先标识,也就是指针类型,然后再标识int类型。当然如果是自定义类型。则需要判断FuncDesc->lprgelemdescParam[i].tdesc.lptdesc.vt的类型是否为29,vt为29即表示该类型为用户自定义类型。总而言之,当类型不为29时,则可根据variant的枚举去判断类型。当类型为29时,则需要获取FuncDesc->lprgelemdescParam[i].tdesclptdesc->hreftype,并使用GetDocumentation去获取文档中类型的字符。

清贫码农 2023-11-29
  • 打赏
  • 举报
回复 1

要获取COM组件中已知函数名和参数名的参数类型,可以使用以下方法:

使用Type Library Viewer工具查看Type Library(TLB)文件。TLB文件包含了COM组件中所有公开接口、方法和参数的信息。你可以从Microsoft Office程序中找到相应的TLB文件,或者使用第三方工具生成。

使用OLE/COM Object Viewer工具查看COM组件的类型库信息。这个工具可以帮助你查看COM组件中的方法、属性和事件等信息。

在代码中使用Type Library Import库来获取参数类型。首先,你需要将Type Library导入到你的项目中,然后使用CoClassInfo函数获取类信息,最后使用DispCallFunc或DispCallFuncI函数调用方法并获取返回值。

以下是一个C++示例,展示了如何使用Type Library Import库获取参数类型:
#import "C:\Program Files (x86)\Common Files\microsoft shared\OFFICE16\MSO.DLL" rename("DialogBox", "MsoDialogBox") rename("RGB", "MsoRGB") rename("DocumentProperties", "MsoDocumentProperties") no_dual_interfaces
#include
#include <Windows.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlctl.h>
#include <msotlb.h>

int main()
{
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
std::cerr << "Failed to initialize COM library." << std::endl;
return 1;
}

// 获取类信息
CComPtr<IMsoDispObj> pDispObj;
hr = CComObject<CMsoDialogBox>::CreateInstance(&pDispObj);
if (FAILED(hr))
{
    std::cerr << "Failed to create instance of MsoDialogBox." << std::endl;
    CoUninitialize();
    return 1;
}

// 获取参数类型
CComVariant varParams[2];
varParams[0] = _variant_t("Caption");
varParams[1] = _variant_t("Message");
CComQIPtr<IMsoDispParams> pDispParams = pDispObj;
hr = pDispParams->Invoke(0x00000000, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, NULL, &varParams, 2, NULL, NULL);
if (FAILED(hr))
{
    std::cerr << "Failed to call method." << std::endl;
    CoUninitialize();
    return 1;
}

// 输出参数类型
CComQIPtr<IDispatch> pDispatch;
hr = pDispObj->QueryInterface(IID_IDispatch, (void**)&pDispatch);
if (SUCCEEDED(hr))
{
    CComVariant varResult;
    hr = pDispatch->Invoke(0x00000000, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, NULL, &varResult, NULL, NULL);
    if (SUCCEEDED(hr))
    {
        std::cout << "Parameter types:" << std::endl;
        for (int i = 0; i < 2; ++i)
        {
            CComVariant varType;
            hr = varResult.GetOneDimArrayInit(&varType);
            if (SUCCEEDED(hr))
            {
                CString strType;
                VariantClear(&varType);
                strType.Format(L"%ls", varResult.bstrVal);
                std::wcout << L"Parameter " << i + 1 << L": " << strType << std::endl;
            }
        }
    }
    pDispatch->Release();
}
CoUninitialize();
return 0;

}
请注意,这个示例仅适用于特定版本的Office,你需要根据实际情况修改TLB文件路径和导入语句。

尘归笑夕 2023-11-29
  • 举报
回复
@清贫码农 感谢回复

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧