MFC通过COM操作在对话框中显示PowerPoint幻灯片(重点解决幻灯片全屏闪烁问题)

最近的项目中有个需求是在界面中显示PPT幻灯片,之前项目中对PPT文件的处理是首先将.ppt或.pptx文件转化为.html文件,然后使用WebBrowser(Navigate2)控件打开进行显示。由于新项目需要有点击按钮切换页面功能,采用之前的方式不能够实现该需求,于是采用COM的方式打开PPT进行显示。在实现的过程中发现在执行m_SlideShowSettings.Run(); 显示幻灯片时,幻灯片时全屏显示的,再将全屏显示的幻灯片移入对话框中,这个过程会出现闪屏的现象,体验效果很不好,尝试了好多种方法,最后采用多线程的方式完美解决此问题。
1.操作环境:
①需要安装office软件,没有安装office的环境无法使用;
②VS2015+MFC
2.详细步骤:
①新建MFC对话框应用程序,取名为ShowPowerPoint,如图所示:
在这里插入图片描述
②在对话框中拖入以下控件,如图所示:
在这里插入图片描述
③生成OFFICE头文件:右击解决方案添加类MFCTypeLib中的MFC类添加注册表可用的类型库(Microsoft PowerPoint 12.0 Object Library<2.9>)如图所示:
在这里插入图片描述
点击上图中的箭头,生成的类中出现许多项:
在这里插入图片描述
点击完成,至此已经生成了相应的头文件。
还有一种方法是选择文件,在office安装目录下找到MSPPT.OLB,其它操作不用改,能达到一样的效果,如下图所示:
在这里插入图片描述
生成的头文件有很多,但是单纯的显示的话,只需要保留其中几个头文件就可以了。
在这里插入图片描述
需要将这些头文件中的一段注释掉,文件太多记得使用查找替换:
//#import “E:\Program Files (x86)\Microsoft Office\Office12\MSPPT.OLB” no_namespace
在InitInstance()函数中加入OLE初始化代码:

//OLE
if (!AfxOleInit())
{
	AfxMessageBox(L"Failed to initialize OLE");
	return false;
}

在ShowPowerPointDlg.h中加入头文件:

#include "CApplication.h"
#include "CPresentations.h"
#include "CPresentation.h"
#include "CSlides.h"
#include "CSlide.h"
#include "CSlideShowWindow.h"
#include "CSlideShowSettings.h"
#include "CSlideShowView.h"

添加对象:

CApplication		m_Application;
CPresentations		m_Presentations;
CPresentation		m_Presentation;
CSlides				m_Slides;
CSlide				m_Slide;
CSlideShowWindow	m_SlideShowWindow;
CSlideShowSettings	m_SlideShowSettings;
CSlideShowView		m_SlideShowView;

unsigned __stdcall ShowPPTFunc(LPVOID nlps);
unsigned __stdcall ShowPPTFunc(LPVOID nlps)
{
	CShowPowerPointDlg* dlg = (CShowPowerPointDlg *)nlps;
	while (true)
	{
		HWND hWnd = ::FindWindow(_T("ScreenClass"), 0);//幻灯片窗口
		if (NULL != hWnd)
		{
			CWnd *pWnd = dlg->GetDlgItem(IDC_STATIC);//随便的显示控件
			::SetParent(hWnd, pWnd->GetSafeHwnd());//设置父窗口
			CRect rect;
			pWnd->GetWindowRect(&rect);
			CWnd *pWnd2 = CWnd::FromHandle(hWnd);
			rect.SetRect(0, 0, rect.Width(), rect.Height());
			pWnd2->MoveWindow(&rect);
			pWnd2->Invalidate();			
			break;
		}
	}
	return 0;
}

//打开
void CShowPowerPointDlg::OnBnClickedOpen()
{
	// TODO: 在此添加控件通知处理程序代码

	//查找PPT文件
	CString strFilter = L"PowerPoint Files (*.ppt;*.pptx)|*.ppt;*.pptx|All Files(*.*)|*.*||";
	CFileDialog FileDlg(TRUE, L"PPT", NULL, OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_PATHMUSTEXIST, strFilter);
	FileDlg.DoModal();
	CString strFilePath;
	strFilePath = FileDlg.GetPathName();

	try
	{
		if (!m_Application.CreateDispatch(_T("Powerpoint.Application"), NULL))
		{
			AfxMessageBox(_T("创建PowerPoint应用程序失败!"));
			return ;
		}
		if (!m_Application.m_lpDispatch)
		{
			AfxMessageBox(_T("PPT application was not initialized!"));
			return ;
		}

		//开启线程监测幻灯片窗口_T("ScreenClass"),如果没有这一步操作,转到下面的注释代码,会出现全屏显示的幻灯片
		//然后幻灯片移到会话框中,出现闪屏的现象,视觉效果比较差
		HANDLE hThread;
		unsigned int threadid;
		hThread = (HANDLE)::_beginthreadex(NULL, 0, &ShowPPTFunc, (LPVOID)this, 0, &threadid);
		CloseHandle(hThread);

		m_Presentations.AttachDispatch(m_Application.get_Presentations());
		m_Presentation.AttachDispatch(m_Presentations.Open(strFilePath, TRUE, -1, 0));
		m_Slides = m_Presentation.get_Slides();
		m_Slide = m_Slides.Item(COleVariant((long)1));
		m_SlideShowSettings = m_Presentation.get_SlideShowSettings();
		m_SlideShowSettings.put_LoopUntilStopped(TRUE); //设置循环放映  
		m_SlideShowSettings.Run(); //运行ppt	
		ShowPageNum();
		//在对话框中显示
		//HWND hWnd = ::FindWindow(_T("ScreenClass"), 0);//幻灯片窗口
		//if (NULL != hWnd)
		//{
		//	CWnd *pWnd = GetDlgItem(IDC_STATIC);//随便的显示控件
		//	::SetParent(hWnd, pWnd->GetSafeHwnd());//设置父窗口
		//	CRect rect;
		//	pWnd->GetWindowRect(&rect);
		//	CWnd *pWnd2 = CWnd::FromHandle(hWnd);
		//	rect.SetRect(0, 0, rect.Width(), rect.Height());
		//	pWnd2->MoveWindow(&rect);
		//	pWnd2->Invalidate();		
		//}
	}
	catch (...)
	{
		m_Application.ReleaseDispatch();
		return ;
	}
}

//关闭
void CShowPowerPointDlg::OnBnClickedClose()
{
	// TODO: 在此添加控件通知处理程序代码
	try
	{	
		m_Presentation.Close();
		m_Presentation.ReleaseDispatch();
		m_Presentations.ReleaseDispatch();
		m_Slide.ReleaseDispatch();
		m_SlideShowSettings.ReleaseDispatch();
		m_SlideShowWindow.ReleaseDispatch();
		m_SlideShowView.ReleaseDispatch();
		m_Application.ReleaseDispatch();
		m_Application.Quit();
	}
	catch (...)
	{

	}
	CDialogEx::OnOK();
}

//首页
void CShowPowerPointDlg::OnBnClickedStart()
{
	// TODO: 在此添加控件通知处理程序代码
	m_Presentation = m_Application.get_ActivePresentation();
	m_SlideShowWindow = m_Presentation.get_SlideShowWindow();
	m_SlideShowView = m_SlideShowWindow.get_View();
	m_SlideShowView.First();
	m_SlideShowWindow.Activate();//刷新
	ShowPageNum();
}

//尾页
void CShowPowerPointDlg::OnBnClickedEnd()
{
	// TODO: 在此添加控件通知处理程序代码
	m_Presentation = m_Application.get_ActivePresentation();
	m_SlideShowWindow = m_Presentation.get_SlideShowWindow();
	m_SlideShowView = m_SlideShowWindow.get_View();
	m_SlideShowView.Last();
	m_SlideShowWindow.Activate();//刷新
	ShowPageNum();
}

//上一页
void CShowPowerPointDlg::OnBnClickedLast()
{
	// TODO: 在此添加控件通知处理程序代码
	m_Presentation = m_Application.get_ActivePresentation();
	m_SlideShowWindow = m_Presentation.get_SlideShowWindow();
	m_SlideShowView = m_SlideShowWindow.get_View();
	m_SlideShowView.Previous();
	m_SlideShowWindow.Activate();//刷新
	ShowPageNum();
}

//下一页
void CShowPowerPointDlg::OnBnClickedNext()
{
	// TODO: 在此添加控件通知处理程序代码
	m_Presentation = m_Application.get_ActivePresentation();
	m_SlideShowWindow = m_Presentation.get_SlideShowWindow();
	m_SlideShowView = m_SlideShowWindow.get_View();
	m_SlideShowView.Next();
	m_SlideShowWindow.Activate();//刷新
	ShowPageNum();
}

//显示页码
void CShowPowerPointDlg::ShowPageNum()
{
	// TODO: 在此添加控件通知处理程序代码	
	m_Presentation = m_Application.get_ActivePresentation();
	m_SlideShowWindow = m_Presentation.get_SlideShowWindow();
	m_SlideShowView = m_SlideShowWindow.get_View();
	m_Slide = m_SlideShowView.get_Slide();
	CString strPages; strPages.Format(L"%d/%d", m_Slide.get_SlideIndex(), m_Slides.get_Count());
	GetDlgItem(IDC_EDIT1)->SetWindowText(strPages);
}

至此在对话框中打开ppt的功能就完成啦!效果如图所示:
在这里插入图片描述下载链接:
https://download.csdn.net/download/xhlzjd/11240220

MFC 显示PPT //启动 PowerPoint: void CMainFrame::OnPowerpointStartpowerpoint() { /// Check if the IDispatch connection exists with PowerPoint, // if not create one. if (m_ppt.m_lpDispatch == NULL) { // Create IDispatch connection to PowerPoint. m_ppt.CreateDispatch("PowerPoint.Application"); }; // Bring the PowerPoint application to the front. m_ppt.Activate(); } void CMainFrame::OnPowerpointStartslideshow() { _Presentation oPresentation; SlideShowSettings oShow; // Attach to the Active Presentation. oPresentation.AttachDispatch(m_ppt.GetActivePresentation()); // Attach to the slide-show settings. oShow.AttachDispatch(oPresentation.GetSlideShowSettings()); // Run the slide show. oShow.Run(); } // 创建幻灯片: void CMainFrame::OnPowerpointCreateslide() { // Connect to the active presentation. There is no error trapping. // If the active presentation the framework traps // the error and displays a message box. _Presentation ActivePresentation(m_ppt.GetActivePresentation()); // Connect to the slides collection. Slides oSlides(ActivePresentation.GetSlides()); // This constant is defined in the PowerPoint Object model. // You can use the Object Browser, with Visual Basic Editor // (VBE), to look up the different constant values. const ppLayoutTitleOnly = 11; // Add a new slide to the presentation. This code adds the new // slide to the end of the presentation. oSlides.Add(oSlides.GetCount() + 1l, ppLayoutTitleOnly); } // 创建演示文稿: void CMainFrame::OnPowerpointCreatepresentation() { Presentations PresCollection; // Make sure there is a dispatch pointer for PowerPoint. if(m_ppt.m_lpDispatch == NULL) { // Display a message indicating that PowerPoint is not running. MessageBox("PowerPoint is not running.", "Start PowerPoint"); } else { // Bring PowerPoint to the front. m_ppt.Activate(); // Attach the presentations collection to the PresCollection // variable. PresCollection.AttachDispatch(m_ppt.GetPresentations()); // Create a new presentation. PresCollection.Add(1);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值