Use a dialog instead of a normal window.

oldstable
Jonathan Ernst 2005-03-10 15:46:33 +00:00 committed by Alexandre Julliard
parent 99615021fb
commit 9b4b9ce88f
4 changed files with 280 additions and 388 deletions

View File

@ -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 ?"
}

View File

@ -1,8 +1,9 @@
/*
* Q&D Uninstaller (main.c)
* Uninstaller
*
* Copyright 2000 Andreas Mohr <andi@lisas.de>
* Copyright 2004 Hannu Valtonen <Hannu.Valtonen@hut.fi>
* 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#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 <andi@lisas.de> and Hannu Valtonen <Hannu.Valtonen@hut.fi>";
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 )
{
token = argv[i++];
/* Handle requests just to list the applications */
if( !lstrcmpA( token, "--list" ) )
if( !lstrcmpW( token, listW ) )
{
ListUninstallPrograms();
return 0;
}
else if( !lstrcmpA( token, "--remove" ) )
else if( !lstrcmpW( token, removeW ) )
{
if( 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 ));
}

View File

@ -1,5 +1,7 @@
/*
* Copyright 2000 Andreas Mohr <andi@lisas.de>
* 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 <windows.h>
#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

View File

@ -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 <windows.h>
#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 */