diff --git a/openlp/plugins/presentations/lib/impresscom.py b/openlp/plugins/presentations/lib/impresscom.py new file mode 100644 index 000000000..beeba6e7c --- /dev/null +++ b/openlp/plugins/presentations/lib/impresscom.py @@ -0,0 +1,118 @@ +from win32com.client import Dispatch + +# OOo API documentation: +# http://api.openoffice.org/docs/common/ref/com/sun/star/presentation/XSlideShowController.html +# http://docs.go-oo.org/sd/html/classsd_1_1SlideShow.html +# http://www.oooforum.org/forum/viewtopic.phtml?t=5252 +# http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Working_with_Presentations +# http://mail.python.org/pipermail/python-win32/2008-January/006676.html + +class ImpressCOMApp(object): + def __init__(self): + self.createApp() + + def createApp(self): + try: + self._sm = Dispatch("com.sun.star.ServiceManager") + self._app = self._sm.createInstance( "com.sun.star.frame.Desktop" ) + except: + self._sm = None + self._app = None + return + + def getApp(self): + if self._app == None: + self.createApp() + if self._app == None: + return None + return self._app + + app = property(getApp) + + def quit(self): + self._app.Terminate() + self._app = None + self._sm = None + +class ImpressCOMPres(object): + def __init__(self, oooApp, filename): + self.oooApp = oooApp + self.filename = filename + self.open() + + def getPres(self): + if self._pres == None: + self.open() + return self._pres + + pres = property(getPres) + + def open(self): + self.comp = self.oooApp.app.loadComponentFromURL("file:///" + self.filename, "_blank", 0, []) + self.presdoc = self.comp.getPresentation() + self.presdoc.start() + self._pres = self.presdoc.getController() + + def close(self): + self.pres.deactivate() + self.presdoc.end() + self.comp.dispose() + self._pres = None + self.presdoc = None + self.comp = None + + def isActive(self): + return self.pres.isRunning() and self.pres.isActive() + + def resume(self): + return self.pres.resume() + + def pause(self): + return self.pres.pause() + + def blankScreen(self): + self.pres.blankScreen(0) + + def stop(self): + self.pres.deactivate() + # self.presdoc.end() + + def go(self): + self.pres.activate() + # self.presdoc.start() + + def getSlideNumber(self): + return self.pres.getCurrentSlideIndex + + def setSlideNumber(self, slideno): + self.pres.gotoSlideIndex(slideno) + + slideNumber = property(getSlideNumber, setSlideNumber) + + def nextStep(self): + self.pres.gotoNextEffect() + + def prevStep(self): + self.pres.gotoPreviousSlide() + + def moveWindow(self, top, height, left, width): + # position the window somehow + pass + +class ImpressCOMSlide(object): + def __init__(self, pres, index): + self.pres = pres + self.slide = pres.getSlideByIndex(index) + + def preview(self): + if self.preview == None: + # get a slide somehow + pass + return self.preview + +if __name__ == '__main__': + ooo = ImpressCOMApp() + show = ImpressCOMPres(ooo, "c:/test1.ppt") + show.go() + show.resume() + show.nextStep() diff --git a/openlp/plugins/presentations/lib/powerpoint.py b/openlp/plugins/presentations/lib/powerpoint.py new file mode 100644 index 000000000..5d3c5989c --- /dev/null +++ b/openlp/plugins/presentations/lib/powerpoint.py @@ -0,0 +1,139 @@ +from win32com.client import Dispatch + +# PPT API documentation: +# http://msdn.microsoft.com/en-us/library/aa269321(office.10).aspx + + +class PowerPointApp(object): + def __init__(self): + self.createApp() + + def createApp(self): + try: + self._app = Dispatch("PowerPoint.Application") + except: + self._app = None + return + self._app.Visible = True + self._app.WindowState = 2 + + def getApp(self): + if self._app == None: + self.createApp() + if self._app == None: + return None + if self._app.Windows.Count == 0: + self.createApp() + return self._app + + app = property(getApp) + + def quit(self): + self._app.Quit() + self._app = None + +class PowerPointPres(object): + def __init__(self, pptApp, filename): + self.pptApp = pptApp + self.filename = filename + self.open() + + def getPres(self): + if self._pres == None: + for p in self.pptApp.app.Presentations: + if p.FullName == self.filename: + self._pres = p + break + if self._pres != None: + try: + x = self._pres.Name + except: + self._pres = None + if self._pres == None: + self.openPres() + return self._pres + + pres = property(getPres) + + def open(self): + self.pptApp.app.Presentations.Open(self.filename, False, False, True) + self._pres = self.pptApp.app.Presentations(ppt.app.Presentations.Count) + + def close(self): + self.pres.Close() + self._pres = None + + def isActive(self): + if self.pres.SlideShowWindow == None: + return False + if self.pres.SlideShowWindow.View == None: + return False + return True + + def resume(self): + self.pres.SlideShowSettings.Run() + self.pres.SlideShowWindow.View.State = 1 + self.pres.SlideShowWindow.Activate() + + def pause(self): + if self.isActive(): + self.pres.SlideShowWindow.View.State = 2 + + def blankScreen(self): + if self.isActive(): + self.pres.SlideShowWindow.View.State = 3 + + def stop(self): + if self.isActive(): + self.pres.SlideShowWindow.View.Exit() + + def go(self): + self.pres.SlideShowSettings.Run() + + def getCurrentSlideIndex(self): + if self.isActive(): + return self.pres.SlideShowWindow.View.CurrentShowPosition + else: + return -1 + + def setCurrentSlideIndex(self, slideno): + if not self.isActive(): + self.resume() + self.pres.SlideShowWindow.View.GotoSlide(slideno) + + currentSlideIndex = property(getSlideNumber, setSlideNumber) + + def nextStep(self): + if not self.isActive(): + self.resume() + self.pres.SlideShowWindow.View.Next() + + def prevStep(self): + if not self.isActive(): + self.resume() + self.pres.SlideShowWindow.View.Previous() + + def moveWindow(self, top, height, left, width): + if not self.isActive(): + self.resume() + self.pres.SlideShowWindow.Top = top / 20 + self.pres.SlideShowWindow.Height = height / 20 + self.pres.SlideShowWindow.Left = left / 20 + self.pres.SlideShowWindow.Width = width / 20 + +class PowerPointSlide(object): + def __init__(self, pres, index): + self.pres = pres + self.slide = pres.Slides[index] + + def preview(self): + if self.preview == None: + self.slide.Copy + # import win32clipboard as w + # import win32con + # w.OpenClipboard() + # self.preview = w.GetClipboardData.GetData(win32con.CF_BITMAP) + # w.CloseClipboard() + return self.preview + + diff --git a/openlp/plugins/presentations/lib/pptview.py b/openlp/plugins/presentations/lib/pptview.py new file mode 100644 index 000000000..941223cc2 --- /dev/null +++ b/openlp/plugins/presentations/lib/pptview.py @@ -0,0 +1,126 @@ +import sys +import win32api +from PyQt4 import QtGui, QtCore +from ctypes import * +from ctypes.wintypes import RECT + +pptdll = cdll.LoadLibrary(r"C:\Documents and Settings\jonathan\My Documents\Personal\openlp\openlp-2\trunk\openlp\libraries\pptviewlib\pptviewlib.dll") + +class BoxLayout(QtGui.QWidget): + def __init__(self, parent=None): + QtGui.QWidget.__init__(self, parent) + self.pptid = -1 + self.setWindowTitle('box layout') + + PPTLabel = QtGui.QLabel('Open PowerPoint file') + slideLabel = QtGui.QLabel('Go to slide #') + self.PPTEdit = QtGui.QLineEdit() + self.slideEdit = QtGui.QLineEdit() + self.total = QtGui.QLabel() + PPTBtn = QtGui.QPushButton("Open") + PPTDlgBtn = QtGui.QPushButton("...") + slideBtn = QtGui.QPushButton("Go") + prev = QtGui.QPushButton("Prev") + next = QtGui.QPushButton("Next") + blank = QtGui.QPushButton("Blank") + unblank = QtGui.QPushButton("Unblank") + restart = QtGui.QPushButton("Restart") + close = QtGui.QPushButton("Close") + resume = QtGui.QPushButton("Resume") + stop = QtGui.QPushButton("Stop") + pptwindow = QtGui.QWidget() + + grid = QtGui.QGridLayout() + grid.addWidget(PPTLabel, 0, 0) + grid.addWidget(self.PPTEdit, 0, 1) + grid.addWidget(PPTDlgBtn, 0, 2) + grid.addWidget(PPTBtn, 0, 3) + grid.addWidget(slideLabel, 1, 0) + grid.addWidget(self.slideEdit, 1, 1) + grid.addWidget(slideBtn, 1, 3) + grid.addWidget(prev, 2, 0) + grid.addWidget(next, 2, 1) + grid.addWidget(blank, 3, 0) + grid.addWidget(unblank, 3, 1) + grid.addWidget(restart, 4, 0) + grid.addWidget(stop, 4, 1) + grid.addWidget(resume, 4, 2) + grid.addWidget(pptwindow, 5, 0, 10, 3) + self.connect(PPTBtn, QtCore.SIGNAL('clicked()'), self.OpenClick) + self.connect(PPTDlgBtn, QtCore.SIGNAL('clicked()'), self.OpenDialog) + self.connect(slideBtn, QtCore.SIGNAL('clicked()'), self.GotoClick) + self.connect(prev, QtCore.SIGNAL('clicked()'), self.PrevClick) + self.connect(next, QtCore.SIGNAL('clicked()'), self.NextClick) + self.connect(blank, QtCore.SIGNAL('clicked()'), self.BlankClick) + self.connect(unblank, QtCore.SIGNAL('clicked()'), self.UnblankClick) + self.connect(restart, QtCore.SIGNAL('clicked()'), self.RestartClick) + self.connect(close, QtCore.SIGNAL('clicked()'), self.CloseClick) + self.connect(stop, QtCore.SIGNAL('clicked()'), self.StopClick) + self.connect(resume, QtCore.SIGNAL('clicked()'), self.ResumeClick) + + self.setLayout(grid) + + self.resize(300, 150) + + def PrevClick(self): + if self.pptid<0: return + pptdll.PrevStep(self.pptid) + self.slideEdit.setText(pptdll.GetCurrentSlide(self.pptid)) + + def NextClick(self): + if(self.pptid<0): return + pptdll.NextStep(self.pptid) + self.slideEdit.setText(pptdll.GetCurrentSlide(self.pptid)) + + def BlankClick(self): + if(self.pptid<0): return + pptdll.Blank(self.pptid) + + def UnblankClick(self): + if(self.pptid<0): return + pptdll.Unblank(self.pptid) + + def RestartClick(self): + if(self.pptid<0): return + pptdll.RestartShow(self.pptid) + self.slideEdit.setText(pptdll.GetCurrentSlide(self.pptid)) + + def StopClick(self): + if(self.pptid<0): return + pptdll.Stop(self.pptid) + + def ResumeClick(self): + if(self.pptid<0): return + pptdll.Resume(self.pptid) + + def CloseClick(self): + if(self.pptid<0): return + pptdll.Close(self.pptid) + self.pptid = -1 + + def OpenClick(self): + if(self.pptid>=0): + self.CloseClick() + rect = RECT() + rect.left = 100 + rect.top = 100 + rect.width = 900 + rect.hight = 700 + #self.pptid = pptdll.OpenPPT(self.PPTEdit.text, None, rect, "c:\temp\slide") + self.pptid = pptdll.OpenPPT("C:\\test 1.ppt", None, rect, "c:\temp\slide") + self.total.setText(pptdll.GetSlideCount(self.pptid)) + self.slideEdit.setText(str(pptdll.GetCurrentSlide(self.pptid))) + + def GotoClick(self): + if(self.pptid<0): return + pptdll.GotoSlide(self.pptid, self.slideEdit.text) + self.slideEdit.setText(pptdll.GetCurrentSlide(self.pptid)) + + def OpenDialog(self): + self.PPTEdit.setText(QtGui.QFileDialog.getOpenFileName(self, 'Open file')) + +app = QtGui.QApplication(sys.argv) +qb = BoxLayout() +qb.show() +sys.exit(app.exec_()) + diff --git a/openlp/plugins/presentations/lib/pptviewlib/README.TXT b/openlp/plugins/presentations/lib/pptviewlib/README.TXT new file mode 100644 index 000000000..43954d150 --- /dev/null +++ b/openlp/plugins/presentations/lib/pptviewlib/README.TXT @@ -0,0 +1,116 @@ + +PPTVIEWLIB - Control PowerPoint Viewer 2003/2007 (for openlp.org) +Copyright (C) 2008 Jonathan Corwin (j@corwin.co.uk) + +This library wrappers the free Microsoft PowerPoint Viewer (2003/2007) program, +allowing it to be more easily controlled from another program. + +The PowerPoint Viewer must already be installed on the destination machine, and is +freely available at microsoft.com. + +The full Microsoft Office PowerPoint and PowerPoint Viewer 97 have a COM interface allowing +automation. This ability was removed from the 2003+ viewer offerings. + +To developers: I am not a C/C++ or Win32 API programmer as you can probably tell. +The code and API of this DLL could certainly do with some tidying up, and the +error trapping, where it exists, is very basic. I'll happily accept patches! + +This library is covered by the GPL (http://www.gnu.org/licenses/) +It is NOT covered by the LGPL, so can only be used in GPL compatable programs. +(http://www.gnu.org/licenses/why-not-lgpl.html) + +This README.TXT must be distributed with the pptviewlib.dll + +This library has a limit of 50 PowerPoints which can be opened simultaneously. + +USAGE +----- +int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath); + + Opens the PowerPoint file, counts the number of slides, sizes and positions accordingly + and creates preview images of each slide. Note PowerPoint Viewer only allows the + slideshow to be resized whilst it is being loaded. It can be moved at any time however. + + The only way to count the number of slides is to step through the entire show. Therefore + there will be a delay whilst opening large presentations for the first time. + For pre XP/2003 systems, the slideshow will flicker as the screen snapshots are taken. + + filename: The PowerPoint file to be opened. Full path + hParentWnd: The window which will become the parent of the slideshow window. + Can be NULL. + rect: The location/dimensions of the slideshow window. + If all properties of this structure are zero, the dimensions of the hParentWnd + are used. + previewpath If specified, the prefix to use for snapshot images of each slide, in the + form: previewpath + n + ".bmp", where n is the slide number. + A file called previewpath + "info.txt" will also be created containing information + about the PPT file, to speed up future openings of the unmodified file. + Note it is up the calling program to directly access these images if they + are required. + + RETURNS: An unique identifier to pass to other methods in this library. + If < 0, then the PPT failed to open. + If >=0, ClosePPT must be called when the PPT is no longer being used + or when the calling program is closed to release resources/hooks. + +void ClosePPT(int id); + Closes the presentation, releasing any resources and hooks. + + id: The value returned from OpenPPT. + +int GetCurrentSlide(int id); + Returns the current slide number (from 1) + + id: The value returned from OpenPPT. + +int GetSlideCount(int id); + Returns the total number of slides. + + id: The value returned from OpenPPT. + +void NextStep(int id); + Advances one step (animation) through the slideshow. + + id: The value returned from OpenPPT. + +void PrevStep(int id); + Goes backwards one step (animation) through the slideshow. + + id: The value returned from OpenPPT. + +void GotoSlide(int id, int slideno); + Goes directly to a specific slide in the slideshow + + id: The value returned from OpenPPT. + slideno: The number of the slide (from 1) to go directly to. + + If the slide has already been displayed, then the completed slide with animations performed + will be shown. This is how the PowerPoint Viewer works so have no control over this. + +void RestartShow(int id); + Restarts the show from the beginning. To reset animations, behind the scenes it + has to travel to the end and step backwards though the entire show. Therefore + for large presentations there might be a delay. + + id: The value returned from OpenPPT. + +void Blank(int id); + Blanks the screen, colour black. + + id: The value returned from OpenPPT. + +void Unblank(int id) + Unblanks the screen, restoring it to it's pre-blank state. + + id: The value returned from OpenPPT. + +void Stop(int id) + Moves the slideshow off the screen. (There is no concept of stop show in the PowerPoint Viewer) + + id: The value returned from OpenPPT. + +void Resume(int id) + Moves the slideshow display back onto the screen following a Stop() + + id: The value returned from OpenPPT. + diff --git a/openlp/plugins/presentations/lib/pptviewlib/ppttest.py b/openlp/plugins/presentations/lib/pptviewlib/ppttest.py new file mode 100644 index 000000000..f65e84f52 --- /dev/null +++ b/openlp/plugins/presentations/lib/pptviewlib/ppttest.py @@ -0,0 +1,147 @@ +import sys +from PyQt4 import QtGui, QtCore +from ctypes import * +from ctypes.wintypes import RECT + +class PPTViewer(QtGui.QWidget): + def __init__(self, parent=None): + QtGui.QWidget.__init__(self, parent) + self.pptid = -1 + self.setWindowTitle('PowerPoint Viewer Test') + + PPTLabel = QtGui.QLabel('Open PowerPoint file') + slideLabel = QtGui.QLabel('Go to slide #') + self.PPTEdit = QtGui.QLineEdit() + self.slideEdit = QtGui.QLineEdit() + self.total = QtGui.QLabel() + PPTBtn = QtGui.QPushButton("Open") + PPTDlgBtn = QtGui.QPushButton("...") + slideBtn = QtGui.QPushButton("Go") + prev = QtGui.QPushButton("Prev") + next = QtGui.QPushButton("Next") + blank = QtGui.QPushButton("Blank") + unblank = QtGui.QPushButton("Unblank") + restart = QtGui.QPushButton("Restart") + close = QtGui.QPushButton("Close") + resume = QtGui.QPushButton("Resume") + stop = QtGui.QPushButton("Stop") + pptwindow = QtGui.QWidget() + + grid = QtGui.QGridLayout() + grid.addWidget(PPTLabel, 0, 0) + grid.addWidget(self.PPTEdit, 0, 1) + grid.addWidget(PPTDlgBtn, 0, 2) + grid.addWidget(PPTBtn, 0, 3) + grid.addWidget(slideLabel, 1, 0) + grid.addWidget(self.slideEdit, 1, 1) + grid.addWidget(slideBtn, 1, 3) + grid.addWidget(prev, 2, 0) + grid.addWidget(next, 2, 1) + grid.addWidget(blank, 3, 0) + grid.addWidget(unblank, 3, 1) + grid.addWidget(restart, 4, 0) + grid.addWidget(close, 4, 1) + grid.addWidget(stop, 5, 0) + grid.addWidget(resume, 5, 1) + grid.addWidget(pptwindow, 6, 0, 10, 3) + self.connect(PPTBtn, QtCore.SIGNAL('clicked()'), self.OpenClick) + self.connect(PPTDlgBtn, QtCore.SIGNAL('clicked()'), self.OpenDialog) + self.connect(slideBtn, QtCore.SIGNAL('clicked()'), self.GotoClick) + self.connect(prev, QtCore.SIGNAL('clicked()'), self.PrevClick) + self.connect(next, QtCore.SIGNAL('clicked()'), self.NextClick) + self.connect(blank, QtCore.SIGNAL('clicked()'), self.BlankClick) + self.connect(unblank, QtCore.SIGNAL('clicked()'), self.UnblankClick) + self.connect(restart, QtCore.SIGNAL('clicked()'), self.RestartClick) + self.connect(close, QtCore.SIGNAL('clicked()'), self.CloseClick) + self.connect(stop, QtCore.SIGNAL('clicked()'), self.StopClick) + self.connect(resume, QtCore.SIGNAL('clicked()'), self.ResumeClick) + + self.setLayout(grid) + + self.resize(300, 150) + + def PrevClick(self): + if self.pptid<0: return + pptdll.PrevStep(self.pptid) + self.UpdateCurrSlide() + app.processEvents() + + def NextClick(self): + if(self.pptid<0): return + pptdll.NextStep(self.pptid) + self.UpdateCurrSlide() + app.processEvents() + + def BlankClick(self): + if(self.pptid<0): return + pptdll.Blank(self.pptid) + app.processEvents() + + def UnblankClick(self): + if(self.pptid<0): return + pptdll.Unblank(self.pptid) + app.processEvents() + + def RestartClick(self): + if(self.pptid<0): return + pptdll.RestartShow(self.pptid) + self.UpdateCurrSlide() + app.processEvents() + + def StopClick(self): + if(self.pptid<0): return + pptdll.Stop(self.pptid) + app.processEvents() + + def ResumeClick(self): + if(self.pptid<0): return + pptdll.Resume(self.pptid) + app.processEvents() + + def CloseClick(self): + if(self.pptid<0): return + pptdll.ClosePPT(self.pptid) + self.pptid = -1 + app.processEvents() + + def OpenClick(self): + oldid = self.pptid; + rect = RECT(100,100,900,700) + filename = str(self.PPTEdit.text()) + print filename + self.pptid = pptdll.OpenPPT(filename, None, rect, "c:\\temp\\slide") + print "id: " + str(self.pptid) + if oldid>=0: + pptdll.ClosePPT(oldid); + slides = pptdll.GetSlideCount(self.pptid) + print "slidecount: " + str(slides) + self.total.setNum(pptdll.GetSlideCount(self.pptid)) + self.UpdateCurrSlide() + + def UpdateCurrSlide(self): + if(self.pptid<0): return + slide = str(pptdll.GetCurrentSlide(self.pptid)) + print "currslide: " + slide + self.slideEdit.setText(slide) + app.processEvents() + + def GotoClick(self): + if(self.pptid<0): return + print self.slideEdit.text() + pptdll.GotoSlide(self.pptid, int(self.slideEdit.text())) + self.UpdateCurrSlide() + app.processEvents() + + def OpenDialog(self): + self.PPTEdit.setText(QtGui.QFileDialog.getOpenFileName(self, 'Open file')) + +if __name__ == '__main__': + #pptdll = cdll.LoadLibrary(r"C:\Documents and Settings\jonathan\Desktop\pptviewlib.dll") + pptdll = cdll.LoadLibrary(r"pptviewlib.dll") + pptdll.SetDebug(1) + print "Begin..." + app = QtGui.QApplication(sys.argv) + qb = PPTViewer() + qb.show() + sys.exit(app.exec_()) + diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp new file mode 100644 index 000000000..4e5d8cfd8 --- /dev/null +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp @@ -0,0 +1,753 @@ +/* + * PPTVIEWLIB - Control PowerPoint Viewer 2003/2007 (for openlp.org) + * Copyright (C) 2008 Jonathan Corwin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include +#include "pptviewlib.h" + +// Because of the callbacks used by SetWindowsHookEx, the memory used needs to be +// sharable across processes (the callbacks are done from a different process) +// Therefore use data_seg with RWS memory. +// +// See http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx for alternative +// method of holding memory, removing fixed limits which would allow dynamic number +// of items, rather than a fixed number. Use a Local\ mapping, since global has UAC +// issues in Vista. +#pragma data_seg(".PPTVIEWLIB") +PPTVIEWOBJ pptviewobj[MAX_PPTOBJS] = {NULL}; +HHOOK globalhook = NULL; +BOOL debug = FALSE; +#pragma data_seg() +#pragma comment(linker, "/SECTION:.PPTVIEWLIB,RWS") + +#define DEBUG(...) if(debug) printf(__VA_ARGS__) + + +HINSTANCE hInstance = NULL; + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + hInstance = (HINSTANCE)hModule; + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + DEBUG("PROCESS_ATTACH\n"); + break; + case DLL_THREAD_ATTACH: + DEBUG("THREAD_ATTACH\n"); + break; + case DLL_THREAD_DETACH: + DEBUG("THREAD_DETACH\n"); + break; + case DLL_PROCESS_DETACH: + // Clean up... hopefully there is only the one process attached? + // We'll find out soon enough during tests! + DEBUG("PROCESS_DETACH\n"); + for(int i = 0; i.bmp" will be appended to complete the path. E.g. "c:\temp\slide" would +// create "c:\temp\slide1.bmp" slide2.bmp, slide3.bmp etc. +// It will also create a *info.txt containing information about the ppt +DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath) +{ + STARTUPINFO si; + PROCESS_INFORMATION pi; + char cmdline[MAX_PATH * 2]; + int id; + + DEBUG("OpenPPT start: %s; %s\n", filename, previewpath); + DEBUG("OpenPPT start: %u; %i, %i, %i, %i\n", hParentWnd, rect.top, rect.left, rect.bottom, rect.right); + if(GetPPTViewerPath(cmdline, sizeof(cmdline))==FALSE) + { + DEBUG("OpenPPT: GetPPTViewerPath failed\n"); + return -1; + } + id = -1; + for(int i = 0; ibottom-wndrect->top; + pptviewobj[id].rect.right = wndrect->right-wndrect->left; + } + else + { + pptviewobj[id].rect.top = rect.top; + pptviewobj[id].rect.left = rect.left; + pptviewobj[id].rect.bottom = rect.bottom; + pptviewobj[id].rect.right = rect.right; + } + strcat_s(cmdline, MAX_PATH * 2, "/S \""); + strcat_s(cmdline, MAX_PATH * 2, filename); + strcat_s(cmdline, MAX_PATH * 2, "\""); + memset(&si, 0, sizeof(si)); + memset(&pi, 0, sizeof(pi)); + BOOL gotinfo = GetPPTInfo(id); + /* + * I'd really like to just hook on the new threadid. However this always gives + * error 87. Perhaps I'm hooking to soon? No idea... however can't wait + * since I need to ensure I pick up the WM_CREATE as this is the only + * time the window can be resized in such away the content scales correctly + * + * hook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,pi.dwThreadId); + */ + if(globalhook!=NULL) + UnhookWindowsHookEx(globalhook); + globalhook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,NULL); + if(globalhook==0) + { + DEBUG("OpenPPT: SetWindowsHookEx failed\n"); + ClosePPT(id); + return -1; + } + pptviewobj[id].state = PPT_STARTED; + Sleep(10); + if(!CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) + { + DEBUG("OpenPPT: CreateProcess failed\n"); + ClosePPT(id); + return -1; + } + pptviewobj[id].dwProcessId = pi.dwProcessId; + pptviewobj[id].dwThreadId = pi.dwThreadId; + pptviewobj[id].hThread = pi.hThread; + pptviewobj[id].hProcess = pi.hProcess; + while(pptviewobj[id].state==PPT_STARTED) + Sleep(10); + if(gotinfo) + { + DEBUG("OpenPPT: Info loaded, no refresh\n"); + pptviewobj[id].state = PPT_LOADED; + Resume(id); + } + else + { + DEBUG("OpenPPT: Get info\n"); + pptviewobj[id].steps = 0; + int steps = 0; + while(pptviewobj[id].state==PPT_OPENED) + { + if(steps<=pptviewobj[id].steps) + { + Sleep(20); + DEBUG("OpenPPT: Step %d/%d\n",steps,pptviewobj[id].steps); + steps++; + NextStep(id); + } + Sleep(10); + } + DEBUG("OpenPPT: Steps %d, first slide steps %d\n",pptviewobj[id].steps,pptviewobj[id].firstSlideSteps); + SavePPTInfo(id); + if(pptviewobj[id].state==PPT_CLOSING){ + ClosePPT(id); + id=-1; + } + else + RestartShow(id); + } + if(id>=0) + { + if(pptviewobj[id].mhook!=NULL) + UnhookWindowsHookEx(pptviewobj[id].mhook); + pptviewobj[id].mhook = NULL; + } + DEBUG("OpenPPT: Exit: id=%i\n", id); + return id; +} +// Load information about the ppt from an info.txt file. +// Format: +// version +// filedate +// filesize +// slidecount +// first slide steps +BOOL GetPPTInfo(int id) +{ + struct _stat filestats; + char info[MAX_PATH]; + FILE* pFile; + char buf[100]; + + DEBUG("GetPPTInfo: start\n"); + if(_stat(pptviewobj[id].filename, &filestats)!=0) + return FALSE; + sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath); + int err = fopen_s(&pFile, info, "r"); + if(err!=0) + { + DEBUG("GetPPTInfo: file open failed - %d\n", err); + return FALSE; + } + fgets(buf, 100, pFile); // version == 1 + fgets(buf, 100, pFile); + if(filestats.st_mtime!=atoi(buf)) + { + fclose (pFile); + return FALSE; + } + fgets(buf, 100, pFile); + if(filestats.st_size!=atoi(buf)) + { + fclose (pFile); + return FALSE; + } + fgets(buf, 100, pFile); // slidecount + int slidecount = atoi(buf); + fgets(buf, 100, pFile); // first slide steps + int firstslidesteps = atoi(buf); + // check all the preview images still exist + for(int i = 1; i<=slidecount; i++) + { + sprintf_s(info, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, i); + if(GetFileAttributes(info)==INVALID_FILE_ATTRIBUTES) + return FALSE; + } + fclose(pFile); + pptviewobj[id].slideCount = slidecount; + pptviewobj[id].firstSlideSteps = firstslidesteps; + DEBUG("GetPPTInfo: exit ok\n"); + return TRUE; +} + +BOOL SavePPTInfo(int id) +{ + struct _stat filestats; + char info[MAX_PATH]; + FILE* pFile; + + DEBUG("SavePPTInfo: start\n"); + if(_stat(pptviewobj[id].filename, &filestats)!=0) + { + DEBUG("SavePPTInfo: stat of %s failed\n", pptviewobj[id].filename); + return FALSE; + } + sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath); + int err = fopen_s(&pFile, info, "w"); + if(err!=0) + { + DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err); + return FALSE; + } + fprintf(pFile, "1\n"); + fprintf(pFile, "%u\n", filestats.st_mtime); + fprintf(pFile, "%u\n", filestats.st_size); + fprintf(pFile, "%u\n", pptviewobj[id].slideCount); + fprintf(pFile, "%u\n", pptviewobj[id].firstSlideSteps); + fclose (pFile); + DEBUG("SavePPTInfo: exit ok\n"); + return TRUE; +} + +// Get the path of the PowerPoint viewer from the registry +BOOL GetPPTViewerPath(char *pptviewerpath, int strsize) +{ + HKEY hkey; + DWORD dwtype, dwsize; + LRESULT lresult; + + DEBUG("GetPPTViewerPath: start\n"); + if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS) + if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\Show\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS) + return FALSE; + dwtype = REG_SZ; + dwsize = (DWORD)strsize; + lresult = RegQueryValueEx(hkey, NULL, NULL, &dwtype, (LPBYTE)pptviewerpath, &dwsize ); + RegCloseKey(hkey); + if(lresult!=ERROR_SUCCESS) + return FALSE; + pptviewerpath[strlen(pptviewerpath)-4] = '\0'; // remove "%1" from end of key value + DEBUG("GetPPTViewerPath: exit ok\n"); + return TRUE; +} + +// Unhook the Windows hook +void Unhook(int id) +{ + DEBUG("Unhook: start %d\n", id); + if(pptviewobj[id].hook!=NULL) + UnhookWindowsHookEx(pptviewobj[id].hook); + if(pptviewobj[id].mhook!=NULL) + UnhookWindowsHookEx(pptviewobj[id].mhook); + pptviewobj[id].hook = NULL; + pptviewobj[id].mhook = NULL; + DEBUG("Unhook: exit ok\n"); +} + +// Close the PowerPoint viewer, release resources +DllExport void ClosePPT(int id) +{ + DEBUG("ClosePPT: start%d\n", id); + pptviewobj[id].state = PPT_CLOSED; + Unhook(id); + if(pptviewobj[id].hWnd==0) + TerminateThread(pptviewobj[id].hThread, 0); + else + PostMessage(pptviewobj[id].hWnd, WM_CLOSE, 0, 0); + CloseHandle(pptviewobj[id].hThread); + CloseHandle(pptviewobj[id].hProcess); + memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ)); + DEBUG("ClosePPT: exit ok\n"); + return; +} +// Moves the show back onto the display +DllExport void Resume(int id) +{ + DEBUG("Resume: %d\n", id); + MoveWindow(pptviewobj[id].hWnd, pptviewobj[id].rect.left, pptviewobj[id].rect.top, + pptviewobj[id].rect.right - pptviewobj[id].rect.left, + pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE); + Unblank(id); +} +// Moves the show off the screen so it can't be seen +DllExport void Stop(int id) +{ + DEBUG("Stop:%d\n", id); + MoveWindow(pptviewobj[id].hWnd, -32000, -32000, + pptviewobj[id].rect.right - pptviewobj[id].rect.left, + pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE); +} + +// Return the total number of slides +DllExport int GetSlideCount(int id) +{ + DEBUG("GetSlideCount:%d\n", id); + if(pptviewobj[id].state==0) + return -1; + else + return pptviewobj[id].slideCount; +} + +// Return the number of the slide currently viewing +DllExport int GetCurrentSlide(int id) +{ + DEBUG("GetCurrentSlide:%d\n", id); + if(pptviewobj[id].state==0) + return -1; + else + return pptviewobj[id].currentSlide; +} + +// Take a step forwards through the show +DllExport void NextStep(int id) +{ + DEBUG("NextStep:%d\n", id); + if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) + return; + PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, -WHEEL_DELTA), 0); +} + +// Take a step backwards through the show +DllExport void PrevStep(int id) +{ + DEBUG("PrevStep:%d\n", id); + PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), 0); +} + +// Blank the show (black screen) +DllExport void Blank(int id) +{ + // B just toggles blank on/off. However pressing any key unblanks. + // So send random unmapped letter first (say 'A'), then we can + // better guarantee B will blank instead of trying to guess + // whether it was already blank or not. + DEBUG("Blank:%d\n", id); + HWND h1 = GetForegroundWindow(); + HWND h2 = GetFocus(); + SetForegroundWindow(pptviewobj[id].hWnd); + SetFocus(pptviewobj[id].hWnd); + Sleep(50); // slight pause, otherwise event triggering this call may grab focus back! + keybd_event((int)'A', 0, 0, 0); + keybd_event((int)'A', 0, KEYEVENTF_KEYUP, 0); + keybd_event((int)'B', 0, 0, 0); + keybd_event((int)'B', 0, KEYEVENTF_KEYUP, 0); + SetForegroundWindow(h1); + SetFocus(h2); + //PostMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, 'B', 0x00300001); + //PostMessage(pptviewobj[id].hWnd2, WM_CHAR, 'b', 0x00300001); + //PostMessage(pptviewobj[id].hWnd2, WM_KEYUP, 'B', 0xC0300001); +} +// Unblank the show +DllExport void Unblank(int id) +{ + DEBUG("Unblank:%d\n", id); + // Pressing any key resumes. + // For some reason SendMessage works for unblanking, but not blanking. +// SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, 'A', 0); + SendMessage(pptviewobj[id].hWnd2, WM_CHAR, 'A', 0); +// SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, 'A', 0); +// HWND h1 = GetForegroundWindow(); +// HWND h2 = GetFocus(); +// Sleep(50); // slight pause, otherwise event triggering this call may grab focus back! +// SetForegroundWindow(pptviewobj[id].hWnd); +// SetFocus(pptviewobj[id].hWnd); +// keybd_event((int)'A', 0, 0, 0); +// SetForegroundWindow(h1); +// SetFocus(h2); +} + +// Go directly to a slide +DllExport void GotoSlide(int id, int slideno) +{ + DEBUG("GotoSlide %i %i:\n", id, slideno); + // Did try WM_KEYDOWN/WM_CHAR/WM_KEYUP with SendMessage but didn't work + // perhaps I was sending to the wrong window? No idea. + // Anyway fall back to keybd_event, which is OK as long we makesure + // the slideshow has focus first + char ch[10]; + + if(slideno<0) return; + _itoa_s(slideno, ch, 10, 10); + HWND h1 = GetForegroundWindow(); + HWND h2 = GetFocus(); + SetForegroundWindow(pptviewobj[id].hWnd); + SetFocus(pptviewobj[id].hWnd); + Sleep(50); // slight pause, otherwise event triggering this call may grab focus back! + for(int i=0;i<10;i++) + { + if(ch[i]=='\0') break; + keybd_event((BYTE)ch[i], 0, 0, 0); + keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0); + } + keybd_event(VK_RETURN, 0, 0, 0); + keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0); + SetForegroundWindow(h1); + SetFocus(h2); + + //for(int i=0;i<10;i++) + //{ + // if(ch[i]=='\0') break; + // SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, ch[i], 0); + // SendMessage(pptviewobj[id].hWnd2, WM_CHAR, ch[i], 0); + // SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, ch[i], 0); + //} + //SendMessage(pptviewobj[id].hWnd2, WM_KEYDOWN, VK_RETURN, 0); + //SendMessage(pptviewobj[id].hWnd2, WM_CHAR, VK_RETURN, 0); + //SendMessage(pptviewobj[id].hWnd2, WM_KEYUP, VK_RETURN, 0); + //keybd_event(VK_RETURN, 0, 0, 0); +} + +// Restart the show from the beginning +DllExport void RestartShow(int id) +{ + // If we just go direct to slide one, then it remembers that all other slides have + // been animated, so ends up just showing the completed slides of those slides that + // have been animated next time we advance. + // Only way I've found to get around this is to step backwards all the way through. + // Lets move the window out of the way first so the audience doesn't see this. + DEBUG("RestartShow:%d\n", id); + Stop(id); + GotoSlide(id, pptviewobj[id].slideCount); + while(pptviewobj[id].currentSlide>1) + { + PrevStep(id); + Sleep(10); + } + for(int i=0;i<=pptviewobj[id].firstSlideSteps;i++) + { + PrevStep(id); + Sleep(10); + } + Resume(id); +} + +// This hook is started with the PPTVIEW.EXE process and waits for the +// WM_CREATEWND message. At this point (and only this point) can the +// window be resized to the correct size. +// Release the hook as soon as we're complete to free up resources +LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + HHOOK hook = globalhook; + if(nCode==HCBT_CREATEWND) + { + char csClassName[16]; + HWND hCurrWnd = (HWND)wParam; + DWORD retProcId = NULL; + GetClassName(hCurrWnd, csClassName, sizeof(csClassName)); + if((strcmp(csClassName, "paneClassDC")==0) + ||(strcmp(csClassName, "screenClass")==0)) + { + int id=-1; + DWORD windowthread = GetWindowThreadProcessId(hCurrWnd,NULL); + for(int i=0; i=0) + { + if(strcmp(csClassName, "paneClassDC")==0) + pptviewobj[id].hWnd2=hCurrWnd; + else + { + pptviewobj[id].hWnd=hCurrWnd; + CBT_CREATEWND* cw = (CBT_CREATEWND*)lParam; + if(pptviewobj[id].hParentWnd!=NULL) + cw->lpcs->hwndParent = pptviewobj[id].hParentWnd; + cw->lpcs->cy=(pptviewobj[id].rect.bottom-pptviewobj[id].rect.top); + cw->lpcs->cx=(pptviewobj[id].rect.right-pptviewobj[id].rect.left); + cw->lpcs->y=-32000; + cw->lpcs->x=-32000; + } + if((pptviewobj[id].hWnd!=NULL)&&(pptviewobj[id].hWnd2!=NULL)) + { + UnhookWindowsHookEx(globalhook); + globalhook=NULL; + pptviewobj[id].hook = SetWindowsHookEx(WH_CALLWNDPROC,CwpProc,hInstance,pptviewobj[id].dwThreadId); + pptviewobj[id].mhook = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInstance,pptviewobj[id].dwThreadId); + Sleep(10); + pptviewobj[id].state = PPT_OPENED; + } + } + } + } + return CallNextHookEx(hook,nCode,wParam,lParam); +} + +// This hook exists whilst the slideshow is loading but only listens on the +// slideshows thread. It listens out for mousewheel events +LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + HHOOK hook = NULL; + MSG *pMSG = (MSG *)lParam; + DWORD windowthread = GetWindowThreadProcessId(pMSG->hwnd,NULL); + int id=-1; + for(int i=0; i=0&&nCode==HC_ACTION&&wParam==PM_REMOVE&&pMSG->message==WM_MOUSEWHEEL) + { + if(pptviewobj[id].state!=PPT_LOADED) + { + if(pptviewobj[id].currentSlide==1) + pptviewobj[id].firstSlideSteps++; + pptviewobj[id].steps++; + } + } + return CallNextHookEx(hook, nCode, wParam, lParam); +} +// This hook exists whilst the slideshow is running but only listens on the +// slideshows thread. It listens out for slide changes, message WM_USER+22. +LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){ + CWPSTRUCT *cwp; + cwp = (CWPSTRUCT *)lParam; + HHOOK hook = NULL; + char filename[MAX_PATH]; + + DWORD windowthread = GetWindowThreadProcessId(cwp->hwnd,NULL); + int id=-1; + for(int i=0; i=0)&&(nCode==HC_ACTION)) + { + if(cwp->message==WM_USER+22) + { + if(pptviewobj[id].state != PPT_LOADED) + { + if((pptviewobj[id].currentSlide>0) + && (pptviewobj[id].previewpath!=NULL&&strlen(pptviewobj[id].previewpath)>0)) + { + sprintf_s(filename, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, pptviewobj[id].currentSlide); + CaptureAndSaveWindow(cwp->hwnd, filename); + } + } + if(cwp->wParam==0) + { + if(pptviewobj[id].currentSlide>0) + { + pptviewobj[id].state = PPT_LOADED; + pptviewobj[id].currentSlide = pptviewobj[id].slideCount+1; + } + } + else + { + pptviewobj[id].currentSlide = cwp->wParam - 255; + if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) + pptviewobj[id].slideCount = pptviewobj[id].currentSlide; + } + } + if((pptviewobj[id].state != PPT_CLOSED)&&(cwp->message==WM_CLOSE||cwp->message==WM_QUIT)) + pptviewobj[id].state = PPT_CLOSING; + } + return CallNextHookEx(hook,nCode,wParam,lParam); +} + +VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename) +{ + HBITMAP hBmp; + if ((hBmp = CaptureWindow(hWnd)) == NULL) + return; + + RECT client; + GetClientRect (hWnd, &client); + UINT uiBytesPerRow = 3 * client.right; // RGB takes 24 bits + UINT uiRemainderForPadding; + + if ((uiRemainderForPadding = uiBytesPerRow % sizeof (DWORD)) > 0) + uiBytesPerRow += (sizeof (DWORD) - uiRemainderForPadding); + + UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom; + PBYTE pDataBits; + + if ((pDataBits = new BYTE [uiBytesPerAllRows]) != NULL) + { + BITMAPINFOHEADER bmi = {0}; + BITMAPFILEHEADER bmf = {0}; + + // Prepare to get the data out of HBITMAP: + bmi.biSize = sizeof (bmi); + bmi.biPlanes = 1; + bmi.biBitCount = 24; + bmi.biHeight = client.bottom; + bmi.biWidth = client.right; + + // Get it: + HDC hDC = GetDC (hWnd); + GetDIBits (hDC, hBmp, 0, client.bottom, pDataBits, + (BITMAPINFO*) &bmi, DIB_RGB_COLORS); + ReleaseDC (hWnd, hDC); + + // Fill the file header: + bmf.bfOffBits = sizeof (bmf) + sizeof (bmi); + bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows; + bmf.bfType = 0x4D42; + + // Writing: + FILE* pFile; + int err = fopen_s(&pFile, filename, "wb"); + if (err == 0) + { + fwrite (&bmf, sizeof (bmf), 1, pFile); + fwrite (&bmi, sizeof (bmi), 1, pFile); + fwrite (pDataBits, sizeof (BYTE), uiBytesPerAllRows, pFile); + fclose (pFile); + } + delete [] pDataBits; + } + DeleteObject (hBmp); +} +HBITMAP CaptureWindow (HWND hWnd) { + HDC hDC; + BOOL bOk = FALSE; + HBITMAP hImage = NULL; + + hDC = GetDC (hWnd); + RECT rcClient; + GetClientRect (hWnd, &rcClient); + if ((hImage = CreateCompatibleBitmap (hDC, rcClient.right, rcClient.bottom)) != NULL) + { + HDC hMemDC; + HBITMAP hDCBmp; + + if ((hMemDC = CreateCompatibleDC (hDC)) != NULL) + { + hDCBmp = (HBITMAP) SelectObject (hMemDC, hImage); + HMODULE hLib = LoadLibrary("User32"); + // PrintWindow works for windows outside displayable area + // but was only introduced in WinXP. BitBlt requires the window to be topmost + // and within the viewable area of the display + if(GetProcAddress(hLib, "PrintWindow")==NULL) + { + SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); + BitBlt (hMemDC, 0, 0, rcClient.right, rcClient.bottom, hDC, 0, 0, SRCCOPY); + SetWindowPos(hWnd, HWND_NOTOPMOST, -32000, -32000, 0, 0, SWP_NOSIZE); + } + else + { + PrintWindow(hWnd, hMemDC, 0); + } + SelectObject (hMemDC, hDCBmp); + DeleteDC (hMemDC); + bOk = TRUE; + } + } + ReleaseDC (hWnd, hDC); + if (! bOk) + { + if (hImage) + { + DeleteObject (hImage); + hImage = NULL; + } + } + return hImage; +} diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll new file mode 100644 index 000000000..13ea7d182 Binary files /dev/null and b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll differ diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h new file mode 100644 index 000000000..a40f07cd3 --- /dev/null +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h @@ -0,0 +1,54 @@ + +#define DllExport extern "C" __declspec( dllexport ) + +enum PPTVIEWSTATE { PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, PPT_CLOSING}; + +DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath); +DllExport void ClosePPT(int id); +DllExport int GetCurrentSlide(int id); +DllExport int GetSlideCount(int id); +DllExport void NextStep(int id); +DllExport void PrevStep(int id); +DllExport void GotoSlide(int id, int slideno); +DllExport void RestartShow(int id); +DllExport void Blank(int id); +DllExport void Unblank(int id); +DllExport void Stop(int id); +DllExport void Resume(int id); +DllExport void SetDebug(BOOL onoff); + +LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam); +BOOL GetPPTViewerPath(char *pptviewerpath, int strsize); +HBITMAP CaptureWindow (HWND hWnd); +VOID SaveBitmap (CHAR* filename, HBITMAP hBmp) ; +VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename); +BOOL GetPPTInfo(int id); +BOOL SavePPTInfo(int id); + + +void Unhook(int id); + +#define MAX_PPTOBJS 50 + +struct PPTVIEWOBJ +{ + HHOOK hook; + HHOOK mhook; + HWND hWnd; + HWND hWnd2; + HWND hParentWnd; + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; + RECT rect; + int slideCount; + int currentSlide; + int firstSlideSteps; + int steps; + char filename[MAX_PATH]; + char previewpath[MAX_PATH]; + PPTVIEWSTATE state; +}; \ No newline at end of file diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj new file mode 100644 index 000000000..13a9e4282 --- /dev/null +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.vcproj @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openlp/plugins/presentations/lib/pptviewlib/test.ppt b/openlp/plugins/presentations/lib/pptviewlib/test.ppt new file mode 100644 index 000000000..1d90168b1 Binary files /dev/null and b/openlp/plugins/presentations/lib/pptviewlib/test.ppt differ