X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=installer%2Finstaller.c;h=3e0e95e166aa9f058e53ea1979583cd8d661b2f0;hb=d9b87736710215927a329967c1ebc45bc8d665fa;hp=397cd59a70a863a686c03cdf729630efbd2a25c7;hpb=da97caafcee0c98ab921da77fbec70aa26727d98;p=swftools.git diff --git a/installer/installer.c b/installer/installer.c index 397cd59..3e0e95e 100644 --- a/installer/installer.c +++ b/installer/installer.c @@ -19,45 +19,354 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include +#include +#include #include #include #include "depack.h" #include "../config.h" //for swftools version +#include "../lib/os.h" //for registry functions extern char*crndata; +static char*install_path = "c:\\swftools\\"; +static char pathBuf[1024]; +static int do_abort = 0; + +static HWND wnd_progress = 0; +static HWND wnd_params = 0; + +static HBITMAP logo; + +#define USER_SETMESSAGE 0x7f01 + +struct progress_data { + int width,height; + int bar_width; + int bar_height; + int bar_posx; + int bar_posy; + int pos,step,range; + char*text1; + char*text2; + char*text3; + HWND hwndButton; + HWND wnd_text3; +}; +struct params_data { + int width,height; + int ok; + HWND installButton; + HWND edit; + HWND explore; +}; + LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - printf("%08x, %d %08x %08x\n", hwnd, message, wParam, lParam); - switch(message) + //printf("%08x, %d %08x %08x\n", hwnd, message, wParam, lParam); + + /* in order for the delegation below to also work for + WM_CREATE, we need to assign our window pointers *before* the + CreateWindow returns, because that's when the WM_CREATE event + is sent */ + if(message == WM_CREATE) { + CREATESTRUCT*cs = ((LPCREATESTRUCT)lParam); + if(cs->lpCreateParams && !strcmp((char*)cs->lpCreateParams, "params")) { + wnd_params = hwnd; + } + if(cs->lpCreateParams && !strcmp((char*)cs->lpCreateParams, "progress")) { + wnd_progress = hwnd; + } + } + + if(hwnd == 0) { + return DefWindowProc(hwnd, message, wParam, lParam); + } else if(hwnd == wnd_progress) { + static struct progress_data data; + + switch(message) + { + case USER_SETMESSAGE: + data.text3 = (char*)wParam; + SendMessage(data.wnd_text3, WM_SETTEXT, 0, (LPARAM)data.text3); + return 0; + case WM_CREATE: { + memset(&data, 0, sizeof(data)); + data.text1 = "Installing SWFTools"; + data.text2 = (char*)malloc(strlen(install_path)+250); + sprintf(data.text2, "to %s", install_path); + data.pos = 0; + data.step = 1; + + CREATESTRUCT*cs = ((LPCREATESTRUCT)lParam); + RECT rc; + GetClientRect (hwnd, &rc); + data.width = rc.right - rc.left; + data.height = rc.bottom - rc.top; + data.bar_width = cs->cx - 17; + data.bar_height= 16; + data.bar_posx = (data.width -data.bar_width)/2; + data.bar_posy = 56; + data.range = 50; + + data.hwndButton = CreateWindow ( + PROGRESS_CLASS, + "Progress", + WS_CHILD | WS_VISIBLE, + data.bar_posx, + data.bar_posy, + data.bar_width, + data.bar_height, + hwnd, /* Parent */ + (HMENU)1, + cs->hInstance, + NULL + ); + + data.wnd_text3 = CreateWindow ( + WC_STATIC, + "text3", + WS_CHILD | WS_VISIBLE, + data.bar_posx, + 72, + (rc.right - rc.left - data.bar_posx*2), + 20, + hwnd, /* Parent */ + (HMENU)1, + cs->hInstance, + NULL + ); + SendMessage(data.wnd_text3, WM_SETTEXT, 0, (LPARAM)""); + + SendMessage(data.hwndButton, PBM_SETRANGE, 0, (LPARAM) MAKELONG(0,data.range)); + SendMessage(data.hwndButton, PBM_SETSTEP, (WPARAM) data.step, 0); + return 0; + } + case PBM_STEPIT: { + if(data.pos+data.step < data.range) { + data.pos += data.step; + SendMessage(data.hwndButton, PBM_STEPIT, wParam, lParam); + } + } + case WM_PAINT: { + TEXTMETRIC tm; + HDC hdc; /* A device context used for drawing */ + PAINTSTRUCT ps; /* Also used during window drawing */ + RECT rc; /* A rectangle used during drawing */ + + hdc = GetDC(hwnd); + SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); + GetTextMetrics(hdc, &tm); + ReleaseDC(hwnd, hdc); + + hdc = BeginPaint (hwnd, &ps); + + /* + // draw logo + HDC memDc=CreateCompatibleDC(hdc); + SelectObject(memDc,logo); + BitBlt(hdc,0,0,406,93,memDc,0,0,SRCCOPY); + DeleteDC(memDc); + // / + */ + + SetBkMode(hdc, TRANSPARENT); + + rc.top = 8; rc.left= 0; rc.right = data.width; rc.bottom = 24; + DrawText(hdc, data.text1, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); + + char buf[256]; + char*text = data.text2; + if(tm.tmAveCharWidth * strlen(text) > data.width) { + int chars = (data.width / tm.tmAveCharWidth)-8; + if(chars>240) chars=240; + strncpy(buf, text, chars); + strcpy(&buf[chars],"..."); + text = buf; + } + + rc.top = 32; rc.left= 0; rc.right = data.width; rc.bottom = 48; + DrawText(hdc, text, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); + + EndPaint (hwnd, &ps); + return 0; + } + case WM_DESTROY: + wnd_progress = 0; + return DefWindowProc(hwnd, message, wParam, lParam); + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + } else if(hwnd == wnd_params) { + static struct params_data data; + switch(message) + { + case WM_CREATE: { + memset(&data, 0, sizeof(data)); + CREATESTRUCT*cs = ((LPCREATESTRUCT)lParam); + RECT rc; + GetClientRect (hwnd, &rc); + data.width = rc.right - rc.left; + data.height = rc.bottom - rc.top; + + //EDITTEXT IDD_EDIT,68,8,72,12, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP + HWND text = CreateWindow( + WC_STATIC, + "Select Installation Directory:", + WS_CHILD | WS_VISIBLE, + 32, + 16, + data.width-32*2, + 20, + hwnd, /* Parent */ + 0, + cs->hInstance, + NULL + ); + + data.edit = CreateWindow ( + WC_EDIT, + "EditPath", + WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_AUTOHSCROLL, + 32, + 48, + (data.width-64)-32*2, + 20, + hwnd, /* Parent */ + (HMENU)0x1234, + cs->hInstance, + NULL + ); + + data.explore = CreateWindow ( + WC_BUTTON, + "Browse", + WS_CHILD | WS_VISIBLE | WS_TABSTOP, + data.width-32-64, + 48, + 64, + 20, + hwnd, /* Parent */ + (HMENU)0x9999, + cs->hInstance, + NULL + ); + + data.installButton = CreateWindow ( + WC_BUTTON, + "Install", + WS_CHILD | WS_VISIBLE | WS_TABSTOP, + (data.width - 80)/2, + data.height - 32*2, + 80, + 32, + hwnd, /* Parent */ + (HMENU)0xabcd, + cs->hInstance, + NULL + ); + + SendMessage(data.edit, WM_SETTEXT, 0, (LPARAM)install_path); + return 0; + } + case USER_SETMESSAGE: { + //install_path = (char*)lParam; + SendMessage(data.edit, WM_SETTEXT, 0, (LPARAM)install_path); + printf("Setting path to %s\n", install_path); + return 0; + } + case WM_PAINT: { + return DefWindowProc(hwnd, message, wParam, lParam); + } + case WM_COMMAND: { + if((wParam&0xffff) == 0x9999) { + BROWSEINFOA browse; + memset(&browse, 0, sizeof(browse)); + browse.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_USENEWUI;// | BIF_RETURNONLYFSDIRS; //BIF_VALIDATE + browse.pszDisplayName = (CHAR*)malloc(MAX_PATH); + memset(browse.pszDisplayName, 0, MAX_PATH); + browse.lpszTitle = "Select installation directory"; + /*browse.pidlRoot = (ITEMIDLIST*)malloc(sizeof(ITEMIDLIST)*200); + memset((void*)browse.pidlRoot, 0, sizeof(ITEMIDLIST)*200);*/ + printf("Start browsing %s\n", browse.pszDisplayName); + //SHGetDesktopFolder + //ParseDisplayName(install_path,0,&browse.pidlRoot,0,0); + //SHParseDisplayName(install_path,0,&browse.pidlRoot,0,0); + //SHBrowseForFolderA(&browse); + browse.pidlRoot = SHBrowseForFolder(&browse); + printf("Browsing returns %s / %08x\n", browse.pszDisplayName, browse.pidlRoot); + if(browse.pszDisplayName) { + if(SHGetPathFromIDList(browse.pidlRoot, browse.pszDisplayName)) { + printf("Path is %s\n", browse.pszDisplayName); + install_path = browse.pszDisplayName; + } + } + SendMessage(data.edit, WM_SETTEXT, 0, (LPARAM)install_path); + return 0; + } else if((wParam&0xffff) == 0xabcd) { + data.ok = 1; + DestroyWindow(wnd_params); + return 0; + } else if((wParam&0xffff) == 0x1234) { + SendMessage(data.edit, WM_GETTEXT, sizeof(pathBuf), (LPARAM)&(pathBuf[0])); + if(pathBuf[0]) { + install_path = pathBuf; + printf("Path edited: now \"%s\"\n", install_path); + } + return 0; + } + return DefWindowProc(hwnd, message, wParam, lParam); + } + case WM_KEYDOWN: { + if(wParam == 0x49) { + DestroyWindow(wnd_params); + } + return 0; + } + case WM_DESTROY: + if(!data.ok) { + do_abort = 1; + PostQuitMessage (0); + } + wnd_params = 0; + return DefWindowProc(hwnd, message, wParam, lParam); + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + } + return DefWindowProc(hwnd, message, wParam, lParam); +} + +void processMessages() +{ + MSG msg; + while(PeekMessage(&msg,NULL,0,0,0)) { - case WM_DESTROY: - PostQuitMessage(0); - break; - default: - return DefWindowProc(hwnd, message, wParam, lParam); + GetMessage(&msg, NULL, 0, 0); + TranslateMessage(&msg); + DispatchMessage(&msg); } - return 0; } -#if USE_CONSOLE -static HANDLE console; -#endif static char*lastmessage = 0; void myarchivestatus(int type, char*text) { - DWORD written = 0; -#if USE_CONSOLE - if(console) { - WriteConsole(console, text, strlen(text), &written, 0); - WriteConsole(console, "\n", 1, &written, 0); - fflush(stdout); - } -#endif - if(!written) { - printf("%s\n", text); + if(text && text[0]=='[') + return; + //printf("%s\n", text); + + SendMessage(wnd_progress, USER_SETMESSAGE, (WPARAM)strdup(text), 0); + SendMessage(wnd_progress, WM_PAINT, 0, 0); + int t; + for(t=0;t<9;t++) { + SendMessage(wnd_progress, PBM_STEPIT, 0, 0); + /* while we're here, we might also make ourselves useful */ + processMessages(); + /* we want the user to see what we're writing, right? */ + Sleep(30); } if(type<0) { @@ -74,54 +383,116 @@ void myarchivestatus(int type, char*text) } } +int addRegistryEntries(char*install_dir) +{ + int ret; + ret = setRegistryEntry("Software\\quiss.org\\swftools\\InstallPath", install_dir); + if(!ret) return 0; + return 1; +} + int WINAPI WinMain(HINSTANCE me,HINSTANCE hPrevInst,LPSTR lpszArgs, int nWinMode) { - WNDCLASS wcl; - char*install_dir = "C:\\swftools\\"; + WNDCLASSEX wcl; wcl.hInstance = me; wcl.lpszClassName= "SWFTools-Installer"; wcl.lpfnWndProc = WindowFunc; - wcl.style = 0; //default style - wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION); + wcl.style = CS_HREDRAW | CS_VREDRAW; + wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wcl.hIconSm = LoadIcon(NULL, IDI_APPLICATION); wcl.hCursor = LoadCursor(NULL, IDC_ARROW); wcl.lpszMenuName = NULL; //no menu wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; - wcl.hbrBackground=(HBRUSH)GetStockObject(DKGRAY_BRUSH); + //wcl.hbrBackground= (HBRUSH) GetStockObject(DKGRAY_BRUSH); + //wcl.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH); + wcl.hbrBackground= (HBRUSH) GetStockObject(LTGRAY_BRUSH); + //wcl.hbrBackground= (HBRUSH) GetStockObject (GRAY_BRUSH); + wcl.cbSize = sizeof(WNDCLASSEX); - if(!RegisterClass(&wcl)) + if(!RegisterClassEx(&wcl)) { return 0; + } + + logo = LoadBitmap(me, "SWFTOOLS"); + + install_path = getRegistryEntry("Software\\quiss.org\\swftools\\InstallPath"); + if(!install_path || !install_path[0]) + install_path = "c:\\swftools\\"; + + CoInitialize(0); + InitCommonControls(); -#if USE_CONSOLE - FreeConsole(); -#endif + CreateWindow ( + wcl.lpszClassName, /* Class name */ + "SWFTools Installer", /* Caption */ + WS_OVERLAPPEDWINDOW&(~WS_SIZEBOX), /* Style */ + CW_USEDEFAULT, /* Initial x (use default) */ + CW_USEDEFAULT, /* Initial y (use default) */ + 320, /* Initial x size */ + 200, /* Initial y size */ + NULL, /* No parent window */ + NULL, /* No menu */ + me, /* This program instance */ + (void*)"params" /* Creation parameters */ + ); + + ShowWindow (wnd_params, nWinMode); + UpdateWindow (wnd_params); - char buf[1024]; - sprintf(buf, "Do you want me to install SWFTools into the directory %s now?", install_dir); - int ret = MessageBox(0, buf, "SWFTools Install", MB_YESNO|MB_ICONQUESTION); + MSG msg; + while(wnd_params) + { + GetMessage(&msg,NULL,0,0); + TranslateMessage(&msg); + DispatchMessage(&msg); + } - if(ret == IDNO) + if(do_abort) return 0; + + /*char buf[1024]; + sprintf(buf, "Do you want me to install SWFTools into the directory %s now?", install_path); + int ret = MessageBox(0, buf, "SWFTools Install", MB_YESNO|MB_ICONQUESTION); + if(ret == IDNO) + return 0;*/ -#if USE_CONSOLE - if(AllocConsole()) { - DWORD written; - console = GetStdHandle(STD_OUTPUT_HANDLE); - WriteConsole(console, "\r\n", 1, &written, 0); - } -#endif + CreateWindow ( + wcl.lpszClassName, /* Class name */ + "Installing...", /* Caption */ + WS_OVERLAPPEDWINDOW&(~WS_SIZEBOX), /* Style */ + CW_USEDEFAULT, /* Initial x (use default) */ + CW_USEDEFAULT, /* Initial y (use default) */ + 260, /* Initial x size */ + 128, /* Initial y size */ + NULL, /* No parent window */ + NULL, /* No menu */ + me, /* This program instance */ + (void*)"progress" /* Creation parameters */ + ); + ShowWindow (wnd_progress, nWinMode); + UpdateWindow (wnd_progress); + + int success = unpack_archive(crndata, install_path, myarchivestatus); + + DestroyWindow(wnd_progress); - int success = unpack_archive(crndata, "C:\\swftools\\", myarchivestatus); + while(wnd_progress) + processMessages(); -#if USE_CONSOLE - FreeConsole(); -#endif + if(!addRegistryEntries(install_path)) { + success = 0; + MessageBox(0, "Couldn't create Registry Entries", "SWFTools Install", MB_OK|MB_ICONERROR); + } if(success) { - sprintf(buf, "SWFTools Version %s has been installed into %s successfully", VERSION, install_dir); - ret = MessageBox(0, buf, "SWFTools Install", MB_OK|MB_ICONINFORMATION); + char buf[1024]; + sprintf(buf, "SWFTools Version %s has been installed into %s successfully", VERSION, install_path); + MessageBox(0, buf, "SWFTools Install", MB_OK|MB_ICONINFORMATION); } else { + /* error will already have been notified by either myarchivestatus or some other + routine */ /*sprintf(buf, "Installation failed\nLast message: %s", lastmessage); ret = MessageBox(0, buf, "SWFTools Install", MB_OK|MB_ICONERROR);*/ }