From f04964e07343bfc94b5fdd6d06c0c7f8dda21028 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 12 Mar 2011 00:12:52 +0000 Subject: [PATCH 1/7] Song sequence, alert position and make OOo not invisible anymore --- openlp/core/ui/maindisplay.py | 17 +++++++++++++---- openlp/core/utils/__init__.py | 2 +- openlp/plugins/songs/lib/mediaitem.py | 13 ++++++------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 72ebe422a..858383f12 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -181,6 +181,7 @@ class MainDisplay(DisplayWidget): # Wait for the webview to update before displaying text. while not self.webLoaded: Receiver.send_message(u'openlp_process_events') + self.setGeometry(self.screen[u'size']) self.frame.evaluateJavaScript(u'show_text("%s")' % \ slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"')) return self.preview() @@ -192,7 +193,7 @@ class MainDisplay(DisplayWidget): `slide` The slide text to be displayed """ - log.debug(u'alert to display') + log.debug(u'alert to display') if self.height() != self.screen[u'size'].height() \ or not self.isVisible() or self.videoWidget.isVisible(): shrink = True @@ -208,12 +209,18 @@ class MainDisplay(DisplayWidget): else: shrinkItem = self if text: - shrinkItem.resize(self.width(), int(height.toString())) + alert_height = int(height.toString()) + shrinkItem.resize(self.width(), alert_height) shrinkItem.setVisible(True) + if self.alertTab.location == 1: + shrinkItem.move(self.screen[u'size'].left(), + (self.screen[u'size'].height() - alert_height) / 2) + elif self.alertTab.location == 2: + shrinkItem.move(self.screen[u'size'].left(), + self.screen[u'size'].height() - alert_height) else: shrinkItem.setVisible(False) - shrinkItem.resize(self.screen[u'size'].width(), - self.screen[u'size'].height()) + self.setGeometry(self.screen[u'size']) def directImage(self, name, path): """ @@ -243,6 +250,7 @@ class MainDisplay(DisplayWidget): """ Display an image, as is. """ + self.setGeometry(self.screen[u'size']) if image: js = u'show_image("data:image/png;base64,%s");' % image else: @@ -336,6 +344,7 @@ class MainDisplay(DisplayWidget): """ log.debug(u'video') self.webLoaded = True + self.setGeometry(self.screen[u'size']) # We are running a background theme self.override[u'theme'] = u'' self.override[u'video'] = True diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index f3dacee88..0454c35d0 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -384,7 +384,7 @@ def get_uno_command(): Returns the UNO command to launch an openoffice.org instance. """ COMMAND = u'soffice' - OPTIONS = u'-nologo -norestore -minimized -invisible -nofirststartwizard' + OPTIONS = u'-nologo -norestore -minimized -nofirststartwizard' if UNO_CONNECTION_TYPE == u'pipe': CONNECTION = u'"-accept=pipe,name=openlp_pipe;urp;"' else: diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index feabc98b7..a07b5091f 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -166,20 +166,18 @@ class SongMediaItem(MediaManagerItem): or_(Song.search_title.like(u'%' + self.whitespace.sub(u' ', search_keywords.lower()) + u'%'), Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'), - Song.comments.like(u'%' + search_keywords.lower() + u'%')), - Song.search_title.asc()) + Song.comments.like(u'%' + search_keywords.lower() + u'%'))) self.displayResultsSong(search_results) elif search_type == SongSearch.Titles: log.debug(u'Titles Search') search_results = self.parent.manager.get_all_objects(Song, Song.search_title.like(u'%' + self.whitespace.sub(u' ', - search_keywords.lower()) + u'%'), Song.search_title.asc()) + search_keywords.lower()) + u'%')) self.displayResultsSong(search_results) elif search_type == SongSearch.Lyrics: log.debug(u'Lyrics Search') search_results = self.parent.manager.get_all_objects(Song, - Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'), - Song.search_lyrics.asc()) + Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%')) self.displayResultsSong(search_results) elif search_type == SongSearch.Authors: log.debug(u'Authors Search') @@ -190,7 +188,7 @@ class SongMediaItem(MediaManagerItem): elif search_type == SongSearch.Themes: log.debug(u'Theme Search') search_results = self.parent.manager.get_all_objects(Song, - Song.theme_name == search_keywords, Song.search_lyrics.asc()) + Song.theme_name == search_keywords) self.displayResultsSong(search_results) def onSongListLoad(self): @@ -461,4 +459,5 @@ class SongMediaItem(MediaManagerItem): """ Locale aware collation of song titles """ - return locale.strcoll(unicode(song_1.title), unicode(song_2.title)) + return locale.strcoll(unicode(song_1.title.lower()), + unicode(song_2.title.lower())) From 363b49b4909a567380a5b852bac1c5755e1acc5a Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 12 Mar 2011 17:06:26 +0000 Subject: [PATCH 2/7] attempt to detect end of pptviewer pre-load if ppt is set to loop until ESC --- openlp/core/ui/maindisplay.py | 15 +++++++-------- .../presentations/lib/pptviewcontroller.py | 2 +- .../lib/pptviewlib/pptviewlib.cpp | 13 ++++++++++--- .../lib/pptviewlib/pptviewlib.dll | Bin 47104 -> 83968 bytes 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 858383f12..cc578f4c0 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -143,24 +143,23 @@ class MainDisplay(DisplayWidget): if not background_color.isValid(): background_color = QtCore.Qt.white splash_image = QtGui.QImage(image_file) - initialFrame = QtGui.QImage( + self.initialFrame = QtGui.QImage( self.screens.current[u'size'].width(), self.screens.current[u'size'].height(), - QtGui.QImage.Format_ARGB32_Premultiplied) + QtGui.QImage.Format_ARGB32_Premultiplied) painter_image = QtGui.QPainter() - painter_image.begin(initialFrame) - painter_image.fillRect(initialFrame.rect(), background_color) + painter_image.begin(self.initialFrame) + painter_image.fillRect(self.initialFrame.rect(), background_color) painter_image.drawImage( (self.screens.current[u'size'].width() - splash_image.width()) / 2, (self.screens.current[u'size'].height() - splash_image.height()) / 2, splash_image) serviceItem = ServiceItem() - serviceItem.bg_image_bytes = image_to_byte(initialFrame) + serviceItem.bg_image_bytes = image_to_byte(self.initialFrame) self.webView.setHtml(build_html(serviceItem, self.screen, self.alertTab, self.isLive, None)) - self.initialFrame = True - self.__hideMouse() + self.__hideMouse() # To display or not to display? if not self.screen[u'primary']: self.show() @@ -422,7 +421,7 @@ class MainDisplay(DisplayWidget): """ log.debug(u'buildHtml') self.webLoaded = False - self.initialFrame = False + self.initialFrame = None self.serviceItem = serviceItem background = None # We have an image override so keep the image till the theme changes diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index 0900d1d9d..d9c473ac0 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -84,7 +84,7 @@ class PptviewController(PresentationController): dllpath = os.path.join(self.plugin.pluginManager.basepath, u'presentations', u'lib', u'pptviewlib', u'pptviewlib.dll') self.process = cdll.LoadLibrary(dllpath) - #self.process.SetDebug(1) + self.process.SetDebug(1) def kill(self): """ diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp index 86876a836..54ff53108 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp @@ -404,7 +404,7 @@ DllExport int GetCurrentSlide(int id) // Take a step forwards through the show DllExport void NextStep(int id) { - DEBUG("NextStep:%d\n", id); + DEBUG("NextStep:%d (%d)\n", id, pptviewobj[id].currentSlide); if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) return; PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, -WHEEL_DELTA), 0); @@ -413,7 +413,7 @@ DllExport void NextStep(int id) // Take a step backwards through the show DllExport void PrevStep(int id) { - DEBUG("PrevStep:%d\n", id); + DEBUG("PrevStep:%d (%d)\n", id, pptviewobj[id].currentSlide); PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), 0); } @@ -630,7 +630,7 @@ LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){ if((id>=0)&&(nCode==HC_ACTION)) { if(cwp->message==WM_USER+22) - { + { if(pptviewobj[id].state != PPT_LOADED) { if((pptviewobj[id].currentSlide>0) @@ -651,6 +651,13 @@ LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){ else { pptviewobj[id].currentSlide = cwp->wParam - 255; + if(pptviewobj[id].state != PPT_LOADED) + { + if(pptviewobj[id].currentSlidepptviewobj[id].slideCount) pptviewobj[id].slideCount = pptviewobj[id].currentSlide; } diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll index f8a0de0d33e562014629fc97d25cc11103695e55..d0b8727f0f9483a7870a152786c411c019998868 100644 GIT binary patch literal 83968 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 literal 47104 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 From 23b9884775cd204bd28a8b543abce4e3e15160ac Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sat, 12 Mar 2011 19:00:23 +0000 Subject: [PATCH 3/7] soffice -nodefault --- openlp/core/utils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 0454c35d0..e1fd333a1 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -384,7 +384,7 @@ def get_uno_command(): Returns the UNO command to launch an openoffice.org instance. """ COMMAND = u'soffice' - OPTIONS = u'-nologo -norestore -minimized -nofirststartwizard' + OPTIONS = u'-nologo -norestore -minimized -nodefault -nofirststartwizard' if UNO_CONNECTION_TYPE == u'pipe': CONNECTION = u'"-accept=pipe,name=openlp_pipe;urp;"' else: From e8de37f7b350f6c7028c14c06d3c8bb075da9ef7 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sun, 13 Mar 2011 23:18:19 +0000 Subject: [PATCH 4/7] pptviewer mods --- .../presentations/lib/pptviewcontroller.py | 2 + .../lib/pptviewlib/pptviewlib.cpp | 472 +++++++++++------- .../lib/pptviewlib/pptviewlib.dll | Bin 83968 -> 78848 bytes .../presentations/lib/pptviewlib/pptviewlib.h | 9 +- 4 files changed, 293 insertions(+), 190 deletions(-) diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index d9c473ac0..b97d22c03 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -140,8 +140,10 @@ class PptviewDocument(PresentationDocument): PPTviewLib creates large BMP's, but we want small PNG's for consistency. Convert them here. """ + log.debug(u'create_thumbnails') if self.check_thumbnails(): return + log.debug(u'create_thumbnails proceeding') for idx in range(self.get_slide_count()): path = u'%s\\slide%s.bmp' % (self.get_temp_folder(), unicode(idx + 1)) diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp index 54ff53108..de22e2d41 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp @@ -48,30 +48,28 @@ BOOL debug = FALSE; HINSTANCE hInstance = NULL; -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) +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) +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; - } + DEBUG("OpenPPT start: %u; %i, %i, %i, %i\n", hParentWnd, rect.top, + rect.left, rect.bottom, rect.right); id = -1; - for(int i = 0; i=0) - { - if(pptviewobj[id].mhook!=NULL) - UnhookWindowsHookEx(pptviewobj[id].mhook); - pptviewobj[id].mhook = NULL; - } - DEBUG("OpenPPT: Exit: id=%i\n", id); - return id; + return TRUE; } + // Load information about the ppt from an info.txt file. // Format: // version @@ -242,26 +273,26 @@ BOOL GetPPTInfo(int id) char buf[100]; DEBUG("GetPPTInfo: start\n"); - if(_stat(pptviewobj[id].filename, &filestats)!=0) + 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) + 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)) + if(filestats.st_mtime != atoi(buf)) { fclose (pFile); return FALSE; } fgets(buf, 100, pFile); - if(filestats.st_size!=atoi(buf)) + if(filestats.st_size != atoi(buf)) { - fclose (pFile); + fclose(pFile); return FALSE; } fgets(buf, 100, pFile); // slidecount @@ -269,10 +300,11 @@ BOOL GetPPTInfo(int id) 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++) + 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) + sprintf_s(info, MAX_PATH, "%s%i.bmp", + pptviewobj[id].previewpath, i); + if(GetFileAttributes(info) == INVALID_FILE_ATTRIBUTES) return FALSE; } fclose(pFile); @@ -289,18 +321,22 @@ BOOL SavePPTInfo(int id) FILE* pFile; DEBUG("SavePPTInfo: start\n"); - if(_stat(pptviewobj[id].filename, &filestats)!=0) + 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) + if(err != 0) { DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err); return FALSE; } + else + { + DEBUG("SavePPTInfo: fopen of %s succeeded\n", info); + } fprintf(pFile, "1\n"); fprintf(pFile, "%u\n", filestats.st_mtime); fprintf(pFile, "%u\n", filestats.st_size); @@ -319,15 +355,28 @@ BOOL GetPPTViewerPath(char *pptviewerpath, int strsize) LRESULT lresult; DEBUG("GetPPTViewerPath: start\n"); - if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "PowerPointViewer.Show.12\\shell\\Show\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS) - 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; + if(RegOpenKeyEx(HKEY_CLASSES_ROOT, + "PowerPointViewer.Show.12\\shell\\Show\\command", + 0, KEY_READ, &hkey)!=ERROR_SUCCESS) + { + 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 ); + lresult = RegQueryValueEx(hkey, NULL, NULL, &dwtype, + (LPBYTE)pptviewerpath, &dwsize); RegCloseKey(hkey); - if(lresult!=ERROR_SUCCESS) + if(lresult != ERROR_SUCCESS) return FALSE; pptviewerpath[strlen(pptviewerpath)-4] = '\0'; // remove "%1" from end of key value DEBUG("GetPPTViewerPath: exit ok\n"); @@ -338,9 +387,9 @@ BOOL GetPPTViewerPath(char *pptviewerpath, int strsize) void Unhook(int id) { DEBUG("Unhook: start %d\n", id); - if(pptviewobj[id].hook!=NULL) + if(pptviewobj[id].hook != NULL) UnhookWindowsHookEx(pptviewobj[id].hook); - if(pptviewobj[id].mhook!=NULL) + if(pptviewobj[id].mhook != NULL) UnhookWindowsHookEx(pptviewobj[id].mhook); pptviewobj[id].hook = NULL; pptviewobj[id].mhook = NULL; @@ -353,7 +402,7 @@ DllExport void ClosePPT(int id) DEBUG("ClosePPT: start%d\n", id); pptviewobj[id].state = PPT_CLOSED; Unhook(id); - if(pptviewobj[id].hWnd==0) + if(pptviewobj[id].hWnd == 0) TerminateThread(pptviewobj[id].hThread, 0); else PostMessage(pptviewobj[id].hWnd, WM_CLOSE, 0, 0); @@ -367,9 +416,10 @@ DllExport void ClosePPT(int id) 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); + 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 @@ -377,15 +427,15 @@ 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); + 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) + if(pptviewobj[id].state == 0) return -1; else return pptviewobj[id].slideCount; @@ -395,7 +445,7 @@ DllExport int GetSlideCount(int id) DllExport int GetCurrentSlide(int id) { DEBUG("GetCurrentSlide:%d\n", id); - if(pptviewobj[id].state==0) + if(pptviewobj[id].state == 0) return -1; else return pptviewobj[id].currentSlide; @@ -407,13 +457,17 @@ DllExport void NextStep(int id) DEBUG("NextStep:%d (%d)\n", id, pptviewobj[id].currentSlide); if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) return; - PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, -WHEEL_DELTA), 0); + pptviewobj[id].guess = pptviewobj[id].currentSlide + 1; + 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 (%d)\n", id, pptviewobj[id].currentSlide); + if(pptviewobj[id].currentSlide > 1) + pptviewobj[id].guess = pptviewobj[id].currentSlide - 1; PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), 0); } @@ -469,16 +523,19 @@ DllExport void GotoSlide(int id, int slideno) // the slideshow has focus first char ch[10]; - if(slideno<0) return; + if(slideno < 0) + return; + pptviewobj[id].guess = slideno; _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++) + for(int i = 0; i < 10; i++) { - if(ch[i]=='\0') break; + if(ch[i] == '\0') + break; keybd_event((BYTE)ch[i], 0, 0, 0); keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0); } @@ -511,12 +568,12 @@ DllExport void RestartShow(int id) DEBUG("RestartShow:%d\n", id); Stop(id); GotoSlide(id, pptviewobj[id].slideCount); - while(pptviewobj[id].currentSlide>1) + while(pptviewobj[id].currentSlide > 1) { PrevStep(id); Sleep(10); } - for(int i=0;i<=pptviewobj[id].firstSlideSteps;i++) + for(int i = 0; i <= pptviewobj[id].firstSlideSteps; i++) { PrevStep(id); Sleep(10); @@ -531,53 +588,55 @@ DllExport void RestartShow(int id) LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam) { HHOOK hook = globalhook; - if(nCode==HCBT_CREATEWND) + 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)) + if((strcmp(csClassName, "paneClassDC") == 0) + ||(strcmp(csClassName, "screenClass") == 0)) { - int id=-1; + int id = -1; DWORD windowthread = GetWindowThreadProcessId(hCurrWnd,NULL); - for(int i=0; i=0) + if(id >= 0) { - if(strcmp(csClassName, "paneClassDC")==0) + if(strcmp(csClassName, "paneClassDC") == 0) pptviewobj[id].hWnd2=hCurrWnd; else { - pptviewobj[id].hWnd=hCurrWnd; + pptviewobj[id].hWnd = hCurrWnd; CBT_CREATEWND* cw = (CBT_CREATEWND*)lParam; - if(pptviewobj[id].hParentWnd!=NULL) + 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; + 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)) + 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); + 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); + return CallNextHookEx(hook, nCode, wParam, lParam); } // This hook exists whilst the slideshow is loading but only listens on the @@ -586,22 +645,23 @@ 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; ihwnd, NULL); + int id = -1; + for(int i = 0; i < MAX_PPTOBJS; i++) { - if(pptviewobj[i].dwThreadId==windowthread) + if(pptviewobj[i].dwThreadId == windowthread) { - id=i; + id = i; hook = pptviewobj[id].mhook; break; } } - if(id>=0&&nCode==HC_ACTION&&wParam==PM_REMOVE&&pMSG->message==WM_MOUSEWHEEL) + if(id >= 0 && nCode == HC_ACTION && wParam == PM_REMOVE + && pMSG->message == WM_MOUSEWHEEL) { - if(pptviewobj[id].state!=PPT_LOADED) + if(pptviewobj[id].state != PPT_LOADED) { - if(pptviewobj[id].currentSlide==1) + if(pptviewobj[id].currentSlide == 1) pptviewobj[id].firstSlideSteps++; pptviewobj[id].steps++; } @@ -610,60 +670,94 @@ LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM 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){ +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; ihwnd, NULL); + int id = -1; + for(int i = 0; i < MAX_PPTOBJS; i++) { - if(pptviewobj[i].dwThreadId==windowthread) + if(pptviewobj[i].dwThreadId == windowthread) { - id=i; + id = i; hook = pptviewobj[id].hook; break; } } - if((id>=0)&&(nCode==HC_ACTION)) + if((id >= 0) && (nCode == HC_ACTION)) { - if(cwp->message==WM_USER+22) - { + 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)) + 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); + sprintf_s(filename, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, + pptviewobj[id].currentSlide); CaptureAndSaveWindow(cwp->hwnd, filename); } } - if(cwp->wParam==0) + if(cwp->wParam == 0) { - if(pptviewobj[id].currentSlide>0) + if(pptviewobj[id].currentSlide > 0) { pptviewobj[id].state = PPT_LOADED; - pptviewobj[id].currentSlide = pptviewobj[id].slideCount+1; + pptviewobj[id].currentSlide = pptviewobj[id].slideCount + 1; } } else { - pptviewobj[id].currentSlide = cwp->wParam - 255; if(pptviewobj[id].state != PPT_LOADED) { - if(pptviewobj[id].currentSlidewParam)) { - pptviewobj[id].state = PPT_LOADED; + if(pptviewobj[id].slideNo[1] == cwp->wParam) + { + pptviewobj[id].state = PPT_LOADED; + } + else + { + pptviewobj[id].currentSlide++; + pptviewobj[id].slideCount = pptviewobj[id].currentSlide; + pptviewobj[id].slideNo[pptviewobj[id].currentSlide] = cwp->wParam; + } + } + } + else + { + if(pptviewobj[id].guess > 0 + && pptviewobj[id].slideNo[pptviewobj[id].guess] == 0) + { + pptviewobj[id].currentSlide = 0; + } + for(int i = 1; i < pptviewobj[id].slideCount; i++) + { + if(pptviewobj[id].slideNo[i] == cwp->wParam) + { + pptviewobj[id].currentSlide = i; + break; + } + } + if(pptviewobj[id].currentSlide == 0) + { + pptviewobj[id].slideNo[pptviewobj[id].guess] = cwp->wParam; + pptviewobj[id].currentSlide = pptviewobj[id].guess; } } - 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)) + 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); } @@ -685,26 +779,26 @@ VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename) UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom; PBYTE pDataBits; - if ((pDataBits = new BYTE [uiBytesPerAllRows]) != NULL) + 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.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); + 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.bfOffBits = sizeof(bmf) + sizeof(bmi); bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows; bmf.bfType = 0x4D42; @@ -713,31 +807,33 @@ VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename) 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); + fwrite(&bmf, sizeof(bmf), 1, pFile); + fwrite(&bmi, sizeof(bmi), 1, pFile); + fwrite(pDataBits, sizeof(BYTE), uiBytesPerAllRows, pFile); + fclose(pFile); } delete [] pDataBits; } - DeleteObject (hBmp); + DeleteObject(hBmp); } -HBITMAP CaptureWindow (HWND hWnd) { +HBITMAP CaptureWindow(HWND hWnd) +{ HDC hDC; BOOL bOk = FALSE; HBITMAP hImage = NULL; - hDC = GetDC (hWnd); + hDC = GetDC(hWnd); RECT rcClient; - GetClientRect (hWnd, &rcClient); - if ((hImage = CreateCompatibleBitmap (hDC, rcClient.right, rcClient.bottom)) != NULL) + GetClientRect(hWnd, &rcClient); + if((hImage = CreateCompatibleBitmap(hDC, rcClient.right, rcClient.bottom)) + != NULL) { HDC hMemDC; HBITMAP hDCBmp; - if ((hMemDC = CreateCompatibleDC (hDC)) != NULL) + if((hMemDC = CreateCompatibleDC (hDC)) != NULL) { - hDCBmp = (HBITMAP) SelectObject (hMemDC, hImage); + 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 @@ -757,14 +853,14 @@ HBITMAP CaptureWindow (HWND hWnd) { bOk = TRUE; } } - ReleaseDC (hWnd, hDC); - if (! bOk) + ReleaseDC(hWnd, hDC); + if(!bOk) { if (hImage) { - DeleteObject (hImage); + DeleteObject(hImage); hImage = NULL; } } return hImage; -} +} \ No newline at end of file diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll index d0b8727f0f9483a7870a152786c411c019998868..9c8240636cbf48c43c33e473f722f6420abc948c 100644 GIT binary patch literal 78848 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 E1C)2yFaQ7m literal 83968 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 diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h index 6012b0467..a45f3b4c2 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h @@ -27,11 +27,14 @@ VOID SaveBitmap (CHAR* filename, HBITMAP hBmp) ; VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename); BOOL GetPPTInfo(int id); BOOL SavePPTInfo(int id); - +BOOL InitPPTObject(int id, char *filename, HWND hParentWnd, + RECT rect, char *previewpath); +BOOL StartPPTView(int id); void Unhook(int id); -#define MAX_PPTOBJS 50 +#define MAX_PPTOBJS 16 +#define MAX_SLIDES 256 struct PPTVIEWOBJ { @@ -49,7 +52,9 @@ struct PPTVIEWOBJ int currentSlide; int firstSlideSteps; int steps; + int guess; char filename[MAX_PATH]; char previewpath[MAX_PATH]; + int slideNo[MAX_SLIDES]; PPTVIEWSTATE state; }; From 0b827218bc1a0128a5053d2e95a66c787999ab52 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Tue, 15 Mar 2011 00:10:40 +0000 Subject: [PATCH 5/7] ppt 2010 fix (hopefully). pptviewer tidyups --- .../presentations/lib/messagelistener.py | 3 +- .../presentations/lib/powerpointcontroller.py | 23 +- .../presentations/lib/pptviewcontroller.py | 3 +- .../presentations/lib/pptviewlib/ppttest.py | 2 +- .../lib/pptviewlib/pptviewlib.cpp | 724 +++++++++--------- .../lib/pptviewlib/pptviewlib.dll | Bin 78848 -> 78848 bytes .../presentations/lib/pptviewlib/pptviewlib.h | 61 +- 7 files changed, 431 insertions(+), 385 deletions(-) diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index 4db78f7a5..6554c033a 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -80,7 +80,8 @@ class Controller(object): if self.doc.is_active(): return if not self.doc.is_loaded(): - self.doc.load_presentation() + if not self.doc.load_presentation(): + return if self.is_live: self.doc.start_presentation() if self.doc.slidenumber > 1: diff --git a/openlp/plugins/presentations/lib/powerpointcontroller.py b/openlp/plugins/presentations/lib/powerpointcontroller.py index 4dc9e8f3a..f220f558a 100644 --- a/openlp/plugins/presentations/lib/powerpointcontroller.py +++ b/openlp/plugins/presentations/lib/powerpointcontroller.py @@ -77,8 +77,11 @@ class PowerpointController(PresentationController): """ Loads PowerPoint process """ - self.process = Dispatch(u'PowerPoint.Application') - self.process.Visible = True + log.debug(u'start_process') + if not self.process: + self.process = Dispatch(u'PowerPoint.Application') + if float(self.process.Version) < 13: + self.process.Visible = True self.process.WindowState = 2 def kill(self): @@ -120,13 +123,14 @@ class PowerpointDocument(PresentationDocument): ``presentation`` The file name of the presentations to run. """ - log.debug(u'LoadPresentation') + log.debug(u'load_presentation') if not self.controller.process or not self.controller.process.Visible: self.controller.start_process() try: self.controller.process.Presentations.Open(self.filepath, False, False, True) except pywintypes.com_error: + log.debug(u'PPT open failed') return False self.presentation = self.controller.process.Presentations( self.controller.process.Presentations.Count) @@ -145,6 +149,7 @@ class PowerpointDocument(PresentationDocument): However, for the moment, we want a physical file since it makes life easier elsewhere. """ + log.debug(u'create_thumbnails') if self.check_thumbnails(): return for num in range(0, self.presentation.Slides.Count): @@ -170,6 +175,7 @@ class PowerpointDocument(PresentationDocument): """ Returns ``True`` if a presentation is loaded. """ + log.debug(u'is_loaded') try: if not self.controller.process.Visible: return False @@ -186,6 +192,7 @@ class PowerpointDocument(PresentationDocument): """ Returns ``True`` if a presentation is currently active. """ + log.debug(u'is_active') if not self.is_loaded(): return False try: @@ -201,6 +208,7 @@ class PowerpointDocument(PresentationDocument): """ Unblanks (restores) the presentation. """ + log.debug(u'unblank_screen') self.presentation.SlideShowSettings.Run() self.presentation.SlideShowWindow.View.State = 1 self.presentation.SlideShowWindow.Activate() @@ -209,12 +217,14 @@ class PowerpointDocument(PresentationDocument): """ Blanks the screen. """ + log.debug(u'blank_screen') self.presentation.SlideShowWindow.View.State = 3 def is_blank(self): """ Returns ``True`` if screen is blank. """ + log.debug(u'is_blank') if self.is_active(): return self.presentation.SlideShowWindow.View.State == 3 else: @@ -224,6 +234,7 @@ class PowerpointDocument(PresentationDocument): """ Stops the current presentation and hides the output. """ + log.debug(u'stop_presentation') self.presentation.SlideShowWindow.View.Exit() if os.name == u'nt': @@ -231,6 +242,7 @@ class PowerpointDocument(PresentationDocument): """ Starts a presentation from the beginning. """ + log.debug(u'start_presentation') #SlideShowWindow measures its size/position by points, not pixels try: dpi = win32ui.GetActiveWindow().GetDC().GetDeviceCaps(88) @@ -253,30 +265,35 @@ class PowerpointDocument(PresentationDocument): """ Returns the current slide number. """ + log.debug(u'get_slide_number') return self.presentation.SlideShowWindow.View.CurrentShowPosition def get_slide_count(self): """ Returns total number of slides. """ + log.debug(u'get_slide_count') return self.presentation.Slides.Count def goto_slide(self, slideno): """ Moves to a specific slide in the presentation. """ + log.debug(u'goto_slide') self.presentation.SlideShowWindow.View.GotoSlide(slideno) def next_step(self): """ Triggers the next effect of slide on the running presentation. """ + log.debug(u'next_step') self.presentation.SlideShowWindow.View.Next() def previous_step(self): """ Triggers the previous slide on the running presentation. """ + log.debug(u'previous_step') self.presentation.SlideShowWindow.View.Previous() def get_slide_text(self, slide_no): diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index b97d22c03..e9130ea00 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -84,7 +84,8 @@ class PptviewController(PresentationController): dllpath = os.path.join(self.plugin.pluginManager.basepath, u'presentations', u'lib', u'pptviewlib', u'pptviewlib.dll') self.process = cdll.LoadLibrary(dllpath) - self.process.SetDebug(1) + if log.isEnabledFor(log.DEBUG): + self.process.SetDebug(1) def kill(self): """ diff --git a/openlp/plugins/presentations/lib/pptviewlib/ppttest.py b/openlp/plugins/presentations/lib/pptviewlib/ppttest.py index 1e10def7d..f8d0fabd9 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/ppttest.py +++ b/openlp/plugins/presentations/lib/pptviewlib/ppttest.py @@ -133,7 +133,7 @@ class PPTViewer(QtGui.QWidget): def OpenClick(self): oldid = self.pptid; rect = RECT(100,100,900,700) - filename = unicode(self.PPTEdit.text()) + filename = str(self.PPTEdit.text().replace(u'/', u'\\')) print filename self.pptid = pptdll.OpenPPT(filename, None, rect, 'c:\\temp\\slide') print "id: " + unicode(self.pptid) diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp index de22e2d41..92b849797 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp @@ -27,31 +27,28 @@ #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) +// Because of the callbacks used by SetWindowsHookEx, the memory used needs to +// be sharable across processes (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. +// 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; +PPTVIEW pptviews[MAX_PPTS] = {NULL}; +HHOOK global_hook = NULL; BOOL debug = FALSE; #pragma data_seg() #pragma comment(linker, "/SECTION:.PPTVIEWLIB,RWS") -#define DEBUG(...) if(debug) printf(__VA_ARGS__) +HINSTANCE h_instance = NULL; - -HINSTANCE hInstance = NULL; - -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, - LPVOID lpReserved) +BOOL APIENTRY DllMain(HMODULE h_module, DWORD ul_reason_for_call, + LPVOID lp_reserved) { - hInstance = (HINSTANCE)hModule; + h_instance = (HINSTANCE)h_module; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: @@ -67,25 +64,25 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, // 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) +DllExport int OpenPPT(char *filename, HWND h_parent_wnd, RECT rect, + char *preview_path) { int id; - DEBUG("OpenPPT start: %s; %s\n", filename, previewpath); - DEBUG("OpenPPT start: %u; %i, %i, %i, %i\n", hParentWnd, rect.top, + DEBUG("OpenPPT start: %s; %s\n", filename, preview_path); + DEBUG("OpenPPT start: %u; %i, %i, %i, %i\n", h_parent_wnd, rect.top, rect.left, rect.bottom, rect.right); id = -1; - for(int i = 0; i < MAX_PPTOBJS; i++) + for(int i = 0; i < MAX_PPTS; i++) { - if(pptviewobj[i].state == PPT_CLOSED) + if(pptviews[i].state == PPT_CLOSED) { id = i; break; @@ -116,39 +113,43 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, DEBUG("OpenPPT: Too many PPTs\n"); return -1; } - BOOL gotinfo = InitPPTObject(id, filename, hParentWnd, rect, previewpath); + BOOL got_info = InitPPTObject(id, filename, h_parent_wnd, rect, + preview_path); if(!StartPPTView(id)) { ClosePPT(id); return -1; } - if(!gotinfo) + if(!got_info) { DEBUG("OpenPPT: Get info\n"); - pptviewobj[id].steps = 0; + pptviews[id].steps = 0; int steps = 0; - while(pptviewobj[id].state == PPT_OPENED) + while(pptviews[id].state == PPT_OPENED) { - if(steps <= pptviewobj[id].steps) + if(steps <= pptviews[id].steps) { Sleep(20); - DEBUG("OpenPPT: Step %d/%d\n",steps,pptviewobj[id].steps); + DEBUG("OpenPPT: Step %d/%d\n", steps, pptviews[id].steps); steps++; NextStep(id); } Sleep(10); } DEBUG("OpenPPT: Steps %d, first slide steps %d\n", - pptviewobj[id].steps,pptviewobj[id].firstSlideSteps); + pptviews[id].steps, pptviews[id].first_slide_steps); SavePPTInfo(id); - if(pptviewobj[id].state == PPT_CLOSING || pptviewobj[id].slideCount <= 0) + if(pptviews[id].state == PPT_CLOSING + || pptviews[id].slide_count <= 0) { - // We've gone off the end and pptview is closing. We'll need to start again + // We've gone off the end and pptview is closing. + // We'll need to start again ClosePPT(id); - gotinfo = InitPPTObject(id, filename, hParentWnd, rect, previewpath); - if(gotinfo) - gotinfo = StartPPTView(id); - if(!gotinfo) + got_info = InitPPTObject(id, filename, h_parent_wnd, rect, + preview_path); + if(got_info) + got_info = StartPPTView(id); + if(!got_info) { ClosePPT(id); return -1; @@ -157,55 +158,55 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, else RestartShow(id); } - if(gotinfo) + if(got_info) { DEBUG("OpenPPT: Info loaded, no refresh\n"); - pptviewobj[id].state = PPT_LOADED; + pptviews[id].state = PPT_LOADED; Resume(id); } - if(pptviewobj[id].mhook != NULL) - UnhookWindowsHookEx(pptviewobj[id].mhook); - pptviewobj[id].mhook = NULL; + if(pptviews[id].mhook != NULL) + UnhookWindowsHookEx(pptviews[id].mhook); + pptviews[id].mhook = NULL; DEBUG("OpenPPT: Exit: id=%i\n", id); return id; } -BOOL InitPPTObject(int id, char *filename, HWND hParentWnd, - RECT rect, char *previewpath) +BOOL InitPPTObject(int id, char *filename, HWND h_parent_wnd, + RECT rect, char *preview_path) { - DEBUG("InitPPTObject\n"); - 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].guess = 1; + DEBUG("InitPPTObject %d\n", id); + memset(&pptviews[id], 0, sizeof(pptviews)); + strcpy_s(pptviews[id].filename, MAX_PATH, filename); + strcpy_s(pptviews[id].preview_path, MAX_PATH, preview_path); + pptviews[id].state = PPT_CLOSED; + pptviews[id].slide_count = 0; + pptviews[id].current_slide = 0; + pptviews[id].first_slide_steps = 0; + pptviews[id].guess = 1; for(int i = 0; i < MAX_SLIDES; i++) - pptviewobj[id].slideNo[i] = 0; - pptviewobj[id].hParentWnd = hParentWnd; - pptviewobj[id].hWnd = NULL; - pptviewobj[id].hWnd2 = NULL; - if(hParentWnd != NULL && rect.top == 0 && rect.bottom == 0 + pptviews[id].slide_no[i] = 0; + pptviews[id].h_parent_wnd = h_parent_wnd; + pptviews[id].h_wnd = NULL; + pptviews[id].h_wnd_input = NULL; + if(h_parent_wnd != 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; + LPRECT wnd_rect = NULL; + GetWindowRect(h_parent_wnd, wnd_rect); + pptviews[id].rect.top = 0; + pptviews[id].rect.left = 0; + pptviews[id].rect.bottom = wnd_rect->bottom - wnd_rect->top; + pptviews[id].rect.right = wnd_rect->right - wnd_rect->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; + pptviews[id].rect.top = rect.top; + pptviews[id].rect.left = rect.left; + pptviews[id].rect.bottom = rect.bottom; + pptviews[id].rect.right = rect.right; } - BOOL gotinfo = GetPPTInfo(id); - return gotinfo; + BOOL got_info = GetPPTInfo(id); + return got_info; } BOOL StartPPTView(int id) { @@ -220,40 +221,41 @@ BOOL StartPPTView(int id) DEBUG("StartPPTView\n"); STARTUPINFO si; PROCESS_INFORMATION pi; - char cmdline[MAX_PATH * 2]; + char cmd_line[MAX_PATH * 2]; - if(globalhook != NULL) - UnhookWindowsHookEx(globalhook); - globalhook = SetWindowsHookEx(WH_CBT, CbtProc, hInstance, NULL); - if(globalhook == 0) + if(global_hook != NULL) + UnhookWindowsHookEx(global_hook); + global_hook = SetWindowsHookEx(WH_CBT, CbtProc, h_instance, NULL); + if(global_hook == 0) { DEBUG("OpenPPT: SetWindowsHookEx failed\n"); ClosePPT(id); return FALSE; } - if(GetPPTViewerPath(cmdline, sizeof(cmdline)) == FALSE) + if(GetPPTViewerPath(cmd_line, sizeof(cmd_line)) == FALSE) { DEBUG("OpenPPT: GetPPTViewerPath failed\n"); return FALSE; } - pptviewobj[id].state = PPT_STARTED; + pptviews[id].state = PPT_STARTED; Sleep(10); - strcat_s(cmdline, MAX_PATH * 2, "/F /S \""); - strcat_s(cmdline, MAX_PATH * 2, pptviewobj[id].filename); - strcat_s(cmdline, MAX_PATH * 2, "\""); + strcat_s(cmd_line, MAX_PATH * 2, "/F /S \""); + strcat_s(cmd_line, MAX_PATH * 2, pptviews[id].filename); + strcat_s(cmd_line, MAX_PATH * 2, "\""); memset(&si, 0, sizeof(si)); memset(&pi, 0, sizeof(pi)); - if(!CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) + DEBUG("Command: %s\n", cmd_line); + if(!CreateProcess(NULL, cmd_line, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) { DEBUG("OpenPPT: CreateProcess failed\n"); ClosePPT(id); return FALSE; } - 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) + pptviews[id].dw_process_id = pi.dwProcessId; + pptviews[id].dw_thread_id = pi.dwThreadId; + pptviews[id].h_thread = pi.hThread; + pptviews[id].h_process = pi.hProcess; + while(pptviews[id].state == PPT_STARTED) Sleep(10); return TRUE; } @@ -267,67 +269,67 @@ BOOL StartPPTView(int id) // first slide steps BOOL GetPPTInfo(int id) { - struct _stat filestats; + struct _stat file_stats; char info[MAX_PATH]; - FILE* pFile; + FILE* p_file; char buf[100]; DEBUG("GetPPTInfo: start\n"); - if(_stat(pptviewobj[id].filename, &filestats) != 0) + if(_stat(pptviews[id].filename, &file_stats) != 0) return FALSE; - sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath); - int err = fopen_s(&pFile, info, "r"); + sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviews[id].preview_path); + int err = fopen_s(&p_file, 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)) + fgets(buf, 100, p_file); // version == 1 + fgets(buf, 100, p_file); + if(file_stats.st_mtime != atoi(buf)) { - fclose (pFile); + fclose (p_file); return FALSE; } - fgets(buf, 100, pFile); - if(filestats.st_size != atoi(buf)) + fgets(buf, 100, p_file); + if(file_stats.st_size != atoi(buf)) { - fclose(pFile); + fclose(p_file); return FALSE; } - fgets(buf, 100, pFile); // slidecount - int slidecount = atoi(buf); - fgets(buf, 100, pFile); // first slide steps - int firstslidesteps = atoi(buf); + fgets(buf, 100, p_file); // slidecount + int slide_count = atoi(buf); + fgets(buf, 100, p_file); // first slide steps + int first_slide_steps = atoi(buf); // check all the preview images still exist - for(int i = 1; i <= slidecount; i++) + for(int i = 1; i <= slide_count; i++) { sprintf_s(info, MAX_PATH, "%s%i.bmp", - pptviewobj[id].previewpath, i); + pptviews[id].preview_path, i); if(GetFileAttributes(info) == INVALID_FILE_ATTRIBUTES) return FALSE; } - fclose(pFile); - pptviewobj[id].slideCount = slidecount; - pptviewobj[id].firstSlideSteps = firstslidesteps; + fclose(p_file); + pptviews[id].slide_count = slide_count; + pptviews[id].first_slide_steps = first_slide_steps; DEBUG("GetPPTInfo: exit ok\n"); return TRUE; } BOOL SavePPTInfo(int id) { - struct _stat filestats; + struct _stat file_stats; char info[MAX_PATH]; - FILE* pFile; + FILE* p_file; DEBUG("SavePPTInfo: start\n"); - if(_stat(pptviewobj[id].filename, &filestats) != 0) + if(_stat(pptviews[id].filename, &file_stats) != 0) { - DEBUG("SavePPTInfo: stat of %s failed\n", pptviewobj[id].filename); + DEBUG("SavePPTInfo: stat of %s failed\n", pptviews[id].filename); return FALSE; } - sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath); - int err = fopen_s(&pFile, info, "w"); + sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviews[id].preview_path); + int err = fopen_s(&p_file, info, "w"); if(err != 0) { DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err); @@ -337,48 +339,45 @@ BOOL SavePPTInfo(int id) { DEBUG("SavePPTInfo: fopen of %s succeeded\n", info); } - 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); + fprintf(p_file, "1\n"); + fprintf(p_file, "%u\n", file_stats.st_mtime); + fprintf(p_file, "%u\n", file_stats.st_size); + fprintf(p_file, "%u\n", pptviews[id].slide_count); + fprintf(p_file, "%u\n", pptviews[id].first_slide_steps); + fclose(p_file); DEBUG("SavePPTInfo: exit ok\n"); return TRUE; } // Get the path of the PowerPoint viewer from the registry -BOOL GetPPTViewerPath(char *pptviewerpath, int strsize) +BOOL GetPPTViewerPath(char *pptviewer_path, int str_size) { - HKEY hkey; - DWORD dwtype, dwsize; - LRESULT lresult; + HKEY h_key; + DWORD dw_type, dw_size; + LRESULT l_result; DEBUG("GetPPTViewerPath: start\n"); - if(RegOpenKeyEx(HKEY_CLASSES_ROOT, + if((RegOpenKeyEx(HKEY_CLASSES_ROOT, "PowerPointViewer.Show.12\\shell\\Show\\command", - 0, KEY_READ, &hkey)!=ERROR_SUCCESS) - { - 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) + 0, KEY_READ, &h_key) != ERROR_SUCCESS) + && (RegOpenKeyEx(HKEY_CLASSES_ROOT, + "Applications\\PPTVIEW.EXE\\shell\\open\\command", + 0, KEY_READ, &h_key) != ERROR_SUCCESS) + && (RegOpenKeyEx(HKEY_CLASSES_ROOT, + "Applications\\PPTVIEW.EXE\\shell\\Show\\command", + 0, KEY_READ, &h_key) != ERROR_SUCCESS)) + { + return FALSE; + } + dw_type = REG_SZ; + dw_size = (DWORD)str_size; + l_result = RegQueryValueEx(h_key, NULL, NULL, &dw_type, + (LPBYTE)pptviewer_path, &dw_size); + RegCloseKey(h_key); + if(l_result != ERROR_SUCCESS) return FALSE; - pptviewerpath[strlen(pptviewerpath)-4] = '\0'; // remove "%1" from end of key value + // remove "%1" from the end of the key value + pptviewer_path[strlen(pptviewer_path) - 4] = '\0'; DEBUG("GetPPTViewerPath: exit ok\n"); return TRUE; } @@ -387,12 +386,12 @@ BOOL GetPPTViewerPath(char *pptviewerpath, int strsize) 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; + if(pptviews[id].hook != NULL) + UnhookWindowsHookEx(pptviews[id].hook); + if(pptviews[id].mhook != NULL) + UnhookWindowsHookEx(pptviews[id].mhook); + pptviews[id].hook = NULL; + pptviews[id].mhook = NULL; DEBUG("Unhook: exit ok\n"); } @@ -400,15 +399,15 @@ void Unhook(int id) DllExport void ClosePPT(int id) { DEBUG("ClosePPT: start%d\n", id); - pptviewobj[id].state = PPT_CLOSED; + pptviews[id].state = PPT_CLOSED; Unhook(id); - if(pptviewobj[id].hWnd == 0) - TerminateThread(pptviewobj[id].hThread, 0); + if(pptviews[id].h_wnd == 0) + TerminateThread(pptviews[id].h_thread, 0); else - PostMessage(pptviewobj[id].hWnd, WM_CLOSE, 0, 0); - CloseHandle(pptviewobj[id].hThread); - CloseHandle(pptviewobj[id].hProcess); - memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ)); + PostMessage(pptviews[id].h_wnd, WM_CLOSE, 0, 0); + CloseHandle(pptviews[id].h_thread); + CloseHandle(pptviews[id].h_process); + memset(&pptviews[id], 0, sizeof(pptviews)); DEBUG("ClosePPT: exit ok\n"); return; } @@ -416,59 +415,60 @@ DllExport void ClosePPT(int id) 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); + MoveWindow(pptviews[id].h_wnd, pptviews[id].rect.left, + pptviews[id].rect.top, + pptviews[id].rect.right - pptviews[id].rect.left, + pptviews[id].rect.bottom - pptviews[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); + MoveWindow(pptviews[id].h_wnd, -32000, -32000, + pptviews[id].rect.right - pptviews[id].rect.left, + pptviews[id].rect.bottom - pptviews[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) + if(pptviews[id].state == 0) return -1; else - return pptviewobj[id].slideCount; + return pptviews[id].slide_count; } // Return the number of the slide currently viewing DllExport int GetCurrentSlide(int id) { DEBUG("GetCurrentSlide:%d\n", id); - if(pptviewobj[id].state == 0) + if(pptviews[id].state == 0) return -1; else - return pptviewobj[id].currentSlide; + return pptviews[id].current_slide; } // Take a step forwards through the show DllExport void NextStep(int id) { - DEBUG("NextStep:%d (%d)\n", id, pptviewobj[id].currentSlide); - if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) + DEBUG("NextStep:%d (%d)\n", id, pptviews[id].current_slide); + if(pptviews[id].current_slide > pptviews[id].slide_count) return; - pptviewobj[id].guess = pptviewobj[id].currentSlide + 1; - PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, + pptviews[id].guess = pptviews[id].current_slide + 1; + PostMessage(pptviews[id].h_wnd_input, WM_MOUSEWHEEL, MAKEWPARAM(0, -WHEEL_DELTA), 0); } // Take a step backwards through the show DllExport void PrevStep(int id) { - DEBUG("PrevStep:%d (%d)\n", id, pptviewobj[id].currentSlide); - if(pptviewobj[id].currentSlide > 1) - pptviewobj[id].guess = pptviewobj[id].currentSlide - 1; - PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), 0); + DEBUG("PrevStep:%d (%d)\n", id, pptviews[id].current_slide); + if(pptviews[id].current_slide > 1) + pptviews[id].guess = pptviews[id].current_slide - 1; + PostMessage(pptviews[id].h_wnd_input, WM_MOUSEWHEEL, + MAKEWPARAM(0, WHEEL_DELTA), 0); } // Blank the show (black screen) @@ -481,18 +481,22 @@ DllExport void Blank(int id) 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! + SetForegroundWindow(pptviews[id].h_wnd); + SetFocus(pptviews[id].h_wnd); + // slight pause, otherwise event triggering this call may grab focus back! + Sleep(50); 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); + + // This is the preferred method, but didn't work. Keep it here for + // documentation if we revisit in the future + //PostMessage(pptviews[id].h_wnd_input, WM_KEYDOWN, 'B', 0x00300001); + //PostMessage(pptviews[id].h_wnd_input, WM_CHAR, 'b', 0x00300001); + //PostMessage(pptviews[id].h_wnd_input, WM_KEYUP, 'B', 0xC0300001); } // Unblank the show DllExport void Unblank(int id) @@ -500,38 +504,43 @@ 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); + // However keep the commented code for documentation in case we want + // to revisit later. + + //SendMessage(pptviews[id].h_wnd_input, WM_KEYDOWN, 'A', 0); + SendMessage(pptviews[id].h_wnd_input, WM_CHAR, 'A', 0); + //SendMessage(pptviews[id].h_wnd_input, WM_KEYUP, 'A', 0); + //HWND h1 = GetForegroundWindow(); + //HWND h2 = GetFocus(); + ////slight pause, otherwise event triggering this call may grab focus back! + //Sleep(50); + //SetForegroundWindow(pptviews[id].h_wnd); + //SetFocus(pptviews[id].h_wnd); + //keybd_event((int)'A', 0, 0, 0); + //SetForegroundWindow(h1); + //SetFocus(h2); } // Go directly to a slide -DllExport void GotoSlide(int id, int slideno) +DllExport void GotoSlide(int id, int slide_no) { - DEBUG("GotoSlide %i %i:\n", id, slideno); + DEBUG("GotoSlide %i %i:\n", id, slide_no); // 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) + if(slide_no < 0) return; - pptviewobj[id].guess = slideno; - _itoa_s(slideno, ch, 10, 10); + pptviews[id].guess = slide_no; + _itoa_s(slide_no, 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! + SetForegroundWindow(pptviews[id].h_wnd); + SetFocus(pptviews[id].h_wnd); + // slight pause, otherwise event triggering this call may grab focus back! + Sleep(50); for(int i = 0; i < 10; i++) { if(ch[i] == '\0') @@ -544,36 +553,40 @@ DllExport void GotoSlide(int id, int slideno) SetForegroundWindow(h1); SetFocus(h2); + // I don't know why the below didn't work. + // Kept here as documentation in case we want to try again in the future + // //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(pptviews[id].h_wnd_input, WM_KEYDOWN, ch[i], 0); + // SendMessage(pptviews[id].h_wnd_input, WM_CHAR, ch[i], 0); + // SendMessage(pptviews[id].h_wnd_input, 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); + //SendMessage(pptviews[id].h_wnd_input, WM_KEYDOWN, VK_RETURN, 0); + //SendMessage(pptviews[id].h_wnd_input, WM_CHAR, VK_RETURN, 0); + //SendMessage(pptviews[id].h_wnd_input, 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. + // 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) + GotoSlide(id, pptviews[id].slide_count); + while(pptviews[id].current_slide > 1) { PrevStep(id); Sleep(10); } - for(int i = 0; i <= pptviewobj[id].firstSlideSteps; i++) + for(int i = 0; i <= pptviews[id].first_slide_steps; i++) { PrevStep(id); Sleep(10); @@ -585,23 +598,23 @@ DllExport void RestartShow(int id) // 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) +LRESULT CALLBACK CbtProc(int n_code, WPARAM w_param, LPARAM l_param) { - HHOOK hook = globalhook; - if(nCode == HCBT_CREATEWND) + HHOOK hook = global_hook; + if(n_code == 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)) + char cs_class_name[16]; + HWND h_curr_wnd = (HWND)w_param; + DWORD ret_proc_id = NULL; + GetClassName(h_curr_wnd, cs_class_name, sizeof(cs_class_name)); + if((strcmp(cs_class_name, "paneClassDC") == 0) + ||(strcmp(cs_class_name, "screenClass") == 0)) { int id = -1; - DWORD windowthread = GetWindowThreadProcessId(hCurrWnd,NULL); - for(int i = 0; i < MAX_PPTOBJS; i++) + DWORD window_thread = GetWindowThreadProcessId(h_curr_wnd,NULL); + for(int i = 0; i < MAX_PPTS; i++) { - if(pptviewobj[i].dwThreadId == windowthread) + if(pptviews[i].dw_thread_id == window_thread) { id = i; break; @@ -609,177 +622,186 @@ LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam) } if(id >= 0) { - if(strcmp(csClassName, "paneClassDC") == 0) - pptviewobj[id].hWnd2=hCurrWnd; + if(strcmp(cs_class_name, "paneClassDC") == 0) + pptviews[id].h_wnd_input = h_curr_wnd; 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); + pptviews[id].h_wnd = h_curr_wnd; + CBT_CREATEWND* cw = (CBT_CREATEWND*)l_param; + if(pptviews[id].h_parent_wnd != NULL) + cw->lpcs->hwndParent = pptviews[id].h_parent_wnd; + cw->lpcs->cy = pptviews[id].rect.bottom + - pptviews[id].rect.top; + cw->lpcs->cx = pptviews[id].rect.right + - pptviews[id].rect.left; cw->lpcs->y = -32000; cw->lpcs->x = -32000; } - if((pptviewobj[id].hWnd != NULL) && (pptviewobj[id].hWnd2 != NULL)) + if((pptviews[id].h_wnd != NULL) + && (pptviews[id].h_wnd_input != 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); + UnhookWindowsHookEx(global_hook); + global_hook = NULL; + pptviews[id].hook = SetWindowsHookEx(WH_CALLWNDPROC, + CwpProc, h_instance, pptviews[id].dw_thread_id); + pptviews[id].mhook = SetWindowsHookEx(WH_GETMESSAGE, + GetMsgProc, h_instance, pptviews[id].dw_thread_id); Sleep(10); - pptviewobj[id].state = PPT_OPENED; + pptviews[id].state = PPT_OPENED; } } } } - return CallNextHookEx(hook, nCode, wParam, lParam); + return CallNextHookEx(hook, n_code, w_param, l_param); } // 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) +LRESULT CALLBACK GetMsgProc(int n_code, WPARAM w_param, LPARAM l_param) { HHOOK hook = NULL; - MSG *pMSG = (MSG *)lParam; - DWORD windowthread = GetWindowThreadProcessId(pMSG->hwnd, NULL); + MSG *p_msg = (MSG *)l_param; + DWORD window_thread = GetWindowThreadProcessId(p_msg->hwnd, NULL); int id = -1; - for(int i = 0; i < MAX_PPTOBJS; i++) + for(int i = 0; i < MAX_PPTS; i++) { - if(pptviewobj[i].dwThreadId == windowthread) + if(pptviews[i].dw_thread_id == window_thread) { id = i; - hook = pptviewobj[id].mhook; + hook = pptviews[id].mhook; break; } } - if(id >= 0 && nCode == HC_ACTION && wParam == PM_REMOVE - && pMSG->message == WM_MOUSEWHEEL) + if(id >= 0 && n_code == HC_ACTION && w_param == PM_REMOVE + && p_msg->message == WM_MOUSEWHEEL) { - if(pptviewobj[id].state != PPT_LOADED) + if(pptviews[id].state != PPT_LOADED) { - if(pptviewobj[id].currentSlide == 1) - pptviewobj[id].firstSlideSteps++; - pptviewobj[id].steps++; + if(pptviews[id].current_slide == 1) + pptviews[id].first_slide_steps++; + pptviews[id].steps++; } } - return CallNextHookEx(hook, nCode, wParam, lParam); + return CallNextHookEx(hook, n_code, w_param, l_param); } + // 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) +LRESULT CALLBACK CwpProc(int n_code, WPARAM w_param, LPARAM l_param) { CWPSTRUCT *cwp; - cwp = (CWPSTRUCT *)lParam; + cwp = (CWPSTRUCT *)l_param; HHOOK hook = NULL; char filename[MAX_PATH]; - DWORD windowthread = GetWindowThreadProcessId(cwp->hwnd, NULL); + DWORD window_thread = GetWindowThreadProcessId(cwp->hwnd, NULL); int id = -1; - for(int i = 0; i < MAX_PPTOBJS; i++) + for(int i = 0; i < MAX_PPTS; i++) { - if(pptviewobj[i].dwThreadId == windowthread) + if(pptviews[i].dw_thread_id == window_thread) { id = i; - hook = pptviewobj[id].hook; + hook = pptviews[id].hook; break; } } - if((id >= 0) && (nCode == HC_ACTION)) + if((id >= 0) && (n_code == HC_ACTION)) { if(cwp->message == WM_USER + 22) { - if(pptviewobj[id].state != PPT_LOADED) + if(pptviews[id].state != PPT_LOADED) { - if((pptviewobj[id].currentSlide > 0) - && (pptviewobj[id].previewpath != NULL - && strlen(pptviewobj[id].previewpath) > 0)) + if((pptviews[id].current_slide > 0) + && (pptviews[id].preview_path != NULL + && strlen(pptviews[id].preview_path) > 0)) { - sprintf_s(filename, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, - pptviewobj[id].currentSlide); + sprintf_s(filename, MAX_PATH, "%s%i.bmp", + pptviews[id].preview_path, + pptviews[id].current_slide); CaptureAndSaveWindow(cwp->hwnd, filename); } } if(cwp->wParam == 0) { - if(pptviewobj[id].currentSlide > 0) + if(pptviews[id].current_slide > 0) { - pptviewobj[id].state = PPT_LOADED; - pptviewobj[id].currentSlide = pptviewobj[id].slideCount + 1; + pptviews[id].state = PPT_LOADED; + pptviews[id].current_slide = pptviews[id].slide_count + 1; } } else { - if(pptviewobj[id].state != PPT_LOADED) + if(pptviews[id].state != PPT_LOADED) { - if((pptviewobj[id].currentSlide == 0) - ||(pptviewobj[id].slideNo[pptviewobj[id].currentSlide] != cwp->wParam)) + if((pptviews[id].current_slide == 0) + ||(pptviews[id].slide_no[pptviews[id].current_slide] + != cwp->wParam)) { - if(pptviewobj[id].slideNo[1] == cwp->wParam) + if(pptviews[id].slide_no[1] == cwp->wParam) { - pptviewobj[id].state = PPT_LOADED; + pptviews[id].state = PPT_LOADED; } else { - pptviewobj[id].currentSlide++; - pptviewobj[id].slideCount = pptviewobj[id].currentSlide; - pptviewobj[id].slideNo[pptviewobj[id].currentSlide] = cwp->wParam; + pptviews[id].current_slide++; + pptviews[id].slide_count + = pptviews[id].current_slide; + pptviews[id].slide_no[pptviews[id].current_slide] + = cwp->wParam; } } } else { - if(pptviewobj[id].guess > 0 - && pptviewobj[id].slideNo[pptviewobj[id].guess] == 0) + if(pptviews[id].guess > 0 + && pptviews[id].slide_no[pptviews[id].guess] == 0) { - pptviewobj[id].currentSlide = 0; + pptviews[id].current_slide = 0; } - for(int i = 1; i < pptviewobj[id].slideCount; i++) + for(int i = 1; i < pptviews[id].slide_count; i++) { - if(pptviewobj[id].slideNo[i] == cwp->wParam) + if(pptviews[id].slide_no[i] == cwp->wParam) { - pptviewobj[id].currentSlide = i; + pptviews[id].current_slide = i; break; } } - if(pptviewobj[id].currentSlide == 0) + if(pptviews[id].current_slide == 0) { - pptviewobj[id].slideNo[pptviewobj[id].guess] = cwp->wParam; - pptviewobj[id].currentSlide = pptviewobj[id].guess; + pptviews[id].slide_no[pptviews[id].guess] = cwp->wParam; + pptviews[id].current_slide = pptviews[id].guess; } } } } - if((pptviewobj[id].state != PPT_CLOSED) + if((pptviews[id].state != PPT_CLOSED) && (cwp->message == WM_CLOSE || cwp->message == WM_QUIT)) { - pptviewobj[id].state = PPT_CLOSING; + pptviews[id].state = PPT_CLOSING; } } - return CallNextHookEx(hook,nCode,wParam,lParam); + return CallNextHookEx(hook, n_code, w_param, l_param); } -VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename) +// Take a screenshot of the current slide, and create a .bmp +VOID CaptureAndSaveWindow(HWND h_wnd, CHAR* filename) { - HBITMAP hBmp; - if ((hBmp = CaptureWindow(hWnd)) == NULL) + HBITMAP h_bmp; + if ((h_bmp = CaptureWindow(h_wnd)) == NULL) return; RECT client; - GetClientRect (hWnd, &client); - UINT uiBytesPerRow = 3 * client.right; // RGB takes 24 bits - UINT uiRemainderForPadding; + GetClientRect(h_wnd, &client); + UINT ui_bytes_per_row = 3 * client.right; // RGB takes 24 bits + UINT ui_remainder_for_padding; - if ((uiRemainderForPadding = uiBytesPerRow % sizeof (DWORD)) > 0) - uiBytesPerRow += (sizeof (DWORD) - uiRemainderForPadding); + if ((ui_remainder_for_padding = ui_bytes_per_row % sizeof (DWORD)) > 0) + ui_bytes_per_row += (sizeof(DWORD) - ui_remainder_for_padding); - UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom; - PBYTE pDataBits; + UINT ui_bytes_per_all_rows = ui_bytes_per_row * client.bottom; + PBYTE p_data_bits; - if ((pDataBits = new BYTE[uiBytesPerAllRows]) != NULL) + if ((p_data_bits = new BYTE[ui_bytes_per_all_rows]) != NULL) { BITMAPINFOHEADER bmi = {0}; BITMAPFILEHEADER bmf = {0}; @@ -792,75 +814,77 @@ VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename) bmi.biWidth = client.right; // Get it: - HDC hDC = GetDC(hWnd); - GetDIBits(hDC, hBmp, 0, client.bottom, pDataBits, + HDC h_dc = GetDC(h_wnd); + GetDIBits(h_dc, h_bmp, 0, client.bottom, p_data_bits, (BITMAPINFO*) &bmi, DIB_RGB_COLORS); - ReleaseDC(hWnd, hDC); + ReleaseDC(h_wnd, h_dc); // Fill the file header: bmf.bfOffBits = sizeof(bmf) + sizeof(bmi); - bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows; + bmf.bfSize = bmf.bfOffBits + ui_bytes_per_all_rows; bmf.bfType = 0x4D42; // Writing: - FILE* pFile; - int err = fopen_s(&pFile, filename, "wb"); + FILE* p_file; + int err = fopen_s(&p_file, 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); + fwrite(&bmf, sizeof(bmf), 1, p_file); + fwrite(&bmi, sizeof(bmi), 1, p_file); + fwrite(p_data_bits, sizeof(BYTE), ui_bytes_per_all_rows, p_file); + fclose(p_file); } - delete [] pDataBits; + delete [] p_data_bits; } - DeleteObject(hBmp); + DeleteObject(h_bmp); } -HBITMAP CaptureWindow(HWND hWnd) +HBITMAP CaptureWindow(HWND h_wnd) { - HDC hDC; - BOOL bOk = FALSE; - HBITMAP hImage = NULL; + HDC h_dc; + BOOL b_ok = FALSE; + HBITMAP h_image = NULL; - hDC = GetDC(hWnd); - RECT rcClient; - GetClientRect(hWnd, &rcClient); - if((hImage = CreateCompatibleBitmap(hDC, rcClient.right, rcClient.bottom)) - != NULL) + h_dc = GetDC(h_wnd); + RECT rc_client; + GetClientRect(h_wnd, &rc_client); + if((h_image = CreateCompatibleBitmap(h_dc, rc_client.right, + rc_client.bottom)) != NULL) { - HDC hMemDC; - HBITMAP hDCBmp; + HDC h_mem_dc; + HBITMAP h_dc_bmp; - if((hMemDC = CreateCompatibleDC (hDC)) != NULL) + if((h_mem_dc = CreateCompatibleDC (h_dc)) != NULL) { - hDCBmp = (HBITMAP)SelectObject(hMemDC, hImage); - HMODULE hLib = LoadLibrary("User32"); + h_dc_bmp = (HBITMAP)SelectObject(h_mem_dc, h_image); + HMODULE h_lib = 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) + // but was only introduced in WinXP. BitBlt requires the window + // to be topmost and within the viewable area of the display + if(GetProcAddress(h_lib, "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); + SetWindowPos(h_wnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); + BitBlt (h_mem_dc, 0, 0, rc_client.right, rc_client.bottom, + h_dc, 0, 0, SRCCOPY); + SetWindowPos(h_wnd, HWND_NOTOPMOST, -32000, -32000, 0, 0, + SWP_NOSIZE); } else { - PrintWindow(hWnd, hMemDC, 0); + PrintWindow(h_wnd, h_mem_dc, 0); } - SelectObject (hMemDC, hDCBmp); - DeleteDC (hMemDC); - bOk = TRUE; + SelectObject(h_mem_dc, h_dc_bmp); + DeleteDC(h_mem_dc); + b_ok = TRUE; } } - ReleaseDC(hWnd, hDC); - if(!bOk) + ReleaseDC(h_wnd, h_dc); + if(!b_ok) { - if (hImage) + if (h_image) { - DeleteObject(hImage); - hImage = NULL; + DeleteObject(h_image); + h_image = NULL; } } - return hImage; + return h_image; } \ No newline at end of file diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll index 9c8240636cbf48c43c33e473f722f6420abc948c..d7d7c1fbad33102a7c2fbcddfad39ce06a606ba5 100644 GIT binary patch delta 7501 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 StguvA4q6WVtA`H#rusj<-TQO^ delta 7460 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 diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h index a45f3b4c2..6b98e329b 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.h @@ -1,60 +1,63 @@ -#define DllExport extern "C" __declspec( dllexport ) +#define DllExport extern "C" __declspec(dllexport) +#define DEBUG(...) if(debug) printf(__VA_ARGS__) -enum PPTVIEWSTATE { PPT_CLOSED, PPT_STARTED, PPT_OPENED, PPT_LOADED, PPT_CLOSING}; +enum PPTVIEWSTATE {PPT_CLOSED, PPT_STARTED, PPT_OPENED, + PPT_LOADED, PPT_CLOSING}; -DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewpath); +DllExport int OpenPPT(char *filename, HWND h_parent_wnd, RECT rect, + char *preview_path); DllExport BOOL CheckInstalled(); 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 GotoSlide(int id, int slide_no); 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); +DllExport void SetDebug(BOOL on_off); -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); +LRESULT CALLBACK CbtProc(int n_code, WPARAM w_param, LPARAM l_param); +LRESULT CALLBACK CwpProc(int n_code, WPARAM w_param, LPARAM l_param); +LRESULT CALLBACK GetMsgProc(int n_code, WPARAM w_param, LPARAM l_param); +BOOL GetPPTViewerPath(char *pptviewer_path, int str_size); +HBITMAP CaptureWindow (HWND h_wnd); +VOID SaveBitmap (CHAR* filename, HBITMAP h_bmp); +VOID CaptureAndSaveWindow(HWND h_wnd, CHAR* filename); BOOL GetPPTInfo(int id); BOOL SavePPTInfo(int id); -BOOL InitPPTObject(int id, char *filename, HWND hParentWnd, - RECT rect, char *previewpath); +BOOL InitPPTObject(int id, char *filename, HWND h_parent_wnd, + RECT rect, char *preview_path); BOOL StartPPTView(int id); void Unhook(int id); -#define MAX_PPTOBJS 16 +#define MAX_PPTS 16 #define MAX_SLIDES 256 -struct PPTVIEWOBJ +struct PPTVIEW { HHOOK hook; HHOOK mhook; - HWND hWnd; - HWND hWnd2; - HWND hParentWnd; - HANDLE hProcess; - HANDLE hThread; - DWORD dwProcessId; - DWORD dwThreadId; + HWND h_wnd; // The main pptview window + HWND h_wnd_input; // A child pptview window which takes windows messages + HWND h_parent_wnd; + HANDLE h_process; + HANDLE h_thread; + DWORD dw_process_id; + DWORD dw_thread_id; RECT rect; - int slideCount; - int currentSlide; - int firstSlideSteps; + int slide_count; + int current_slide; + int first_slide_steps; int steps; - int guess; + int guess; // What the current slide might be, based on the last action char filename[MAX_PATH]; - char previewpath[MAX_PATH]; - int slideNo[MAX_SLIDES]; + char preview_path[MAX_PATH]; + int slide_no[MAX_SLIDES]; PPTVIEWSTATE state; }; From 23ca24ccebf815e7562b2b348105276a1401cb06 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Tue, 15 Mar 2011 07:34:04 +0000 Subject: [PATCH 6/7] Revert pptviewer.dll changes for now, they can come later. Lets get the rest in --- .../lib/pptviewlib/pptviewlib.cpp | 881 ++++++++---------- .../lib/pptviewlib/pptviewlib.dll | Bin 78848 -> 47104 bytes .../presentations/lib/pptviewlib/pptviewlib.h | 60 +- 3 files changed, 403 insertions(+), 538 deletions(-) diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp index 92b849797..86876a836 100644 --- a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp +++ b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.cpp @@ -27,62 +27,67 @@ #include #include "pptviewlib.h" -// Because of the callbacks used by SetWindowsHookEx, the memory used needs to -// be sharable across processes (callbacks are done from a different process) + +// 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. - +// 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") -PPTVIEW pptviews[MAX_PPTS] = {NULL}; -HHOOK global_hook = NULL; +PPTVIEWOBJ pptviewobj[MAX_PPTOBJS] = {NULL}; +HHOOK globalhook = NULL; BOOL debug = FALSE; #pragma data_seg() #pragma comment(linker, "/SECTION:.PPTVIEWLIB,RWS") -HINSTANCE h_instance = NULL; +#define DEBUG(...) if(debug) printf(__VA_ARGS__) -BOOL APIENTRY DllMain(HMODULE h_module, DWORD ul_reason_for_call, - LPVOID lp_reserved) + +HINSTANCE hInstance = NULL; + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) { - h_instance = (HINSTANCE)h_module; + 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_PPTS; i++) - ClosePPT(i); - break; + 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 h_parent_wnd, RECT rect, - char *preview_path) +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, preview_path); - DEBUG("OpenPPT start: %u; %i, %i, %i, %i\n", h_parent_wnd, rect.top, - rect.left, rect.bottom, rect.right); - id = -1; - for(int i = 0; i < MAX_PPTS; i++) + 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) { - if(pptviews[i].state == PPT_CLOSED) + DEBUG("OpenPPT: GetPPTViewerPath failed\n"); + return -1; + } + id = -1; + for(int i = 0; ibottom - wnd_rect->top; - pptviews[id].rect.right = wnd_rect->right - wnd_rect->left; + 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 { - pptviews[id].rect.top = rect.top; - pptviews[id].rect.left = rect.left; - pptviews[id].rect.bottom = rect.bottom; - pptviews[id].rect.right = rect.right; + pptviewobj[id].rect.top = rect.top; + pptviewobj[id].rect.left = rect.left; + pptviewobj[id].rect.bottom = rect.bottom; + pptviewobj[id].rect.right = rect.right; } - BOOL got_info = GetPPTInfo(id); - return got_info; -} -BOOL StartPPTView(int id) -{ + strcat_s(cmdline, MAX_PATH * 2, "/F /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 @@ -218,48 +164,69 @@ BOOL StartPPTView(int id) * * hook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,pi.dwThreadId); */ - DEBUG("StartPPTView\n"); - STARTUPINFO si; - PROCESS_INFORMATION pi; - char cmd_line[MAX_PATH * 2]; - - if(global_hook != NULL) - UnhookWindowsHookEx(global_hook); - global_hook = SetWindowsHookEx(WH_CBT, CbtProc, h_instance, NULL); - if(global_hook == 0) + if(globalhook!=NULL) + UnhookWindowsHookEx(globalhook); + globalhook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,NULL); + if(globalhook==0) { DEBUG("OpenPPT: SetWindowsHookEx failed\n"); ClosePPT(id); - return FALSE; + return -1; } - if(GetPPTViewerPath(cmd_line, sizeof(cmd_line)) == FALSE) - { - DEBUG("OpenPPT: GetPPTViewerPath failed\n"); - return FALSE; - } - pptviews[id].state = PPT_STARTED; + pptviewobj[id].state = PPT_STARTED; Sleep(10); - strcat_s(cmd_line, MAX_PATH * 2, "/F /S \""); - strcat_s(cmd_line, MAX_PATH * 2, pptviews[id].filename); - strcat_s(cmd_line, MAX_PATH * 2, "\""); - memset(&si, 0, sizeof(si)); - memset(&pi, 0, sizeof(pi)); - DEBUG("Command: %s\n", cmd_line); - if(!CreateProcess(NULL, cmd_line, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) + if(!CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, 0, NULL, &si, &pi)) { DEBUG("OpenPPT: CreateProcess failed\n"); ClosePPT(id); - return FALSE; + return -1; } - pptviews[id].dw_process_id = pi.dwProcessId; - pptviews[id].dw_thread_id = pi.dwThreadId; - pptviews[id].h_thread = pi.hThread; - pptviews[id].h_process = pi.hProcess; - while(pptviews[id].state == PPT_STARTED) + 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); - return TRUE; + 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||pptviewobj[id].slideCount<=0){ + 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 @@ -269,115 +236,100 @@ BOOL StartPPTView(int id) // first slide steps BOOL GetPPTInfo(int id) { - struct _stat file_stats; + struct _stat filestats; char info[MAX_PATH]; - FILE* p_file; + FILE* pFile; char buf[100]; DEBUG("GetPPTInfo: start\n"); - if(_stat(pptviews[id].filename, &file_stats) != 0) + if(_stat(pptviewobj[id].filename, &filestats)!=0) return FALSE; - sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviews[id].preview_path); - int err = fopen_s(&p_file, info, "r"); - if(err != 0) + 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, p_file); // version == 1 - fgets(buf, 100, p_file); - if(file_stats.st_mtime != atoi(buf)) + fgets(buf, 100, pFile); // version == 1 + fgets(buf, 100, pFile); + if(filestats.st_mtime!=atoi(buf)) { - fclose (p_file); + fclose (pFile); return FALSE; } - fgets(buf, 100, p_file); - if(file_stats.st_size != atoi(buf)) + fgets(buf, 100, pFile); + if(filestats.st_size!=atoi(buf)) { - fclose(p_file); + fclose (pFile); return FALSE; } - fgets(buf, 100, p_file); // slidecount - int slide_count = atoi(buf); - fgets(buf, 100, p_file); // first slide steps - int first_slide_steps = atoi(buf); + 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 <= slide_count; i++) + for(int i = 1; i<=slidecount; i++) { - sprintf_s(info, MAX_PATH, "%s%i.bmp", - pptviews[id].preview_path, i); - if(GetFileAttributes(info) == INVALID_FILE_ATTRIBUTES) + sprintf_s(info, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, i); + if(GetFileAttributes(info)==INVALID_FILE_ATTRIBUTES) return FALSE; } - fclose(p_file); - pptviews[id].slide_count = slide_count; - pptviews[id].first_slide_steps = first_slide_steps; + fclose(pFile); + pptviewobj[id].slideCount = slidecount; + pptviewobj[id].firstSlideSteps = firstslidesteps; DEBUG("GetPPTInfo: exit ok\n"); return TRUE; } BOOL SavePPTInfo(int id) { - struct _stat file_stats; + struct _stat filestats; char info[MAX_PATH]; - FILE* p_file; + FILE* pFile; DEBUG("SavePPTInfo: start\n"); - if(_stat(pptviews[id].filename, &file_stats) != 0) + if(_stat(pptviewobj[id].filename, &filestats)!=0) { - DEBUG("SavePPTInfo: stat of %s failed\n", pptviews[id].filename); + DEBUG("SavePPTInfo: stat of %s failed\n", pptviewobj[id].filename); return FALSE; } - sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviews[id].preview_path); - int err = fopen_s(&p_file, info, "w"); - if(err != 0) + 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; } - else - { - DEBUG("SavePPTInfo: fopen of %s succeeded\n", info); - } - fprintf(p_file, "1\n"); - fprintf(p_file, "%u\n", file_stats.st_mtime); - fprintf(p_file, "%u\n", file_stats.st_size); - fprintf(p_file, "%u\n", pptviews[id].slide_count); - fprintf(p_file, "%u\n", pptviews[id].first_slide_steps); - fclose(p_file); + 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 *pptviewer_path, int str_size) +BOOL GetPPTViewerPath(char *pptviewerpath, int strsize) { - HKEY h_key; - DWORD dw_type, dw_size; - LRESULT l_result; + HKEY hkey; + DWORD dwtype, dwsize; + LRESULT lresult; DEBUG("GetPPTViewerPath: start\n"); - if((RegOpenKeyEx(HKEY_CLASSES_ROOT, - "PowerPointViewer.Show.12\\shell\\Show\\command", - 0, KEY_READ, &h_key) != ERROR_SUCCESS) - && (RegOpenKeyEx(HKEY_CLASSES_ROOT, - "Applications\\PPTVIEW.EXE\\shell\\open\\command", - 0, KEY_READ, &h_key) != ERROR_SUCCESS) - && (RegOpenKeyEx(HKEY_CLASSES_ROOT, - "Applications\\PPTVIEW.EXE\\shell\\Show\\command", - 0, KEY_READ, &h_key) != ERROR_SUCCESS)) - { - return FALSE; - } - dw_type = REG_SZ; - dw_size = (DWORD)str_size; - l_result = RegQueryValueEx(h_key, NULL, NULL, &dw_type, - (LPBYTE)pptviewer_path, &dw_size); - RegCloseKey(h_key); - if(l_result != ERROR_SUCCESS) + if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "PowerPointViewer.Show.12\\shell\\Show\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS) + 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; - // remove "%1" from the end of the key value - pptviewer_path[strlen(pptviewer_path) - 4] = '\0'; + pptviewerpath[strlen(pptviewerpath)-4] = '\0'; // remove "%1" from end of key value DEBUG("GetPPTViewerPath: exit ok\n"); return TRUE; } @@ -386,12 +338,12 @@ BOOL GetPPTViewerPath(char *pptviewer_path, int str_size) void Unhook(int id) { DEBUG("Unhook: start %d\n", id); - if(pptviews[id].hook != NULL) - UnhookWindowsHookEx(pptviews[id].hook); - if(pptviews[id].mhook != NULL) - UnhookWindowsHookEx(pptviews[id].mhook); - pptviews[id].hook = NULL; - pptviews[id].mhook = NULL; + 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"); } @@ -399,15 +351,15 @@ void Unhook(int id) DllExport void ClosePPT(int id) { DEBUG("ClosePPT: start%d\n", id); - pptviews[id].state = PPT_CLOSED; + pptviewobj[id].state = PPT_CLOSED; Unhook(id); - if(pptviews[id].h_wnd == 0) - TerminateThread(pptviews[id].h_thread, 0); + if(pptviewobj[id].hWnd==0) + TerminateThread(pptviewobj[id].hThread, 0); else - PostMessage(pptviews[id].h_wnd, WM_CLOSE, 0, 0); - CloseHandle(pptviews[id].h_thread); - CloseHandle(pptviews[id].h_process); - memset(&pptviews[id], 0, sizeof(pptviews)); + 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; } @@ -415,60 +367,54 @@ DllExport void ClosePPT(int id) DllExport void Resume(int id) { DEBUG("Resume: %d\n", id); - MoveWindow(pptviews[id].h_wnd, pptviews[id].rect.left, - pptviews[id].rect.top, - pptviews[id].rect.right - pptviews[id].rect.left, - pptviews[id].rect.bottom - pptviews[id].rect.top, TRUE); + 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(pptviews[id].h_wnd, -32000, -32000, - pptviews[id].rect.right - pptviews[id].rect.left, - pptviews[id].rect.bottom - pptviews[id].rect.top, TRUE); + 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(pptviews[id].state == 0) + if(pptviewobj[id].state==0) return -1; else - return pptviews[id].slide_count; + return pptviewobj[id].slideCount; } // Return the number of the slide currently viewing DllExport int GetCurrentSlide(int id) { DEBUG("GetCurrentSlide:%d\n", id); - if(pptviews[id].state == 0) + if(pptviewobj[id].state==0) return -1; else - return pptviews[id].current_slide; + return pptviewobj[id].currentSlide; } // Take a step forwards through the show DllExport void NextStep(int id) { - DEBUG("NextStep:%d (%d)\n", id, pptviews[id].current_slide); - if(pptviews[id].current_slide > pptviews[id].slide_count) + DEBUG("NextStep:%d\n", id); + if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) return; - pptviews[id].guess = pptviews[id].current_slide + 1; - PostMessage(pptviews[id].h_wnd_input, WM_MOUSEWHEEL, - MAKEWPARAM(0, -WHEEL_DELTA), 0); + 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 (%d)\n", id, pptviews[id].current_slide); - if(pptviews[id].current_slide > 1) - pptviews[id].guess = pptviews[id].current_slide - 1; - PostMessage(pptviews[id].h_wnd_input, WM_MOUSEWHEEL, - MAKEWPARAM(0, WHEEL_DELTA), 0); + DEBUG("PrevStep:%d\n", id); + PostMessage(pptviewobj[id].hWnd2, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA), 0); } // Blank the show (black screen) @@ -481,22 +427,18 @@ DllExport void Blank(int id) DEBUG("Blank:%d\n", id); HWND h1 = GetForegroundWindow(); HWND h2 = GetFocus(); - SetForegroundWindow(pptviews[id].h_wnd); - SetFocus(pptviews[id].h_wnd); - // slight pause, otherwise event triggering this call may grab focus back! - Sleep(50); + 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); - - // This is the preferred method, but didn't work. Keep it here for - // documentation if we revisit in the future - //PostMessage(pptviews[id].h_wnd_input, WM_KEYDOWN, 'B', 0x00300001); - //PostMessage(pptviews[id].h_wnd_input, WM_CHAR, 'b', 0x00300001); - //PostMessage(pptviews[id].h_wnd_input, WM_KEYUP, 'B', 0xC0300001); + //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) @@ -504,47 +446,39 @@ DllExport void Unblank(int id) DEBUG("Unblank:%d\n", id); // Pressing any key resumes. // For some reason SendMessage works for unblanking, but not blanking. - // However keep the commented code for documentation in case we want - // to revisit later. - - //SendMessage(pptviews[id].h_wnd_input, WM_KEYDOWN, 'A', 0); - SendMessage(pptviews[id].h_wnd_input, WM_CHAR, 'A', 0); - //SendMessage(pptviews[id].h_wnd_input, WM_KEYUP, 'A', 0); - //HWND h1 = GetForegroundWindow(); - //HWND h2 = GetFocus(); - ////slight pause, otherwise event triggering this call may grab focus back! - //Sleep(50); - //SetForegroundWindow(pptviews[id].h_wnd); - //SetFocus(pptviews[id].h_wnd); - //keybd_event((int)'A', 0, 0, 0); - //SetForegroundWindow(h1); - //SetFocus(h2); +// 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 slide_no) +DllExport void GotoSlide(int id, int slideno) { - DEBUG("GotoSlide %i %i:\n", id, slide_no); + 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(slide_no < 0) - return; - pptviews[id].guess = slide_no; - _itoa_s(slide_no, ch, 10, 10); + if(slideno<0) return; + _itoa_s(slideno, ch, 10, 10); HWND h1 = GetForegroundWindow(); HWND h2 = GetFocus(); - SetForegroundWindow(pptviews[id].h_wnd); - SetFocus(pptviews[id].h_wnd); - // slight pause, otherwise event triggering this call may grab focus back! - Sleep(50); - for(int i = 0; i < 10; i++) + 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; + if(ch[i]=='\0') break; keybd_event((BYTE)ch[i], 0, 0, 0); keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0); } @@ -553,40 +487,36 @@ DllExport void GotoSlide(int id, int slide_no) SetForegroundWindow(h1); SetFocus(h2); - // I don't know why the below didn't work. - // Kept here as documentation in case we want to try again in the future - // //for(int i=0;i<10;i++) //{ // if(ch[i]=='\0') break; - // SendMessage(pptviews[id].h_wnd_input, WM_KEYDOWN, ch[i], 0); - // SendMessage(pptviews[id].h_wnd_input, WM_CHAR, ch[i], 0); - // SendMessage(pptviews[id].h_wnd_input, WM_KEYUP, ch[i], 0); + // 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(pptviews[id].h_wnd_input, WM_KEYDOWN, VK_RETURN, 0); - //SendMessage(pptviews[id].h_wnd_input, WM_CHAR, VK_RETURN, 0); - //SendMessage(pptviews[id].h_wnd_input, WM_KEYUP, VK_RETURN, 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. + // 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, pptviews[id].slide_count); - while(pptviews[id].current_slide > 1) + GotoSlide(id, pptviewobj[id].slideCount); + while(pptviewobj[id].currentSlide>1) { PrevStep(id); Sleep(10); } - for(int i = 0; i <= pptviews[id].first_slide_steps; i++) + for(int i=0;i<=pptviewobj[id].firstSlideSteps;i++) { PrevStep(id); Sleep(10); @@ -598,293 +528,236 @@ DllExport void RestartShow(int id) // 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 n_code, WPARAM w_param, LPARAM l_param) +LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam) { - HHOOK hook = global_hook; - if(n_code == HCBT_CREATEWND) + HHOOK hook = globalhook; + if(nCode==HCBT_CREATEWND) { - char cs_class_name[16]; - HWND h_curr_wnd = (HWND)w_param; - DWORD ret_proc_id = NULL; - GetClassName(h_curr_wnd, cs_class_name, sizeof(cs_class_name)); - if((strcmp(cs_class_name, "paneClassDC") == 0) - ||(strcmp(cs_class_name, "screenClass") == 0)) + 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 window_thread = GetWindowThreadProcessId(h_curr_wnd,NULL); - for(int i = 0; i < MAX_PPTS; i++) + int id=-1; + DWORD windowthread = GetWindowThreadProcessId(hCurrWnd,NULL); + for(int i=0; i= 0) + if(id>=0) { - if(strcmp(cs_class_name, "paneClassDC") == 0) - pptviews[id].h_wnd_input = h_curr_wnd; + if(strcmp(csClassName, "paneClassDC")==0) + pptviewobj[id].hWnd2=hCurrWnd; else { - pptviews[id].h_wnd = h_curr_wnd; - CBT_CREATEWND* cw = (CBT_CREATEWND*)l_param; - if(pptviews[id].h_parent_wnd != NULL) - cw->lpcs->hwndParent = pptviews[id].h_parent_wnd; - cw->lpcs->cy = pptviews[id].rect.bottom - - pptviews[id].rect.top; - cw->lpcs->cx = pptviews[id].rect.right - - pptviews[id].rect.left; - cw->lpcs->y = -32000; - cw->lpcs->x = -32000; + 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((pptviews[id].h_wnd != NULL) - && (pptviews[id].h_wnd_input != NULL)) + if((pptviewobj[id].hWnd!=NULL)&&(pptviewobj[id].hWnd2!=NULL)) { - UnhookWindowsHookEx(global_hook); - global_hook = NULL; - pptviews[id].hook = SetWindowsHookEx(WH_CALLWNDPROC, - CwpProc, h_instance, pptviews[id].dw_thread_id); - pptviews[id].mhook = SetWindowsHookEx(WH_GETMESSAGE, - GetMsgProc, h_instance, pptviews[id].dw_thread_id); + 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); - pptviews[id].state = PPT_OPENED; + pptviewobj[id].state = PPT_OPENED; } } } } - return CallNextHookEx(hook, n_code, w_param, l_param); + 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 n_code, WPARAM w_param, LPARAM l_param) +LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { HHOOK hook = NULL; - MSG *p_msg = (MSG *)l_param; - DWORD window_thread = GetWindowThreadProcessId(p_msg->hwnd, NULL); - int id = -1; - for(int i = 0; i < MAX_PPTS; i++) + MSG *pMSG = (MSG *)lParam; + DWORD windowthread = GetWindowThreadProcessId(pMSG->hwnd,NULL); + int id=-1; + for(int i=0; i= 0 && n_code == HC_ACTION && w_param == PM_REMOVE - && p_msg->message == WM_MOUSEWHEEL) + if(id>=0&&nCode==HC_ACTION&&wParam==PM_REMOVE&&pMSG->message==WM_MOUSEWHEEL) { - if(pptviews[id].state != PPT_LOADED) + if(pptviewobj[id].state!=PPT_LOADED) { - if(pptviews[id].current_slide == 1) - pptviews[id].first_slide_steps++; - pptviews[id].steps++; + if(pptviewobj[id].currentSlide==1) + pptviewobj[id].firstSlideSteps++; + pptviewobj[id].steps++; } } - return CallNextHookEx(hook, n_code, w_param, l_param); + 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 n_code, WPARAM w_param, LPARAM l_param) -{ +LRESULT CALLBACK CwpProc(int nCode, WPARAM wParam, LPARAM lParam){ CWPSTRUCT *cwp; - cwp = (CWPSTRUCT *)l_param; + cwp = (CWPSTRUCT *)lParam; HHOOK hook = NULL; char filename[MAX_PATH]; - DWORD window_thread = GetWindowThreadProcessId(cwp->hwnd, NULL); - int id = -1; - for(int i = 0; i < MAX_PPTS; i++) + DWORD windowthread = GetWindowThreadProcessId(cwp->hwnd,NULL); + int id=-1; + for(int i=0; i= 0) && (n_code == HC_ACTION)) + if((id>=0)&&(nCode==HC_ACTION)) { - if(cwp->message == WM_USER + 22) + if(cwp->message==WM_USER+22) { - if(pptviews[id].state != PPT_LOADED) + if(pptviewobj[id].state != PPT_LOADED) { - if((pptviews[id].current_slide > 0) - && (pptviews[id].preview_path != NULL - && strlen(pptviews[id].preview_path) > 0)) + if((pptviewobj[id].currentSlide>0) + && (pptviewobj[id].previewpath!=NULL&&strlen(pptviewobj[id].previewpath)>0)) { - sprintf_s(filename, MAX_PATH, "%s%i.bmp", - pptviews[id].preview_path, - pptviews[id].current_slide); + sprintf_s(filename, MAX_PATH, "%s%i.bmp", pptviewobj[id].previewpath, pptviewobj[id].currentSlide); CaptureAndSaveWindow(cwp->hwnd, filename); } } - if(cwp->wParam == 0) + if(cwp->wParam==0) { - if(pptviews[id].current_slide > 0) + if(pptviewobj[id].currentSlide>0) { - pptviews[id].state = PPT_LOADED; - pptviews[id].current_slide = pptviews[id].slide_count + 1; + pptviewobj[id].state = PPT_LOADED; + pptviewobj[id].currentSlide = pptviewobj[id].slideCount+1; } } else { - if(pptviews[id].state != PPT_LOADED) - { - if((pptviews[id].current_slide == 0) - ||(pptviews[id].slide_no[pptviews[id].current_slide] - != cwp->wParam)) - { - if(pptviews[id].slide_no[1] == cwp->wParam) - { - pptviews[id].state = PPT_LOADED; - } - else - { - pptviews[id].current_slide++; - pptviews[id].slide_count - = pptviews[id].current_slide; - pptviews[id].slide_no[pptviews[id].current_slide] - = cwp->wParam; - } - } - } - else - { - if(pptviews[id].guess > 0 - && pptviews[id].slide_no[pptviews[id].guess] == 0) - { - pptviews[id].current_slide = 0; - } - for(int i = 1; i < pptviews[id].slide_count; i++) - { - if(pptviews[id].slide_no[i] == cwp->wParam) - { - pptviews[id].current_slide = i; - break; - } - } - if(pptviews[id].current_slide == 0) - { - pptviews[id].slide_no[pptviews[id].guess] = cwp->wParam; - pptviews[id].current_slide = pptviews[id].guess; - } - } + pptviewobj[id].currentSlide = cwp->wParam - 255; + if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) + pptviewobj[id].slideCount = pptviewobj[id].currentSlide; } } - if((pptviews[id].state != PPT_CLOSED) - && (cwp->message == WM_CLOSE || cwp->message == WM_QUIT)) - { - pptviews[id].state = PPT_CLOSING; - } + if((pptviewobj[id].state != PPT_CLOSED)&&(cwp->message==WM_CLOSE||cwp->message==WM_QUIT)) + pptviewobj[id].state = PPT_CLOSING; } - return CallNextHookEx(hook, n_code, w_param, l_param); + return CallNextHookEx(hook,nCode,wParam,lParam); } -// Take a screenshot of the current slide, and create a .bmp -VOID CaptureAndSaveWindow(HWND h_wnd, CHAR* filename) +VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename) { - HBITMAP h_bmp; - if ((h_bmp = CaptureWindow(h_wnd)) == NULL) + HBITMAP hBmp; + if ((hBmp = CaptureWindow(hWnd)) == NULL) return; RECT client; - GetClientRect(h_wnd, &client); - UINT ui_bytes_per_row = 3 * client.right; // RGB takes 24 bits - UINT ui_remainder_for_padding; + GetClientRect (hWnd, &client); + UINT uiBytesPerRow = 3 * client.right; // RGB takes 24 bits + UINT uiRemainderForPadding; - if ((ui_remainder_for_padding = ui_bytes_per_row % sizeof (DWORD)) > 0) - ui_bytes_per_row += (sizeof(DWORD) - ui_remainder_for_padding); + if ((uiRemainderForPadding = uiBytesPerRow % sizeof (DWORD)) > 0) + uiBytesPerRow += (sizeof (DWORD) - uiRemainderForPadding); - UINT ui_bytes_per_all_rows = ui_bytes_per_row * client.bottom; - PBYTE p_data_bits; + UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom; + PBYTE pDataBits; - if ((p_data_bits = new BYTE[ui_bytes_per_all_rows]) != NULL) + 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.biSize = sizeof (bmi); bmi.biPlanes = 1; bmi.biBitCount = 24; bmi.biHeight = client.bottom; bmi.biWidth = client.right; // Get it: - HDC h_dc = GetDC(h_wnd); - GetDIBits(h_dc, h_bmp, 0, client.bottom, p_data_bits, - (BITMAPINFO*) &bmi, DIB_RGB_COLORS); - ReleaseDC(h_wnd, h_dc); + 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 + ui_bytes_per_all_rows; + bmf.bfOffBits = sizeof (bmf) + sizeof (bmi); + bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows; bmf.bfType = 0x4D42; // Writing: - FILE* p_file; - int err = fopen_s(&p_file, filename, "wb"); + FILE* pFile; + int err = fopen_s(&pFile, filename, "wb"); if (err == 0) { - fwrite(&bmf, sizeof(bmf), 1, p_file); - fwrite(&bmi, sizeof(bmi), 1, p_file); - fwrite(p_data_bits, sizeof(BYTE), ui_bytes_per_all_rows, p_file); - fclose(p_file); + fwrite (&bmf, sizeof (bmf), 1, pFile); + fwrite (&bmi, sizeof (bmi), 1, pFile); + fwrite (pDataBits, sizeof (BYTE), uiBytesPerAllRows, pFile); + fclose (pFile); } - delete [] p_data_bits; + delete [] pDataBits; } - DeleteObject(h_bmp); + DeleteObject (hBmp); } -HBITMAP CaptureWindow(HWND h_wnd) -{ - HDC h_dc; - BOOL b_ok = FALSE; - HBITMAP h_image = NULL; +HBITMAP CaptureWindow (HWND hWnd) { + HDC hDC; + BOOL bOk = FALSE; + HBITMAP hImage = NULL; - h_dc = GetDC(h_wnd); - RECT rc_client; - GetClientRect(h_wnd, &rc_client); - if((h_image = CreateCompatibleBitmap(h_dc, rc_client.right, - rc_client.bottom)) != NULL) + hDC = GetDC (hWnd); + RECT rcClient; + GetClientRect (hWnd, &rcClient); + if ((hImage = CreateCompatibleBitmap (hDC, rcClient.right, rcClient.bottom)) != NULL) { - HDC h_mem_dc; - HBITMAP h_dc_bmp; + HDC hMemDC; + HBITMAP hDCBmp; - if((h_mem_dc = CreateCompatibleDC (h_dc)) != NULL) + if ((hMemDC = CreateCompatibleDC (hDC)) != NULL) { - h_dc_bmp = (HBITMAP)SelectObject(h_mem_dc, h_image); - HMODULE h_lib = LoadLibrary("User32"); + 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(h_lib, "PrintWindow") == NULL) + // 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(h_wnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); - BitBlt (h_mem_dc, 0, 0, rc_client.right, rc_client.bottom, - h_dc, 0, 0, SRCCOPY); - SetWindowPos(h_wnd, HWND_NOTOPMOST, -32000, -32000, 0, 0, - SWP_NOSIZE); + 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(h_wnd, h_mem_dc, 0); + PrintWindow(hWnd, hMemDC, 0); } - SelectObject(h_mem_dc, h_dc_bmp); - DeleteDC(h_mem_dc); - b_ok = TRUE; + SelectObject (hMemDC, hDCBmp); + DeleteDC (hMemDC); + bOk = TRUE; } } - ReleaseDC(h_wnd, h_dc); - if(!b_ok) + ReleaseDC (hWnd, hDC); + if (! bOk) { - if (h_image) + if (hImage) { - DeleteObject(h_image); - h_image = NULL; + DeleteObject (hImage); + hImage = NULL; } } - return h_image; -} \ No newline at end of file + return hImage; +} diff --git a/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll b/openlp/plugins/presentations/lib/pptviewlib/pptviewlib.dll index d7d7c1fbad33102a7c2fbcddfad39ce06a606ba5..f8a0de0d33e562014629fc97d25cc11103695e55 100644 GIT binary patch literal 47104 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 literal 78848 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 wo@$sXOf}6f)s-4c>q}Rc`bv9BZ!X Date: Tue, 15 Mar 2011 07:47:23 +0000 Subject: [PATCH 7/7] typo. Should really test before committing :) --- openlp/plugins/presentations/lib/pptviewcontroller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/presentations/lib/pptviewcontroller.py b/openlp/plugins/presentations/lib/pptviewcontroller.py index e9130ea00..5ec560167 100644 --- a/openlp/plugins/presentations/lib/pptviewcontroller.py +++ b/openlp/plugins/presentations/lib/pptviewcontroller.py @@ -84,7 +84,7 @@ class PptviewController(PresentationController): dllpath = os.path.join(self.plugin.pluginManager.basepath, u'presentations', u'lib', u'pptviewlib', u'pptviewlib.dll') self.process = cdll.LoadLibrary(dllpath) - if log.isEnabledFor(log.DEBUG): + if log.isEnabledFor(logging.DEBUG): self.process.SetDebug(1) def kill(self):