2 ===========================================================================
3 Copyright (C) 1997-2006 Id Software, Inc.
5 This file is part of Quake 2 Tools source code.
7 Quake 2 Tools source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
12 Quake 2 Tools source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Quake 2 Tools source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 ===========================================================================
23 //*************************************************************
28 // Routines for MRU support
32 // Gilles Vollant (100144.2636@compuserve.com)
34 //*************************************************************
41 // CreateMruMenu : MRUMENU constructor
42 // wNbLruShowInit : nb of item showed in menu
43 // wNbLruMenuInit : nb of item stored in memory
44 // wMaxSizeLruItemInit : size max. of filename
47 //*************************************************************
53 // Allocate and Initialize an MRU and return a pointer on it
58 // WORD wNbLruShowInit - Maximum number of item displayed on menu
59 // WORD wNbLruMenuInit - Maximum number of item stored in memory
60 // WORD wMaxSizeLruItemInit - Maximum size of an item (ie size of pathname)
61 // WORD wIdMruInit - ID of the first item in the menu (default:IDMRU)
64 // Return: (LPMRUMENU)
66 // Pointer on a MRUMENU structure, used by other function
70 // wNbLruShowInit <= wNbLruMenuInit
73 // History: Date Author Comment
74 // 09/24/94 G. Vollant Created
76 //*************************************************************
78 LPMRUMENU CreateMruMenu (WORD wNbLruShowInit,
79 WORD wNbLruMenuInit,WORD wMaxSizeLruItemInit,WORD wIdMruInit)
82 lpMruMenu = (LPMRUMENU)GlobalAllocPtr(GHND,sizeof(MRUMENU));
84 lpMruMenu->wNbItemFill = 0;
85 lpMruMenu->wNbLruMenu = wNbLruMenuInit;
86 lpMruMenu->wNbLruShow = wNbLruShowInit;
87 lpMruMenu->wIdMru = wIdMruInit;
88 lpMruMenu->wMaxSizeLruItem = wMaxSizeLruItemInit;
89 lpMruMenu->lpMRU = (LPSTR)GlobalAllocPtr(GHND,
90 lpMruMenu->wNbLruMenu*(UINT)lpMruMenu->wMaxSizeLruItem);
91 if (lpMruMenu->lpMRU == NULL)
93 GlobalFreePtr(lpMruMenu);
99 //*************************************************************
101 // CreateMruMenuDefault()
105 // Allocate and Initialize an MRU and return a pointer on it
106 // Use default parameter
112 // Return: (LPMRUMENU)
114 // Pointer on a MRUMENU structure, used by other function
120 // History: Date Author Comment
121 // 09/24/94 G. Vollant Created
123 //*************************************************************
125 LPMRUMENU CreateMruMenuDefault()
127 return CreateMruMenu (NBMRUMENUSHOW,NBMRUMENU,MAXSIZEMRUITEM,IDMRU);
131 //*************************************************************
137 // Clean and free a MRUMENU structure
141 // LPMRUMENU lpMruMenu - pointer on MRUMENU, allocated
142 // by CreateMruMenu() or CreateMruMenuDefault()
151 // History: Date Author Comment
152 // 09/24/94 G. Vollant Created
154 //*************************************************************
155 void DeleteMruMenu(LPMRUMENU lpMruMenu)
157 GlobalFreePtr(lpMruMenu->lpMRU);
158 GlobalFreePtr(lpMruMenu);
161 //*************************************************************
166 // Change the maximum number of item displayed on menu
169 // LPMRUMENU lpMruMenu - pointer on MRUMENU
170 // WORD wNbLruShowInit - Maximum number of item displayed on menu
179 // History: Date Author Comment
180 // 09/24/94 G. Vollant Created
182 //*************************************************************
183 void SetNbLruShow (LPMRUMENU lpMruMenu,WORD wNbLruShowInit)
185 lpMruMenu->wNbLruShow = min(wNbLruShowInit,lpMruMenu->wNbLruMenu);
188 //*************************************************************
193 // Set the filename of an item
196 // LPMRUMENU lpMruMenu - pointer on MRUMENU
197 // WORD wItem - Number of Item to set, zero based
198 // LPSTR lpItem - String, contain the filename of the item
202 // TRUE - Function run successfully
203 // FALSE - Function don't run successfully
207 // used when load .INI or reg database
209 // History: Date Author Comment
210 // 09/24/94 G. Vollant Created
212 //*************************************************************
213 BOOL SetMenuItem (LPMRUMENU lpMruMenu,WORD wItem,LPSTR lpItem)
215 if (wItem >= NBMRUMENU)
217 _fstrncpy((lpMruMenu->lpMRU) +
218 ((lpMruMenu->wMaxSizeLruItem) * (UINT)wItem),
219 lpItem,lpMruMenu->wMaxSizeLruItem-1);
220 lpMruMenu->wNbItemFill = max(lpMruMenu->wNbItemFill,wItem+1);
224 //*************************************************************
229 // Get the filename of an item
232 // LPMRUMENU lpMruMenu - pointer on MRUMENU
233 // WORD wItem - Number of Item to set, zero based
234 // BOOL fIDMBased - TRUE : wItem is based on ID menu item
235 // FALSE : wItem is zero-based
236 // LPSTR lpItem - String where the filename of the item will be
237 // stored by GetMenuItem()
238 // UINT uiSize - Size of the lpItem buffer
242 // TRUE - Function run successfully
243 // FALSE - Function don't run successfully
247 // Used for saving in .INI or reg database, or when user select
248 // an MRU in File menu
250 // History: Date Author Comment
251 // 09/24/94 G. Vollant Created
253 //*************************************************************
254 BOOL GetMenuItem (LPMRUMENU lpMruMenu,WORD wItem,
255 BOOL fIDMBased,LPSTR lpItem,UINT uiSize)
258 wItem -= (lpMruMenu->wIdMru + 1);
259 if (wItem >= lpMruMenu->wNbItemFill)
261 _fstrncpy(lpItem,(lpMruMenu->lpMRU) +
262 ((lpMruMenu->wMaxSizeLruItem) * (UINT)(wItem)),uiSize);
263 *(lpItem+uiSize-1) = '\0';
267 //*************************************************************
272 // Add an item at the begin of the list
275 // LPMRUMENU lpMruMenu - pointer on MRUMENU
276 // LPSTR lpItem - String contain the filename to add
279 // TRUE - Function run successfully
280 // FALSE - Function don't run successfully
284 // Used when used open a file (using File Open common
285 // dialog, Drag and drop or MRU)
287 // History: Date Author Comment
288 // 09/24/94 G. Vollant Created
290 //*************************************************************
291 void AddNewItem (LPMRUMENU lpMruMenu,LPSTR lpItem)
294 for (i=0;i<lpMruMenu->wNbItemFill;i++)
295 if (lstrcmpi(lpItem,(lpMruMenu->lpMRU) +
296 ((lpMruMenu->wMaxSizeLruItem) * (UINT)i)) == 0)
298 // Shift the other items
300 lstrcpy((lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)j),
301 (lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)(j-1)));
302 _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1);
305 lpMruMenu->wNbItemFill = min(lpMruMenu->wNbItemFill+1,lpMruMenu->wNbLruMenu);
306 for (i=lpMruMenu->wNbItemFill-1;i>0;i--)
307 lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i),
308 lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i-1)));
309 _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1);
312 //*************************************************************
320 // LPMRUMENU lpMruMenu - pointer on MRUMENU
321 // WORD wItem - Number of Item to set, zero based
322 // BOOL fIDMBased - TRUE : wItem is based on ID menu item
323 // FALSE : wItem is zero-based
326 // TRUE - Function run successfully
327 // FALSE - Function don't run successfully
331 // Used when used open a file, using MRU, and when an error
332 // occured (by example, when file was deleted)
334 // History: Date Author Comment
335 // 09/24/94 G. Vollant Created
337 //*************************************************************
338 BOOL DelMenuItem(LPMRUMENU lpMruMenu,WORD wItem,BOOL fIDMBased)
342 wItem -= (lpMruMenu->wIdMru + 1);
343 if (lpMruMenu->wNbItemFill <= wItem)
345 lpMruMenu->wNbItemFill--;
346 for (i=wItem;i<lpMruMenu->wNbItemFill;i++)
347 lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i),
348 lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i+1)));
352 //*************************************************************
354 // PlaceMenuMRUItem()
357 // Add MRU at the end of a menu
360 // LPMRUMENU lpMruMenu - pointer on MRUMENU
361 // HMENU hMenu - Handle of menu where MRU must be added
362 // UINT uiItem - Item of menu entry where MRU must be added
368 // Used MRU is modified, for refresh the File menu
370 // History: Date Author Comment
371 // 09/24/94 G. Vollant Created
373 //*************************************************************
374 void PlaceMenuMRUItem(LPMRUMENU lpMruMenu,HMENU hMenu,UINT uiItem)
380 // remove old MRU in menu
381 for (i=0;i<=(int)(lpMruMenu->wNbLruMenu);i++)
382 RemoveMenu(hMenu,i+lpMruMenu->wIdMru,MF_BYCOMMAND);
384 if (lpMruMenu->wNbItemFill == 0)
387 // If they are item, insert a separator before the files
388 InsertMenu(hMenu,uiItem,MF_SEPARATOR,lpMruMenu->wIdMru,NULL);
390 wNbShow = min(lpMruMenu->wNbItemFill,lpMruMenu->wNbLruShow);
391 for (i=(int)wNbShow-1;i>=0;i--)
394 if (lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20))
396 wsprintf(lpTxt,"&%lu %s",
397 (DWORD)(i+1),lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem*(UINT)i));
398 InsertMenu(hMenu,(((WORD)i)!=(wNbShow-1)) ? (lpMruMenu->wIdMru+i+2) : lpMruMenu->wIdMru,
399 MF_STRING,lpMruMenu->wIdMru+i+1,lpTxt);
400 GlobalFreePtr(lpTxt);
406 ///////////////////////////////////////////
410 //*************************************************************
415 // Save MRU in a private .INI
418 // LPMRUMENU lpMruMenu - pointer on MRUMENU
419 // LPSTR lpszSection - Points to a null-terminated string containing
420 // the name of the section
421 // LPSTR lpszFile - Points to a null-terminated string that names
422 // the initialization file.
425 // TRUE - Function run successfully
426 // FALSE - Function don't run successfully
430 // See WritePrivateProfileString API for more info on lpszSection and lpszFile
432 // History: Date Author Comment
433 // 09/24/94 G. Vollant Created
435 //*************************************************************
436 BOOL SaveMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile)
441 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
445 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
448 wsprintf(szEntry,"File%lu",(DWORD)i+1);
449 if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10))
451 WritePrivateProfileString(lpszSection,szEntry,lpTxt,lpszFile);
453 GlobalFreePtr(lpTxt);
454 WritePrivateProfileString(NULL,NULL,NULL,lpszFile); // flush cache
459 //*************************************************************
464 // Load MRU from a private .INI
467 // LPMRUMENU lpMruMenu - pointer on MRUMENU
468 // LPSTR lpszSection - Points to a null-terminated string containing
469 // the name of the section
470 // LPSTR lpszFile - Points to a null-terminated string that names
471 // the initialization file.
474 // TRUE - Function run successfully
475 // FALSE - Function don't run successfully
479 // See GetPrivateProfileString API for more info on lpszSection and lpszFile
481 // History: Date Author Comment
482 // 09/24/94 G. Vollant Created
484 //*************************************************************
485 BOOL LoadMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile)
489 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
493 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
497 wsprintf(szEntry,"File%lu",(DWORD)i+1);
498 GetPrivateProfileString(lpszSection,szEntry,"",lpTxt,
499 lpMruMenu->wMaxSizeLruItem + 10,lpszFile);
502 SetMenuItem(lpMruMenu,i,lpTxt);
504 GlobalFreePtr(lpTxt);
510 BOOL IsWin395OrHigher(void)
514 wVer = LOWORD(GetVersion());
515 wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer);
517 return (wVer >= 0x035F); // 5F = 95 dec
521 //*************************************************************
526 // Save MRU in the registry
529 // LPMRUMENU lpMruMenu - pointer on MRUMENU
530 // LPSTR lpszKey - Points to a null-terminated string
531 // specifying the name of a key that
532 // this function opens or creates.
535 // TRUE - Function run successfully
536 // FALSE - Function don't run successfully
540 // Win32 function designed for Windows NT and Windows 95
541 // See RegCreateKeyEx API for more info on lpszKey
543 // History: Date Author Comment
544 // 09/24/94 G. Vollant Created
546 //*************************************************************
547 BOOL SaveMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey)
554 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
558 RegCreateKeyEx(HKEY_CURRENT_USER,lpszKey,0,NULL,
559 REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hCurKey,&dwDisp);
561 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
564 wsprintf(szEntry,"File%lu",(DWORD)i+1);
565 if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10))
567 RegSetValueEx(hCurKey,szEntry,0,REG_SZ,lpTxt,lstrlen(lpTxt));
569 RegCloseKey(hCurKey);
570 GlobalFreePtr(lpTxt);
574 //*************************************************************
579 // Load MRU from the registry
582 // LPMRUMENU lpMruMenu - pointer on MRUMENU
583 // LPSTR lpszKey - Points to a null-terminated string
584 // specifying the name of a key that
585 // this function opens or creates.
588 // TRUE - Function run successfully
589 // FALSE - Function don't run successfully
593 // Win32 function designed for Windows NT and Windows 95
594 // See RegOpenKeyEx API for more info on lpszKey
596 // History: Date Author Comment
597 // 09/24/94 G. Vollant Created
599 //*************************************************************
600 BOOL LoadMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey)
606 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
610 RegOpenKeyEx(HKEY_CURRENT_USER,lpszKey,0,KEY_READ,&hCurKey);
613 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
617 wsprintf(szEntry,"File%lu",(DWORD)i+1);
619 dwSizeBuf = lpMruMenu->wMaxSizeLruItem + 10;
620 RegQueryValueEx(hCurKey,szEntry,NULL,&dwType,(LPBYTE)lpTxt,&dwSizeBuf);
621 *(lpTxt+dwSizeBuf)='\0';
624 SetMenuItem(lpMruMenu,i,lpTxt);
626 RegCloseKey(hCurKey);
627 GlobalFreePtr(lpTxt);
632 //*************************************************************
637 // Get the Win32 platform
641 // Return: (WIN32KIND)
642 // WINNT - Run under Windows NT
643 // WIN32S - Run under Windows 3.1x + Win32s
644 // WIN95ORGREATHER - Run under Windows 95
648 // Win32 function designed for Windows NT and Windows 95
649 // See RegOpenKeyEx API for more info on lpszKey
651 // History: Date Author Comment
652 // 09/24/94 G. Vollant Created
654 //*************************************************************
655 WIN32KIND GetWin32Kind()
657 BOOL IsWin395OrHigher(void);
661 if ((GetVersion() & 0x80000000) == 0)
663 wVer = LOWORD(GetVersion());
664 wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer);
667 return WIN95ORGREATHER;