pptviewer mods

This commit is contained in:
Jonathan Corwin 2011-03-13 23:18:19 +00:00
parent 23b9884775
commit e8de37f7b3
4 changed files with 293 additions and 190 deletions

View File

@ -140,8 +140,10 @@ class PptviewDocument(PresentationDocument):
PPTviewLib creates large BMP's, but we want small PNG's for consistency. PPTviewLib creates large BMP's, but we want small PNG's for consistency.
Convert them here. Convert them here.
""" """
log.debug(u'create_thumbnails')
if self.check_thumbnails(): if self.check_thumbnails():
return return
log.debug(u'create_thumbnails proceeding')
for idx in range(self.get_slide_count()): for idx in range(self.get_slide_count()):
path = u'%s\\slide%s.bmp' % (self.get_temp_folder(), path = u'%s\\slide%s.bmp' % (self.get_temp_folder(),
unicode(idx + 1)) unicode(idx + 1))

View File

@ -48,30 +48,28 @@ BOOL debug = FALSE;
HINSTANCE hInstance = NULL; HINSTANCE hInstance = NULL;
BOOL APIENTRY DllMain( HMODULE hModule, BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call,
DWORD ul_reason_for_call, LPVOID lpReserved)
LPVOID lpReserved
)
{ {
hInstance = (HINSTANCE)hModule; hInstance = (HINSTANCE)hModule;
switch (ul_reason_for_call) switch (ul_reason_for_call)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
DEBUG("PROCESS_ATTACH\n"); DEBUG("PROCESS_ATTACH\n");
break; break;
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:
DEBUG("THREAD_ATTACH\n"); DEBUG("THREAD_ATTACH\n");
break; break;
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
DEBUG("THREAD_DETACH\n"); DEBUG("THREAD_DETACH\n");
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
// Clean up... hopefully there is only the one process attached? // Clean up... hopefully there is only the one process attached?
// We'll find out soon enough during tests! // We'll find out soon enough during tests!
DEBUG("PROCESS_DETACH\n"); DEBUG("PROCESS_DETACH\n");
for(int i = 0; i<MAX_PPTOBJS; i++) for(int i = 0; i<MAX_PPTOBJS; i++)
ClosePPT(i); ClosePPT(i);
break; break;
} }
return TRUE; return TRUE;
} }
@ -96,34 +94,86 @@ DllExport BOOL CheckInstalled()
// "<n>.bmp" will be appended to complete the path. E.g. "c:\temp\slide" would // "<n>.bmp" will be appended to complete the path. E.g. "c:\temp\slide" would
// create "c:\temp\slide1.bmp" slide2.bmp, slide3.bmp etc. // create "c:\temp\slide1.bmp" slide2.bmp, slide3.bmp etc.
// It will also create a *info.txt containing information about the ppt // 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; int id;
DEBUG("OpenPPT start: %s; %s\n", filename, previewpath); 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); DEBUG("OpenPPT start: %u; %i, %i, %i, %i\n", hParentWnd, rect.top,
if(GetPPTViewerPath(cmdline, sizeof(cmdline))==FALSE) rect.left, rect.bottom, rect.right);
{
DEBUG("OpenPPT: GetPPTViewerPath failed\n");
return -1;
}
id = -1; id = -1;
for(int i = 0; i<MAX_PPTOBJS; i++) for(int i = 0; i < MAX_PPTOBJS; i++)
{ {
if(pptviewobj[i].state==PPT_CLOSED) if(pptviewobj[i].state == PPT_CLOSED)
{ {
id=i; id = i;
break; break;
} }
} }
if(id<0) if(id < 0)
{ {
DEBUG("OpenPPT: Too many PPTs\n"); DEBUG("OpenPPT: Too many PPTs\n");
return -1; return -1;
} }
BOOL gotinfo = InitPPTObject(id, filename, hParentWnd, rect, previewpath);
if(!StartPPTView(id))
{
ClosePPT(id);
return -1;
}
if(!gotinfo)
{
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)
{
// 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)
{
ClosePPT(id);
return -1;
}
}
else
RestartShow(id);
}
if(gotinfo)
{
DEBUG("OpenPPT: Info loaded, no refresh\n");
pptviewobj[id].state = PPT_LOADED;
Resume(id);
}
if(pptviewobj[id].mhook != NULL)
UnhookWindowsHookEx(pptviewobj[id].mhook);
pptviewobj[id].mhook = NULL;
DEBUG("OpenPPT: Exit: id=%i\n", id);
return id;
}
BOOL InitPPTObject(int id, char *filename, HWND hParentWnd,
RECT rect, char *previewpath)
{
DEBUG("InitPPTObject\n");
memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ)); memset(&pptviewobj[id], 0, sizeof(PPTVIEWOBJ));
strcpy_s(pptviewobj[id].filename, MAX_PATH, filename); strcpy_s(pptviewobj[id].filename, MAX_PATH, filename);
strcpy_s(pptviewobj[id].previewpath, MAX_PATH, previewpath); strcpy_s(pptviewobj[id].previewpath, MAX_PATH, previewpath);
@ -131,10 +181,14 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewp
pptviewobj[id].slideCount = 0; pptviewobj[id].slideCount = 0;
pptviewobj[id].currentSlide = 0; pptviewobj[id].currentSlide = 0;
pptviewobj[id].firstSlideSteps = 0; pptviewobj[id].firstSlideSteps = 0;
pptviewobj[id].guess = 1;
for(int i = 0; i < MAX_SLIDES; i++)
pptviewobj[id].slideNo[i] = 0;
pptviewobj[id].hParentWnd = hParentWnd; pptviewobj[id].hParentWnd = hParentWnd;
pptviewobj[id].hWnd = NULL; pptviewobj[id].hWnd = NULL;
pptviewobj[id].hWnd2 = NULL; pptviewobj[id].hWnd2 = NULL;
if(hParentWnd!=NULL&&rect.top==0&&rect.bottom==0&&rect.left==0&&rect.right==0) if(hParentWnd != NULL && rect.top == 0 && rect.bottom == 0
&& rect.left == 0 && rect.right == 0)
{ {
LPRECT wndrect = NULL; LPRECT wndrect = NULL;
GetWindowRect(hParentWnd, wndrect); GetWindowRect(hParentWnd, wndrect);
@ -150,12 +204,11 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewp
pptviewobj[id].rect.bottom = rect.bottom; pptviewobj[id].rect.bottom = rect.bottom;
pptviewobj[id].rect.right = rect.right; pptviewobj[id].rect.right = rect.right;
} }
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); BOOL gotinfo = GetPPTInfo(id);
return gotinfo;
}
BOOL StartPPTView(int id)
{
/* /*
* I'd really like to just hook on the new threadid. However this always gives * 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 * error 87. Perhaps I'm hooking to soon? No idea... however can't wait
@ -164,69 +217,47 @@ DllExport int OpenPPT(char *filename, HWND hParentWnd, RECT rect, char *previewp
* *
* hook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,pi.dwThreadId); * hook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,pi.dwThreadId);
*/ */
if(globalhook!=NULL) DEBUG("StartPPTView\n");
STARTUPINFO si;
PROCESS_INFORMATION pi;
char cmdline[MAX_PATH * 2];
if(globalhook != NULL)
UnhookWindowsHookEx(globalhook); UnhookWindowsHookEx(globalhook);
globalhook = SetWindowsHookEx(WH_CBT,CbtProc,hInstance,NULL); globalhook = SetWindowsHookEx(WH_CBT, CbtProc, hInstance, NULL);
if(globalhook==0) if(globalhook == 0)
{ {
DEBUG("OpenPPT: SetWindowsHookEx failed\n"); DEBUG("OpenPPT: SetWindowsHookEx failed\n");
ClosePPT(id); ClosePPT(id);
return -1; return FALSE;
}
if(GetPPTViewerPath(cmdline, sizeof(cmdline)) == FALSE)
{
DEBUG("OpenPPT: GetPPTViewerPath failed\n");
return FALSE;
} }
pptviewobj[id].state = PPT_STARTED; pptviewobj[id].state = PPT_STARTED;
Sleep(10); 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, "\"");
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
if(!CreateProcess(NULL, cmdline, 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"); DEBUG("OpenPPT: CreateProcess failed\n");
ClosePPT(id); ClosePPT(id);
return -1; return FALSE;
} }
pptviewobj[id].dwProcessId = pi.dwProcessId; pptviewobj[id].dwProcessId = pi.dwProcessId;
pptviewobj[id].dwThreadId = pi.dwThreadId; pptviewobj[id].dwThreadId = pi.dwThreadId;
pptviewobj[id].hThread = pi.hThread; pptviewobj[id].hThread = pi.hThread;
pptviewobj[id].hProcess = pi.hProcess; pptviewobj[id].hProcess = pi.hProcess;
while(pptviewobj[id].state==PPT_STARTED) while(pptviewobj[id].state == PPT_STARTED)
Sleep(10); Sleep(10);
if(gotinfo) return TRUE;
{
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. // Load information about the ppt from an info.txt file.
// Format: // Format:
// version // version
@ -242,26 +273,26 @@ BOOL GetPPTInfo(int id)
char buf[100]; char buf[100];
DEBUG("GetPPTInfo: start\n"); DEBUG("GetPPTInfo: start\n");
if(_stat(pptviewobj[id].filename, &filestats)!=0) if(_stat(pptviewobj[id].filename, &filestats) != 0)
return FALSE; return FALSE;
sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath); sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath);
int err = fopen_s(&pFile, info, "r"); int err = fopen_s(&pFile, info, "r");
if(err!=0) if(err != 0)
{ {
DEBUG("GetPPTInfo: file open failed - %d\n", err); DEBUG("GetPPTInfo: file open failed - %d\n", err);
return FALSE; return FALSE;
} }
fgets(buf, 100, pFile); // version == 1 fgets(buf, 100, pFile); // version == 1
fgets(buf, 100, pFile); fgets(buf, 100, pFile);
if(filestats.st_mtime!=atoi(buf)) if(filestats.st_mtime != atoi(buf))
{ {
fclose (pFile); fclose (pFile);
return FALSE; return FALSE;
} }
fgets(buf, 100, pFile); fgets(buf, 100, pFile);
if(filestats.st_size!=atoi(buf)) if(filestats.st_size != atoi(buf))
{ {
fclose (pFile); fclose(pFile);
return FALSE; return FALSE;
} }
fgets(buf, 100, pFile); // slidecount fgets(buf, 100, pFile); // slidecount
@ -269,10 +300,11 @@ BOOL GetPPTInfo(int id)
fgets(buf, 100, pFile); // first slide steps fgets(buf, 100, pFile); // first slide steps
int firstslidesteps = atoi(buf); int firstslidesteps = atoi(buf);
// check all the preview images still exist // 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); sprintf_s(info, MAX_PATH, "%s%i.bmp",
if(GetFileAttributes(info)==INVALID_FILE_ATTRIBUTES) pptviewobj[id].previewpath, i);
if(GetFileAttributes(info) == INVALID_FILE_ATTRIBUTES)
return FALSE; return FALSE;
} }
fclose(pFile); fclose(pFile);
@ -289,18 +321,22 @@ BOOL SavePPTInfo(int id)
FILE* pFile; FILE* pFile;
DEBUG("SavePPTInfo: start\n"); 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); DEBUG("SavePPTInfo: stat of %s failed\n", pptviewobj[id].filename);
return FALSE; return FALSE;
} }
sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath); sprintf_s(info, MAX_PATH, "%sinfo.txt", pptviewobj[id].previewpath);
int err = fopen_s(&pFile, info, "w"); int err = fopen_s(&pFile, info, "w");
if(err!=0) if(err != 0)
{ {
DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err); DEBUG("SavePPTInfo: fopen of %s failed%i\n", info, err);
return FALSE; return FALSE;
} }
else
{
DEBUG("SavePPTInfo: fopen of %s succeeded\n", info);
}
fprintf(pFile, "1\n"); fprintf(pFile, "1\n");
fprintf(pFile, "%u\n", filestats.st_mtime); fprintf(pFile, "%u\n", filestats.st_mtime);
fprintf(pFile, "%u\n", filestats.st_size); fprintf(pFile, "%u\n", filestats.st_size);
@ -319,15 +355,28 @@ BOOL GetPPTViewerPath(char *pptviewerpath, int strsize)
LRESULT lresult; LRESULT lresult;
DEBUG("GetPPTViewerPath: start\n"); 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,
if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\open\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS) "PowerPointViewer.Show.12\\shell\\Show\\command",
if(RegOpenKeyEx(HKEY_CLASSES_ROOT, "Applications\\PPTVIEW.EXE\\shell\\Show\\command", 0, KEY_READ, &hkey)!=ERROR_SUCCESS) 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; return FALSE;
}
}
}
dwtype = REG_SZ; dwtype = REG_SZ;
dwsize = (DWORD)strsize; dwsize = (DWORD)strsize;
lresult = RegQueryValueEx(hkey, NULL, NULL, &dwtype, (LPBYTE)pptviewerpath, &dwsize ); lresult = RegQueryValueEx(hkey, NULL, NULL, &dwtype,
(LPBYTE)pptviewerpath, &dwsize);
RegCloseKey(hkey); RegCloseKey(hkey);
if(lresult!=ERROR_SUCCESS) if(lresult != ERROR_SUCCESS)
return FALSE; return FALSE;
pptviewerpath[strlen(pptviewerpath)-4] = '\0'; // remove "%1" from end of key value pptviewerpath[strlen(pptviewerpath)-4] = '\0'; // remove "%1" from end of key value
DEBUG("GetPPTViewerPath: exit ok\n"); DEBUG("GetPPTViewerPath: exit ok\n");
@ -338,9 +387,9 @@ BOOL GetPPTViewerPath(char *pptviewerpath, int strsize)
void Unhook(int id) void Unhook(int id)
{ {
DEBUG("Unhook: start %d\n", id); DEBUG("Unhook: start %d\n", id);
if(pptviewobj[id].hook!=NULL) if(pptviewobj[id].hook != NULL)
UnhookWindowsHookEx(pptviewobj[id].hook); UnhookWindowsHookEx(pptviewobj[id].hook);
if(pptviewobj[id].mhook!=NULL) if(pptviewobj[id].mhook != NULL)
UnhookWindowsHookEx(pptviewobj[id].mhook); UnhookWindowsHookEx(pptviewobj[id].mhook);
pptviewobj[id].hook = NULL; pptviewobj[id].hook = NULL;
pptviewobj[id].mhook = NULL; pptviewobj[id].mhook = NULL;
@ -353,7 +402,7 @@ DllExport void ClosePPT(int id)
DEBUG("ClosePPT: start%d\n", id); DEBUG("ClosePPT: start%d\n", id);
pptviewobj[id].state = PPT_CLOSED; pptviewobj[id].state = PPT_CLOSED;
Unhook(id); Unhook(id);
if(pptviewobj[id].hWnd==0) if(pptviewobj[id].hWnd == 0)
TerminateThread(pptviewobj[id].hThread, 0); TerminateThread(pptviewobj[id].hThread, 0);
else else
PostMessage(pptviewobj[id].hWnd, WM_CLOSE, 0, 0); PostMessage(pptviewobj[id].hWnd, WM_CLOSE, 0, 0);
@ -367,9 +416,10 @@ DllExport void ClosePPT(int id)
DllExport void Resume(int id) DllExport void Resume(int id)
{ {
DEBUG("Resume: %d\n", id); DEBUG("Resume: %d\n", id);
MoveWindow(pptviewobj[id].hWnd, pptviewobj[id].rect.left, pptviewobj[id].rect.top, MoveWindow(pptviewobj[id].hWnd, pptviewobj[id].rect.left,
pptviewobj[id].rect.right - pptviewobj[id].rect.left, pptviewobj[id].rect.top,
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);
Unblank(id); Unblank(id);
} }
// Moves the show off the screen so it can't be seen // 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); DEBUG("Stop:%d\n", id);
MoveWindow(pptviewobj[id].hWnd, -32000, -32000, MoveWindow(pptviewobj[id].hWnd, -32000, -32000,
pptviewobj[id].rect.right - pptviewobj[id].rect.left, pptviewobj[id].rect.right - pptviewobj[id].rect.left,
pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE); pptviewobj[id].rect.bottom - pptviewobj[id].rect.top, TRUE);
} }
// Return the total number of slides // Return the total number of slides
DllExport int GetSlideCount(int id) DllExport int GetSlideCount(int id)
{ {
DEBUG("GetSlideCount:%d\n", id); DEBUG("GetSlideCount:%d\n", id);
if(pptviewobj[id].state==0) if(pptviewobj[id].state == 0)
return -1; return -1;
else else
return pptviewobj[id].slideCount; return pptviewobj[id].slideCount;
@ -395,7 +445,7 @@ DllExport int GetSlideCount(int id)
DllExport int GetCurrentSlide(int id) DllExport int GetCurrentSlide(int id)
{ {
DEBUG("GetCurrentSlide:%d\n", id); DEBUG("GetCurrentSlide:%d\n", id);
if(pptviewobj[id].state==0) if(pptviewobj[id].state == 0)
return -1; return -1;
else else
return pptviewobj[id].currentSlide; return pptviewobj[id].currentSlide;
@ -407,13 +457,17 @@ DllExport void NextStep(int id)
DEBUG("NextStep:%d (%d)\n", id, pptviewobj[id].currentSlide); DEBUG("NextStep:%d (%d)\n", id, pptviewobj[id].currentSlide);
if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount) if(pptviewobj[id].currentSlide>pptviewobj[id].slideCount)
return; 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 // Take a step backwards through the show
DllExport void PrevStep(int id) DllExport void PrevStep(int id)
{ {
DEBUG("PrevStep:%d (%d)\n", id, pptviewobj[id].currentSlide); 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); 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 // the slideshow has focus first
char ch[10]; char ch[10];
if(slideno<0) return; if(slideno < 0)
return;
pptviewobj[id].guess = slideno;
_itoa_s(slideno, ch, 10, 10); _itoa_s(slideno, ch, 10, 10);
HWND h1 = GetForegroundWindow(); HWND h1 = GetForegroundWindow();
HWND h2 = GetFocus(); HWND h2 = GetFocus();
SetForegroundWindow(pptviewobj[id].hWnd); SetForegroundWindow(pptviewobj[id].hWnd);
SetFocus(pptviewobj[id].hWnd); SetFocus(pptviewobj[id].hWnd);
Sleep(50); // slight pause, otherwise event triggering this call may grab focus back! 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, 0, 0);
keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0); keybd_event((BYTE)ch[i], 0, KEYEVENTF_KEYUP, 0);
} }
@ -511,12 +568,12 @@ DllExport void RestartShow(int id)
DEBUG("RestartShow:%d\n", id); DEBUG("RestartShow:%d\n", id);
Stop(id); Stop(id);
GotoSlide(id, pptviewobj[id].slideCount); GotoSlide(id, pptviewobj[id].slideCount);
while(pptviewobj[id].currentSlide>1) while(pptviewobj[id].currentSlide > 1)
{ {
PrevStep(id); PrevStep(id);
Sleep(10); Sleep(10);
} }
for(int i=0;i<=pptviewobj[id].firstSlideSteps;i++) for(int i = 0; i <= pptviewobj[id].firstSlideSteps; i++)
{ {
PrevStep(id); PrevStep(id);
Sleep(10); Sleep(10);
@ -531,53 +588,55 @@ DllExport void RestartShow(int id)
LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK CbtProc(int nCode, WPARAM wParam, LPARAM lParam)
{ {
HHOOK hook = globalhook; HHOOK hook = globalhook;
if(nCode==HCBT_CREATEWND) if(nCode == HCBT_CREATEWND)
{ {
char csClassName[16]; char csClassName[16];
HWND hCurrWnd = (HWND)wParam; HWND hCurrWnd = (HWND)wParam;
DWORD retProcId = NULL; DWORD retProcId = NULL;
GetClassName(hCurrWnd, csClassName, sizeof(csClassName)); GetClassName(hCurrWnd, csClassName, sizeof(csClassName));
if((strcmp(csClassName, "paneClassDC")==0) if((strcmp(csClassName, "paneClassDC") == 0)
||(strcmp(csClassName, "screenClass")==0)) ||(strcmp(csClassName, "screenClass") == 0))
{ {
int id=-1; int id = -1;
DWORD windowthread = GetWindowThreadProcessId(hCurrWnd,NULL); DWORD windowthread = GetWindowThreadProcessId(hCurrWnd,NULL);
for(int i=0; i<MAX_PPTOBJS; i++) for(int i = 0; i < MAX_PPTOBJS; i++)
{ {
if(pptviewobj[i].dwThreadId==windowthread) if(pptviewobj[i].dwThreadId == windowthread)
{ {
id=i; id = i;
break; break;
} }
} }
if(id>=0) if(id >= 0)
{ {
if(strcmp(csClassName, "paneClassDC")==0) if(strcmp(csClassName, "paneClassDC") == 0)
pptviewobj[id].hWnd2=hCurrWnd; pptviewobj[id].hWnd2=hCurrWnd;
else else
{ {
pptviewobj[id].hWnd=hCurrWnd; pptviewobj[id].hWnd = hCurrWnd;
CBT_CREATEWND* cw = (CBT_CREATEWND*)lParam; CBT_CREATEWND* cw = (CBT_CREATEWND*)lParam;
if(pptviewobj[id].hParentWnd!=NULL) if(pptviewobj[id].hParentWnd != NULL)
cw->lpcs->hwndParent = pptviewobj[id].hParentWnd; cw->lpcs->hwndParent = pptviewobj[id].hParentWnd;
cw->lpcs->cy=(pptviewobj[id].rect.bottom-pptviewobj[id].rect.top); cw->lpcs->cy = (pptviewobj[id].rect.bottom-pptviewobj[id].rect.top);
cw->lpcs->cx=(pptviewobj[id].rect.right-pptviewobj[id].rect.left); cw->lpcs->cx = (pptviewobj[id].rect.right-pptviewobj[id].rect.left);
cw->lpcs->y=-32000; cw->lpcs->y = -32000;
cw->lpcs->x=-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); UnhookWindowsHookEx(globalhook);
globalhook=NULL; globalhook = NULL;
pptviewobj[id].hook = SetWindowsHookEx(WH_CALLWNDPROC,CwpProc,hInstance,pptviewobj[id].dwThreadId); pptviewobj[id].hook = SetWindowsHookEx(WH_CALLWNDPROC,
pptviewobj[id].mhook = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInstance,pptviewobj[id].dwThreadId); CwpProc,hInstance, pptviewobj[id].dwThreadId);
pptviewobj[id].mhook = SetWindowsHookEx(WH_GETMESSAGE,
GetMsgProc, hInstance, pptviewobj[id].dwThreadId);
Sleep(10); Sleep(10);
pptviewobj[id].state = PPT_OPENED; 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 // 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; HHOOK hook = NULL;
MSG *pMSG = (MSG *)lParam; MSG *pMSG = (MSG *)lParam;
DWORD windowthread = GetWindowThreadProcessId(pMSG->hwnd,NULL); DWORD windowthread = GetWindowThreadProcessId(pMSG->hwnd, NULL);
int id=-1; int id = -1;
for(int i=0; i<MAX_PPTOBJS; i++) 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; hook = pptviewobj[id].mhook;
break; 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].firstSlideSteps++;
pptviewobj[id].steps++; 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 // 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. // 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; CWPSTRUCT *cwp;
cwp = (CWPSTRUCT *)lParam; cwp = (CWPSTRUCT *)lParam;
HHOOK hook = NULL; HHOOK hook = NULL;
char filename[MAX_PATH]; char filename[MAX_PATH];
DWORD windowthread = GetWindowThreadProcessId(cwp->hwnd,NULL); DWORD windowthread = GetWindowThreadProcessId(cwp->hwnd, NULL);
int id=-1; int id = -1;
for(int i=0; i<MAX_PPTOBJS; i++) 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; hook = pptviewobj[id].hook;
break; 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].state != PPT_LOADED)
{ {
if((pptviewobj[id].currentSlide>0) if((pptviewobj[id].currentSlide > 0)
&& (pptviewobj[id].previewpath!=NULL&&strlen(pptviewobj[id].previewpath)>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); 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].state = PPT_LOADED;
pptviewobj[id].currentSlide = pptviewobj[id].slideCount+1; pptviewobj[id].currentSlide = pptviewobj[id].slideCount + 1;
} }
} }
else else
{ {
pptviewobj[id].currentSlide = cwp->wParam - 255;
if(pptviewobj[id].state != PPT_LOADED) if(pptviewobj[id].state != PPT_LOADED)
{ {
if(pptviewobj[id].currentSlide<pptviewobj[id].slideCount) if((pptviewobj[id].currentSlide == 0)
||(pptviewobj[id].slideNo[pptviewobj[id].currentSlide] != cwp->wParam))
{ {
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; pptviewobj[id].state = PPT_CLOSING;
}
} }
return CallNextHookEx(hook,nCode,wParam,lParam); return CallNextHookEx(hook,nCode,wParam,lParam);
} }
@ -685,26 +779,26 @@ VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename)
UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom; UINT uiBytesPerAllRows = uiBytesPerRow * client.bottom;
PBYTE pDataBits; PBYTE pDataBits;
if ((pDataBits = new BYTE [uiBytesPerAllRows]) != NULL) if ((pDataBits = new BYTE[uiBytesPerAllRows]) != NULL)
{ {
BITMAPINFOHEADER bmi = {0}; BITMAPINFOHEADER bmi = {0};
BITMAPFILEHEADER bmf = {0}; BITMAPFILEHEADER bmf = {0};
// Prepare to get the data out of HBITMAP: // Prepare to get the data out of HBITMAP:
bmi.biSize = sizeof (bmi); bmi.biSize = sizeof(bmi);
bmi.biPlanes = 1; bmi.biPlanes = 1;
bmi.biBitCount = 24; bmi.biBitCount = 24;
bmi.biHeight = client.bottom; bmi.biHeight = client.bottom;
bmi.biWidth = client.right; bmi.biWidth = client.right;
// Get it: // Get it:
HDC hDC = GetDC (hWnd); HDC hDC = GetDC(hWnd);
GetDIBits (hDC, hBmp, 0, client.bottom, pDataBits, GetDIBits(hDC, hBmp, 0, client.bottom, pDataBits,
(BITMAPINFO*) &bmi, DIB_RGB_COLORS); (BITMAPINFO*) &bmi, DIB_RGB_COLORS);
ReleaseDC (hWnd, hDC); ReleaseDC(hWnd, hDC);
// Fill the file header: // Fill the file header:
bmf.bfOffBits = sizeof (bmf) + sizeof (bmi); bmf.bfOffBits = sizeof(bmf) + sizeof(bmi);
bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows; bmf.bfSize = bmf.bfOffBits + uiBytesPerAllRows;
bmf.bfType = 0x4D42; bmf.bfType = 0x4D42;
@ -713,31 +807,33 @@ VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename)
int err = fopen_s(&pFile, filename, "wb"); int err = fopen_s(&pFile, filename, "wb");
if (err == 0) if (err == 0)
{ {
fwrite (&bmf, sizeof (bmf), 1, pFile); fwrite(&bmf, sizeof(bmf), 1, pFile);
fwrite (&bmi, sizeof (bmi), 1, pFile); fwrite(&bmi, sizeof(bmi), 1, pFile);
fwrite (pDataBits, sizeof (BYTE), uiBytesPerAllRows, pFile); fwrite(pDataBits, sizeof(BYTE), uiBytesPerAllRows, pFile);
fclose (pFile); fclose(pFile);
} }
delete [] pDataBits; delete [] pDataBits;
} }
DeleteObject (hBmp); DeleteObject(hBmp);
} }
HBITMAP CaptureWindow (HWND hWnd) { HBITMAP CaptureWindow(HWND hWnd)
{
HDC hDC; HDC hDC;
BOOL bOk = FALSE; BOOL bOk = FALSE;
HBITMAP hImage = NULL; HBITMAP hImage = NULL;
hDC = GetDC (hWnd); hDC = GetDC(hWnd);
RECT rcClient; RECT rcClient;
GetClientRect (hWnd, &rcClient); GetClientRect(hWnd, &rcClient);
if ((hImage = CreateCompatibleBitmap (hDC, rcClient.right, rcClient.bottom)) != NULL) if((hImage = CreateCompatibleBitmap(hDC, rcClient.right, rcClient.bottom))
!= NULL)
{ {
HDC hMemDC; HDC hMemDC;
HBITMAP hDCBmp; 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"); HMODULE hLib = LoadLibrary("User32");
// PrintWindow works for windows outside displayable area // PrintWindow works for windows outside displayable area
// but was only introduced in WinXP. BitBlt requires the window to be topmost // but was only introduced in WinXP. BitBlt requires the window to be topmost
@ -757,12 +853,12 @@ HBITMAP CaptureWindow (HWND hWnd) {
bOk = TRUE; bOk = TRUE;
} }
} }
ReleaseDC (hWnd, hDC); ReleaseDC(hWnd, hDC);
if (! bOk) if(!bOk)
{ {
if (hImage) if (hImage)
{ {
DeleteObject (hImage); DeleteObject(hImage);
hImage = NULL; hImage = NULL;
} }
} }

View File

@ -27,11 +27,14 @@ VOID SaveBitmap (CHAR* filename, HBITMAP hBmp) ;
VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename); VOID CaptureAndSaveWindow(HWND hWnd, CHAR* filename);
BOOL GetPPTInfo(int id); BOOL GetPPTInfo(int id);
BOOL SavePPTInfo(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); void Unhook(int id);
#define MAX_PPTOBJS 50 #define MAX_PPTOBJS 16
#define MAX_SLIDES 256
struct PPTVIEWOBJ struct PPTVIEWOBJ
{ {
@ -49,7 +52,9 @@ struct PPTVIEWOBJ
int currentSlide; int currentSlide;
int firstSlideSteps; int firstSlideSteps;
int steps; int steps;
int guess;
char filename[MAX_PATH]; char filename[MAX_PATH];
char previewpath[MAX_PATH]; char previewpath[MAX_PATH];
int slideNo[MAX_SLIDES];
PPTVIEWSTATE state; PPTVIEWSTATE state;
}; };