Implement the remaining MRU functions, fix a couple of differences
from native comctl32, add tests of MRU behaviour and documentation.
This commit is contained in:
parent
03d9cf286e
commit
d6139af2da
|
@ -106,9 +106,8 @@ typedef HRESULT (CALLBACK *DPALOADPROC)(LPLOADDATA,IStream*,LPARAM);
|
||||||
* NOTES
|
* NOTES
|
||||||
* No more information available yet!
|
* No more information available yet!
|
||||||
*/
|
*/
|
||||||
|
HRESULT WINAPI DPA_LoadStream (HDPA *phDpa, DPALOADPROC loadProc,
|
||||||
HRESULT WINAPI
|
IStream *pStream, LPARAM lParam)
|
||||||
DPA_LoadStream (HDPA *phDpa, DPALOADPROC loadProc, IStream *pStream, LPARAM lParam)
|
|
||||||
{
|
{
|
||||||
HRESULT errCode;
|
HRESULT errCode;
|
||||||
LARGE_INTEGER position;
|
LARGE_INTEGER position;
|
||||||
|
@ -205,9 +204,8 @@ DPA_LoadStream (HDPA *phDpa, DPALOADPROC loadProc, IStream *pStream, LPARAM lPar
|
||||||
* NOTES
|
* NOTES
|
||||||
* No more information available yet!
|
* No more information available yet!
|
||||||
*/
|
*/
|
||||||
|
HRESULT WINAPI DPA_SaveStream (const HDPA hDpa, DPALOADPROC loadProc,
|
||||||
HRESULT WINAPI
|
IStream *pStream, LPARAM lParam)
|
||||||
DPA_SaveStream (const HDPA hDpa, DPALOADPROC loadProc, IStream *pStream, LPARAM lParam)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
FIXME ("hDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
|
FIXME ("hDpa=%p loadProc=%p pStream=%p lParam=%lx\n",
|
||||||
|
@ -220,6 +218,8 @@ DPA_SaveStream (const HDPA hDpa, DPALOADPROC loadProc, IStream *pStream, LPARAM
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* DPA_Merge [COMCTL32.11]
|
* DPA_Merge [COMCTL32.11]
|
||||||
*
|
*
|
||||||
|
* Merge two dynamic pointers arrays.
|
||||||
|
*
|
||||||
* PARAMS
|
* PARAMS
|
||||||
* hdpa1 [I] handle to a dynamic pointer array
|
* hdpa1 [I] handle to a dynamic pointer array
|
||||||
* hdpa2 [I] handle to a dynamic pointer array
|
* hdpa2 [I] handle to a dynamic pointer array
|
||||||
|
@ -235,10 +235,9 @@ DPA_SaveStream (const HDPA hDpa, DPALOADPROC loadProc, IStream *pStream, LPARAM
|
||||||
* NOTES
|
* NOTES
|
||||||
* No more information available yet!
|
* No more information available yet!
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags,
|
||||||
BOOL WINAPI
|
PFNDPACOMPARE pfnCompare, PFNDPAMERGE pfnMerge,
|
||||||
DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags,
|
LPARAM lParam)
|
||||||
PFNDPACOMPARE pfnCompare, PFNDPAMERGE pfnMerge, LPARAM lParam)
|
|
||||||
{
|
{
|
||||||
INT nCount;
|
INT nCount;
|
||||||
LPVOID *pWork1, *pWork2;
|
LPVOID *pWork1, *pWork2;
|
||||||
|
@ -373,7 +372,6 @@ DPA_Merge (const HDPA hdpa1, const HDPA hdpa2, DWORD dwFlags,
|
||||||
* Success: pointer to allocated memory block
|
* Success: pointer to allocated memory block
|
||||||
* Failure: NULL
|
* Failure: NULL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LPVOID WINAPI Alloc (DWORD dwSize)
|
LPVOID WINAPI Alloc (DWORD dwSize)
|
||||||
{
|
{
|
||||||
return LocalAlloc( LMEM_ZEROINIT, dwSize );
|
return LocalAlloc( LMEM_ZEROINIT, dwSize );
|
||||||
|
@ -398,7 +396,6 @@ LPVOID WINAPI Alloc (DWORD dwSize)
|
||||||
* If lpSrc is a NULL-pointer, then ReAlloc allocates a memory
|
* If lpSrc is a NULL-pointer, then ReAlloc allocates a memory
|
||||||
* block like Alloc.
|
* block like Alloc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LPVOID WINAPI ReAlloc (LPVOID lpSrc, DWORD dwSize)
|
LPVOID WINAPI ReAlloc (LPVOID lpSrc, DWORD dwSize)
|
||||||
{
|
{
|
||||||
if (lpSrc)
|
if (lpSrc)
|
||||||
|
@ -420,7 +417,6 @@ LPVOID WINAPI ReAlloc (LPVOID lpSrc, DWORD dwSize)
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
BOOL WINAPI Free (LPVOID lpMem)
|
BOOL WINAPI Free (LPVOID lpMem)
|
||||||
{
|
{
|
||||||
return !LocalFree( lpMem );
|
return !LocalFree( lpMem );
|
||||||
|
@ -440,7 +436,6 @@ BOOL WINAPI Free (LPVOID lpMem)
|
||||||
* Success: size of the specified memory block
|
* Success: size of the specified memory block
|
||||||
* Failure: 0
|
* Failure: 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DWORD WINAPI GetSize (LPVOID lpMem)
|
DWORD WINAPI GetSize (LPVOID lpMem)
|
||||||
{
|
{
|
||||||
return LocalSize( lpMem );
|
return LocalSize( lpMem );
|
||||||
|
@ -448,33 +443,90 @@ DWORD WINAPI GetSize (LPVOID lpMem)
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* The MRU-API is a set of functions to manipulate MRU(Most Recently Used)
|
* MRU-Functions {COMCTL32}
|
||||||
* lists.
|
|
||||||
*
|
*
|
||||||
* Stored in the reg. as a set of values under a single key. Each item in the
|
* NOTES
|
||||||
* list has a value name that is a single char. 'a' - 'z', '{', '|' or '}'.
|
* The MRU-Api is a set of functions to manipulate lists of M.R.U. (Most Recently
|
||||||
* The order of the list is stored with value name 'MRUList' which is a string
|
* Used) items. It is an undocumented Api that is used (at least) by the shell
|
||||||
* containing the value names (i.e. 'a', 'b', etc.) in the relevant order.
|
* and explorer to implement their recent documents feature.
|
||||||
|
*
|
||||||
|
* Since these functions are undocumented, they are unsupported by MS and
|
||||||
|
* may change at any time.
|
||||||
|
*
|
||||||
|
* Internally, the list is implemented as a last in, last out list of items
|
||||||
|
* persisted into the system registry under a caller chosen key. Each list
|
||||||
|
* item is given a one character identifier in the Ascii range from 'a' to
|
||||||
|
* '}'. A list of the identifiers in order from newest to oldest is stored
|
||||||
|
* under the same key in a value named "MRUList".
|
||||||
|
*
|
||||||
|
* Items are re-ordered by changing the order of the values in the MRUList
|
||||||
|
* value. When a new item is added, it becomes the new value of the oldest
|
||||||
|
* identifier, and that identifier is moved to the front of the MRUList value.
|
||||||
|
*
|
||||||
|
* Wine stores MRU-lists in the same registry format as Windows, so when
|
||||||
|
* switching between the builtin and native comctl32.dll no problems or
|
||||||
|
* incompatibilities should occur.
|
||||||
|
*
|
||||||
|
* The following undocumented structure is used to create an MRU-list:
|
||||||
|
*|typedef INT (CALLBACK *MRUStringCmpFn)(LPCTSTR lhs, LPCTSTR rhs);
|
||||||
|
*|typedef INT (CALLBACK *MRUBinaryCmpFn)(LPCVOID lhs, LPCVOID rhs, DWORD length);
|
||||||
|
*|
|
||||||
|
*|typedef struct tagCREATEMRULIST
|
||||||
|
*|{
|
||||||
|
*| DWORD cbSize;
|
||||||
|
*| DWORD nMaxItems;
|
||||||
|
*| DWORD dwFlags;
|
||||||
|
*| HKEY hKey;
|
||||||
|
*| LPCTSTR lpszSubKey;
|
||||||
|
*| PROC lpfnCompare;
|
||||||
|
*|} CREATEMRULIST, *LPCREATEMRULIST;
|
||||||
|
*
|
||||||
|
* MEMBERS
|
||||||
|
* cbSize [I] The size of the CREATEMRULIST structure. This must be set
|
||||||
|
* to sizeof(CREATEMRULIST) by the caller.
|
||||||
|
* nMaxItems [I] The maximum number of items allowed in the list. Because
|
||||||
|
* of the limited number of identifiers, this should be set to
|
||||||
|
* a value from 1 to 30 by the caller.
|
||||||
|
* dwFlags [I] If bit 0 is set, the list will be used to store binary
|
||||||
|
* data, otherwise it is assumed to store strings. If bit 1
|
||||||
|
* is set, every change made to the list will be reflected in
|
||||||
|
* the registry immediately, otherwise changes will only be
|
||||||
|
* written when the list is closed.
|
||||||
|
* hKey [I] The registry key that the list should be written under.
|
||||||
|
* This must be supplied by the caller.
|
||||||
|
* lpszSubKey [I] A caller supplied name of a subkey under hKey to write
|
||||||
|
* the list to. This may not be blank.
|
||||||
|
* lpfnCompare [I] A caller supplied comparason function, which may be either
|
||||||
|
* an MRUStringCmpFn if dwFlags does not have bit 0 set, or a
|
||||||
|
* MRUBinaryCmpFn otherwise.
|
||||||
|
*
|
||||||
|
* FUNCTIONS
|
||||||
|
* - Create an MRU-list with CreateMRUList() or CreateMRUListLazy().
|
||||||
|
* - Add items to an MRU-list with AddMRUString() or AddMRUData().
|
||||||
|
* - Remove items from an MRU-list with DelMRUString().
|
||||||
|
* - Find data in an MRU-list with FindMRUString() or FindMRUData().
|
||||||
|
* - Iterate through an MRU-list with EnumMRUList().
|
||||||
|
* - Free an MRU-list with FreeMRUList().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct tagCREATEMRULISTA
|
typedef struct tagCREATEMRULISTA
|
||||||
{
|
{
|
||||||
DWORD cbSize; /* size of struct */
|
DWORD cbSize;
|
||||||
DWORD nMaxItems; /* max no. of items in list */
|
DWORD nMaxItems;
|
||||||
DWORD dwFlags; /* see below */
|
DWORD dwFlags;
|
||||||
HKEY hKey; /* root reg. key under which list is saved */
|
HKEY hKey;
|
||||||
LPCSTR lpszSubKey; /* reg. subkey */
|
LPCSTR lpszSubKey;
|
||||||
PROC lpfnCompare; /* item compare proc */
|
PROC lpfnCompare;
|
||||||
} CREATEMRULISTA, *LPCREATEMRULISTA;
|
} CREATEMRULISTA, *LPCREATEMRULISTA;
|
||||||
|
|
||||||
typedef struct tagCREATEMRULISTW
|
typedef struct tagCREATEMRULISTW
|
||||||
{
|
{
|
||||||
DWORD cbSize; /* size of struct */
|
DWORD cbSize;
|
||||||
DWORD nMaxItems; /* max no. of items in list */
|
DWORD nMaxItems;
|
||||||
DWORD dwFlags; /* see below */
|
DWORD dwFlags;
|
||||||
HKEY hKey; /* root reg. key under which list is saved */
|
HKEY hKey;
|
||||||
LPCWSTR lpszSubKey; /* reg. subkey */
|
LPCWSTR lpszSubKey;
|
||||||
PROC lpfnCompare; /* item compare proc */
|
PROC lpfnCompare;
|
||||||
} CREATEMRULISTW, *LPCREATEMRULISTW;
|
} CREATEMRULISTW, *LPCREATEMRULISTW;
|
||||||
|
|
||||||
/* dwFlags */
|
/* dwFlags */
|
||||||
|
@ -517,9 +569,9 @@ typedef struct tagWINEMRULIST
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* MRU_SaveChanged (internal)
|
* MRU_SaveChanged (internal)
|
||||||
*
|
*
|
||||||
* Localize MRU saving code
|
* Local MRU saving code
|
||||||
*/
|
*/
|
||||||
VOID MRU_SaveChanged( LPWINEMRULIST mp )
|
static void MRU_SaveChanged ( LPWINEMRULIST mp )
|
||||||
{
|
{
|
||||||
UINT i, err;
|
UINT i, err;
|
||||||
HKEY newkey;
|
HKEY newkey;
|
||||||
|
@ -587,16 +639,17 @@ VOID MRU_SaveChanged( LPWINEMRULIST mp )
|
||||||
* hMRUList [I] Handle to list.
|
* hMRUList [I] Handle to list.
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Success: TRUE
|
* Nothing.
|
||||||
* Failure: FALSE
|
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI
|
void WINAPI FreeMRUList (HANDLE hMRUList)
|
||||||
FreeMRUList (HANDLE hMRUList)
|
|
||||||
{
|
{
|
||||||
LPWINEMRULIST mp = (LPWINEMRULIST)hMRUList;
|
LPWINEMRULIST mp = (LPWINEMRULIST)hMRUList;
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("(%p)\n", hMRUList);
|
||||||
|
if (!hMRUList)
|
||||||
|
return;
|
||||||
|
|
||||||
if (mp->wineFlags & WMRUF_CHANGED) {
|
if (mp->wineFlags & WMRUF_CHANGED) {
|
||||||
/* need to open key and then save the info */
|
/* need to open key and then save the info */
|
||||||
MRU_SaveChanged( mp );
|
MRU_SaveChanged( mp );
|
||||||
|
@ -609,7 +662,7 @@ FreeMRUList (HANDLE hMRUList)
|
||||||
Free(mp->realMRU);
|
Free(mp->realMRU);
|
||||||
Free(mp->array);
|
Free(mp->array);
|
||||||
Free((LPWSTR)mp->extview.lpszSubKey);
|
Free((LPWSTR)mp->extview.lpszSubKey);
|
||||||
return Free(mp);
|
Free(mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -629,8 +682,8 @@ FreeMRUList (HANDLE hMRUList)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Position in list 0 -> MRU. -1 if item not found.
|
* Position in list 0 -> MRU. -1 if item not found.
|
||||||
*/
|
*/
|
||||||
INT WINAPI
|
INT WINAPI FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData,
|
||||||
FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
|
LPINT lpRegNum)
|
||||||
{
|
{
|
||||||
LPWINEMRULIST mp = (LPWINEMRULIST)hList;
|
LPWINEMRULIST mp = (LPWINEMRULIST)hList;
|
||||||
INT ret;
|
INT ret;
|
||||||
|
@ -707,14 +760,22 @@ FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
|
||||||
* No. corresponding to registry name where value is stored 'a' -> 0 etc.
|
* No. corresponding to registry name where value is stored 'a' -> 0 etc.
|
||||||
* -1 on error.
|
* -1 on error.
|
||||||
*/
|
*/
|
||||||
INT WINAPI
|
INT WINAPI AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
|
||||||
AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
|
|
||||||
{
|
{
|
||||||
LPWINEMRULIST mp = (LPWINEMRULIST)hList;
|
LPWINEMRULIST mp = (LPWINEMRULIST)hList;
|
||||||
LPWINEMRUITEM witem;
|
LPWINEMRUITEM witem;
|
||||||
INT i, replace, ret;
|
INT i, replace;
|
||||||
|
|
||||||
if ((replace = FindMRUData (hList, lpData, cbData, NULL)) < 0) {
|
if ((replace = FindMRUData (hList, lpData, cbData, NULL)) >= 0) {
|
||||||
|
/* Item exists, just move it to the front */
|
||||||
|
LPSTR pos = strchr(mp->realMRU, replace + 'a');
|
||||||
|
while (pos > mp->realMRU)
|
||||||
|
{
|
||||||
|
pos[0] = pos[-1];
|
||||||
|
pos--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
/* either add a new entry or replace oldest */
|
/* either add a new entry or replace oldest */
|
||||||
if (mp->cursize < mp->extview.nMaxItems) {
|
if (mp->cursize < mp->extview.nMaxItems) {
|
||||||
/* Add in a new item */
|
/* Add in a new item */
|
||||||
|
@ -726,11 +787,6 @@ AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
|
||||||
replace = mp->realMRU[mp->cursize - 1] - 'a';
|
replace = mp->realMRU[mp->cursize - 1] - 'a';
|
||||||
Free(mp->array[replace]);
|
Free(mp->array[replace]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* free up the old data */
|
|
||||||
Free(mp->array[replace]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate space for new item and move in the data */
|
/* Allocate space for new item and move in the data */
|
||||||
mp->array[replace] = witem = Alloc(cbData + sizeof(WINEMRUITEM));
|
mp->array[replace] = witem = Alloc(cbData + sizeof(WINEMRUITEM));
|
||||||
|
@ -739,59 +795,100 @@ AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
|
||||||
memcpy( &witem->datastart, lpData, cbData);
|
memcpy( &witem->datastart, lpData, cbData);
|
||||||
|
|
||||||
/* now rotate MRU list */
|
/* now rotate MRU list */
|
||||||
mp->wineFlags |= WMRUF_CHANGED;
|
for(i=mp->cursize-1; i>=1; i--)
|
||||||
for(i=mp->cursize-1; i>=1; i--) {
|
|
||||||
mp->realMRU[i] = mp->realMRU[i-1];
|
mp->realMRU[i] = mp->realMRU[i-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The new item gets the front spot */
|
||||||
|
mp->wineFlags |= WMRUF_CHANGED;
|
||||||
mp->realMRU[0] = replace + 'a';
|
mp->realMRU[0] = replace + 'a';
|
||||||
|
|
||||||
TRACE("(%p, %p, %ld) adding data, /%c/ now most current\n",
|
TRACE("(%p, %p, %ld) adding data, /%c/ now most current\n",
|
||||||
hList, lpData, cbData, replace+'a');
|
hList, lpData, cbData, replace+'a');
|
||||||
ret = replace;
|
|
||||||
|
|
||||||
if (!(mp->extview.dwFlags & MRUF_DELAYED_SAVE)) {
|
if (!(mp->extview.dwFlags & MRUF_DELAYED_SAVE)) {
|
||||||
/* save changed stuff right now */
|
/* save changed stuff right now */
|
||||||
MRU_SaveChanged( mp );
|
MRU_SaveChanged( mp );
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return replace;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* AddMRUStringW [COMCTL32.401]
|
* AddMRUStringW [COMCTL32.401]
|
||||||
*
|
*
|
||||||
* Add item to MRU string list. If item already exists in list them it is
|
* Add an item to an MRU string list.
|
||||||
* 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
|
* PARAMS
|
||||||
* hList [I] Handle to list.
|
* hList [I] Handle to list.
|
||||||
* lpszString [I] ptr to string to add.
|
* lpszString [I] The string to add.
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* No. corresponding to registry name where value is stored 'a' -> 0 etc.
|
* Success: The number corresponding to the registry name where the string
|
||||||
* -1 on error.
|
* 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
|
INT WINAPI AddMRUStringW(HANDLE hList, LPCWSTR lpszString)
|
||||||
AddMRUStringW(HANDLE hList, LPCWSTR lpszString)
|
|
||||||
{
|
{
|
||||||
FIXME("(%p, %s) empty stub!\n", hList, debugstr_w(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 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return AddMRUData(hList, lpszString,
|
||||||
|
(strlenW(lpszString) + 1) * sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* AddMRUStringA [COMCTL32.153]
|
* AddMRUStringA [COMCTL32.153]
|
||||||
*
|
*
|
||||||
* See AddMRUStringW.
|
* See AddMRUStringW.
|
||||||
*/
|
*/
|
||||||
INT WINAPI
|
INT WINAPI AddMRUStringA(HANDLE hList, LPCSTR lpszString)
|
||||||
AddMRUStringA(HANDLE hList, LPCSTR lpszString)
|
|
||||||
{
|
{
|
||||||
FIXME("(%p, %s) empty stub!\n", hList, debugstr_a(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;
|
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);
|
||||||
|
ret = AddMRUData(hList, stringW, len);
|
||||||
|
Free(stringW);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* DelMRUString [COMCTL32.156]
|
* DelMRUString [COMCTL32.156]
|
||||||
*
|
*
|
||||||
|
@ -804,8 +901,7 @@ AddMRUStringA(HANDLE hList, LPCSTR lpszString)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* TRUE if successful, FALSE if nItemPos is out of range.
|
* TRUE if successful, FALSE if nItemPos is out of range.
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI
|
BOOL WINAPI DelMRUString(HANDLE hList, INT nItemPos)
|
||||||
DelMRUString(HANDLE hList, INT nItemPos)
|
|
||||||
{
|
{
|
||||||
FIXME("(%p, %d): stub\n", hList, nItemPos);
|
FIXME("(%p, %d): stub\n", hList, nItemPos);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -816,11 +912,10 @@ DelMRUString(HANDLE hList, INT nItemPos)
|
||||||
*
|
*
|
||||||
* See FindMRUStringA.
|
* See FindMRUStringA.
|
||||||
*/
|
*/
|
||||||
INT WINAPI
|
INT WINAPI FindMRUStringW (HANDLE hList, LPCWSTR lpszString, LPINT lpRegNum)
|
||||||
FindMRUStringW (HANDLE hList, LPCWSTR lpszString, LPINT lpRegNum)
|
|
||||||
{
|
{
|
||||||
FIXME("stub\n");
|
return FindMRUData(hList, lpszString,
|
||||||
return -1;
|
(lstrlenW(lpszString) + 1) * sizeof(WCHAR), lpRegNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
|
@ -838,8 +933,7 @@ FindMRUStringW (HANDLE hList, LPCWSTR lpszString, LPINT lpRegNum)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Position in list 0 -> MRU. -1 if item not found.
|
* Position in list 0 -> MRU. -1 if item not found.
|
||||||
*/
|
*/
|
||||||
INT WINAPI
|
INT WINAPI FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
|
||||||
FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
|
|
||||||
{
|
{
|
||||||
DWORD len = MultiByteToWideChar(CP_ACP, 0, lpszString, -1, NULL, 0);
|
DWORD len = MultiByteToWideChar(CP_ACP, 0, lpszString, -1, NULL, 0);
|
||||||
LPWSTR stringW = Alloc(len * sizeof(WCHAR));
|
LPWSTR stringW = Alloc(len * sizeof(WCHAR));
|
||||||
|
@ -854,7 +948,7 @@ FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* CreateMRUListLazy_common (internal)
|
* CreateMRUListLazy_common (internal)
|
||||||
*/
|
*/
|
||||||
HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
static HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
||||||
{
|
{
|
||||||
UINT i, err;
|
UINT i, err;
|
||||||
HKEY newkey;
|
HKEY newkey;
|
||||||
|
@ -901,7 +995,7 @@ HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
||||||
*mp->realMRU = 0;
|
*mp->realMRU = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("MRU list = %s\n", mp->realMRU);
|
TRACE("MRU list = %s, datasize = %ld\n", mp->realMRU, datasize);
|
||||||
|
|
||||||
mp->cursize = datasize - 1;
|
mp->cursize = datasize - 1;
|
||||||
/* datasize now has number of items in the MRUList */
|
/* datasize now has number of items in the MRUList */
|
||||||
|
@ -939,16 +1033,16 @@ HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
|
||||||
*
|
*
|
||||||
* See CreateMRUListLazyA.
|
* See CreateMRUListLazyA.
|
||||||
*/
|
*/
|
||||||
HANDLE WINAPI
|
HANDLE WINAPI CreateMRUListLazyW (LPCREATEMRULISTW lpcml, DWORD dwParam2,
|
||||||
CreateMRUListLazyW (LPCREATEMRULISTW lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
|
DWORD dwParam3, DWORD dwParam4)
|
||||||
{
|
{
|
||||||
LPWINEMRULIST mp;
|
LPWINEMRULIST mp;
|
||||||
|
|
||||||
if (lpcml == NULL)
|
/* Native does not check for a NULL lpcml */
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (lpcml->cbSize < sizeof(CREATEMRULISTW))
|
if (lpcml->cbSize != sizeof(CREATEMRULISTW) || !lpcml->hKey ||
|
||||||
return 0;
|
IsBadStringPtrW(lpcml->lpszSubKey, -1))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
mp = Alloc(sizeof(WINEMRULIST));
|
mp = Alloc(sizeof(WINEMRULIST));
|
||||||
memcpy(&mp->extview, lpcml, sizeof(CREATEMRULISTW));
|
memcpy(&mp->extview, lpcml, sizeof(CREATEMRULISTW));
|
||||||
|
@ -973,16 +1067,16 @@ CreateMRUListLazyW (LPCREATEMRULISTW lpcml, DWORD dwParam2, DWORD dwParam3, DWOR
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Handle to MRU list.
|
* Handle to MRU list.
|
||||||
*/
|
*/
|
||||||
HANDLE WINAPI
|
HANDLE WINAPI CreateMRUListLazyA (LPCREATEMRULISTA lpcml, DWORD dwParam2,
|
||||||
CreateMRUListLazyA (LPCREATEMRULISTA lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
|
DWORD dwParam3, DWORD dwParam4)
|
||||||
{
|
{
|
||||||
LPWINEMRULIST mp;
|
LPWINEMRULIST mp;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
|
||||||
if (lpcml == NULL)
|
/* Native does not check for a NULL lpcml */
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (lpcml->cbSize < sizeof(CREATEMRULISTA))
|
if (lpcml->cbSize != sizeof(CREATEMRULISTA) || !lpcml->hKey ||
|
||||||
|
IsBadStringPtrA(lpcml->lpszSubKey, -1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mp = Alloc(sizeof(WINEMRULIST));
|
mp = Alloc(sizeof(WINEMRULIST));
|
||||||
|
@ -1000,8 +1094,7 @@ CreateMRUListLazyA (LPCREATEMRULISTA lpcml, DWORD dwParam2, DWORD dwParam3, DWOR
|
||||||
*
|
*
|
||||||
* See CreateMRUListA.
|
* See CreateMRUListA.
|
||||||
*/
|
*/
|
||||||
HANDLE WINAPI
|
HANDLE WINAPI CreateMRUListW (LPCREATEMRULISTW lpcml)
|
||||||
CreateMRUListW (LPCREATEMRULISTW lpcml)
|
|
||||||
{
|
{
|
||||||
return CreateMRUListLazyW(lpcml, 0, 0, 0);
|
return CreateMRUListLazyW(lpcml, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -1017,8 +1110,7 @@ CreateMRUListW (LPCREATEMRULISTW lpcml)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Handle to MRU list.
|
* Handle to MRU list.
|
||||||
*/
|
*/
|
||||||
HANDLE WINAPI
|
HANDLE WINAPI CreateMRUListA (LPCREATEMRULISTA lpcml)
|
||||||
CreateMRUListA (LPCREATEMRULISTA lpcml)
|
|
||||||
{
|
{
|
||||||
return CreateMRUListLazyA (lpcml, 0, 0, 0);
|
return CreateMRUListLazyA (lpcml, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -1110,9 +1202,7 @@ DWORD nBufferSize)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* The number of characters copied.
|
* The number of characters copied.
|
||||||
*/
|
*/
|
||||||
|
INT WINAPI Str_GetPtrA (LPCSTR lpSrc, LPSTR lpDest, INT nMaxLen)
|
||||||
INT WINAPI
|
|
||||||
Str_GetPtrA (LPCSTR lpSrc, LPSTR lpDest, INT nMaxLen)
|
|
||||||
{
|
{
|
||||||
INT len;
|
INT len;
|
||||||
|
|
||||||
|
@ -1157,9 +1247,7 @@ Str_GetPtrA (LPCSTR lpSrc, LPSTR lpDest, INT nMaxLen)
|
||||||
* Set lpSrc to NULL to free the memory allocated by a previous call
|
* Set lpSrc to NULL to free the memory allocated by a previous call
|
||||||
* to this function.
|
* to this function.
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI Str_SetPtrA (LPSTR *lppDest, LPCSTR lpSrc)
|
||||||
BOOL WINAPI
|
|
||||||
Str_SetPtrA (LPSTR *lppDest, LPCSTR lpSrc)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p %p)\n", lppDest, lpSrc);
|
TRACE("(%p %p)\n", lppDest, lpSrc);
|
||||||
|
|
||||||
|
@ -1186,9 +1274,7 @@ Str_SetPtrA (LPSTR *lppDest, LPCSTR lpSrc)
|
||||||
*
|
*
|
||||||
* See Str_GetPtrA.
|
* See Str_GetPtrA.
|
||||||
*/
|
*/
|
||||||
|
INT WINAPI Str_GetPtrW (LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
|
||||||
INT WINAPI
|
|
||||||
Str_GetPtrW (LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
|
|
||||||
{
|
{
|
||||||
INT len;
|
INT len;
|
||||||
|
|
||||||
|
@ -1221,9 +1307,7 @@ Str_GetPtrW (LPCWSTR lpSrc, LPWSTR lpDest, INT nMaxLen)
|
||||||
*
|
*
|
||||||
* See Str_SetPtrA.
|
* See Str_SetPtrA.
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI Str_SetPtrW (LPWSTR *lppDest, LPCWSTR lpSrc)
|
||||||
BOOL WINAPI
|
|
||||||
Str_SetPtrW (LPWSTR *lppDest, LPCWSTR lpSrc)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p %p)\n", lppDest, lpSrc);
|
TRACE("(%p %p)\n", lppDest, lpSrc);
|
||||||
|
|
||||||
|
@ -1260,8 +1344,7 @@ Str_SetPtrW (LPWSTR *lppDest, LPCWSTR lpSrc)
|
||||||
* Length, in bytes, of the converted string.
|
* Length, in bytes, of the converted string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
INT
|
INT Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen)
|
||||||
Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen)
|
|
||||||
{
|
{
|
||||||
INT len;
|
INT len;
|
||||||
|
|
||||||
|
@ -1306,9 +1389,7 @@ Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen)
|
||||||
* TRUE: conversion successful
|
* TRUE: conversion successful
|
||||||
* FALSE: error
|
* FALSE: error
|
||||||
*/
|
*/
|
||||||
|
BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc)
|
||||||
BOOL
|
|
||||||
Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p %s)\n", lppDest, lpSrc);
|
TRACE("(%p %s)\n", lppDest, lpSrc);
|
||||||
|
|
||||||
|
@ -1350,9 +1431,7 @@ Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc)
|
||||||
* fixed-size memory blocks. These arrays can store any kind of data
|
* fixed-size memory blocks. These arrays can store any kind of data
|
||||||
* (e.g. strings and icons).
|
* (e.g. strings and icons).
|
||||||
*/
|
*/
|
||||||
|
HDSA WINAPI DSA_Create (INT nSize, INT nGrow)
|
||||||
HDSA WINAPI
|
|
||||||
DSA_Create (INT nSize, INT nGrow)
|
|
||||||
{
|
{
|
||||||
HDSA hdsa;
|
HDSA hdsa;
|
||||||
|
|
||||||
|
@ -1384,9 +1463,7 @@ DSA_Create (INT nSize, INT nGrow)
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DSA_Destroy (const HDSA hdsa)
|
||||||
BOOL WINAPI
|
|
||||||
DSA_Destroy (const HDSA hdsa)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", hdsa);
|
TRACE("(%p)\n", hdsa);
|
||||||
|
|
||||||
|
@ -1414,9 +1491,7 @@ DSA_Destroy (const HDSA hdsa)
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DSA_GetItem (const HDSA hdsa, INT nIndex, LPVOID pDest)
|
||||||
BOOL WINAPI
|
|
||||||
DSA_GetItem (const HDSA hdsa, INT nIndex, LPVOID pDest)
|
|
||||||
{
|
{
|
||||||
LPVOID pSrc;
|
LPVOID pSrc;
|
||||||
|
|
||||||
|
@ -1447,9 +1522,7 @@ DSA_GetItem (const HDSA hdsa, INT nIndex, LPVOID pDest)
|
||||||
* Success: pointer to an item
|
* Success: pointer to an item
|
||||||
* Failure: NULL
|
* Failure: NULL
|
||||||
*/
|
*/
|
||||||
|
LPVOID WINAPI DSA_GetItemPtr (const HDSA hdsa, INT nIndex)
|
||||||
LPVOID WINAPI
|
|
||||||
DSA_GetItemPtr (const HDSA hdsa, INT nIndex)
|
|
||||||
{
|
{
|
||||||
LPVOID pSrc;
|
LPVOID pSrc;
|
||||||
|
|
||||||
|
@ -1482,9 +1555,7 @@ DSA_GetItemPtr (const HDSA hdsa, INT nIndex)
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DSA_SetItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
|
||||||
BOOL WINAPI
|
|
||||||
DSA_SetItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
|
|
||||||
{
|
{
|
||||||
INT nSize, nNewItems;
|
INT nSize, nNewItems;
|
||||||
LPVOID pDest, lpTemp;
|
LPVOID pDest, lpTemp;
|
||||||
|
@ -1540,9 +1611,7 @@ DSA_SetItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
|
||||||
* Success: position of the new item
|
* Success: position of the new item
|
||||||
* Failure: -1
|
* Failure: -1
|
||||||
*/
|
*/
|
||||||
|
INT WINAPI DSA_InsertItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
|
||||||
INT WINAPI
|
|
||||||
DSA_InsertItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
|
|
||||||
{
|
{
|
||||||
INT nNewItems, nSize;
|
INT nNewItems, nSize;
|
||||||
LPVOID lpTemp, lpDest;
|
LPVOID lpTemp, lpDest;
|
||||||
|
@ -1603,9 +1672,7 @@ DSA_InsertItem (const HDSA hdsa, INT nIndex, LPVOID pSrc)
|
||||||
* Success: number of the deleted element
|
* Success: number of the deleted element
|
||||||
* Failure: -1
|
* Failure: -1
|
||||||
*/
|
*/
|
||||||
|
INT WINAPI DSA_DeleteItem (const HDSA hdsa, INT nIndex)
|
||||||
INT WINAPI
|
|
||||||
DSA_DeleteItem (const HDSA hdsa, INT nIndex)
|
|
||||||
{
|
{
|
||||||
LPVOID lpDest,lpSrc;
|
LPVOID lpDest,lpSrc;
|
||||||
INT nSize;
|
INT nSize;
|
||||||
|
@ -1657,9 +1724,7 @@ DSA_DeleteItem (const HDSA hdsa, INT nIndex)
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DSA_DeleteAllItems (const HDSA hdsa)
|
||||||
BOOL WINAPI
|
|
||||||
DSA_DeleteAllItems (const HDSA hdsa)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", hdsa);
|
TRACE("(%p)\n", hdsa);
|
||||||
|
|
||||||
|
@ -1688,9 +1753,7 @@ DSA_DeleteAllItems (const HDSA hdsa)
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DPA_Destroy (const HDPA hdpa)
|
||||||
BOOL WINAPI
|
|
||||||
DPA_Destroy (const HDPA hdpa)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", hdpa);
|
TRACE("(%p)\n", hdpa);
|
||||||
|
|
||||||
|
@ -1717,9 +1780,7 @@ DPA_Destroy (const HDPA hdpa)
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DPA_Grow (const HDPA hdpa, INT nGrow)
|
||||||
BOOL WINAPI
|
|
||||||
DPA_Grow (const HDPA hdpa, INT nGrow)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p %d)\n", hdpa, nGrow);
|
TRACE("(%p %d)\n", hdpa, nGrow);
|
||||||
|
|
||||||
|
@ -1751,9 +1812,7 @@ DPA_Grow (const HDPA hdpa, INT nGrow)
|
||||||
* - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
|
* - If 'hdpa' is a NULL-Pointer, the original implementation crashes,
|
||||||
* this implementation just returns NULL.
|
* this implementation just returns NULL.
|
||||||
*/
|
*/
|
||||||
|
HDPA WINAPI DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
|
||||||
HDPA WINAPI
|
|
||||||
DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
|
|
||||||
{
|
{
|
||||||
INT nNewItems, nSize;
|
INT nNewItems, nSize;
|
||||||
HDPA hdpaTemp;
|
HDPA hdpaTemp;
|
||||||
|
@ -1811,9 +1870,7 @@ DPA_Clone (const HDPA hdpa, const HDPA hdpaNew)
|
||||||
* Success: pointer
|
* Success: pointer
|
||||||
* Failure: NULL
|
* Failure: NULL
|
||||||
*/
|
*/
|
||||||
|
LPVOID WINAPI DPA_GetPtr (const HDPA hdpa, INT nIndex)
|
||||||
LPVOID WINAPI
|
|
||||||
DPA_GetPtr (const HDPA hdpa, INT nIndex)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p %d)\n", hdpa, nIndex);
|
TRACE("(%p %d)\n", hdpa, nIndex);
|
||||||
|
|
||||||
|
@ -1847,9 +1904,7 @@ DPA_GetPtr (const HDPA hdpa, INT nIndex)
|
||||||
* Success: index of the specified pointer
|
* Success: index of the specified pointer
|
||||||
* Failure: -1
|
* Failure: -1
|
||||||
*/
|
*/
|
||||||
|
INT WINAPI DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
|
||||||
INT WINAPI
|
|
||||||
DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
|
|
||||||
{
|
{
|
||||||
INT i;
|
INT i;
|
||||||
|
|
||||||
|
@ -1879,9 +1934,7 @@ DPA_GetPtrIndex (const HDPA hdpa, LPVOID p)
|
||||||
* Success: index of the inserted pointer
|
* Success: index of the inserted pointer
|
||||||
* Failure: -1
|
* Failure: -1
|
||||||
*/
|
*/
|
||||||
|
INT WINAPI DPA_InsertPtr (const HDPA hdpa, INT i, LPVOID p)
|
||||||
INT WINAPI
|
|
||||||
DPA_InsertPtr (const HDPA hdpa, INT i, LPVOID p)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p %d %p)\n", hdpa, i, p);
|
TRACE("(%p %d %p)\n", hdpa, i, p);
|
||||||
|
|
||||||
|
@ -1914,9 +1967,7 @@ DPA_InsertPtr (const HDPA hdpa, INT i, LPVOID p)
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DPA_SetPtr (const HDPA hdpa, INT i, LPVOID p)
|
||||||
BOOL WINAPI
|
|
||||||
DPA_SetPtr (const HDPA hdpa, INT i, LPVOID p)
|
|
||||||
{
|
{
|
||||||
LPVOID *lpTemp;
|
LPVOID *lpTemp;
|
||||||
|
|
||||||
|
@ -1967,9 +2018,7 @@ DPA_SetPtr (const HDPA hdpa, INT i, LPVOID p)
|
||||||
* Success: deleted pointer
|
* Success: deleted pointer
|
||||||
* Failure: NULL
|
* Failure: NULL
|
||||||
*/
|
*/
|
||||||
|
LPVOID WINAPI DPA_DeletePtr (const HDPA hdpa, INT i)
|
||||||
LPVOID WINAPI
|
|
||||||
DPA_DeletePtr (const HDPA hdpa, INT i)
|
|
||||||
{
|
{
|
||||||
LPVOID *lpDest, *lpSrc, lpTemp = NULL;
|
LPVOID *lpDest, *lpSrc, lpTemp = NULL;
|
||||||
INT nSize;
|
INT nSize;
|
||||||
|
@ -2022,9 +2071,7 @@ DPA_DeletePtr (const HDPA hdpa, INT i)
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DPA_DeleteAllPtrs (const HDPA hdpa)
|
||||||
BOOL WINAPI
|
|
||||||
DPA_DeleteAllPtrs (const HDPA hdpa)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", hdpa);
|
TRACE("(%p)\n", hdpa);
|
||||||
|
|
||||||
|
@ -2058,9 +2105,7 @@ DPA_DeleteAllPtrs (const HDPA hdpa)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* NONE
|
* NONE
|
||||||
*/
|
*/
|
||||||
|
static VOID DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r,
|
||||||
static VOID
|
|
||||||
DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r,
|
|
||||||
PFNDPACOMPARE pfnCompare, LPARAM lParam)
|
PFNDPACOMPARE pfnCompare, LPARAM lParam)
|
||||||
{
|
{
|
||||||
INT m;
|
INT m;
|
||||||
|
@ -2109,9 +2154,7 @@ DPA_QuickSort (LPVOID *lpPtrs, INT l, INT r,
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
|
BOOL WINAPI DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
|
||||||
BOOL WINAPI
|
|
||||||
DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
|
|
||||||
{
|
{
|
||||||
if (!hdpa || !pfnCompare)
|
if (!hdpa || !pfnCompare)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -2148,9 +2191,7 @@ DPA_Sort (const HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
|
||||||
* Function is NOT tested!
|
* Function is NOT tested!
|
||||||
* If something goes wrong, blame HIM not ME! (Eric Kohl)
|
* If something goes wrong, blame HIM not ME! (Eric Kohl)
|
||||||
*/
|
*/
|
||||||
|
INT WINAPI DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart,
|
||||||
INT WINAPI
|
|
||||||
DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart,
|
|
||||||
PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
|
PFNDPACOMPARE pfnCompare, LPARAM lParam, UINT uOptions)
|
||||||
{
|
{
|
||||||
if (!hdpa || !pfnCompare || !pFind)
|
if (!hdpa || !pfnCompare || !pFind)
|
||||||
|
@ -2232,9 +2273,7 @@ DPA_Search (const HDPA hdpa, LPVOID pFind, INT nStart,
|
||||||
* The DPA_ functions can be used to create and manipulate arrays of
|
* The DPA_ functions can be used to create and manipulate arrays of
|
||||||
* pointers.
|
* pointers.
|
||||||
*/
|
*/
|
||||||
|
HDPA WINAPI DPA_CreateEx (INT nGrow, HANDLE hHeap)
|
||||||
HDPA WINAPI
|
|
||||||
DPA_CreateEx (INT nGrow, HANDLE hHeap)
|
|
||||||
{
|
{
|
||||||
HDPA hdpa;
|
HDPA hdpa;
|
||||||
|
|
||||||
|
@ -2275,9 +2314,7 @@ DPA_CreateEx (INT nGrow, HANDLE hHeap)
|
||||||
* The DPA_ functions can be used to create and manipulate arrays of
|
* The DPA_ functions can be used to create and manipulate arrays of
|
||||||
* pointers.
|
* pointers.
|
||||||
*/
|
*/
|
||||||
|
HDPA WINAPI DPA_Create (INT nGrow)
|
||||||
HDPA WINAPI
|
|
||||||
DPA_Create (INT nGrow)
|
|
||||||
{
|
{
|
||||||
return DPA_CreateEx( nGrow, 0 );
|
return DPA_CreateEx( nGrow, 0 );
|
||||||
}
|
}
|
||||||
|
@ -2302,8 +2339,7 @@ typedef struct tagNOTIFYDATA
|
||||||
* DoNotify [Internal]
|
* DoNotify [Internal]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static LRESULT
|
static LRESULT DoNotify (LPNOTIFYDATA lpNotify, UINT uCode, LPNMHDR lpHdr)
|
||||||
DoNotify (LPNOTIFYDATA lpNotify, UINT uCode, LPNMHDR lpHdr)
|
|
||||||
{
|
{
|
||||||
NMHDR nmhdr;
|
NMHDR nmhdr;
|
||||||
LPNMHDR lpNmh = NULL;
|
LPNMHDR lpNmh = NULL;
|
||||||
|
@ -2355,7 +2391,6 @@ DoNotify (LPNOTIFYDATA lpNotify, UINT uCode, LPNMHDR lpHdr)
|
||||||
* message is taken from the NMHDR structure.
|
* message is taken from the NMHDR structure.
|
||||||
* If hwndFrom is not -1 then lpHdr can be NULL.
|
* If hwndFrom is not -1 then lpHdr can be NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LRESULT WINAPI SendNotify (HWND hwndTo, HWND hwndFrom, UINT uCode, LPNMHDR lpHdr)
|
LRESULT WINAPI SendNotify (HWND hwndTo, HWND hwndFrom, UINT uCode, LPNMHDR lpHdr)
|
||||||
{
|
{
|
||||||
NOTIFYDATA notify;
|
NOTIFYDATA notify;
|
||||||
|
@ -2393,7 +2428,6 @@ LRESULT WINAPI SendNotify (HWND hwndTo, HWND hwndFrom, UINT uCode, LPNMHDR lpHdr
|
||||||
* message is taken from the NMHDR structure.
|
* message is taken from the NMHDR structure.
|
||||||
* If hwndFrom is not -1 then lpHdr can be NULL.
|
* If hwndFrom is not -1 then lpHdr can be NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LRESULT WINAPI SendNotifyEx (HWND hwndTo, HWND hwndFrom, UINT uCode,
|
LRESULT WINAPI SendNotifyEx (HWND hwndTo, HWND hwndFrom, UINT uCode,
|
||||||
LPNMHDR lpHdr, DWORD dwParam5)
|
LPNMHDR lpHdr, DWORD dwParam5)
|
||||||
{
|
{
|
||||||
|
@ -2436,9 +2470,8 @@ LRESULT WINAPI SendNotifyEx (HWND hwndTo, HWND hwndFrom, UINT uCode,
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* none
|
* none
|
||||||
*/
|
*/
|
||||||
|
VOID WINAPI DPA_EnumCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc,
|
||||||
VOID WINAPI
|
LPVOID lParam)
|
||||||
DPA_EnumCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc, LPVOID lParam)
|
|
||||||
{
|
{
|
||||||
INT i;
|
INT i;
|
||||||
|
|
||||||
|
@ -2471,9 +2504,8 @@ DPA_EnumCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc, LPVOID lParam)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* none
|
* none
|
||||||
*/
|
*/
|
||||||
|
void WINAPI DPA_DestroyCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc,
|
||||||
void WINAPI
|
LPVOID lParam)
|
||||||
DPA_DestroyCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc, LPVOID lParam)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p %p %p)\n", hdpa, enumProc, lParam);
|
TRACE("(%p %p %p)\n", hdpa, enumProc, lParam);
|
||||||
|
|
||||||
|
@ -2495,9 +2527,8 @@ DPA_DestroyCallback (HDPA hdpa, PFNDPAENUMCALLBACK enumProc, LPVOID lParam)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* none
|
* none
|
||||||
*/
|
*/
|
||||||
|
VOID WINAPI DSA_EnumCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
|
||||||
VOID WINAPI
|
LPVOID lParam)
|
||||||
DSA_EnumCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc, LPVOID lParam)
|
|
||||||
{
|
{
|
||||||
INT i;
|
INT i;
|
||||||
|
|
||||||
|
@ -2531,9 +2562,8 @@ DSA_EnumCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc, LPVOID lParam)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* none
|
* none
|
||||||
*/
|
*/
|
||||||
|
void WINAPI DSA_DestroyCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc,
|
||||||
void WINAPI
|
LPVOID lParam)
|
||||||
DSA_DestroyCallback (HDSA hdsa, PFNDSAENUMCALLBACK enumProc, LPVOID lParam)
|
|
||||||
{
|
{
|
||||||
TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);
|
TRACE("(%p %p %p)\n", hdsa, enumProc, lParam);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
Makefile
|
Makefile
|
||||||
dpa.ok
|
dpa.ok
|
||||||
imagelist.ok
|
imagelist.ok
|
||||||
|
mru.ok
|
||||||
subclass.ok
|
subclass.ok
|
||||||
tab.ok
|
tab.ok
|
||||||
testlist.c
|
testlist.c
|
||||||
|
|
|
@ -3,11 +3,12 @@ TOPOBJDIR = ../../..
|
||||||
SRCDIR = @srcdir@
|
SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
TESTDLL = comctl32.dll
|
TESTDLL = comctl32.dll
|
||||||
IMPORTS = comctl32 user32 gdi32
|
IMPORTS = comctl32 shlwapi user32 gdi32 advapi32
|
||||||
|
|
||||||
CTESTS = \
|
CTESTS = \
|
||||||
dpa.c \
|
dpa.c \
|
||||||
imagelist.c \
|
imagelist.c \
|
||||||
|
mru.c \
|
||||||
subclass.c \
|
subclass.c \
|
||||||
tab.c
|
tab.c
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,295 @@
|
||||||
|
/*
|
||||||
|
* comctl32 MRU unit tests
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Jon Griffiths <jon_p_griffiths@yahoo.com>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "wingdi.h"
|
||||||
|
#include "winuser.h"
|
||||||
|
#include "winnls.h"
|
||||||
|
#include "winreg.h"
|
||||||
|
#include "commctrl.h"
|
||||||
|
#include "shlwapi.h"
|
||||||
|
|
||||||
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
/* Keys for testing MRU functions */
|
||||||
|
#define REG_TEST_BASEKEYA "Software\\Wine"
|
||||||
|
#define REG_TEST_BASESUBKEYA "Test"
|
||||||
|
#define REG_TEST_KEYA REG_TEST_BASEKEYA "\\" REG_TEST_BASESUBKEYA
|
||||||
|
#define REG_TEST_SUBKEYA "MRUTest"
|
||||||
|
#define REG_TEST_FULLKEY REG_TEST_KEYA "\\" REG_TEST_SUBKEYA
|
||||||
|
|
||||||
|
/* Undocumented MRU structures & functions */
|
||||||
|
typedef struct tagCREATEMRULISTA
|
||||||
|
{
|
||||||
|
DWORD cbSize;
|
||||||
|
DWORD nMaxItems;
|
||||||
|
DWORD dwFlags;
|
||||||
|
HKEY hKey;
|
||||||
|
LPCSTR lpszSubKey;
|
||||||
|
PROC lpfnCompare;
|
||||||
|
} CREATEMRULISTA, *LPCREATEMRULISTA;
|
||||||
|
|
||||||
|
#define MRUF_STRING_LIST 0
|
||||||
|
#define MRUF_BINARY_LIST 1
|
||||||
|
#define MRUF_DELAYED_SAVE 2
|
||||||
|
|
||||||
|
#define LIST_SIZE 3 /* Max entries for each mru */
|
||||||
|
|
||||||
|
static CREATEMRULISTA mruA =
|
||||||
|
{
|
||||||
|
sizeof(CREATEMRULISTA),
|
||||||
|
LIST_SIZE,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_TEST_SUBKEYA,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static HMODULE hComctl32;
|
||||||
|
static HANDLE (WINAPI *pCreateMRUListA)(LPCREATEMRULISTA);
|
||||||
|
static void (WINAPI *pFreeMRUList)(HANDLE);
|
||||||
|
static INT (WINAPI *pAddMRUStringA)(HANDLE,LPCSTR);
|
||||||
|
/*
|
||||||
|
static INT (WINAPI *pFindMRUStringA)(HANDLE,LPCSTR,LPINT);
|
||||||
|
static INT (WINAPI *pEnumMRUList)(HANDLE,INT,LPVOID,DWORD);
|
||||||
|
*/
|
||||||
|
|
||||||
|
static BOOL create_reg_entries(void)
|
||||||
|
{
|
||||||
|
HKEY hKey = NULL;
|
||||||
|
|
||||||
|
ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
|
||||||
|
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
|
||||||
|
if (!hKey) return FALSE;
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delete_reg_entries(void)
|
||||||
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
if (RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_BASEKEYA, 0, KEY_ALL_ACCESS,
|
||||||
|
&hKey))
|
||||||
|
return;
|
||||||
|
SHDeleteKeyA(hKey, REG_TEST_BASESUBKEYA);
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_reg_entries(const char *mrulist, const char**items)
|
||||||
|
{
|
||||||
|
char buff[128];
|
||||||
|
HKEY hKey = NULL;
|
||||||
|
DWORD type, size, ret;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
ok(!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_FULLKEY, &hKey),
|
||||||
|
"Couldn't open test key \"%s\"\n", REG_TEST_FULLKEY);
|
||||||
|
if (!hKey) return;
|
||||||
|
|
||||||
|
type = REG_SZ;
|
||||||
|
size = sizeof(buff);
|
||||||
|
buff[0] = '\0';
|
||||||
|
ret = RegQueryValueExA(hKey, "MRUList", NULL, &type, (LPBYTE)buff, &size);
|
||||||
|
|
||||||
|
ok(!ret && buff[0], "Checking MRU: got %ld from RegQueryValueExW\n", ret);
|
||||||
|
if(ret || !buff[0]) return;
|
||||||
|
|
||||||
|
ok(strcmp(buff, mrulist) == 0, "Checking MRU: Expected list %s, got %s\n",
|
||||||
|
mrulist, buff);
|
||||||
|
if(strcmp(buff, mrulist)) return;
|
||||||
|
|
||||||
|
for (i = 0; i < strlen(mrulist); i++)
|
||||||
|
{
|
||||||
|
char name[2];
|
||||||
|
name[0] = mrulist[i];
|
||||||
|
name[1] = '\0';
|
||||||
|
type = REG_SZ;
|
||||||
|
size = sizeof(buff);
|
||||||
|
buff[0] = '\0';
|
||||||
|
ret = RegQueryValueExA(hKey, name, NULL, &type, (LPBYTE)buff, &size);
|
||||||
|
ok(!ret && buff[0],
|
||||||
|
"Checking MRU item %d ('%c'): got %ld from RegQueryValueExW\n",
|
||||||
|
i, mrulist[i], ret);
|
||||||
|
if(ret || !buff[0]) return;
|
||||||
|
ok(!strcmp(buff, items[mrulist[i]-'a']),
|
||||||
|
"Checking MRU item %d ('%c'): expected \"%s\", got \"%s\"\n",
|
||||||
|
i, mrulist[i], buff, items[mrulist[i] - 'a']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static INT CALLBACK cmp_mru_strA(LPCVOID data1, LPCVOID data2)
|
||||||
|
{
|
||||||
|
return lstrcmpiA(data1, data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE create_mruA(HKEY hKey, DWORD flags, PROC cmp)
|
||||||
|
{
|
||||||
|
mruA.dwFlags = flags;
|
||||||
|
mruA.lpfnCompare = cmp;
|
||||||
|
mruA.hKey = hKey;
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
return pCreateMRUListA(&mruA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_MRUListA(void)
|
||||||
|
{
|
||||||
|
const char *checks[LIST_SIZE+1];
|
||||||
|
HANDLE hMRU;
|
||||||
|
HKEY hKey;
|
||||||
|
INT iRet;
|
||||||
|
|
||||||
|
pCreateMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)151);
|
||||||
|
pFreeMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)152);
|
||||||
|
pAddMRUStringA = (void*)GetProcAddress(hComctl32,(LPCSTR)153);
|
||||||
|
if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if 0 /* Create (NULL) - crashes native */
|
||||||
|
hMRU = pCreateMRUListA(NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Create (size too small) */
|
||||||
|
mruA.cbSize = sizeof(mruA) - 2;
|
||||||
|
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok (!hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(too small) expected NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
mruA.cbSize = sizeof(mruA);
|
||||||
|
|
||||||
|
/* Create (size too big) */
|
||||||
|
mruA.cbSize = sizeof(mruA) + 2;
|
||||||
|
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok (!hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(too big) expected NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
mruA.cbSize = sizeof(mruA);
|
||||||
|
|
||||||
|
/* Create (NULL hKey) */
|
||||||
|
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok (!hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(NULL key) expected NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
|
||||||
|
/* Create (NULL name) */
|
||||||
|
mruA.lpszSubKey = NULL;
|
||||||
|
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok (!hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(NULL name) expected NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
mruA.lpszSubKey = REG_TEST_SUBKEYA;
|
||||||
|
|
||||||
|
/* Create a string MRU */
|
||||||
|
ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey),
|
||||||
|
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
|
||||||
|
if (!hKey)
|
||||||
|
return;
|
||||||
|
hMRU = create_mruA(hKey, MRUF_STRING_LIST, cmp_mru_strA);
|
||||||
|
ok(hMRU && !GetLastError(),
|
||||||
|
"CreateMRUListA(string) expected non-NULL,0 got %p,%ld\n",
|
||||||
|
hMRU, GetLastError());
|
||||||
|
|
||||||
|
if (hMRU)
|
||||||
|
{
|
||||||
|
checks[0] = "Test 1";
|
||||||
|
checks[1] = "Test 2";
|
||||||
|
checks[2] = "Test 3";
|
||||||
|
checks[3] = "Test 4";
|
||||||
|
|
||||||
|
/* Add (NULL list) */
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(NULL, checks[0]);
|
||||||
|
ok(iRet == -1 && !GetLastError(),
|
||||||
|
"AddMRUStringA(NULL list) expected -1,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
|
||||||
|
/* Add (NULL string) */
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, NULL);
|
||||||
|
ok(iRet == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
|
||||||
|
/* Add 3 strings. Check the registry is correct after each add */
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[0]);
|
||||||
|
ok(iRet == 0 && !GetLastError(),
|
||||||
|
"AddMRUStringA(1) expected 0,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
check_reg_entries("a", checks);
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[1]);
|
||||||
|
ok(iRet == 1 && !GetLastError(),
|
||||||
|
"AddMRUStringA(2) expected 1,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
check_reg_entries("ba", checks);
|
||||||
|
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[2]);
|
||||||
|
ok(iRet == 2 && !GetLastError(),
|
||||||
|
"AddMRUStringA(2) expected 2,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
check_reg_entries("cba", checks);
|
||||||
|
|
||||||
|
/* Add a duplicate of the 2nd string - it should move to the front,
|
||||||
|
* but keep the same index in the registry.
|
||||||
|
*/
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[1]);
|
||||||
|
ok(iRet == 1 && !GetLastError(),
|
||||||
|
"AddMRUStringA(re-add 1) expected 1,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
check_reg_entries("bca", checks);
|
||||||
|
|
||||||
|
/* Add a new string - replaces the oldest string + moves to the front */
|
||||||
|
SetLastError(0);
|
||||||
|
iRet = pAddMRUStringA(hMRU, checks[3]);
|
||||||
|
ok(iRet == 0 && !GetLastError(),
|
||||||
|
"AddMRUStringA(add new) expected 0,0 got %d,%ld\n",
|
||||||
|
iRet, GetLastError());
|
||||||
|
checks[0] = checks[3];
|
||||||
|
check_reg_entries("abc", checks);
|
||||||
|
|
||||||
|
/* Finished with this MRU */
|
||||||
|
pFreeMRUList(hMRU);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free (NULL list) - Doesn't crash */
|
||||||
|
pFreeMRUList(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(mru)
|
||||||
|
{
|
||||||
|
hComctl32 = GetModuleHandleA("comctl32.dll");
|
||||||
|
if (!hComctl32)
|
||||||
|
return;
|
||||||
|
|
||||||
|
delete_reg_entries();
|
||||||
|
if (!create_reg_entries())
|
||||||
|
return;
|
||||||
|
|
||||||
|
test_MRUListA();
|
||||||
|
|
||||||
|
delete_reg_entries();
|
||||||
|
}
|
Loading…
Reference in New Issue