diff --git a/programs/uninstaller/En.rc b/programs/uninstaller/En.rc new file mode 100644 index 00000000000..a85ee961868 --- /dev/null +++ b/programs/uninstaller/En.rc @@ -0,0 +1,43 @@ +/* + * Uninstaller (English Resources) + * + * Copyright 2005 Jonathan Ernst + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +IDD_UNINSTALLER DIALOG DISCARDABLE 0, 0, 330, 160 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "Wine Application Uninstaller" +FONT 10, "MS Sans Serif" +BEGIN + LTEXT "Please select the application you wish to uninstall:",IDC_PLEASESELECT,10,10,250,14 + LISTBOX IDC_LIST,10,43,250,106,LBS_NOINTEGRALHEIGHT | + LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "&Uninstall",IDC_UNINSTALL,270,48,50,14 + PUSHBUTTON "&About",IDC_ABOUT,270,65,50,14 + PUSHBUTTON "&Exit",IDC_EXIT,270,81,50,14 +END + + +STRINGTABLE DISCARDABLE { + IDS_APPNAME, "Wine Application Unsinstaller" + IDS_ABOUT, "Wine Application Uninstaller (C) 2005 by Andreas Mohr, Hannu Valtonen and Jonathan Ernst." + IDS_ABOUTTITLE, "About Unsinstaller" + IDS_REGISTRYKEYNOTAVAILABLE, "Uninstall registry key not available (yet), nothing to do !" + IDS_UNINSTALLFAILED, "Execution of uninstall command '%s' failed, perhaps due to missing executable.\r\nDo you want to remove the uninstall entry from the registry ?" +} diff --git a/programs/uninstaller/main.c b/programs/uninstaller/main.c index 5c0039211ce..458a1c3c434 100644 --- a/programs/uninstaller/main.c +++ b/programs/uninstaller/main.c @@ -1,8 +1,9 @@ /* - * Q&D Uninstaller (main.c) + * Uninstaller * - * Copyright 2000 Andreas Mohr - * Copyright 2004 Hannu Valtonen + * Copyright 2000 Andreas Mohr + * Copyright 2004 Hannu Valtonen + * Copyright 2005 Jonathan Ernst * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,100 +23,90 @@ * - add search box for locating entries quickly */ - #include #include #include #include #include -#include "main.h" +#include "resource.h" #include "regstr.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(uninstaller); -/* Work around a Wine bug which defines handles as UINT rather than LPVOID */ -#ifdef WINE_STRICT -#define NULL_HANDLE NULL -#else -#define NULL_HANDLE 0 -#endif - -/* use multi-select listbox */ -#undef USE_MULTIPLESEL - -/* Delete uninstall registry key after execution. - * This is probably a bad idea, because it's the - * uninstall program that is supposed to do that. - */ -#undef DEL_REG_KEY - -char appname[18]; - -static char about_string[] = - "Wine Application Uninstaller (C) 2004 by Andreas Mohr and Hannu Valtonen "; -static char program_description[] = - "Please select the application you wish to uninstall:"; - typedef struct { - char *key; + WCHAR *key; WCHAR *descr; - char *command; + WCHAR *command; int active; } uninst_entry; +static uninst_entry *entries = NULL; +static unsigned int numentries = 0; +static int list_need_update = 1; +static int oldsel = -1; +static WCHAR sAppName[MAX_STRING_LEN]; +static WCHAR sAboutTitle[MAX_STRING_LEN]; +static WCHAR sAbout[MAX_STRING_LEN]; +static WCHAR sRegistryKeyNotAvailable[MAX_STRING_LEN]; +static WCHAR sUninstallFailed[MAX_STRING_LEN]; -uninst_entry *entries = NULL; +static int FetchUninstallInformation(void); +static void UninstallProgram(void); +static void UpdateList(HWND hList); +static int cmp_by_name(const void *a, const void *b); +static INT_PTR CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); -unsigned int numentries = 0; -int list_need_update = 1; -int oldsel = -1; -struct { - DWORD style; - LPCSTR text; - HWND hwnd; -} button[] = -{ - { BS_PUSHBUTTON, "Add/Remove", 0 }, - { BS_PUSHBUTTON, "About", 0 }, - { BS_PUSHBUTTON, "Exit", 0 } -}; +static const WCHAR BackSlashW[] = { '\\', 0 }; +static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; +static const WCHAR PathUninstallW[] = { + 'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'U','n','i','n','s','t','a','l','l',0 }; +static const WCHAR UninstallCommandlineW[] = {'U','n','i','n','s','t','a','l','l','S','t','r','i','n','g',0}; -#define NUM (sizeof(button)/sizeof(button[0])) - -int FetchUninstallInformation(void); -void UninstallProgram(void); - -void ListUninstallPrograms(void) +/** + * Used to output program list when used with --list + */ +static void ListUninstallPrograms(void) { unsigned int i; - int len; + int lenDescr, lenKey; char *descr; + char *key; if (! FetchUninstallInformation()) return; for (i=0; i < numentries; i++) { - len = WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, NULL, 0, NULL, NULL); - descr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, descr, len, NULL, NULL); - printf("%s|||%s\n", entries[i].key, descr); + lenDescr = WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, NULL, 0, NULL, NULL); + lenKey = WideCharToMultiByte(CP_UNIXCP, 0, entries[i].key, -1, NULL, 0, NULL, NULL); + descr = HeapAlloc(GetProcessHeap(), 0, lenDescr); + key = HeapAlloc(GetProcessHeap(), 0, lenKey); + WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, descr, lenDescr, NULL, NULL); + WideCharToMultiByte(CP_UNIXCP, 0, entries[i].key, -1, key, lenKey, NULL, NULL); + printf("%s|||%s\n", key, descr); HeapFree(GetProcessHeap(), 0, descr); + HeapFree(GetProcessHeap(), 0, key); } } -void RemoveSpecificProgram(char *name) +static void RemoveSpecificProgram(WCHAR *nameW) { unsigned int i; + int lenName; + char *name; if (! FetchUninstallInformation()) return; for (i=0; i < numentries; i++) { - if (strcmp(entries[i].key, name) == 0) + if (lstrcmpW(entries[i].key, nameW) == 0) { entries[i].active++; break; @@ -126,30 +117,34 @@ void RemoveSpecificProgram(char *name) UninstallProgram(); else { + lenName = WideCharToMultiByte(CP_UNIXCP, 0, nameW, -1, NULL, 0, NULL, NULL); + name = HeapAlloc(GetProcessHeap(), 0, lenName); + WideCharToMultiByte(CP_UNIXCP, 0, nameW, -1, name, lenName, NULL, NULL); fprintf(stderr, "Error: could not match application [%s]\n", name); + HeapFree(GetProcessHeap(), 0, name); } } -int main( int argc, char *argv[]) + +int wmain(int argc, WCHAR *argv[]) { - MSG msg; - WNDCLASS wc; - HWND hWnd; - LPSTR token = NULL; + LPCWSTR token = NULL; + HINSTANCE hInst = GetModuleHandleW(0); + static const WCHAR listW[] = { '-','-','l','i','s','t',0 }; + static const WCHAR removeW[] = { '-','-','r','e','m','o','v','e',0 }; int i = 1; - HINSTANCE hInst = NULL; while( i= argc ) { @@ -162,303 +157,208 @@ int main( int argc, char *argv[]) } else { - WINE_ERR( "unknown option %s\n",token); + WINE_ERR( "unknown option %s\n",wine_dbgstr_w(token)); return 1; } } - LoadString( hInst, IDS_APPNAME, appname, sizeof(appname)); + /* Load MessageBox's strings */ + LoadStringW(hInst, IDS_APPNAME, sAppName, sizeof(sAppName)/sizeof(WCHAR)); + LoadStringW(hInst, IDS_ABOUTTITLE, sAboutTitle, sizeof(sAboutTitle)/sizeof(WCHAR)); + LoadStringW(hInst, IDS_ABOUT, sAbout, sizeof(sAbout)/sizeof(WCHAR)); + LoadStringW(hInst, IDS_REGISTRYKEYNOTAVAILABLE, sRegistryKeyNotAvailable, sizeof(sRegistryKeyNotAvailable)/sizeof(WCHAR)); + LoadStringW(hInst, IDS_UNINSTALLFAILED, sUninstallFailed, sizeof(sUninstallFailed)/sizeof(WCHAR)); - wc.style = 0; - wc.lpfnWndProc = MainProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInst; - wc.hIcon = LoadIcon( hInst, appname ); - wc.hCursor = LoadCursor( NULL_HANDLE, IDI_APPLICATION ); - wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); - wc.lpszMenuName = NULL; - wc.lpszClassName = appname; - - if (!RegisterClass(&wc)) exit(1); - hWnd = CreateWindow( appname, "Wine Application Uninstaller", - WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL_HANDLE, NULL_HANDLE, hInst, NULL ); - - if (!hWnd) exit(1); - - ShowWindow( hWnd, SW_SHOW ); - UpdateWindow( hWnd ); - - while( GetMessage(&msg, NULL_HANDLE, 0, 0) ) { - TranslateMessage( &msg ); - DispatchMessage( &msg ); - } - return msg.wParam; + return DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_UNINSTALLER), NULL, DlgProc); } -int cmp_by_name(const void *a, const void *b) + +/** + * Used to sort entries by name. + */ +static int cmp_by_name(const void *a, const void *b) { return lstrcmpiW(((const uninst_entry *)a)->descr, ((const uninst_entry *)b)->descr); } -int FetchUninstallInformation(void) + +/** + * Fetch informations from the uninstall key. + */ +static int FetchUninstallInformation(void) { HKEY hkeyUninst, hkeyApp; int i; DWORD sizeOfSubKeyName, displen, uninstlen; - char subKeyName[256]; - char key_app[1024]; - char *p; - + WCHAR subKeyName[256]; + WCHAR key_app[1024]; + WCHAR *p; + numentries = 0; oldsel = -1; - if ( RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL, - 0, KEY_READ, &hkeyUninst) != ERROR_SUCCESS ) + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, PathUninstallW, 0, KEY_READ, &hkeyUninst) != ERROR_SUCCESS) { - MessageBox(0, "Uninstall registry key not available (yet), nothing to do !", appname, MB_OK); - return 0; + MessageBoxW(0, sRegistryKeyNotAvailable, sAppName, MB_OK); + return 0; } if (!entries) - entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry)); + entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry)); - strcpy(key_app, REGSTR_PATH_UNINSTALL); - strcat(key_app, "\\"); - p = key_app+strlen(REGSTR_PATH_UNINSTALL)+1; + lstrcpyW(key_app, PathUninstallW); + lstrcatW(key_app, BackSlashW); + p = key_app+lstrlenW(PathUninstallW)+1; sizeOfSubKeyName = 255; - for ( i=0; - RegEnumKeyExA( hkeyUninst, i, subKeyName, &sizeOfSubKeyName, - NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS; - ++i ) + for (i=0; RegEnumKeyExW( hkeyUninst, i, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS; ++i) { - static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; - - strcpy(p, subKeyName); - RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_app, 0, KEY_READ, &hkeyApp); - - if ( (RegQueryValueExW(hkeyApp, DisplayNameW, - 0, 0, NULL, &displen) == ERROR_SUCCESS) - && (RegQueryValueExA(hkeyApp, REGSTR_VAL_UNINSTALLER_COMMANDLINE, - 0, 0, NULL, &uninstlen) == ERROR_SUCCESS) ) - { - numentries++; - entries = HeapReAlloc(GetProcessHeap(), 0, entries, numentries*sizeof(uninst_entry)); - entries[numentries-1].key = - HeapAlloc(GetProcessHeap(), 0, strlen(subKeyName)+1); - strcpy(entries[numentries-1].key, subKeyName); - entries[numentries-1].descr = - HeapAlloc(GetProcessHeap(), 0, displen); - RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, - (LPBYTE)entries[numentries-1].descr, &displen); - entries[numentries-1].command = - HeapAlloc(GetProcessHeap(), 0, uninstlen); - entries[numentries-1].active = 0; - RegQueryValueExA(hkeyApp, REGSTR_VAL_UNINSTALLER_COMMANDLINE, 0, 0, - entries[numentries-1].command, &uninstlen); - WINE_TRACE("allocated entry #%d: %s (%s), %s\n", - numentries, entries[numentries-1].key, - wine_dbgstr_w(entries[numentries-1].descr), - entries[numentries-1].command); - } - RegCloseKey(hkeyApp); - - sizeOfSubKeyName = 255; + lstrcpyW(p, subKeyName); + RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_app, 0, KEY_READ, &hkeyApp); + if ((RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, NULL, &displen) == ERROR_SUCCESS) + && (RegQueryValueExW(hkeyApp, UninstallCommandlineW, 0, 0, NULL, &uninstlen) == ERROR_SUCCESS)) + { + numentries++; + entries = HeapReAlloc(GetProcessHeap(), 0, entries, numentries*sizeof(uninst_entry)); + entries[numentries-1].key = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(subKeyName)+1)*sizeof(WCHAR)); + lstrcpyW(entries[numentries-1].key, subKeyName); + entries[numentries-1].descr = HeapAlloc(GetProcessHeap(), 0, displen); + RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, (LPBYTE)entries[numentries-1].descr, &displen); + entries[numentries-1].command = HeapAlloc(GetProcessHeap(), 0, uninstlen); + entries[numentries-1].active = 0; + RegQueryValueExW(hkeyApp, UninstallCommandlineW, 0, 0, (LPBYTE)entries[numentries-1].command, &uninstlen); + WINE_TRACE("allocated entry #%d: %s (%s), %s\n", + numentries, wine_dbgstr_w(entries[numentries-1].key), wine_dbgstr_w(entries[numentries-1].descr), wine_dbgstr_w(entries[numentries-1].command)); + } + RegCloseKey(hkeyApp); + sizeOfSubKeyName = 255; } qsort(entries, numentries, sizeof(uninst_entry), cmp_by_name); RegCloseKey(hkeyUninst); return 1; } -void UninstallProgram(void) + +static void UninstallProgram(void) { unsigned int i; - char errormsg[1024]; + WCHAR errormsg[1024]; BOOL res; - STARTUPINFO si; + STARTUPINFOW si; PROCESS_INFORMATION info; DWORD exit_code; -#ifdef DEL_REG_KEY HKEY hkey; -#endif - for (i=0; i < numentries; i++) { - if (!(entries[i].active)) /* don't uninstall this one */ - continue; - WINE_TRACE("uninstalling %s\n", wine_dbgstr_w(entries[i].descr)); - memset(&si, 0, sizeof(STARTUPINFO)); - si.cb = sizeof(STARTUPINFO); - si.wShowWindow = SW_NORMAL; - res = CreateProcess(NULL, entries[i].command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &info); - if (res) - { /* wait for the process to exit */ - WaitForSingleObject(info.hProcess, INFINITE); - res = GetExitCodeProcess(info.hProcess, &exit_code); - WINE_TRACE("%d: %08lx\n", res, exit_code); -#ifdef DEL_REG_KEY - /* delete the application's uninstall entry */ - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL, - 0, KEY_READ, &hkey) == ERROR_SUCCESS) - { - RegDeleteKey(hkey, entries[i].key); - RegCloseKey(hkey); - } -#endif - } - else - { - sprintf(errormsg, "Execution of uninstall command '%s' failed, perhaps due to missing executable.", entries[i].command); - MessageBox(0, errormsg, appname, MB_OK); - } + if (!(entries[i].active)) /* don't uninstall this one */ + continue; + WINE_TRACE("uninstalling %s\n", wine_dbgstr_w(entries[i].descr)); + memset(&si, 0, sizeof(STARTUPINFOW)); + si.cb = sizeof(STARTUPINFOW); + si.wShowWindow = SW_NORMAL; + res = CreateProcessW(NULL, entries[i].command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &info); + if (res) + { /* wait for the process to exit */ + WaitForSingleObject(info.hProcess, INFINITE); + res = GetExitCodeProcess(info.hProcess, &exit_code); + WINE_TRACE("%d: %08lx\n", res, exit_code); + } + else + { + wsprintfW(errormsg, sUninstallFailed, entries[i].command); + if(MessageBoxW(0, errormsg, sAppName, MB_YESNO | MB_ICONQUESTION)==IDYES) + { + /* delete the application's uninstall entry */ + RegOpenKeyExW(HKEY_LOCAL_MACHINE, PathUninstallW, 0, KEY_READ, &hkey); + RegDeleteKeyW(hkey, entries[i].key); + RegCloseKey(hkey); + } + } } WINE_TRACE("finished uninstall phase.\n"); list_need_update = 1; } -LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) + +static INT_PTR CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { - HFONT static_font, listbox_font; + TEXTMETRICW tm; HDC hdc; - PAINTSTRUCT ps; - TEXTMETRIC tm; - unsigned int i; - int cxChar, cyChar, y, bx, maxx, maxy, wx, wy; - static HWND hwndList = 0, static_text = 0; - DWORD style; - RECT rect; - - switch( msg ) { - case WM_CREATE: - { - hdc = GetDC(hWnd); - GetTextMetrics(hdc, &tm); - static_font = CreateFont(tm.tmHeight + tm.tmExternalLeading, 0, 0, 0, 600, FALSE, 0, 0, 0, 0, 0, 0, 0, "Times New Roman"); - listbox_font = CreateFont(tm.tmHeight + tm.tmExternalLeading, 0, 0, 0, 0, TRUE, 0, 0, 0, 0, 0, 0, 0, "Times New Roman"); - cxChar = tm.tmAveCharWidth; - cyChar = tm.tmHeight + tm.tmExternalLeading; - ReleaseDC(hWnd, hdc); - /* FIXME: implement sorting and use LBS_SORT here ! */ - style = (WS_CHILD|WS_VISIBLE|LBS_STANDARD) & ~LBS_SORT; -#ifdef USE_MULTIPLESEL - style |= LBS_MULTIPLESEL; -#endif - bx = maxx = cxChar * 3; - y = maxy = cyChar * 1; - static_text = CreateWindow("static", program_description, - WS_CHILD|WS_VISIBLE|SS_LEFT, - maxx, maxy, - cxChar * sizeof(program_description), cyChar * 1, - hWnd, (HMENU)1, - ((LPCREATESTRUCT)lParam)->hInstance, NULL); - SendMessage(static_text, WM_SETFONT, (WPARAM)static_font, MAKELPARAM(FALSE, 0)); - maxy += cyChar * 2; /*static text + distance */ - hwndList = CreateWindow("listbox", NULL, - style, - maxx, maxy, - cxChar * 50 + GetSystemMetrics(SM_CXVSCROLL), cyChar * 10, - hWnd, (HMENU) 1, - (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); - SendMessage(hwndList, WM_SETFONT, (WPARAM)listbox_font, MAKELPARAM(FALSE, 0)); - GetWindowRect(hwndList, &rect); - maxx += (rect.right - rect.left)*1.1; - maxy += (rect.bottom - rect.top)*1.1; - wx = 20*cxChar; - wy = 7*cyChar/4; - y = cyChar * 3; - for (i=0; i < NUM; i++) - { - button[i].hwnd = CreateWindow("button", button[i].text, - WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, - maxx, y, - wx, wy, - hWnd, (HMENU)i, - ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if (!button[i].hwnd) - PostQuitMessage(0); - y += 2*cyChar; - } - maxx += wx + cxChar * 4; - maxy += cyChar * 2; /* window border */ - SetWindowPos( hWnd, 0, - 0, 0, maxx, maxy, - SWP_NOMOVE); - return 0; - } - - case WM_PAINT: - { - hdc = BeginPaint( hWnd, &ps ); - if (list_need_update) - { - int prevsel; - prevsel = SendMessage(hwndList, LB_GETCURSEL, 0, 0); - if (!(FetchUninstallInformation())) - { - PostQuitMessage(0); - return 0; - } - SendMessage(hwndList, LB_RESETCONTENT, 0, 0); - SendMessage(hwndList, WM_SETREDRAW, FALSE, 0); - for (i=0; i < numentries; i++) - { - WINE_TRACE("adding %s\n", wine_dbgstr_w(entries[i].descr)); - SendMessageW(hwndList, LB_ADDSTRING, 0, (LPARAM)entries[i].descr); - } - WINE_TRACE("setting prevsel %d\n", prevsel); - if (prevsel != -1) - SendMessage(hwndList, LB_SETCURSEL, prevsel, 0 ); - SendMessage(hwndList, WM_SETREDRAW, TRUE, 0); - list_need_update = 0; - } - EndPaint( hWnd, &ps ); - return 0; - } - - case WM_DESTROY: - PostQuitMessage( 0 ); - return 0; - - case WM_COMMAND: - if ((HWND)lParam == hwndList) - { - if (HIWORD(wParam) == LBN_SELCHANGE) - { - int sel = SendMessage(hwndList, LB_GETCURSEL, 0, 0); - -#ifndef USE_MULTIPLESEL - if (oldsel != -1) - { - entries[oldsel].active ^= 1; /* toggle */ - WINE_TRACE("toggling %d old %s\n", entries[oldsel].active, - wine_dbgstr_w(entries[oldsel].descr)); - } -#endif - entries[sel].active ^= 1; /* toggle */ - WINE_TRACE("toggling %d %s\n", entries[sel].active, - wine_dbgstr_w(entries[oldsel].descr)); - oldsel = sel; - } - } - else - if ((HWND)lParam == button[0].hwnd) /* Uninstall button */ - { - UninstallProgram(); - - InvalidateRect(hWnd, NULL, TRUE); - UpdateWindow(hWnd); - - } - else - if ((HWND)lParam == button[1].hwnd) /* About button */ - MessageBox(0, about_string, "About Wine Application Uninstaller", MB_OK); - else - if ((HWND)lParam == button[2].hwnd) /* Exit button */ - PostQuitMessage(0); - return 0; + HWND hList = GetDlgItem(hwnd, IDC_LIST); + switch(Message) + { + case WM_INITDIALOG: + hdc = GetDC(hwnd); + GetTextMetricsW(hdc, &tm); + UpdateList(hList); + ReleaseDC(hwnd, hdc); + break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_UNINSTALL: + { + int count = SendMessageW(hList, LB_GETSELCOUNT, 0, 0); + if(count != 0) + { + UninstallProgram(); + UpdateList(hList); + } + break; + } + case IDC_LIST: + if (HIWORD(wParam) == LBN_SELCHANGE) + { + int sel = SendMessageW(hList, LB_GETCURSEL, 0, 0); + if (oldsel != -1) + { + entries[oldsel].active ^= 1; /* toggle */ + WINE_TRACE("toggling %d old %s\n", entries[oldsel].active, + wine_dbgstr_w(entries[oldsel].descr)); + } + entries[sel].active ^= 1; /* toggle */ + WINE_TRACE("toggling %d %s\n", entries[sel].active, + wine_dbgstr_w(entries[oldsel].descr)); + oldsel = sel; + } + break; + case IDC_ABOUT: + MessageBoxW(0, sAbout, sAboutTitle, MB_OK); + break; + case IDC_EXIT: + EndDialog(hwnd, 0); + break; + } + break; + default: + return FALSE; + } + return TRUE; +} + + +static void UpdateList(HWND hList) +{ + unsigned int i; + if (list_need_update) + { + int prevsel; + prevsel = SendMessageW(hList, LB_GETCURSEL, 0, 0); + if (!(FetchUninstallInformation())) + { + PostQuitMessage(0); + return; + } + SendMessageW(hList, LB_RESETCONTENT, 0, 0); + SendMessageW(hList, WM_SETREDRAW, FALSE, 0); + for (i=0; i < numentries; i++) + { + WINE_TRACE("adding %s\n", wine_dbgstr_w(entries[i].descr)); + SendMessageW(hList, LB_ADDSTRING, 0, (LPARAM)entries[i].descr); + } + WINE_TRACE("setting prevsel %d\n", prevsel); + if (prevsel != -1) + SendMessageW(hList, LB_SETCURSEL, prevsel, 0 ); + SendMessageW(hList, WM_SETREDRAW, TRUE, 0); + list_need_update = 0; } - - return( DefWindowProc( hWnd, msg, wParam, lParam )); } diff --git a/programs/uninstaller/main.h b/programs/uninstaller/resource.h similarity index 53% rename from programs/uninstaller/main.h rename to programs/uninstaller/resource.h index 1f2fb234aff..5d93f33cff3 100644 --- a/programs/uninstaller/main.h +++ b/programs/uninstaller/resource.h @@ -1,5 +1,7 @@ /* - * Copyright 2000 Andreas Mohr + * Uninstaller resource definitions + * + * Copyright 2005 Jonathan Ernst * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,8 +18,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include - -#define IDS_APPNAME 1101 - -LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +#define IDD_UNINSTALLER 101 +#define IDC_FILTER 1001 +#define IDC_LIST 1002 +#define IDC_UNINSTALL 1003 +#define IDC_ABOUT 1004 +#define IDC_EXIT 1005 +#define IDC_PLEASESELECT 1006 +#define IDS_APPNAME 1007 +#define IDS_ABOUT 1008 +#define IDS_ABOUTTITLE 1009 +#define IDS_REGISTRYKEYNOTAVAILABLE 1010 +#define IDS_UNINSTALLFAILED 1011 +#define MAX_STRING_LEN 255 diff --git a/programs/uninstaller/rsrc.rc b/programs/uninstaller/rsrc.rc index c5054e3918b..ef7ecaff15a 100644 --- a/programs/uninstaller/rsrc.rc +++ b/programs/uninstaller/rsrc.rc @@ -5,6 +5,7 @@ * Copyright 2003 Vincent Béron * Copyright 2003 Ivan Leo Puoti * Copyright 2004 David Kredba + * Copyright 2005 Jonathan Ernst * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,7 +23,8 @@ */ #include -#include "main.h" +#include "resource.h" +#include "En.rc" /* BINRES uninstaller.ico */ UNINSTALLER ICON MOVEABLE uninstaller.ico @@ -76,66 +78,3 @@ UNINSTALLER ICON MOVEABLE uninstaller.ico '00 03 C0 00 00 03 C0 00 00 0F C0 00 00 07 C0 00' '00 03 80 00 00 31 1F FF FF F8 3F FF FF FC' } */ - -/* Czech Resources */ -LANGUAGE LANG_CZECH, SUBLANG_NEUTRAL - -STRINGTABLE { - IDS_APPNAME, "Deinstalátor" - - } -/* End of Czech Resources */ - -/* English-US Resources */ -LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL - -STRINGTABLE { - IDS_APPNAME, "Uninstaller" - -} -/* End of English-US Resources */ - -/* French Resources */ -LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL - -STRINGTABLE { - IDS_APPNAME, "Désinstalleur" - -} -/* End of French Resources */ - -/* German Resources */ -LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL - -STRINGTABLE { - IDS_APPNAME, "Uninstaller" - -} -/* End of German Resources */ - -/* Italian Resources */ -LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL - -STRINGTABLE { - IDS_APPNAME, "Disinstallatore" - -} -/* End of Italian Resources */ - -/* Portuguese Resources */ -LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL - -STRINGTABLE { - IDS_APPNAME, "Desinstalador" - -} -/* End of Portuguese Resources */ - -/* Spanish Resources */ -LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL - -STRINGTABLE { - IDS_APPNAME, "Desinstalador" - -} -/* End of Spanish Resources */