#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QDesktopServices>
#include <QUrl>
#include <windows.h>
#include <winuser.h>
#include <QTime>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
OpenWindow("e:\\111.xls");
// OpenWindow("e:\\123.doc");
}
MainWindow::~MainWindow()
{
delete ui;
CloseWindow();
}
void MainWindow::WaitForOpenWindow()
{
if (!m_fileName.isEmpty()){
QDesktopServices::openUrl(QUrl::fromLocalFile(m_fileName));
// Sleep(1500);
// QTime t;
// t.start();
// while(t.elapsed()<1500)
// QCoreApplication::processEvents();
int lastSeparatorIndex = m_fileName.lastIndexOf("/");
if (lastSeparatorIndex == -1){
lastSeparatorIndex = m_fileName.lastIndexOf("\\");
}
QString name = m_fileName.mid(lastSeparatorIndex + 1);
//如打开的word名称是123.docx,则窗口标题名称为123.docx - Word ,,, 123.doc - WPS Office
std::string strName = name.toStdString() + " - WPS Office";//我用的是WPS,如果是Office则需要修改
//进行类型转换
int dwLen = strlen(strName.c_str()) + 1;
int nwLen = MultiByteToWideChar(CP_ACP, 0, strName.c_str(), dwLen, NULL, 0);//算出合适的长度
LPWSTR lpszPath = new WCHAR[dwLen];
MultiByteToWideChar(CP_ACP, 0, strName.c_str(), dwLen, lpszPath, nwLen);
int dec = 0;
while (m_fileShowHwnd == NULL){
dec++;qDebug()<<"dec:"<<dec;
//用类名和窗口标题名找到窗口句柄
m_fileShowHwnd = FindWindow(L"XLMAIN", lpszPath);//word: OpusApp , excel:XLMAIN ,PPT:PPTFrameClass
//不会立即找到句柄,有延时
if (dec > 1000000){
// MessageBox(NULL, TEXT("No word!"), TEXT("Error"), MB_SYSTEMMODAL);
break;
}
}
}
}
//入参:要打开文件绝对路径
void MainWindow::OpenWindow(const QString & str)
{
m_fileName = str;
WaitForOpenWindow();
//嵌入窗口,设置父窗口。减30是把为了把关闭按钮遮挡住。
SetParent(m_fileShowHwnd, (HWND)ui->frame->winId());
//移动窗口,把关闭按钮遮住
// MoveWindow(m_FileShowHwnd, 0, -30, ui->frame->width(), ui->frame->height() + 30, true);
MoveWindow(m_fileShowHwnd, 0, 0, ui->frame->width(), ui->frame->height(), true);
update();
}
#if 0
void MainWindow::CloseWindow()
{
if (m_FileShowHwnd != nullptr){
SendMessage(m_FileShowHwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
int k = GetLastError();
qDebug() << "SendMessage k " << k << "\n";
m_FileShowHwnd = NULL;
}
}
#else
void MainWindow::CloseWindow()
{
if (m_fileShowHwnd != nullptr)
{
DWORD dwPID;
::GetWindowThreadProcessId(m_fileShowHwnd, &dwPID);
qDebug() << "GetWindowThreadProcessId dwPID = " << dwPID << "\n";
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
if (hProcess)
{
qDebug() << "OpenProcess hProcess = " << hProcess << "\n";
UINT unExitCode = 0;
BOOL bRet = TerminateProcess(hProcess, unExitCode);
if (!bRet)
{
DWORD dwErorCode = GetLastError();
qDebug() << "TerminateProcess error = " << dwErorCode << "\n";
}
}
m_fileShowHwnd = NULL;
}
}
#endif
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
void WaitForOpenWindow();
void OpenWindow(const QString & str);
void CloseWindow();//关闭office窗口
private:
Ui::MainWindow *ui;
QString m_fileName;
HWND m_fileShowHwnd = NULL;
};
#endif // MAINWINDOW_H
LIBS += -luser32
原理很简单,就是先按正常方式打开word,然后调用微软的FindWindow找到刚打开的这个word窗口,最后用SetParent方法设置此word窗口的父窗口为qt的窗口即可。