📄 comctl32undoc.c
字号:
LPINT lpRegNum)
{
LPWINEMRULIST mp = (LPWINEMRULIST)hList;
INT ret;
UINT i;
LPSTR dataA = NULL;
if (!mp->extview.lpfnCompare)
return -1;
if(!(mp->extview.dwFlags & MRUF_BINARY_LIST) && !mp->isUnicode) {
DWORD len = WideCharToMultiByte(CP_ACP, 0, lpData, -1,
NULL, 0, NULL, NULL);
dataA = 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,
cbData))
break;
}
else {
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 = Alloc(len);
INT cmp;
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)&mp->array[i]->datastart, -1,
itemA, len, NULL, NULL);
cmp = mp->extview.lpfnCompare(dataA, itemA);
Free(itemA);
if(!cmp)
break;
}
}
}
if(dataA)
Free(dataA);
if (i < mp->cursize)
ret = i;
else
ret = -1;
if (lpRegNum && (ret != -1))
*lpRegNum = 'a' + i;
TRACE("(%p, %p, %d, %p) returning %d\n",
hList, lpData, cbData, lpRegNum, ret);
return ret;
}
/**************************************************************************
* AddMRUData [COMCTL32.167]
*
* Add item to MRU binary list. If item already exists in list then it is
* simply moved up to the top of the list and not added again. If list is
* full then the least recently used item is removed to make room.
*
* PARAMS
* hList [I] Handle to list.
* lpData [I] ptr to data to add.
* cbData [I] no. of bytes of data.
*
* RETURNS
* No. corresponding to registry name where value is stored 'a' -> 0 etc.
* -1 on error.
*/
INT WINAPI AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
{
LPWINEMRULIST mp = (LPWINEMRULIST)hList;
LPWINEMRUITEM witem;
INT i, replace;
if ((replace = FindMRUData (hList, lpData, cbData, NULL)) >= 0) {
/* Item exists, just move it to the front */
LPWSTR pos = strchrW(mp->realMRU, replace + 'a');
while (pos > mp->realMRU)
{
pos[0] = pos[-1];
pos--;
}
}
else {
/* 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';
Free(mp->array[replace]);
}
/* Allocate space for new item and move in the data */
mp->array[replace] = witem = Alloc(cbData + sizeof(WINEMRUITEM));
witem->itemFlag |= WMRUIF_CHANGED;
witem->size = cbData;
memcpy( &witem->datastart, lpData, cbData);
/* now rotate MRU list */
for(i=mp->cursize-1; i>=1; i--)
mp->realMRU[i] = mp->realMRU[i-1];
}
/* The new item gets the front spot */
mp->wineFlags |= WMRUF_CHANGED;
mp->realMRU[0] = replace + 'a';
TRACE("(%p, %p, %d) adding data, /%c/ now most current\n",
hList, lpData, cbData, replace+'a');
if (!(mp->extview.dwFlags & MRUF_DELAYED_SAVE)) {
/* save changed stuff right now */
MRU_SaveChanged( mp );
}
return replace;
}
/**************************************************************************
* AddMRUStringW [COMCTL32.401]
*
* Add an item to an MRU string list.
*
* PARAMS
* hList [I] Handle to list.
* lpszString [I] The string to add.
*
* RETURNS
* Success: The number corresponding to the registry name where the string
* has been stored (0 maps to 'a', 1 to 'b' and so on).
* Failure: -1, if hList is NULL or memory allocation fails. If lpszString
* is invalid, the function returns 0, and GetLastError() returns
* ERROR_INVALID_PARAMETER. The last error value is set only in
* this case.
*
* NOTES
* -If lpszString exists in the list already, it is moved to the top of the
* MRU list (it is not duplicated).
* -If the list is full the least recently used list entry is replaced with
* lpszString.
* -If this function returns 0 you should check the last error value to
* ensure the call really succeeded.
*/
INT WINAPI AddMRUStringW(HANDLE hList, LPCWSTR lpszString)
{
TRACE("(%p,%s)\n", hList, debugstr_w(lpszString));
if (!hList)
return -1;
if (!lpszString || IsBadStringPtrW(lpszString, -1))
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
return AddMRUData(hList, lpszString,
(strlenW(lpszString) + 1) * sizeof(WCHAR));
}
/**************************************************************************
* AddMRUStringA [COMCTL32.153]
*
* See AddMRUStringW.
*/
INT WINAPI AddMRUStringA(HANDLE hList, LPCSTR lpszString)
{
DWORD len;
LPWSTR stringW;
INT ret;
TRACE("(%p,%s)\n", hList, debugstr_a(lpszString));
if (!hList)
return -1;
if (IsBadStringPtrA(lpszString, -1))
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
len = MultiByteToWideChar(CP_ACP, 0, lpszString, -1, NULL, 0) * sizeof(WCHAR);
stringW = Alloc(len);
if (!stringW)
return -1;
MultiByteToWideChar(CP_ACP, 0, lpszString, -1, stringW, len/sizeof(WCHAR));
ret = AddMRUData(hList, stringW, len);
Free(stringW);
return ret;
}
/**************************************************************************
* DelMRUString [COMCTL32.156]
*
* Removes item from either string or binary list (despite its name)
*
* PARAMS
* hList [I] list handle
* nItemPos [I] item position to remove 0 -> MRU
*
* RETURNS
* TRUE if successful, FALSE if nItemPos is out of range.
*/
BOOL WINAPI DelMRUString(HANDLE hList, INT nItemPos)
{
FIXME("(%p, %d): stub\n", hList, nItemPos);
return TRUE;
}
/**************************************************************************
* FindMRUStringW [COMCTL32.402]
*
* See FindMRUStringA.
*/
INT WINAPI FindMRUStringW (HANDLE hList, LPCWSTR lpszString, LPINT lpRegNum)
{
return FindMRUData(hList, lpszString,
(lstrlenW(lpszString) + 1) * sizeof(WCHAR), lpRegNum);
}
/**************************************************************************
* FindMRUStringA [COMCTL32.155]
*
* Searches string list for item that matches lpszString.
* 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
* lpszString [I] string to find
* lpRegNum [O] position in registry (maybe NULL)
*
* RETURNS
* Position in list 0 -> MRU. -1 if item not found.
*/
INT WINAPI FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
{
DWORD len = MultiByteToWideChar(CP_ACP, 0, lpszString, -1, NULL, 0);
LPWSTR stringW = Alloc(len * sizeof(WCHAR));
INT ret;
MultiByteToWideChar(CP_ACP, 0, lpszString, -1, stringW, len);
ret = FindMRUData(hList, stringW, len * sizeof(WCHAR), lpRegNum);
Free(stringW);
return ret;
}
/*************************************************************************
* CreateMRUListLazy_common (internal)
*/
static HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
{
UINT i, err;
HKEY newkey;
DWORD datasize, dwdisp;
WCHAR realname[2];
LPWINEMRUITEM witem;
DWORD type;
/* get space to save indices that will turn into names
* but in order of most to least recently used
*/
mp->realMRU = Alloc((mp->extview.nMaxItems + 2) * sizeof(WCHAR));
/* get space to save pointers to actual data in order of
* 'a' to 'z' (0 to n).
*/
mp->array = Alloc(mp->extview.nMaxItems * sizeof(LPVOID));
/* open the sub key */
if ((err = RegCreateKeyExW( mp->extview.hKey, mp->extview.lpszSubKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_READ | KEY_WRITE,
0,
&newkey,
&dwdisp))) {
/* error - what to do ??? */
ERR("(%u %u %x %p %s %p): Could not open key, error=%d\n",
mp->extview.cbSize, mp->extview.nMaxItems, mp->extview.dwFlags,
mp->extview.hKey, debugstr_w(mp->extview.lpszSubKey),
mp->extview.lpfnCompare, err);
return 0;
}
/* get values from key 'MRUList' */
if (newkey) {
datasize = (mp->extview.nMaxItems + 1) * sizeof(WCHAR);
if((err=RegQueryValueExW( newkey, strMRUList, 0, &type,
(LPBYTE)mp->realMRU, &datasize))) {
/* not present - set size to 1 (will become 0 later) */
datasize = 1;
*mp->realMRU = 0;
}
else
datasize /= sizeof(WCHAR);
TRACE("MRU list = %s, datasize = %d\n", debugstr_w(mp->realMRU), datasize);
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(RegQueryValueExW( newkey, realname, 0, &type, 0, &datasize)) {
/* not present - what to do ??? */
ERR("Key %s not found 1\n", debugstr_w(realname));
}
mp->array[i] = witem = Alloc(datasize + sizeof(WINEMRUITEM));
witem->size = datasize;
if(RegQueryValueExW( newkey, realname, 0, &type,
&witem->datastart, &datasize)) {
/* not present - what to do ??? */
ERR("Key %s not found 2\n", debugstr_w(realname));
}
}
RegCloseKey( newkey );
}
else
mp->cursize = 0;
TRACE("(%u %u %x %p %s %p): Current Size = %d\n",
mp->extview.cbSize, mp->extview.nMaxItems, mp->extview.dwFlags,
mp->extview.hKey, debugstr_w(mp->extview.lpszSubKey),
mp->extview.lpfnCompare, mp->cursize);
return (HANDLE)mp;
}
/**************************************************************************
* CreateMRUListLazyW [COMCTL32.404]
*
* See CreateMRUListLazyA.
*/
HANDLE WINAPI CreateMRUListLazyW (LPCREATEMRULISTW lpcml, DWORD dwParam2,
DWORD dwParam3, DWORD dwParam4)
{
LPWINEMRULIST mp;
/* Native does not check for a NULL lpcml */
if (lpcml->cbSize != sizeof(CREATEMRULISTW) || !lpcml->hKey ||
IsBadStringPtrW(lpcml->lpszSubKey, -1))
return NULL;
mp = Alloc(sizeof(WINEMRULIST));
memcpy(&mp->extview, lpcml, sizeof(CREATEMRULISTW));
mp->extview.lpszSubKey = Alloc((strlenW(lpcml->lpszSubKey) + 1) * sizeof(WCHAR));
strcpyW(mp->extview.lpszSubKey, lpcml->lpszSubKey);
mp->isUnicode = TRUE;
return CreateMRUListLazy_common(mp);
}
/**************************************************************************
* CreateMRUListLazyA [COMCTL32.157]
*
* Creates a most-recently-used list.
*
* PARAMS
* lpcml [I] ptr to CREATEMRULIST structure.
* dwParam2 [I] Unknown
* dwParam3 [I] Unknown
* dwParam4 [I] Unknown
*
* RETURNS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -