MRU Lists Function:
The functions are all exported from COMCTL32.DLL and, as you've no doubt come to expect, they're all exported by ordinal.
The Registry Format
Windows 95 MRU lists are stored in the registry as a set of values gathered together under a single key. Each item in the list is represented by a separate registry value. The value names are all single characters, using the letters 'a' to 'z', and '{', '|' and '}' (the following three characters in the ascii table). Obviously that means there can't be more than 29 items in a list.
There is also a value named 'MRUList' which represents the order of the items in the list. It is just a string
containing the various item names in the correct order(remember the names are all single characters).
Creating a List
typedef struct {
DWORD cbSize;
DWORD nMaxItems;
DWORD dwFlags;
HKEY hKey;
LPCSTR lpszSubKey;
PROC lpfnCompare;
} CREATEMRULIST;
MRUF_STRING_LIST 0 //list items are stored in the registry as string values
MRUF_BINARY_LIST 1 //items are stored as binary data
MRUF_DELAYED_SAVE 2 //the order data is only saved when the list handle is finally freed
HANDLE WINAPI CreateMRUList(LPCCREATEMRULIST lpCreateInfo);index 151
void WINAPI FreeMRUList(HANDLE hList); index 152
int CALLBACK MRUCompareString(LPCSTR lpszString1, LPCSTR lpszString2); // MRUF_STRING_LIST
int CALLBACK MRUCompareData(LPCVOID lpData1,LPCVOID lpData2, DWORD cbData); // MRUF_BINARY_LIST
For string lists, the comparison function should accept two LPCSTR parameters (the two strings to be compared). For binary lists, the comparison function should accept three parameters - two LPCVOID parameters (the data for
the two items) and a DWORD specifying the number of bytes to compare.
Adding Items
You can add an item to the list using the AddMRUString
function or the AddMRUData function (the function decla-
rations are shown in Figure 5). AddMRUString passes the
new item in as a string. AddMRUData passes the item in
as a chunk of binary data - you specify a
pointer to a buffer and the number of bytes
in the buffer.
If the item being added already exists, it
isn't added again - its position is just moved
to the front of the list order. If the list is full,
the least recently used item in the list is rep-
laced with the new item. The return value is
a number corresponding to the registry
name where the item is stored. 0 corres-
ponds with the 'a' value, 1 corresponds with 'b', etc. If there was an error adding the item, the function
returns -1.
The ordinal values for AddMRUString and Add-
MRUData are 153 and 167 respectively.
int WINAPI AddMRUString(
HANDLE hList,
LPCSTR lpszString);
int WINAPI AddMRUData(
HANDLE hList,
LPCVOID lpData,
DWORD cbData);
Figure 5 Add Functions
Removing Items
To remove an item from an MRU list, you can use the Del-
MRUString function (see Figure 6), passing it the position in
the list of the item you wish to remove (0 specifies the most
recently used item - this is not the same as the return value
from the AddMRUxxx functions). DelMRUString can also
be used for removing items from binary lists - there isn't a
corresponding DelMRUData function, al-
though you could easily #define an alias
for the sake of consistency.
Unfortunately, that isn't the end of the
story. Due to a bug in the DelMRUString
implementation, if you attempt to add a new item to the list after removing an item, you may end up
corrupting memory or causing your application to crash. To
work around this, you should always close the list and
reopen it again before you attempt any other operations on
the list.
DelMRUString returns TRUE if the item was removed
successfully. If the specified position is out of range, the
return value is FALSE. The ordinal value is 156.
BOOL WINAPI DelMRUString(
HANDLE hList,
int nItemPos);
Figure 6 Delete Function
Searching the List
If you need to search for a particular item
in the list, you should use the functions
FindMRUString and FindMRUData (the
function declarations can be seen in Figure
8). Much like the AddMRUxxx functions,
FindMRUString specifies the item as a
string and FindMRUData passes it in as
binary data in a buffer.
The return value is the position in the
list order, 0 being the most recently used
item. You can also determine the registry
int WINAPI FindMRUString(
HANDLE hList,
LPCSTR lpszString,
LPINT lpRegNum);
int WINAPI FindMRUData(
HANDLE hList,
LPCVOID lpData,
DWORD cbData,
LPINT lpRegNum);
Figure 8 Find Functions
value where the item is stored by specifying a non-null
value for the lpdwRegNum pointer. It will be filled in with a
number corresponding to the item's registry name (this is
the same as the value returned by the AddMRUxxx
functions).
If the item could not be found, or there was some other
error, the functions will return -1. The ordinal values for
FindMRUString and FindMRUData are 155 and 169 res-
pectively.
Windows NT and Unicode Strings
Unlike most undocumented functions, you don't have to
worry about using unicode strings on Windows NT and ansi
strings on Windows 95. The string-related MRU functions
all accept ansi strings, regardless of the operating system
(although, internally, the string data is stored in unicode on
Windows NT).
What's even nicer, though, is that there are also uni-
code equivalents of all the string-related functions if you
need them (although they're only available on NT). If you
do use them, though, don't forget that your string compari-
son function will also have to accept unicode strings. The
effected functions are CreateMRUList, AddMRUString,
FindMRUString and EnumMRUList (ordinals 400 to 403).
Unfortunately, if you're using a binary list on NT, you
have to use the wide-string version of EnumMRUList (the
ansi version has a bug in it which prevents it from returning
the item data). Of course, if you need your application to
run on Windows 95 as well, you'll have to link to the
function at run-time with GetProcAddress (it gets rather
messy). I guess that's one of the reasons why they don't
documented this stuff.