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();
	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();
	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();
	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();
	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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章