3 Part of the swftools installer (Main program).
5 Copyright (c) 2004 Matthias Kramm <kramm@quiss.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
30 #include "../config.h" //for swftools version
31 #include "../lib/os.h" //for registry functions
33 static int config_forAllUsers = 0;
34 static int config_createLinks = 0;
35 static int config_createStartmenu = 1;
36 static int config_createDesktop = 1;
41 static char*install_path = "c:\\swftools\\";
42 static char pathBuf[1024];
43 static int do_abort = 0;
45 static HWND wnd_params = 0;
46 static HWND wnd_progress = 0;
47 static HWND wnd_finish = 0;
48 static HWND wnd_background = 0;
52 #define USER_SETMESSAGE 0x7f01
54 struct progress_data {
83 LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
85 //printf("%08x, %d %08x %08x\n", hwnd, message, wParam, lParam);
87 /* in order for the delegation below to also work for
88 WM_CREATE, we need to assign our window pointers *before* the
89 CreateWindow returns, because that's when the WM_CREATE event
92 if(message == WM_CREATE) {
93 CREATESTRUCT*cs = ((LPCREATESTRUCT)lParam);
94 if(cs->lpCreateParams && !strcmp((char*)cs->lpCreateParams, "params")) {
97 else if(cs->lpCreateParams && !strcmp((char*)cs->lpCreateParams, "progress")) {
100 else if(cs->lpCreateParams && !strcmp((char*)cs->lpCreateParams, "finish")) {
103 else if(cs->lpCreateParams && !strcmp((char*)cs->lpCreateParams, "background")) {
104 wnd_background = hwnd;
109 return DefWindowProc(hwnd, message, wParam, lParam);
110 } else if(hwnd == wnd_progress) {
111 static struct progress_data data;
115 case USER_SETMESSAGE:
116 data.text3 = (char*)wParam;
117 SendMessage(data.wnd_text3, WM_SETTEXT, 0, (LPARAM)data.text3);
120 memset(&data, 0, sizeof(data));
121 data.text1 = "Installing SWFTools";
122 data.text2 = (char*)malloc(strlen(install_path)+250);
124 sprintf(data.text2, "to %s", install_path);
128 CREATESTRUCT*cs = ((LPCREATESTRUCT)lParam);
130 GetClientRect (hwnd, &rc);
131 data.width = rc.right - rc.left;
132 data.height = rc.bottom - rc.top;
133 data.bar_width = cs->cx - 17;
135 data.bar_posx = (data.width -data.bar_width)/2;
139 data.hwndButton = CreateWindow (
142 WS_CHILD | WS_VISIBLE,
153 SendMessage(data.hwndButton, PBM_SETRANGE, 0, (LPARAM) MAKELONG(0,data.range));
154 SendMessage(data.hwndButton, PBM_SETSTEP, (WPARAM) data.step, 0);
158 if(data.pos+data.step < data.range) {
159 data.pos += data.step;
160 SendMessage(data.hwndButton, PBM_STEPIT, wParam, lParam);
165 HDC hdc; /* A device context used for drawing */
166 PAINTSTRUCT ps; /* Also used during window drawing */
167 RECT rc; /* A rectangle used during drawing */
170 SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
171 GetTextMetrics(hdc, &tm);
172 ReleaseDC(hwnd, hdc);
174 hdc = BeginPaint (hwnd, &ps);
178 HDC memDc=CreateCompatibleDC(hdc);
179 SelectObject(memDc,logo);
180 BitBlt(hdc,0,0,406,93,memDc,0,0,SRCCOPY);
185 SetBkMode(hdc, TRANSPARENT);
187 rc.top = 8; rc.left= 0; rc.right = data.width; rc.bottom = 24;
188 DrawText(hdc, data.text1, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
191 char*text = data.text2;
192 if(tm.tmAveCharWidth * strlen(text) > data.width) {
193 int chars = (data.width / tm.tmAveCharWidth)-8;
194 if(chars>240) chars=240;
195 strncpy(buf, text, chars);
196 strcpy(&buf[chars],"...");
200 rc.top = 32; rc.left= 0; rc.right = data.width; rc.bottom = 48;
201 DrawText(hdc, text, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
203 //rc.top = data.height-32; rc.left= 0; rc.right = data.width; rc.bottom = data.height;
204 //DrawText(hdc, data.text3, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
206 EndPaint (hwnd, &ps);
211 return DefWindowProc(hwnd, message, wParam, lParam);
213 return DefWindowProc(hwnd, message, wParam, lParam);
215 } else if(hwnd == wnd_params) {
216 static struct params_data data;
220 memset(&data, 0, sizeof(data));
221 CREATESTRUCT*cs = ((LPCREATESTRUCT)lParam);
223 GetClientRect (hwnd, &rc);
224 data.width = rc.right - rc.left;
225 data.height = rc.bottom - rc.top;
227 //EDITTEXT IDD_EDIT,68,8,72,12, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
228 data.edit = CreateWindow (
231 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL,
234 (data.width-64)-32*2,
242 data.explore = CreateWindow (
245 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
256 data.installButton = CreateWindow (
259 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
270 SendMessage(data.edit, WM_SETTEXT, 0, (LPARAM)install_path);
273 case USER_SETMESSAGE: {
274 //install_path = (char*)lParam;
275 SendMessage(data.edit, WM_SETTEXT, 0, (LPARAM)install_path);
276 printf("Setting path to %s\n", install_path);
285 SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
286 GetTextMetrics(hdc, &tm);
287 ReleaseDC(hwnd, hdc);
288 hdc = BeginPaint (hwnd, &ps);
289 SetBkMode(hdc, TRANSPARENT);
290 rc.top = 32; rc.left= 16; rc.right = data.width-32*2; rc.bottom = 20;
291 DrawText(hdc, "Select Installation directory", -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
292 EndPaint (hwnd, &ps);
296 if((wParam&0xffff) == 0x9999) {
298 memset(&browse, 0, sizeof(browse));
299 browse.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_USENEWUI;// | BIF_RETURNONLYFSDIRS; //BIF_VALIDATE
300 browse.pszDisplayName = (CHAR*)malloc(MAX_PATH);
301 memset(browse.pszDisplayName, 0, MAX_PATH);
302 browse.lpszTitle = "Select installation directory";
303 /*browse.pidlRoot = (ITEMIDLIST*)malloc(sizeof(ITEMIDLIST)*200);
304 memset((void*)browse.pidlRoot, 0, sizeof(ITEMIDLIST)*200);*/
305 printf("Start browsing %s\n", browse.pszDisplayName);
307 //ParseDisplayName(install_path,0,&browse.pidlRoot,0,0);
308 //SHParseDisplayName(install_path,0,&browse.pidlRoot,0,0);
309 //SHBrowseForFolderA(&browse);
310 browse.pidlRoot = SHBrowseForFolder(&browse);
311 printf("Browsing returns %s / %08x\n", browse.pszDisplayName, browse.pidlRoot);
312 if(browse.pszDisplayName) {
313 if(SHGetPathFromIDList(browse.pidlRoot, browse.pszDisplayName)) {
314 printf("Path is %s\n", browse.pszDisplayName);
315 install_path = browse.pszDisplayName;
318 SendMessage(data.edit, WM_SETTEXT, 0, (LPARAM)install_path);
320 } else if((wParam&0xffff) == 0xabcd) {
324 } else if((wParam&0xffff) == 0x1234) {
325 SendMessage(data.edit, WM_GETTEXT, sizeof(pathBuf), (LPARAM)&(pathBuf[0]));
327 install_path = pathBuf;
331 return DefWindowProc(hwnd, message, wParam, lParam);
345 return DefWindowProc(hwnd, message, wParam, lParam);
347 return DefWindowProc(hwnd, message, wParam, lParam);
349 } else if(hwnd == wnd_finish) {
350 static struct finish_data data;
355 CREATESTRUCT*cs = ((LPCREATESTRUCT)lParam);
356 GetClientRect (hwnd, &rc);
357 data.width = rc.right - rc.left;
358 data.height = rc.bottom - rc.top;
360 data.text = malloc(strlen(install_path)+256);
361 sprintf(data.text, "SWFTools has been installed into directory\r\n%s\r\nsucessfully.", install_path);
363 data.installButton = CreateWindow (
366 WS_CHILD | WS_VISIBLE | WS_TABSTOP,
377 if(config_createLinks) {
378 data.check1 = CreateWindow (
380 "Create Desktop Shortcut",
381 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_CHECKBOX,
382 32, data.height - 96,
384 hwnd, (HMENU)0xabcf, cs->hInstance, NULL);
386 data.check2 = CreateWindow (
388 "Create Start Menu Entry",
389 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_CHECKBOX,
390 32, data.height - 64,
392 hwnd, (HMENU)0xabd0, cs->hInstance, NULL);
394 SendDlgItemMessage(hwnd, 0xabcf, BM_SETCHECK, config_createStartmenu, 0);
395 SendDlgItemMessage(hwnd, 0xabd0, BM_SETCHECK, config_createDesktop, 0);
404 SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
405 GetTextMetrics(hdc, &tm);
406 ReleaseDC(hwnd, hdc);
407 hdc = BeginPaint (hwnd, &ps);
408 SetBkMode(hdc, TRANSPARENT);
411 rc.right = data.width;
412 rc.bottom = data.height-40-32;
413 DrawText(hdc, data.text, -1, &rc, DT_CENTER | DT_VCENTER);
414 EndPaint (hwnd, &ps);
417 return DefWindowProc(hwnd, message, wParam, lParam);
420 if((wParam&0xffff) == 0xabce) {
425 if((wParam&0xffff) == 0xabcf) {
426 config_createDesktop = SendDlgItemMessage(hwnd, 0xabcf, BM_GETCHECK, 0, 0);
427 config_createDesktop^=1;
428 SendDlgItemMessage(hwnd, 0xabcf, BM_SETCHECK, config_createDesktop, 0);
431 if((wParam&0xffff) == 0xabd0) {
432 config_createStartmenu = SendDlgItemMessage(hwnd, 0xabd0, BM_GETCHECK, 0, 0);
433 config_createStartmenu^=1;
434 SendDlgItemMessage(hwnd, 0xabd0, BM_SETCHECK, config_createStartmenu, 0);
439 free(data.text);data.text = 0;
445 return DefWindowProc(hwnd, message, wParam, lParam);
448 } else if(hwnd == wnd_background) {
455 hdc = BeginPaint(hwnd, &ps);
456 SetBkMode(hdc, TRANSPARENT);
458 HPEN pen = CreatePen(PS_SOLID, 2, RGB(255, 255, 0));
459 HPEN oldPen = (HPEN)SelectObject(hdc, pen);
461 MoveToEx(hdc, 10, 10, 0);
462 //LineTo(hdc, 100, 100);
464 SelectObject(hdc, oldPen);
472 return DefWindowProc(hwnd, message, wParam, lParam);
475 void processMessages()
478 while(PeekMessage(&msg,NULL,0,0,0))
480 GetMessage(&msg, NULL, 0, 0);
481 TranslateMessage(&msg);
482 DispatchMessage(&msg);
486 static char*lastmessage = 0;
487 void myarchivestatus(int type, char*text)
489 if(text && text[0]=='[')
491 //printf("%s\n", text);
493 SendMessage(wnd_progress, USER_SETMESSAGE, (WPARAM)strdup(text), 0);
494 SendMessage(wnd_progress, WM_PAINT, 0, 0);
497 SendMessage(wnd_progress, PBM_STEPIT, 0, 0);
498 /* while we're here, we might also make ourselves useful */
500 /* we want the user to see what we're writing, right? */
506 int ret = MessageBox(0, text, "Error", MB_RETRYCANCEL|MB_ICONERROR);
508 /* there is no MB_CANCEL, so, *sigh*, we have to display
509 the "retry" button. So pretend it's doing anything... */
518 int addRegistryEntries(char*install_dir)
521 ret = setRegistryEntry("Software\\quiss.org\\swftools\\InstallPath", install_dir);
526 int CreateShortcut(char*path, char*description, char*filename, char*arguments, int iconindex, char*iconpath, char*workdir)
528 WCHAR wszFilename[MAX_PATH];
529 IShellLink *ps1 = NULL;
530 IPersistFile *pPf = NULL;
532 hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (void*)&ps1);
533 if(FAILED(hr)) return 0;
534 hr = ps1->lpVtbl->QueryInterface(ps1, &IID_IPersistFile, (void **)&pPf);
535 if(FAILED(hr)) return 0;
536 hr = ps1->lpVtbl->SetPath(ps1, path);
537 if(FAILED(hr)) return 0;
538 hr = ps1->lpVtbl->SetDescription(ps1, description);
541 hr = ps1->lpVtbl->SetArguments(ps1, arguments);
542 if(FAILED(hr)) return 0;
545 hr = ps1->lpVtbl->SetIconLocation(ps1, iconpath, iconindex);
546 if (FAILED(hr)) return 0;
549 hr = ps1->lpVtbl->SetWorkingDirectory(ps1, workdir);
550 if (FAILED(hr)) return 0;
552 MultiByteToWideChar(CP_ACP, 0, filename, -1, wszFilename, MAX_PATH);
553 hr = pPf->lpVtbl->Save(pPf, wszFilename, TRUE);
557 pPf->lpVtbl->Release(pPf);
558 ps1->lpVtbl->Release(ps1);
563 static HRESULT (WINAPI *f_SHGetSpecialFolderPath)(HWND hwnd, LPTSTR lpszPath, int nFolder, BOOL fCreate);
564 static char path_startmenu[MAX_PATH];
565 static char path_desktop[MAX_PATH];
567 int WINAPI WinMain(HINSTANCE me,HINSTANCE hPrevInst,LPSTR lpszArgs, int nWinMode)
571 wcl.lpfnWndProc = WindowFunc;
572 wcl.lpszClassName= "SWFTools-Install";
573 wcl.style = CS_HREDRAW | CS_VREDRAW;
574 wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
575 wcl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
576 wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
577 wcl.lpszMenuName = NULL; //no menu
580 wcl.hbrBackground= (HBRUSH)GetStockObject(LTGRAY_BRUSH);
581 wcl.cbSize = sizeof(WNDCLASSEX);
584 memcpy(&wcl_text, &wcl, sizeof(WNDCLASSEX));
585 wcl_text.lpszClassName= "TextClass";
586 wcl_text.hbrBackground = GetStockObject(HOLLOW_BRUSH);
588 WNDCLASSEX wcl_background;
589 memcpy(&wcl_background, &wcl, sizeof(WNDCLASSEX));
590 wcl_background.lpszClassName= "SWFTools Installer";
591 wcl_background.hbrBackground= CreateSolidBrush(RGB(0, 0, 128));
593 HINSTANCE shell32 = LoadLibrary("shell32.dll");
595 MessageBox(0, "Could not load shell32.dll", "Install.exe", MB_OK);
598 f_SHGetSpecialFolderPath = (HRESULT (WINAPI*)(HWND,LPTSTR,int,BOOL))GetProcAddress(shell32, "SHGetSpecialFolderPathA");
599 if(!f_SHGetSpecialFolderPath) {
600 MessageBox(0, "Could not load shell32.dll", "Install.exe", MB_OK);
604 HRESULT ret = CoInitialize(NULL);
606 MessageBox(0, "Could not initialize COM interface", "Install.exe", MB_OK);
610 char mypath[MAX_PATH];
611 path_startmenu[0] = 0;
613 if(config_forAllUsers) {
614 f_SHGetSpecialFolderPath(NULL, path_desktop, CSIDL_COMMON_DESKTOPDIRECTORY, 0);
615 f_SHGetSpecialFolderPath(NULL, path_startmenu, CSIDL_COMMON_PROGRAMS, 0);
617 f_SHGetSpecialFolderPath(NULL, path_desktop, CSIDL_DESKTOPDIRECTORY, 0);
618 f_SHGetSpecialFolderPath(NULL, path_startmenu, CSIDL_PROGRAMS, 0);
621 if(!RegisterClassEx(&wcl)) {
622 MessageBox(0, "Could not register window class", "Install.exe", MB_OK);
625 if(!RegisterClassEx(&wcl_background)) {
626 MessageBox(0, "Could not register window class 2", "Install.exe", MB_OK);
630 HWND background = CreateWindow(wcl_background.lpszClassName, "Setup SWFTools",
632 GetSystemMetrics(SM_CXFULLSCREEN),
633 GetSystemMetrics(SM_CYFULLSCREEN),
635 (void*)"background");
638 MessageBox(0, "Could not create installation background window", "Install.exe", MB_OK);
642 ShowWindow(background, SW_SHOWMAXIMIZED);
643 SetForegroundWindow(background);
644 UpdateWindow(background);
647 GetWindowRect(background, &r);
648 int xx = 320, yy = 200;
649 if(r.right - r.left > 320)
650 xx = r.right - r.left;
651 if(r.right - r.left > 200)
652 yy = r.bottom - r.top;
654 logo = LoadBitmap(me, "SWFTOOLS");
656 install_path = getRegistryEntry("Software\\quiss.org\\swftools\\InstallPath");
657 if(!install_path || !install_path[0])
658 install_path = "c:\\swftools\\";
661 InitCommonControls();
663 HWND installpath_window = CreateWindow(
664 wcl.lpszClassName, /* Class name */
665 "SWFTools Installer", /* Caption */
666 /*WS_CHILD |*/ WS_CAPTION,
667 (xx-320)/2, /* Initial x */
668 (yy-200)/2, /* Initial y */
669 320, /* Initial x size */
670 200, /* Initial y size */
671 background, /* No parent window */
673 me, /* This program instance */
674 (void*)"params" /* Creation parameters */
677 if(!installpath_window) {
678 MessageBox(background, "Could not create installation window", "Install.exe", MB_OK);
682 ShowWindow (wnd_params, nWinMode);
683 SetFocus(wnd_params);
684 SetForegroundWindow(wnd_params);
685 UpdateWindow (wnd_params);
690 GetMessage(&msg,NULL,0,0);
691 TranslateMessage(&msg);
692 DispatchMessage(&msg);
696 MessageBox(background, "Aborting Installation", "Error", MB_OK|MB_ICONERROR);
701 sprintf(buf, "Do you want me to install SWFTools into the directory %s now?", install_path);
702 int ret = MessageBox(0, buf, "SWFTools Install", MB_YESNO|MB_ICONQUESTION);
707 wcl.lpszClassName, /* Class name */
708 "Installing...", /* Caption */
709 //WS_CHILD | WS_CAPTION,
711 (xx-260)/2, (yy-128)/2,
712 260, /* Initial x size */
713 128, /* Initial y size */
714 background, /* No parent window */
716 me, /* This program instance */
717 (void*)"progress" /* Creation parameters */
719 ShowWindow (wnd_progress, nWinMode);
720 SetFocus(wnd_progress);
721 SetForegroundWindow(wnd_progress);
722 UpdateWindow (wnd_progress);
724 int success = unpack_archive(crndata, install_path, myarchivestatus);
726 DestroyWindow(wnd_progress);
731 MessageBox(background, "Aborting Installation", "Error", MB_OK|MB_ICONERROR);
735 char* pdf2swf_path = concatPaths(install_path, "pdf2swf_gui.exe");
736 FILE*fi = fopen(pdf2swf_path, "rb");
738 config_createLinks = 1;
742 int h = config_createLinks?200:160;
744 wcl.lpszClassName, /* Class name */
745 "Finished", /* Caption */
746 /*WS_CHILD |*/ WS_CAPTION,
747 //WS_OVERLAPPEDWINDOW&(~WS_SIZEBOX), /* Style */
748 (xx-320)/2, (yy-h)/2,
749 320, /* Initial x size */
750 h, /* Initial y size */
751 background, /* No parent window */
753 me, /* This program instance */
754 (void*)"finish" /* Creation parameters */
756 ShowWindow(wnd_finish, nWinMode);
757 SetFocus(wnd_finish);
758 SetForegroundWindow(wnd_finish);
759 UpdateWindow(wnd_finish);
764 MessageBox(0, "Aborting Installation", "Error", MB_OK|MB_ICONERROR);
768 if(!addRegistryEntries(install_path)) {
769 MessageBox(0, "Couldn't create Registry Entries", "SWFTools Install", MB_OK|MB_ICONERROR);
773 if(config_createLinks) {
774 if(config_createDesktop && path_desktop[0]) {
775 char* linkName = concatPaths(path_desktop, "pdf2swf.lnk");
776 if(!CreateShortcut(pdf2swf_path, "pdf2swf", linkName, 0, 0, 0, install_path)) {
777 MessageBox(0, "Couldn't create desktop shortcut", "Install.exe", MB_OK);
781 if(config_createStartmenu && path_startmenu[0]) {
782 char* group = concatPaths(path_startmenu, "pdf2swf");
783 CreateDirectory(group, 0);
784 char* linkName = concatPaths(group, "pdf2swf.lnk");
785 if(!CreateShortcut(pdf2swf_path, "pdf2swf", linkName, 0, 0, 0, install_path)) {
786 MessageBox(0, "Couldn't create start menu entry", "Install.exe", MB_OK);