#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, ¶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 contentList;
}
VARIANT result;
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 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, ¶msOpen, &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, ¶msNoArgs, &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, ¶msNoArgs, &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, ¶msItem, &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, ¶msNoArgs, &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, ¶msNoArgs, &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, ¶msItem, &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, ¶msNoArgs, &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, ¶msNoArgs, &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, ¶msNoArgs, &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, ¶msOpen, &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, ¶msNoArgs, &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, ¶msRun, 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 *”
最新发布