Implement most of the MRU related functions.
This commit is contained in:
parent
2011fa2d34
commit
45e9cea3d1
|
@ -24,6 +24,7 @@
|
|||
#include "objbase.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "comctl32.h"
|
||||
|
@ -429,20 +430,94 @@ typedef struct tagCREATEMRULIST
|
|||
* Need to check what return value means identical - 0?
|
||||
*/
|
||||
|
||||
typedef struct tagMRU
|
||||
typedef struct tagWINEMRUITEM
|
||||
{
|
||||
DWORD dwParam1; /* some kind of flag */
|
||||
DWORD dwParam2;
|
||||
DWORD dwParam3;
|
||||
HKEY hkeyMRU;
|
||||
LPCSTR lpszSubKey;
|
||||
DWORD dwParam6;
|
||||
} MRU, *HMRU;
|
||||
DWORD size; /* size of data stored */
|
||||
DWORD itemFlag; /* flags */
|
||||
BYTE datastart;
|
||||
} WINEMRUITEM, *LPWINEMRUITEM;
|
||||
|
||||
/* itemFlag */
|
||||
#define WMRUIF_CHANGED 0x0001 /* this dataitem changed */
|
||||
|
||||
typedef struct tagWINEMRULIST
|
||||
{
|
||||
CREATEMRULIST extview; /* original create information */
|
||||
DWORD wineFlags; /* internal flags */
|
||||
DWORD cursize; /* current size of realMRU */
|
||||
LPSTR realMRU; /* pointer to string of index names */
|
||||
LPWINEMRUITEM *array; /* array of pointers to data */
|
||||
/* in 'a' to 'z' order */
|
||||
} WINEMRULIST, *LPWINEMRULIST;
|
||||
|
||||
/* 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
|
||||
*
|
||||
*/
|
||||
VOID MRU_SaveChanged( LPWINEMRULIST mp )
|
||||
{
|
||||
INT i, err;
|
||||
HKEY newkey;
|
||||
CHAR realname[2];
|
||||
LPWINEMRUITEM witem;
|
||||
|
||||
/* 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))) {
|
||||
/* 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,
|
||||
0,
|
||||
"",
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_READ | KEY_WRITE,
|
||||
0,
|
||||
&newkey,
|
||||
0))) {
|
||||
ERR("failed to create key /%s/, err=%d\n",
|
||||
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);
|
||||
if (err) {
|
||||
ERR("error saving MRUList, err=%d\n", err);
|
||||
}
|
||||
TRACE("saving MRUList=/%s/\n", mp->realMRU);
|
||||
}
|
||||
realname[1] = 0;
|
||||
for(i=0; i<mp->cursize; i++) {
|
||||
witem = mp->array[i];
|
||||
if (witem->itemFlag & WMRUIF_CHANGED) {
|
||||
witem->itemFlag &= ~WMRUIF_CHANGED;
|
||||
realname[0] = 'a' + i;
|
||||
err = RegSetValueExA(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);
|
||||
}
|
||||
TRACE("saving value for name /%s/ size=%ld\n",
|
||||
realname, witem->size);
|
||||
}
|
||||
}
|
||||
RegCloseKey( newkey );
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CreateMRUListA [COMCTL32.151]
|
||||
|
@ -469,21 +544,74 @@ CreateMRUListA (LPCREATEMRULIST lpcml)
|
|||
DWORD WINAPI
|
||||
FreeMRUListA (HANDLE hMRUList)
|
||||
{
|
||||
FIXME("(%08x) empty stub!\n", hMRUList);
|
||||
LPWINEMRULIST mp = (LPWINEMRULIST)hMRUList;
|
||||
INT i;
|
||||
|
||||
#if 0
|
||||
if (!(hmru->dwParam1 & 1001)) {
|
||||
RegSetValueExA (hmru->hKeyMRU, "MRUList", 0, REG_SZ,
|
||||
hmru->lpszMRUString,
|
||||
strlen (hmru->lpszMRUString));
|
||||
TRACE("\n");
|
||||
if (mp->wineFlags & WMRUF_CHANGED) {
|
||||
/* need to open key and then save the info */
|
||||
MRU_SaveChanged( mp );
|
||||
}
|
||||
|
||||
for(i=0; i<mp->extview.nMaxItems; i++) {
|
||||
if (mp->array[i])
|
||||
COMCTL32_Free(mp->array[i]);
|
||||
}
|
||||
COMCTL32_Free(mp->realMRU);
|
||||
COMCTL32_Free(mp->array);
|
||||
return COMCTL32_Free(mp);
|
||||
}
|
||||
|
||||
RegClosKey (hmru->hkeyMRU
|
||||
COMCTL32_Free32 (hmru->lpszMRUString);
|
||||
#endif
|
||||
|
||||
return COMCTL32_Free ((LPVOID)hMRUList);
|
||||
/**************************************************************************
|
||||
* FindMRUData [COMCTL32.169]
|
||||
*
|
||||
* Searches binary list for item that matches lpData of length cbData.
|
||||
* Returns position in list order 0 -> MRU and if lpRegNum != NULL then value
|
||||
* corresponding to item's reg. name will be stored in it ('a' -> 0).
|
||||
*
|
||||
* PARAMS
|
||||
* hList [I] list handle
|
||||
* lpData [I] data to find
|
||||
* cbData [I] length of data
|
||||
* lpRegNum [O] position in registry (maybe NULL)
|
||||
*
|
||||
* RETURNS
|
||||
* Position in list 0 -> MRU. -1 if item not found.
|
||||
*/
|
||||
INT WINAPI
|
||||
FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
|
||||
{
|
||||
LPWINEMRULIST mp = (LPWINEMRULIST)hList;
|
||||
INT i, ret;
|
||||
|
||||
if (!mp->extview.lpfnCompare) {
|
||||
ERR("MRU list not properly created. No compare procedure.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i=0; i<mp->cursize; i++) {
|
||||
if (mp->extview.dwFlags & MRUF_BINARY_LIST) {
|
||||
if (!mp->extview.lpfnCompare(lpData, &mp->array[i]->datastart,
|
||||
cbData))
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (!mp->extview.lpfnCompare(lpData, &mp->array[i]->datastart))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < mp->cursize)
|
||||
ret = i;
|
||||
else
|
||||
ret = -1;
|
||||
if (lpRegNum && (ret != -1))
|
||||
*lpRegNum = 'a' + i;
|
||||
|
||||
TRACE("(%08x, %p, %ld, %p) returning %d\n",
|
||||
hList, lpData, cbData, lpRegNum, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -506,9 +634,51 @@ FreeMRUListA (HANDLE hMRUList)
|
|||
INT WINAPI
|
||||
AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
|
||||
{
|
||||
FIXME("(%08x, %p, %ld) empty stub!\n", hList, lpData, cbData);
|
||||
LPWINEMRULIST mp = (LPWINEMRULIST)hList;
|
||||
LPWINEMRUITEM witem;
|
||||
INT i, replace, ret;
|
||||
|
||||
return 0;
|
||||
if ((replace = FindMRUData (hList, lpData, cbData, NULL)) < 0) {
|
||||
/* either add a new entry or replace oldest */
|
||||
if (mp->cursize < mp->extview.nMaxItems) {
|
||||
/* Add in a new item */
|
||||
replace = mp->cursize;
|
||||
mp->cursize++;
|
||||
}
|
||||
else {
|
||||
/* get the oldest entry and replace data */
|
||||
replace = mp->realMRU[mp->cursize - 1] - 'a';
|
||||
COMCTL32_Free(mp->array[replace]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* free up the old data */
|
||||
COMCTL32_Free(mp->array[replace]);
|
||||
}
|
||||
|
||||
/* Allocate space for new item and move in the data */
|
||||
mp->array[replace] = witem = (LPWINEMRUITEM)COMCTL32_Alloc(cbData +
|
||||
sizeof(WINEMRUITEM));
|
||||
witem->itemFlag |= WMRUIF_CHANGED;
|
||||
witem->size = cbData;
|
||||
memcpy( &witem->datastart, lpData, cbData);
|
||||
|
||||
/* now rotate MRU list */
|
||||
mp->wineFlags |= WMRUF_CHANGED;
|
||||
for(i=mp->cursize-1; i>=1; i--) {
|
||||
mp->realMRU[i] = mp->realMRU[i-1];
|
||||
}
|
||||
mp->realMRU[0] = replace + 'a';
|
||||
TRACE("(%08x, %p, %ld) adding data, /%c/ now most current\n",
|
||||
hList, lpData, cbData, replace+'a');
|
||||
ret = replace;
|
||||
|
||||
if (!(mp->extview.dwFlags & MRUF_DELAYED_SAVE)) {
|
||||
/* save changed stuff right now */
|
||||
MRU_SaveChanged( mp );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -553,31 +723,6 @@ DelMRUString(HANDLE hList, INT nItemPos)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* FindMRUData [COMCTL32.169]
|
||||
*
|
||||
* Searches binary list for item that matches lpData of length cbData.
|
||||
* Returns position in list order 0 -> MRU and if lpRegNum != NULL then value
|
||||
* corresponding to item's reg. name will be stored in it ('a' -> 0).
|
||||
*
|
||||
* PARAMS
|
||||
* hList [I] list handle
|
||||
* lpData [I] data to find
|
||||
* cbData [I] length of data
|
||||
* lpRegNum [O] position in registry (maybe NULL)
|
||||
*
|
||||
* RETURNS
|
||||
* Position in list 0 -> MRU. -1 if item not found.
|
||||
*/
|
||||
INT WINAPI
|
||||
FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
|
||||
{
|
||||
FIXME("(%08x, %p, %ld, %p) empty stub!\n",
|
||||
hList, lpData, cbData, lpRegNum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* FindMRUStringA [COMCTL32.155]
|
||||
*
|
||||
|
@ -596,10 +741,8 @@ FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
|
|||
INT WINAPI
|
||||
FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
|
||||
{
|
||||
FIXME("(%08x, %s, %p) empty stub!\n", hList, debugstr_a(lpszString),
|
||||
return FindMRUData(hList, (LPVOID)lpszString, lstrlenA(lpszString),
|
||||
lpRegNum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -608,19 +751,13 @@ FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
|
|||
HANDLE WINAPI
|
||||
CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
|
||||
{
|
||||
/* DWORD dwLocal1; *
|
||||
* HKEY hkeyResult; *
|
||||
* DWORD dwLocal3; *
|
||||
* LPVOID lMRU; *
|
||||
* DWORD dwLocal5; *
|
||||
* DWORD dwLocal6; *
|
||||
* DWORD dwLocal7; *
|
||||
* DWORD dwDisposition; */
|
||||
|
||||
/* internal variables */
|
||||
LPVOID ptr;
|
||||
|
||||
FIXME("(%p) empty stub!\n", lpcml);
|
||||
LPWINEMRULIST mp;
|
||||
INT i, err;
|
||||
HKEY newkey;
|
||||
DWORD datasize, dwdisp;
|
||||
CHAR realname[2];
|
||||
LPWINEMRUITEM witem;
|
||||
DWORD type;
|
||||
|
||||
if (lpcml == NULL)
|
||||
return 0;
|
||||
|
@ -628,16 +765,80 @@ CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2, DWORD dwParam3, DWORD
|
|||
if (lpcml->cbSize < sizeof(CREATEMRULIST))
|
||||
return 0;
|
||||
|
||||
FIXME("(%lu %lu %lx %lx \"%s\" %p)\n",
|
||||
mp = (LPWINEMRULIST) COMCTL32_Alloc(sizeof(WINEMRULIST));
|
||||
memcpy(mp, lpcml, sizeof(CREATEMRULIST));
|
||||
|
||||
/* get space to save indexes that will turn into names
|
||||
* but in order of most to least recently used
|
||||
*/
|
||||
mp->realMRU = (LPSTR) COMCTL32_Alloc(mp->extview.nMaxItems + 2);
|
||||
|
||||
/* get space to save pointers to actual data in order of
|
||||
* 'a' to 'z' (0 to n).
|
||||
*/
|
||||
mp->array = (LPVOID) COMCTL32_Alloc(mp->extview.nMaxItems *
|
||||
sizeof(LPVOID));
|
||||
|
||||
/* open the sub key */
|
||||
if ((err = RegCreateKeyExA( mp->extview.hKey, mp->extview.lpszSubKey,
|
||||
0,
|
||||
"",
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_READ | KEY_WRITE,
|
||||
0,
|
||||
&newkey,
|
||||
&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);
|
||||
(DWORD)lpcml->hKey, lpcml->lpszSubKey, lpcml->lpfnCompare,
|
||||
err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dummy pointer creation */
|
||||
ptr = COMCTL32_Alloc (32);
|
||||
/* get values from key 'MRUList' */
|
||||
if (newkey) {
|
||||
datasize = mp->extview.nMaxItems + 1;
|
||||
if((err=RegQueryValueExA( newkey, "MRUList", 0, &type, mp->realMRU,
|
||||
&datasize))) {
|
||||
/* not present - set size to 1 (will become 0 later) */
|
||||
datasize = 1;
|
||||
*mp->realMRU = 0;
|
||||
}
|
||||
|
||||
FIXME("-- ret = %p\n", ptr);
|
||||
TRACE("MRU list = %s\n", mp->realMRU);
|
||||
|
||||
return (HANDLE)ptr;
|
||||
mp->cursize = datasize - 1;
|
||||
/* datasize now has number of items in the MRUList */
|
||||
|
||||
/* get actual values for each entry */
|
||||
realname[1] = 0;
|
||||
for(i=0; i<mp->cursize; i++) {
|
||||
realname[0] = 'a' + i;
|
||||
if(RegQueryValueExA( newkey, realname, 0, &type, 0, &datasize)) {
|
||||
/* not present - what to do ??? */
|
||||
ERR("Key %s not found 1\n", realname);
|
||||
}
|
||||
mp->array[i] = witem = (LPWINEMRUITEM)COMCTL32_Alloc(datasize +
|
||||
sizeof(WINEMRUITEM));
|
||||
witem->size = datasize;
|
||||
if(RegQueryValueExA( newkey, realname, 0, &type,
|
||||
&witem->datastart, &datasize)) {
|
||||
/* not present - what to do ??? */
|
||||
ERR("Key %s not found 2\n", realname);
|
||||
}
|
||||
}
|
||||
RegCloseKey( newkey );
|
||||
}
|
||||
else
|
||||
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);
|
||||
|
||||
return (HANDLE)mp;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -661,9 +862,21 @@ CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2, DWORD dwParam3, DWORD
|
|||
INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer,
|
||||
DWORD nBufferSize)
|
||||
{
|
||||
FIXME("(%08x, %d, %p, %ld): stub\n", hList, nItemPos, lpBuffer,
|
||||
nBufferSize);
|
||||
return 0;
|
||||
LPWINEMRULIST mp = (LPWINEMRULIST) hList;
|
||||
LPWINEMRUITEM witem;
|
||||
INT desired, datasize;
|
||||
|
||||
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];
|
||||
datasize = min( witem->size, nBufferSize );
|
||||
memcpy( lpBuffer, &witem->datastart, datasize);
|
||||
TRACE("(%08x, %d, %p, %ld): returning len=%d\n",
|
||||
hList, nItemPos, lpBuffer, nBufferSize, datasize);
|
||||
return datasize;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
|
Loading…
Reference in New Issue