VariantClear和VariantInit的区别

本文深入探讨了VariantClear和VariantInit两个函数的作用与使用场景。VariantClear用于清除VARIANTARG或VARIANT类型的变量,将其类型设置为VT_EMPTY并释放其内容。而VariantInit则初始化这些变量,同样设置其类型为VT_EMPTY,但不处理现有内容。文章强调了在内存管理和变量初始化时正确使用这两个函数的重要性。
  • VariantClear:释放当前的变量内容后,置类型为VT_EMPTY

Use this function to clear variables of type VARIANTARG (or VARIANT) before the memory that contains the VARIANTARG is freed (as when a local variable goes out of scope).

The function clears a VARIANTARG by setting the vt member to VT_EMPTY and the wReserved member to 0. The current contents of the VARIANTARG are released first.

If the vt member is VT_BSTR, the string is freed.

If the vt member is VT_DISPATCH, the object is released.

If the vt member has the VT_ARRAY bit set, the array is freed.

  • VariantInit:仅变量类型为VT_EMPTY

Passing invalid (and under some circumstances NULL) pointers to this function causes an unexpected termination of the application.

The VariantInit function initializes the VARIANTARG by setting the vt member to VT_EMPTY.

Unlike VariantClear, this functiondoes not interpret the current contents of the VARIANTARG.

Use VariantInit to initialize new local variables of type VARIANTARG (or VARIANT).

#include "pptcominterface.h" #include <QDebug> #include <QFileInfo> #include <QDir> #ifdef _WIN32 #include <comdef.h> #include <atlbase.h> #include <atlcom.h> #endif QStringList PptComInterface::getPptContent(const QString &filePath) { QStringList contentList; #ifdef _WIN32 // Windows环境下使用COM接口获取PPT内容 CoInitialize(NULL); try { // 创建WPS演示文稿应用对象 CLSID clsid; HRESULT hr = CLSIDFromProgID(L"kso.Application", &clsid); if (FAILED(hr)) { qDebug() << "Failed to get CLSID for kso.Application"; CoUninitialize(); return contentList; } IDispatch *pApp = NULL; hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pApp); if (FAILED(hr)) { qDebug() << "Failed to create WPS Application instance"; CoUninitialize(); return contentList; } // 设置应用可见性 VARIANT x; x.vt = VT_I4; x.lVal = 0; // 不可见 const OLECHAR *szVisible = L"Visible"; DISPID dispidVisible; hr = pApp->GetIDsOfNames(IID_NULL, &szVisible, 1, LOCALE_USER_DEFAULT, &dispidVisible); if (SUCCEEDED(hr)) { DISPPARAMS params = { &x, NULL, 1, 0 }; pApp->Invoke(dispidVisible, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL); } // 打开演示文稿 const OLECHAR *szPresentations = L"Presentations"; DISPID dispidPresentations; hr = pApp->GetIDsOfNames(IID_NULL, &szPresentations, 1, LOCALE_USER_DEFAULT, &dispidPresentations); if (FAILED(hr)) { pApp->Release(); CoUninitialize(); return contentList; } VARIANT result; VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = pApp->Invoke(dispidPresentations, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) { pApp->Release(); CoUninitialize(); return contentList; } IDispatch *pPresentations = result.pdispVal; // 准备文件路径 QString qFilePath = QDir::toNativeSeparators(filePath); wchar_t wFilePath[MAX_PATH]; qFilePath.toWCharArray(wFilePath); wFilePath[qFilePath.length()] = 0; // 创建参数 VARIANTARG args[1]; args[0].vt = VT_BSTR; args[0].bstrVal = SysAllocString(wFilePath); const OLECHAR *szOpen = L"Open"; DISPID dispidOpen; hr = pPresentations->GetIDsOfNames(IID_NULL, &szOpen, 1, LOCALE_USER_DEFAULT, &dispidOpen); if (FAILED(hr)) { VariantClear(&args[0]); pPresentations->Release(); pApp->Release(); CoUninitialize(); return contentList; } DISPPARAMS paramsOpen = { args, NULL, 1, 0 }; hr = pPresentations->Invoke(dispidOpen, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsOpen, &result, NULL, NULL); VariantClear(&args[0]); if (FAILED(hr)) { pPresentations->Release(); pApp->Release(); CoUninitialize(); return contentList; } IDispatch *pPresentation = result.pdispVal; // 提取PPT内容 contentList = extractTextFromPresentation(pPresentation); // 清理 pPresentation->Release(); pPresentations->Release(); pApp->Release(); } catch (...) { qDebug() << "Exception occurred while accessing PPT via COM"; } CoUninitialize(); #else // Linux环境下返回空列表,使用模拟内容 Q_UNUSED(filePath); #endif return contentList; } #ifdef _WIN32 QStringList PptComInterface::extractTextFromPresentation(IDispatch *presentation) { QStringList contentList; try { // 获取Slides集合 const OLECHAR *szSlides = L"Slides"; DISPID dispidSlides; HRESULT hr = presentation->GetIDsOfNames(IID_NULL, &szSlides, 1, LOCALE_USER_DEFAULT, &dispidSlides); if (FAILED(hr)) return contentList; VARIANT result; VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = presentation->Invoke(dispidSlides, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) return contentList; IDispatch *pSlides = result.pdispVal; // 获取Slides数量 const OLECHAR *szCount = L"Count"; DISPID dispidCount; hr = pSlides->GetIDsOfNames(IID_NULL, &szCount, 1, LOCALE_USER_DEFAULT, &dispidCount); if (FAILED(hr)) { pSlides->Release(); return contentList; } VariantInit(&result); hr = pSlides->Invoke(dispidCount, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) { pSlides->Release(); return contentList; } int slideCount = result.intVal; // 遍历每个Slide for (int i = 1; i <= slideCount; i++) { VARIANTARG args[1]; args[0].vt = VT_I4; args[0].lVal = i; const OLECHAR *szItem = L"Item"; DISPID dispidItem; hr = pSlides->GetIDsOfNames(IID_NULL, &szItem, 1, LOCALE_USER_DEFAULT, &dispidItem); if (FAILED(hr)) continue; DISPPARAMS paramsItem = { args, NULL, 1, 0 }; VariantInit(&result); hr = pSlides->Invoke(dispidItem, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsItem, &result, NULL, NULL); if (FAILED(hr)) continue; IDispatch *pSlide = result.pdispVal; // 提取Slide内容 QString slideContent = extractTextFromSlide(pSlide); if (!slideContent.isEmpty()) { contentList << slideContent; } pSlide->Release(); } pSlides->Release(); } catch (...) { qDebug() << "Exception occurred while extracting PPT content"; } return contentList; } QString PptComInterface::extractTextFromSlide(IDispatch *slide) { QString slideContent; try { // 获取Shapes集合 const OLECHAR *szShapes = L"Shapes"; DISPID dispidShapes; HRESULT hr = slide->GetIDsOfNames(IID_NULL, &szShapes, 1, LOCALE_USER_DEFAULT, &dispidShapes); if (FAILED(hr)) return slideContent; VARIANT result; VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = slide->Invoke(dispidShapes, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) return slideContent; IDispatch *pShapes = result.pdispVal; // 获取Shapes数量 const OLECHAR *szCount = L"Count"; DISPID dispidCount; hr = pShapes->GetIDsOfNames(IID_NULL, &szCount, 1, LOCALE_USER_DEFAULT, &dispidCount); if (FAILED(hr)) { pShapes->Release(); return slideContent; } VariantInit(&result); hr = pShapes->Invoke(dispidCount, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) { pShapes->Release(); return slideContent; } int shapeCount = result.intVal; // 遍历每个Shape for (int i = 1; i <= shapeCount; i++) { VARIANTARG args[1]; args[0].vt = VT_I4; args[0].lVal = i; const OLECHAR *szItem = L"Item"; DISPID dispidItem; hr = pShapes->GetIDsOfNames(IID_NULL, &szItem, 1, LOCALE_USER_DEFAULT, &dispidItem); if (FAILED(hr)) continue; DISPPARAMS paramsItem = { args, NULL, 1, 0 }; VariantInit(&result); hr = pShapes->Invoke(dispidItem, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsItem, &result, NULL, NULL); if (FAILED(hr)) continue; IDispatch *pShape = result.pdispVal; // 提取Shape内容 QString shapeText = extractTextFromShape(pShape); if (!shapeText.isEmpty()) { if (!slideContent.isEmpty()) slideContent += "<br>"; slideContent += shapeText; } pShape->Release(); } pShapes->Release(); } catch (...) { qDebug() << "Exception occurred while extracting slide content"; } return slideContent; } QString PptComInterface::extractTextFromShape(IDispatch *shape) { QString shapeText; try { // 获取TextFrame const OLECHAR *szTextFrame = L"TextFrame"; DISPID dispidTextFrame; HRESULT hr = shape->GetIDsOfNames(IID_NULL, &szTextFrame, 1, LOCALE_USER_DEFAULT, &dispidTextFrame); if (FAILED(hr)) return shapeText; VARIANT result; VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = shape->Invoke(dispidTextFrame, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (FAILED(hr)) return shapeText; if (result.vt == VT_DISPATCH && result.pdispVal != NULL) { IDispatch *pTextFrame = result.pdispVal; // 获取TextRange const OLECHAR *szTextRange = L"TextRange"; DISPID dispidTextRange; hr = pTextFrame->GetIDsOfNames(IID_NULL, &szTextRange, 1, LOCALE_USER_DEFAULT, &dispidTextRange); if (SUCCEEDED(hr)) { VariantInit(&result); hr = pTextFrame->Invoke(dispidTextRange, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (SUCCEEDED(hr) && result.vt == VT_DISPATCH && result.pdispVal != NULL) { IDispatch *pTextRange = result.pdispVal; // 获取Text const OLECHAR *szText = L"Text"; DISPID dispidText; hr = pTextRange->GetIDsOfNames(IID_NULL, &szText, 1, LOCALE_USER_DEFAULT, &dispidText); if (SUCCEEDED(hr)) { VariantInit(&result); hr = pTextRange->Invoke(dispidText, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (SUCCEEDED(hr) && result.vt == VT_BSTR) { shapeText = QString::fromWCharArray(result.bstrVal); } } pTextRange->Release(); } } pTextFrame->Release(); } } catch (...) { qDebug() << "Exception occurred while extracting shape text"; } return shapeText; } #endif bool PptComInterface::openPptInWps(const QString &filePath) { #ifdef _WIN32 // 使用ShellExecute打开PPT文件 QString qFilePath = QDir::toNativeSeparators(filePath); wchar_t wFilePath[MAX_PATH]; qFilePath.toWCharArray(wFilePath); wFilePath[qFilePath.length()] = 0; HINSTANCE result = ShellExecute(NULL, L"open", wFilePath, NULL, NULL, SW_SHOWNORMAL); return (INT_PTR)result > 32; #else Q_UNUSED(filePath); return false; #endif } bool PptComInterface::startSlideShow(const QString &filePath) { #ifdef _WIN32 CoInitialize(NULL); try { // 创建WPS演示文稿应用对象 CLSID clsid; HRESULT hr = CLSIDFromProgID(L"kso.Application", &clsid); if (FAILED(hr)) { CoUninitialize(); return false; } IDispatch *pApp = NULL; hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pApp); if (FAILED(hr)) { CoUninitialize(); return false; } // 设置应用可见 VARIANT x; x.vt = VT_I4; x.lVal = 1; // 可见 const OLECHAR *szVisible = L"Visible"; DISPID dispidVisible; hr = pApp->GetIDsOfNames(IID_NULL, &szVisible, 1, LOCALE_USER_DEFAULT, &dispidVisible); if (SUCCEEDED(hr)) { DISPPARAMS params = { &x, NULL, 1, 0 }; pApp->Invoke(dispidVisible, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, NULL); } // 打开演示文稿 const OLECHAR *szPresentations = L"Presentations"; DISPID dispidPresentations; hr = pApp->GetIDsOfNames(IID_NULL, &szPresentations, 1, LOCALE_USER_DEFAULT, &dispidPresentations); if (FAILED(hr)) { pApp->Release(); CoUninitialize(); return false; } VariantInit(&result); DISPPARAMS paramsNoArgs = { NULL, NULL, 0, 0 }; hr = pApp->Invoke(dispidPresentations, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, ¶msNoArgs, &result, NULL, NULL); if (FAILED(hr)) { pApp->Release(); CoUninitialize(); return false; } IDispatch *pPresentations = result.pdispVal; // 准备文件路径 QString qFilePath = QDir::toNativeSeparators(filePath); wchar_t wFilePath[MAX_PATH]; qFilePath.toWCharArray(wFilePath); wFilePath[qFilePath.length()] = 0; // 打开文件 VARIANTARG args[1]; args[0].vt = VT_BSTR; args[0].bstrVal = SysAllocString(wFilePath); const OLECHAR *szOpen = L"Open"; DISPID dispidOpen; hr = pPresentations->GetIDsOfNames(IID_NULL, &szOpen, 1, LOCALE_USER_DEFAULT, &dispidOpen); if (FAILED(hr)) { VariantClear(&args[0]); pPresentations->Release(); pApp->Release(); CoUninitialize(); return false; } DISPPARAMS paramsOpen = { args, NULL, 1, 0 }; hr = pPresentations->Invoke(dispidOpen, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsOpen, &result, NULL, NULL); VariantClear(&args[0]); if (FAILED(hr)) { pPresentations->Release(); pApp->Release(); CoUninitialize(); return false; } IDispatch *pPresentation = result.pdispVal; // 开始幻灯片放映 const OLECHAR *szSlideShowSettings = L"SlideShowSettings"; DISPID dispidSlideShowSettings; hr = pPresentation->GetIDsOfNames(IID_NULL, &szSlideShowSettings, 1, LOCALE_USER_DEFAULT, &dispidSlideShowSettings); if (SUCCEEDED(hr)) { VariantInit(&result); hr = pPresentation->Invoke(dispidSlideShowSettings, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &paramsNoArgs, &result, NULL, NULL); if (SUCCEEDED(hr) && result.vt == VT_DISPATCH && result.pdispVal != NULL) { IDispatch *pSlideShowSettings = result.pdispVal; const OLECHAR *szRun = L"Run"; DISPID dispidRun; hr = pSlideShowSettings->GetIDsOfNames(IID_NULL, &szRun, 1, LOCALE_USER_DEFAULT, &dispidRun); if (SUCCEEDED(hr)) { DISPPARAMS paramsRun = { NULL, NULL, 0, 0 }; pSlideShowSettings->Invoke(dispidRun, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &paramsRun, NULL, NULL, NULL); } pSlideShowSettings->Release(); } } pPresentation->Release(); pPresentations->Release(); pApp->Release(); } catch (...) { qDebug() << "Exception occurred while starting slide show"; } CoUninitialize(); return true; #else Q_UNUSED(filePath); return false; #endif } 请检查编译错误D:\qt\wps\PPT6\ppt12\pptcominterface.cpp:45: error: C2664: “HRESULT IDispatch::GetIDsOfNames(const IID &,LPOLESTR *,UINT,LCID,DISPID *)”: 无法将参数 2 从“const OLECHAR **”转换为“LPOLESTR *”
最新发布
11-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值