Huw D M Davies <hdavies@codeweavers.com> Convert MRULists to Unicode.
Index: dlls/comctl32/comctl32.spec =================================================================== RCS file: /home/wine/wine/dlls/comctl32/comctl32.spec,v retrieving revision 1.24 diff -u -r1.24 comctl32.spec --- dlls/comctl32/comctl32.spec 2001/08/18 16:09:19 1.24 +++ dlls/comctl32/comctl32.spec 2002/01/14 10:46:42 @@ -111,7 +111,7 @@ 91 stdcall _TrackMouseEvent(ptr) _TrackMouseEvent 151 stdcall CreateMRUListA(ptr) CreateMRUListA -152 stdcall FreeMRUList(ptr) FreeMRUListA +152 stdcall FreeMRUList(long) FreeMRUList 153 stdcall AddMRUStringA(long str) AddMRUStringA 154 stdcall EnumMRUListA(long long ptr long) EnumMRUListA 155 stdcall FindMRUStringA(long str ptr) FindMRUStringA @@ -191,11 +191,11 @@ 389 stub @ 390 stub @ -400 stub CreateMRUListW@4 -401 stub AddMRUStringW@8 -402 stub FindMRUStringW@12 -403 stub EnumMRUListW@16 -404 stub CreateMRUListLazyW@16 +400 stdcall CreateMRUListW(ptr) CreateMRUListW +401 stdcall AddMRUStringW(long wstr) AddMRUStringW +402 stdcall FindMRUStringW(long wstr ptr) FindMRUStringW +403 stdcall EnumMRUListW(long long ptr long) EnumMRUListW +404 stdcall CreateMRUListLazyW(ptr long long long) CreateMRUListLazyW 410 stdcall @(long long long long) COMCTL32_410 411 stdcall @(long long long) COMCTL32_411 Index: dlls/comctl32/comctl32undoc.c =================================================================== RCS file: /home/wine/wine/dlls/comctl32/comctl32undoc.c,v retrieving revision 1.53 diff -u -r1.53 comctl32undoc.c --- dlls/comctl32/comctl32undoc.c 2001/09/20 18:58:43 1.53 +++ dlls/comctl32/comctl32undoc.c 2002/01/14 10:46:42 @@ -407,7 +407,7 @@ * containing the value names (i.e. 'a', 'b', etc.) in the relevant order. */ -typedef struct tagCREATEMRULIST +typedef struct tagCREATEMRULISTA { DWORD cbSize; /* size of struct */ DWORD nMaxItems; /* max no. of items in list */ @@ -415,8 +415,18 @@ HKEY hKey; /* root reg. key under which list is saved */ LPCSTR lpszSubKey; /* reg. subkey */ PROC lpfnCompare; /* item compare proc */ -} CREATEMRULIST, *LPCREATEMRULIST; +} CREATEMRULISTA, *LPCREATEMRULISTA; +typedef struct tagCREATEMRULISTW +{ + DWORD cbSize; /* size of struct */ + DWORD nMaxItems; /* max no. of items in list */ + DWORD dwFlags; /* see below */ + HKEY hKey; /* root reg. key under which list is saved */ + LPCWSTR lpszSubKey; /* reg. subkey */ + PROC lpfnCompare; /* item compare proc */ +} CREATEMRULISTW, *LPCREATEMRULISTW; + /* dwFlags */ #define MRUF_STRING_LIST 0 /* list will contain strings */ #define MRUF_BINARY_LIST 1 /* list will contain binary data */ @@ -442,7 +452,8 @@ typedef struct tagWINEMRULIST { - CREATEMRULIST extview; /* original create information */ + CREATEMRULISTW extview; /* original create information */ + BOOL isUnicode; /* is compare fn Unicode */ DWORD wineFlags; /* internal flags */ DWORD cursize; /* current size of realMRU */ LPSTR realMRU; /* pointer to string of index names */ @@ -453,10 +464,6 @@ /* wineFlags */ #define WMRUF_CHANGED 0x0001 /* MRU list has changed */ -HANDLE WINAPI -CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2, - DWORD dwParam3, DWORD dwParam4); - /************************************************************************** * MRU_SaveChanged - Localize MRU saving code * @@ -465,35 +472,36 @@ { INT i, err; HKEY newkey; - CHAR realname[2]; + WCHAR realname[2]; LPWINEMRUITEM witem; + WCHAR emptyW[] = {'\0'}; /* or should we do the following instead of RegOpenKeyEx: */ /* open the sub key */ - if ((err = RegOpenKeyExA( mp->extview.hKey, mp->extview.lpszSubKey, - 0, KEY_WRITE, &newkey))) { + if ((err = RegOpenKeyExW( mp->extview.hKey, mp->extview.lpszSubKey, + 0, KEY_WRITE, &newkey))) { /* not present - what to do ??? */ ERR("Can not open key, error=%d, attempting to create\n", err); - if ((err = RegCreateKeyExA( mp->extview.hKey, mp->extview.lpszSubKey, + if ((err = RegCreateKeyExW( mp->extview.hKey, mp->extview.lpszSubKey, 0, - "", + emptyW, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, 0, &newkey, 0))) { ERR("failed to create key /%s/, err=%d\n", - mp->extview.lpszSubKey, err); + debugstr_w(mp->extview.lpszSubKey), err); return; } } if (mp->wineFlags & WMRUF_CHANGED) { mp->wineFlags &= ~WMRUF_CHANGED; err = RegSetValueExA(newkey, "MRUList", 0, REG_SZ, - mp->realMRU, lstrlenA(mp->realMRU) + 1); + mp->realMRU, strlen(mp->realMRU) + 1); if (err) { ERR("error saving MRUList, err=%d\n", err); } @@ -505,36 +513,21 @@ if (witem->itemFlag & WMRUIF_CHANGED) { witem->itemFlag &= ~WMRUIF_CHANGED; realname[0] = 'a' + i; - err = RegSetValueExA(newkey, realname, 0, + err = RegSetValueExW(newkey, realname, 0, (mp->extview.dwFlags & MRUF_BINARY_LIST) ? REG_BINARY : REG_SZ, &witem->datastart, witem->size); if (err) { - ERR("error saving /%s/, err=%d\n", realname, err); + ERR("error saving /%s/, err=%d\n", debugstr_w(realname), err); } TRACE("saving value for name /%s/ size=%ld\n", - realname, witem->size); + debugstr_w(realname), witem->size); } } RegCloseKey( newkey ); } /************************************************************************** - * CreateMRUListA [COMCTL32.151] - * - * PARAMS - * lpcml [I] ptr to CREATEMRULIST structure. - * - * RETURNS - * Handle to MRU list. - */ -HANDLE WINAPI -CreateMRUListA (LPCREATEMRULIST lpcml) -{ - return CreateMRUListLazyA (lpcml, 0, 0, 0); -} - -/************************************************************************** * FreeMRUList [COMCTL32.152] * * PARAMS @@ -542,7 +535,7 @@ * */ DWORD WINAPI -FreeMRUListA (HANDLE hMRUList) +FreeMRUList (HANDLE hMRUList) { LPWINEMRULIST mp = (LPWINEMRULIST)hMRUList; INT i; @@ -559,6 +552,7 @@ } COMCTL32_Free(mp->realMRU); COMCTL32_Free(mp->array); + COMCTL32_Free((LPWSTR)mp->extview.lpszSubKey); return COMCTL32_Free(mp); } @@ -584,12 +578,20 @@ { LPWINEMRULIST mp = (LPWINEMRULIST)hList; INT i, ret; + LPSTR dataA = NULL; if (!mp->extview.lpfnCompare) { ERR("MRU list not properly created. No compare procedure.\n"); return -1; } + if(!(mp->extview.dwFlags & MRUF_BINARY_LIST) && !mp->isUnicode) { + DWORD len = WideCharToMultiByte(CP_ACP, 0, lpData, -1, + NULL, 0, NULL, NULL); + dataA = COMCTL32_Alloc(len); + WideCharToMultiByte(CP_ACP, 0, lpData, -1, dataA, len, NULL, NULL); + } + for(i=0; i<mp->cursize; i++) { if (mp->extview.dwFlags & MRUF_BINARY_LIST) { if (!mp->extview.lpfnCompare(lpData, &mp->array[i]->datastart, @@ -597,10 +599,27 @@ break; } else { - if (!mp->extview.lpfnCompare(lpData, &mp->array[i]->datastart)) - break; + if(mp->isUnicode) { + if (!mp->extview.lpfnCompare(lpData, &mp->array[i]->datastart)) + break; + } else { + DWORD len = WideCharToMultiByte(CP_ACP, 0, + (LPWSTR)&mp->array[i]->datastart, -1, + NULL, 0, NULL, NULL); + LPSTR itemA = COMCTL32_Alloc(len); + INT cmp; + WideCharToMultiByte(CP_ACP, 0, (LPWSTR)&mp->array[i]->datastart, -1, + itemA, len, NULL, NULL); + + cmp = mp->extview.lpfnCompare(dataA, itemA); + COMCTL32_Free(itemA); + if(!cmp) + break; + } } } + if(dataA) + COMCTL32_Free(dataA); if (i < mp->cursize) ret = i; else @@ -682,7 +701,7 @@ } /************************************************************************** - * AddMRUStringA [COMCTL32.153] + * AddMRUStringW [COMCTL32.401] * * Add item to MRU string list. If item already exists in list them it is * simply moved up to the top of the list and not added again. If list is @@ -697,6 +716,17 @@ * -1 on error. */ INT WINAPI +AddMRUStringW(HANDLE hList, LPCWSTR lpszString) +{ + FIXME("(%08x, %s) empty stub!\n", hList, debugstr_w(lpszString)); + + return 0; +} + +/************************************************************************** + * AddMRUStringA [COMCTL32.153] + */ +INT WINAPI AddMRUStringA(HANDLE hList, LPCSTR lpszString) { FIXME("(%08x, %s) empty stub!\n", hList, debugstr_a(lpszString)); @@ -724,6 +754,16 @@ } /************************************************************************** + * FindMRUStringW [COMCTL32.402] + */ +INT WINAPI +FindMRUStringW (HANDLE hList, LPCWSTR lpszString, LPINT lpRegNum) +{ + FIXME("stub\n"); + return -1; +} + +/************************************************************************** * FindMRUStringA [COMCTL32.155] * * Searches string list for item that matches lpszString. @@ -741,34 +781,30 @@ INT WINAPI FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum) { - return FindMRUData(hList, (LPVOID)lpszString, lstrlenA(lpszString), - lpRegNum); + DWORD len = MultiByteToWideChar(CP_ACP, 0, lpszString, -1, NULL, 0); + LPWSTR stringW = COMCTL32_Alloc(len * sizeof(WCHAR)); + INT ret; + + MultiByteToWideChar(CP_ACP, 0, lpszString, -1, stringW, len); + ret = FindMRUData(hList, stringW, len * sizeof(WCHAR), lpRegNum); + COMCTL32_Free(stringW); + return ret; } -/************************************************************************** - * CreateMRUListLazyA [COMCTL32.157] +/************************************************************************* + * CreateMRUListLazy_common */ -HANDLE WINAPI -CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4) +HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp) { - LPWINEMRULIST mp; INT i, err; HKEY newkey; DWORD datasize, dwdisp; - CHAR realname[2]; + WCHAR realname[2]; LPWINEMRUITEM witem; DWORD type; - - if (lpcml == NULL) - return 0; - - if (lpcml->cbSize < sizeof(CREATEMRULIST)) - return 0; - - mp = (LPWINEMRULIST) COMCTL32_Alloc(sizeof(WINEMRULIST)); - memcpy(mp, lpcml, sizeof(CREATEMRULIST)); + WCHAR emptyW[] = {'\0'}; - /* get space to save indexes that will turn into names + /* get space to save indices that will turn into names * but in order of most to least recently used */ mp->realMRU = (LPSTR) COMCTL32_Alloc(mp->extview.nMaxItems + 2); @@ -780,9 +816,9 @@ sizeof(LPVOID)); /* open the sub key */ - if ((err = RegCreateKeyExA( mp->extview.hKey, mp->extview.lpszSubKey, - 0, - "", + if ((err = RegCreateKeyExW( mp->extview.hKey, mp->extview.lpszSubKey, + 0, + emptyW, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, 0, @@ -790,9 +826,9 @@ &dwdisp))) { /* error - what to do ??? */ ERR("(%lu %lu %lx %lx \"%s\" %p): Can not open key, error=%d\n", - lpcml->cbSize, lpcml->nMaxItems, lpcml->dwFlags, - (DWORD)lpcml->hKey, lpcml->lpszSubKey, lpcml->lpfnCompare, - err); + mp->extview.cbSize, mp->extview.nMaxItems, mp->extview.dwFlags, + (DWORD)mp->extview.hKey, debugstr_w(mp->extview.lpszSubKey), + mp->extview.lpfnCompare, err); return 0; } @@ -815,17 +851,17 @@ realname[1] = 0; for(i=0; i<mp->cursize; i++) { realname[0] = 'a' + i; - if(RegQueryValueExA( newkey, realname, 0, &type, 0, &datasize)) { + if(RegQueryValueExW( newkey, realname, 0, &type, 0, &datasize)) { /* not present - what to do ??? */ - ERR("Key %s not found 1\n", realname); + ERR("Key %s not found 1\n", debugstr_w(realname)); } mp->array[i] = witem = (LPWINEMRUITEM)COMCTL32_Alloc(datasize + sizeof(WINEMRUITEM)); witem->size = datasize; - if(RegQueryValueExA( newkey, realname, 0, &type, + if(RegQueryValueExW( newkey, realname, 0, &type, &witem->datastart, &datasize)) { /* not present - what to do ??? */ - ERR("Key %s not found 2\n", realname); + ERR("Key %s not found 2\n", debugstr_w(realname)); } } RegCloseKey( newkey ); @@ -834,16 +870,89 @@ mp->cursize = 0; TRACE("(%lu %lu %lx %lx \"%s\" %p): Current Size = %ld\n", - lpcml->cbSize, lpcml->nMaxItems, lpcml->dwFlags, - (DWORD)lpcml->hKey, lpcml->lpszSubKey, lpcml->lpfnCompare, - mp->cursize); - + mp->extview.cbSize, mp->extview.nMaxItems, mp->extview.dwFlags, + (DWORD)mp->extview.hKey, debugstr_w(mp->extview.lpszSubKey), + mp->extview.lpfnCompare, mp->cursize); return (HANDLE)mp; } /************************************************************************** - * EnumMRUListA [COMCTL32.154] - * + * CreateMRUListLazyW [COMCTL32.404] + */ +HANDLE WINAPI +CreateMRUListLazyW (LPCREATEMRULISTW lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4) +{ + LPWINEMRULIST mp; + + if (lpcml == NULL) + return 0; + + if (lpcml->cbSize < sizeof(CREATEMRULISTW)) + return 0; + + mp = (LPWINEMRULIST) COMCTL32_Alloc(sizeof(WINEMRULIST)); + memcpy(&mp->extview, lpcml, sizeof(CREATEMRULISTW)); + mp->extview.lpszSubKey = COMCTL32_Alloc((strlenW(lpcml->lpszSubKey) + 1) * + sizeof(WCHAR)); + strcpyW((LPWSTR)mp->extview.lpszSubKey, lpcml->lpszSubKey); + mp->isUnicode = TRUE; + + return CreateMRUListLazy_common(mp); +} + +/************************************************************************** + * CreateMRUListLazyA [COMCTL32.157] + */ +HANDLE WINAPI +CreateMRUListLazyA (LPCREATEMRULISTA lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4) +{ + LPWINEMRULIST mp; + DWORD len; + + if (lpcml == NULL) + return 0; + + if (lpcml->cbSize < sizeof(CREATEMRULISTA)) + return 0; + + mp = (LPWINEMRULIST) COMCTL32_Alloc(sizeof(WINEMRULIST)); + memcpy(&mp->extview, lpcml, sizeof(CREATEMRULISTW)); + len = MultiByteToWideChar(CP_ACP, 0, lpcml->lpszSubKey, -1, NULL, 0); + mp->extview.lpszSubKey = COMCTL32_Alloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpcml->lpszSubKey, -1, + (LPWSTR)mp->extview.lpszSubKey, len); + mp->isUnicode = FALSE; + return CreateMRUListLazy_common(mp); +} + +/************************************************************************** + * CreateMRUListW [COMCTL32.400] + * + * PARAMS + * lpcml [I] ptr to CREATEMRULIST structure. + * + * RETURNS + * Handle to MRU list. + */ +HANDLE WINAPI +CreateMRUListW (LPCREATEMRULISTW lpcml) +{ + return CreateMRUListLazyW(lpcml, 0, 0, 0); +} + +/************************************************************************** + * CreateMRUListA [COMCTL32.151] + */ +HANDLE WINAPI +CreateMRUListA (LPCREATEMRULISTA lpcml) +{ + return CreateMRUListLazyA (lpcml, 0, 0, 0); +} + + +/************************************************************************** + * EnumMRUListW [COMCTL32.403] + * * Enumerate item in a list * * PARAMS @@ -859,7 +968,7 @@ * If lpBuffer == NULL or nItemPos is -ve return value is no. of items in * the list. */ -INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer, +INT WINAPI EnumMRUListW(HANDLE hList, INT nItemPos, LPVOID lpBuffer, DWORD nBufferSize) { LPWINEMRULIST mp = (LPWINEMRULIST) hList; @@ -878,6 +987,40 @@ hList, nItemPos, lpBuffer, nBufferSize, datasize); return datasize; } + +/************************************************************************** + * EnumMRUListA [COMCTL32.154] + * + */ +INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer, +DWORD nBufferSize) +{ + LPWINEMRULIST mp = (LPWINEMRULIST) hList; + LPWINEMRUITEM witem; + INT desired, datasize; + DWORD lenA; + + if (nItemPos >= mp->cursize) return -1; + if ((nItemPos < 0) || !lpBuffer) return mp->cursize; + desired = mp->realMRU[nItemPos]; + desired -= 'a'; + TRACE("nItemPos=%d, desired=%d\n", nItemPos, desired); + witem = mp->array[desired]; + if(mp->extview.dwFlags & MRUF_BINARY_LIST) { + datasize = min( witem->size, nBufferSize ); + memcpy( lpBuffer, &witem->datastart, datasize); + } else { + lenA = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)&witem->datastart, -1, + NULL, 0, NULL, NULL); + datasize = min( witem->size, nBufferSize ); + WideCharToMultiByte(CP_ACP, 0, (LPWSTR)&witem->datastart, -1, + lpBuffer, datasize, NULL, NULL); + } + TRACE("(%08x, %d, %p, %ld): returning len=%d\n", + hList, nItemPos, lpBuffer, nBufferSize, datasize); + return datasize; +} + /************************************************************************** * Str_GetPtrA [COMCTL32.233]