Various bits of experimental presentation code I've had lying around

bzr-revno: 206
This commit is contained in:
Jonathan Corwin 2008-12-10 20:40:18 +00:00
parent d90ca07e1c
commit 410702b890
10 changed files with 1656 additions and 0 deletions

View File

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

View File

@ -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

View File

@ -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_())

View File

@ -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.

View File

@ -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_())

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#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<MAX_PPTOBJS; i++)
ClosePPT(i);
break;
}
return TRUE;
}
DllExport void SetDebug(BOOL onoff)
{
printf("SetDebug\n");
debug = onoff;
DEBUG("enabled\n");
}
// Open the PointPoint, count the slides and take a snapshot of each slide
// for use in previews
// previewpath is a prefix for the location to put preview images of each slide.
// "<n>.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; i<MAX_PPTOBJS; i++)
{
if(pptviewobj[i].state==PPT_CLOSED)
{
id=i;
break;
}
}
if(id<0)
{
DEBUG("OpenPPT: Too many PPTs\n");
return -1;
}
memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ));
strcpy_s(pptviewobj[id].filename, MAX_PATH, filename);
strcpy_s(pptviewobj[id].previewpath, MAX_PATH, previewpath);
pptviewobj[id].state = PPT_CLOSED;
pptviewobj[id].slideCount = 0;
pptviewobj[id].currentSlide = 0;
pptviewobj[id].firstSlideSteps = 0;
pptviewobj[id].hParentWnd = hParentWnd;
pptviewobj[id].hWnd = NULL;
pptviewobj[id].hWnd2 = NULL;
if(hParentWnd!=NULL&&rect.top==0&&rect.bottom==0&&rect.left==0&&rect.right==0)
{
LPRECT wndrect = NULL;
GetWindowRect(hParentWnd, wndrect);
pptviewobj[id].rect.top = 0;
pptviewobj[id].rect.left = 0;
pptviewobj[id].rect.bottom = wndrect->bottom-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<MAX_PPTOBJS; i++)
{
if(pptviewobj[i].dwThreadId==windowthread)
{
id=i;
break;
}
}
if(id>=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<MAX_PPTOBJS; i++)
{
if(pptviewobj[i].dwThreadId==windowthread)
{
id=i;
hook = pptviewobj[id].mhook;
break;
}
}
if(id>=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<MAX_PPTOBJS; i++)
{
if(pptviewobj[i].dwThreadId==windowthread)
{
id=i;
hook = pptviewobj[id].hook;
break;
}
}
if((id>=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;
}

View File

@ -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;
};

View File

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="pptviewlib"
ProjectGUID="{04CC20D1-DC5A-4189-8181-4011E3C21DCF}"
RootNamespace="pptviewlib"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PPTVIEWLIB_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
ModuleDefinitionFile=""
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PPTVIEWLIB_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
ModuleDefinitionFile="pptviewlib.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\pptviewlib.cpp"
>
</File>
<File
RelativePath=".\README.TXT"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\pptviewlib.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

Binary file not shown.