Le mardi 08 mars 2005 Ã 23:29 +0800, Dmitry Timoshkov a Ãcrit : > "Jonathan Ernst" <[EMAIL PROTECTED]> wrote: > > [...]
Thanks, fixed. > You can't use toupper with unicode strings. I can't suggest a win32 equivalent > from the top of my head, you need to find out. It seems that CharUpperW works well. [...] > > Last but not least, since these changes the uninstaller crashes (very) > > often. I have an unhandled exception when retrieving some apps from the > > uninstall key and I don't know what cause this: > > > > err:seh:EXC_DefaultHandling Unhandled exception code c0000005 flags 0 > > addr 0x77ecf5d4 > > Very likely a common error happening often in the process of unicodification: > buffer overflow due to not a correct memory allocation, or a not correct > initialization of a variable pointing to a buffer length (size of buffer in > bytes vs. WCHARs). Thanks for the hint. I found the allocation problem. [...] Fixed Now everything works; thanks for your step by step help; I hope that what I'me learning now will let me make more additions to Wine ! But: It is even possible to uninstall more than one app at a time, but I wish that when an uninstaller has finished to uninstall an application the list is updated, but it's not. What's and where's a clean way to do it ? Please find attached main.c's diff. Jonathan P.S. Do I really have to split this new uninstaller in different patches as nearly everything changed ?
Index: main.c =================================================================== RCS file: /home/wine/wine/programs/uninstaller/main.c,v retrieving revision 1.19 diff -u -r1.19 main.c --- main.c 9 Dec 2004 14:07:59 -0000 1.19 +++ main.c 8 Mar 2005 16:40:50 -0000 @@ -1,8 +1,9 @@ /* - * Q&D Uninstaller (main.c) + * Uninstaller * * Copyright 2000 Andreas Mohr <[EMAIL PROTECTED]> * Copyright 2004 Hannu Valtonen <[EMAIL PROTECTED]> + * Copyright 2005 Jonathan Ernst <[EMAIL PROTECTED]> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,104 +19,94 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * ToDo: - * - 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 <windows.h> +#include "resource.h" #include "regstr.h" +#include "wine/unicode.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 <[EMAIL PROTECTED]> and Hannu Valtonen <[EMAIL PROTECTED]>"; -static char program_description[] = - "Please select the application you wish to uninstall:"; +WINE_DEFAULT_DEBUG_CHANNEL(uninstaller); 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 *sFilter; +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]; + +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 WCHAR *stristr(const WCHAR *String, const WCHAR *Pattern); + + +static const WCHAR BackSlashW[] = { '\\', 0 }; +static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0}; +static const WCHAR PathUninistallW[] = { + '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}; -uninst_entry *entries = NULL; - -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 } -}; - -#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,236 @@ 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); + } +} + + +/** + * Fetch informations from the uninstall key. + */ +static int FetchUninstallInformation(void) +{ + HKEY hkeyUninst, hkeyApp; + int i; + DWORD sizeOfSubKeyName, displen, uninstlen; + WCHAR subKeyName[256]; + WCHAR key_app[1024]; + WCHAR *p; + + numentries = 0; + oldsel = -1; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, PathUninistallW, 0, KEY_READ, &hkeyUninst) != ERROR_SUCCESS) + { + MessageBoxW(0, sRegistryKeyNotAvailable, sAppName, MB_OK); + return 0; + } + + if (!entries) + entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry)); + + lstrcpyW(key_app, PathUninistallW); + lstrcatW(key_app, BackSlashW); + p = key_app+lstrlenW(PathUninistallW)+1; + + sizeOfSubKeyName = 255; + for (i=0; RegEnumKeyExW( hkeyUninst, i, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS; ++i) + { + 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)); + if(sFilter != NULL && stristr(entries[numentries-1].descr,sFilter)==NULL) + numentries--; + } + RegCloseKey(hkeyApp); + sizeOfSubKeyName = 255; + } + qsort(entries, numentries, sizeof(uninst_entry), cmp_by_name); + RegCloseKey(hkeyUninst); + return 1; +} + + +static void UninstallProgram(void) +{ + unsigned int i; + WCHAR errormsg[1024]; + BOOL res; + STARTUPINFOW si; + PROCESS_INFORMATION info; + DWORD exit_code; + HKEY hkey; + 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(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, PathUninistallW, 0, KEY_READ, &hkey); + RegDeleteKeyW(hkey, entries[i].key); + RegCloseKey(hkey); + } + } + } + WINE_TRACE("finished uninstall phase.\n"); + list_need_update = 1; +} + + +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; } } -int main( int argc, char *argv[]) + +INT_PTR CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { - MSG msg; - WNDCLASS wc; - HWND hWnd; - LPSTR token = NULL; + TEXTMETRICW tm; + HDC hdc; + 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_FILTER: + { + if (HIWORD(wParam) == EN_CHANGE) + { + list_need_update = 1; + int len = GetWindowTextLengthW(GetDlgItem(hwnd, IDC_FILTER)); + if(len > 0) + { + sFilter = (WCHAR*)GlobalAlloc(GPTR, len + 1); + GetDlgItemTextW(hwnd, IDC_FILTER, sFilter, len + 1); + } + else sFilter = NULL; + UpdateList(hList); + } + } + break; + case IDC_UNINSTALL: + { + int count = SendMessageW(hList, LB_GETSELCOUNT, 0, 0); + if(count != 0) + { + UninstallProgram(hList); + 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; +} + + +int wmain(int argc, WCHAR *argv[]) +{ + 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 +359,73 @@ } 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)); + LoadStringW(hInst, IDS_ABOUTTITLE, sAboutTitle, sizeof(sAboutTitle)); + LoadStringW(hInst, IDS_ABOUT, sAbout, sizeof(sAbout)); + LoadStringW(hInst, IDS_REGISTRYKEYNOTAVAILABLE, sRegistryKeyNotAvailable, sizeof(sRegistryKeyNotAvailable)); + LoadStringW(hInst, IDS_UNINSTALLFAILED, sUninstallFailed, sizeof(sUninstallFailed)); - 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) -{ - HKEY hkeyUninst, hkeyApp; - int i; - DWORD sizeOfSubKeyName, displen, uninstlen; - char subKeyName[256]; - char key_app[1024]; - char *p; - - numentries = 0; - oldsel = -1; - if ( RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL, - 0, KEY_READ, &hkeyUninst) != ERROR_SUCCESS ) - { - MessageBox(0, "Uninstall registry key not available (yet), nothing to do !", appname, MB_OK); - return 0; - } - - if (!entries) - entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry)); - - strcpy(key_app, REGSTR_PATH_UNINSTALL); - strcat(key_app, "\\"); - p = key_app+strlen(REGSTR_PATH_UNINSTALL)+1; - - sizeOfSubKeyName = 255; - for ( i=0; - RegEnumKeyExA( 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; - } - qsort(entries, numentries, sizeof(uninst_entry), cmp_by_name); - RegCloseKey(hkeyUninst); - return 1; -} - -void UninstallProgram(void) +/** + * Case insensitive substring search. + * + * Public domain code found here: http://fux0r.phathookups.com/programming-tutorials/C/C-snippits/stristr.c + * + */ +static WCHAR *stristr(const WCHAR *String, const WCHAR *Pattern) { - unsigned int i; - char errormsg[1024]; - BOOL res; - STARTUPINFO si; - PROCESS_INFORMATION info; - DWORD exit_code; -#ifdef DEL_REG_KEY - HKEY hkey; -#endif + const WCHAR *pptr, *sptr, *start; + uint slen, plen; - for (i=0; i < numentries; i++) + for (start = String, + pptr = Pattern, + slen = lstrlenW(String), + plen = lstrlenW(Pattern); + /* while string length not shorter than pattern length */ + slen >= plen; + start++, slen--) { - 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); - } - } - WINE_TRACE("finished uninstall phase.\n"); - list_need_update = 1; -} - -LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - HFONT static_font, listbox_font; - 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; - } + /* find start of pattern in string */ + while (CharUpperW(*start) != CharUpperW(*Pattern)) + { + start++; + slen--; - 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; - } + /* if pattern longer than string */ + if (slen < plen) + return NULL; + } - case WM_DESTROY: - PostQuitMessage( 0 ); - return 0; + sptr = start; + pptr = Pattern; - 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 */ + while (CharUpperW(*sptr) == CharUpperW(*pptr)) { - UninstallProgram(); - - InvalidateRect(hWnd, NULL, TRUE); - UpdateWindow(hWnd); + sptr++; + pptr++; + /* if end of pattern then pattern was found */ + if ('\0' == *pptr) + return start; } - 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; } - - return( DefWindowProc( hWnd, msg, wParam, lParam )); + return NULL; }
signature.asc
Description: Ceci est une partie de message =?ISO-8859-1?Q?num=E9riquement?= =?ISO-8859-1?Q?_sign=E9e?=