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 //*************************************************************
36 #include "globaldefs.h"
42 // CreateMruMenu : MRUMENU constructor
43 // wNbLruShowInit : nb of item showed in menu
44 // wNbLruMenuInit : nb of item stored in memory
45 // wMaxSizeLruItemInit : size max. of filename
48 //*************************************************************
54 // Allocate and Initialize an MRU and return a pointer on it
59 // WORD wNbLruShowInit - Maximum number of item displayed on menu
60 // WORD wNbLruMenuInit - Maximum number of item stored in memory
61 // WORD wMaxSizeLruItemInit - Maximum size of an item (ie size of pathname)
62 // WORD wIdMruInit - ID of the first item in the menu (default:IDMRU)
65 // Return: (LPMRUMENU)
67 // Pointer on a MRUMENU structure, used by other function
71 // wNbLruShowInit <= wNbLruMenuInit
74 // History: Date Author Comment
75 // 09/24/94 G. Vollant Created
77 //*************************************************************
79 LPMRUMENU CreateMruMenu (WORD wNbLruShowInit,
80 WORD wNbLruMenuInit,WORD wMaxSizeLruItemInit,WORD wIdMruInit)
83 lpMruMenu = (LPMRUMENU)GlobalAllocPtr(GHND,sizeof(MRUMENU));
85 lpMruMenu->wNbItemFill = 0;
86 lpMruMenu->wNbLruMenu = wNbLruMenuInit;
87 lpMruMenu->wNbLruShow = wNbLruShowInit;
88 lpMruMenu->wIdMru = wIdMruInit;
89 lpMruMenu->wMaxSizeLruItem = wMaxSizeLruItemInit;
90 lpMruMenu->lpMRU = (LPSTR)GlobalAllocPtr(GHND,
91 lpMruMenu->wNbLruMenu*(UINT)lpMruMenu->wMaxSizeLruItem);
92 if (lpMruMenu->lpMRU == NULL)
94 GlobalFreePtr(lpMruMenu);
100 //*************************************************************
102 // CreateMruMenuDefault()
106 // Allocate and Initialize an MRU and return a pointer on it
107 // Use default parameter
113 // Return: (LPMRUMENU)
115 // Pointer on a MRUMENU structure, used by other function
121 // History: Date Author Comment
122 // 09/24/94 G. Vollant Created
124 //*************************************************************
126 LPMRUMENU CreateMruMenuDefault()
128 return CreateMruMenu (NBMRUMENUSHOW,NBMRUMENU,MAXSIZEMRUITEM,IDMRU);
132 //*************************************************************
138 // Clean and free a MRUMENU structure
142 // LPMRUMENU lpMruMenu - pointer on MRUMENU, allocated
143 // by CreateMruMenu() or CreateMruMenuDefault()
152 // History: Date Author Comment
153 // 09/24/94 G. Vollant Created
155 //*************************************************************
156 void DeleteMruMenu(LPMRUMENU lpMruMenu)
158 GlobalFreePtr(lpMruMenu->lpMRU);
159 GlobalFreePtr(lpMruMenu);
162 //*************************************************************
167 // Change the maximum number of item displayed on menu
170 // LPMRUMENU lpMruMenu - pointer on MRUMENU
171 // WORD wNbLruShowInit - Maximum number of item displayed on menu
180 // History: Date Author Comment
181 // 09/24/94 G. Vollant Created
183 //*************************************************************
184 void SetNbLruShow (LPMRUMENU lpMruMenu,WORD wNbLruShowInit)
186 lpMruMenu->wNbLruShow = min(wNbLruShowInit,lpMruMenu->wNbLruMenu);
189 //*************************************************************
194 // Set the filename of an item
197 // LPMRUMENU lpMruMenu - pointer on MRUMENU
198 // WORD wItem - Number of Item to set, zero based
199 // LPSTR lpItem - String, contain the filename of the item
203 // TRUE - Function run successfully
204 // FALSE - Function don't run successfully
208 // used when load .INI or reg database
210 // History: Date Author Comment
211 // 09/24/94 G. Vollant Created
213 //*************************************************************
214 BOOL SetMenuItem (LPMRUMENU lpMruMenu,WORD wItem,LPSTR lpItem)
216 if (wItem >= NBMRUMENU)
218 _fstrncpy((lpMruMenu->lpMRU) +
219 ((lpMruMenu->wMaxSizeLruItem) * (UINT)wItem),
220 lpItem,lpMruMenu->wMaxSizeLruItem-1);
221 lpMruMenu->wNbItemFill = max(lpMruMenu->wNbItemFill,wItem+1);
225 //*************************************************************
230 // Get the filename of an item
233 // LPMRUMENU lpMruMenu - pointer on MRUMENU
234 // WORD wItem - Number of Item to set, zero based
235 // BOOL fIDMBased - TRUE : wItem is based on ID menu item
236 // FALSE : wItem is zero-based
237 // LPSTR lpItem - String where the filename of the item will be
238 // stored by GetMenuItem()
239 // UINT uiSize - Size of the lpItem buffer
243 // TRUE - Function run successfully
244 // FALSE - Function don't run successfully
248 // Used for saving in .INI or reg database, or when user select
249 // an MRU in File menu
251 // History: Date Author Comment
252 // 09/24/94 G. Vollant Created
254 //*************************************************************
255 BOOL GetMenuItem (LPMRUMENU lpMruMenu,WORD wItem,
256 BOOL fIDMBased,LPSTR lpItem,UINT uiSize)
259 wItem -= (lpMruMenu->wIdMru + 1);
260 if (wItem >= lpMruMenu->wNbItemFill)
262 _fstrncpy(lpItem,(lpMruMenu->lpMRU) +
263 ((lpMruMenu->wMaxSizeLruItem) * (UINT)(wItem)),uiSize);
264 *(lpItem+uiSize-1) = '\0';
268 //*************************************************************
273 // Add an item at the begin of the list
276 // LPMRUMENU lpMruMenu - pointer on MRUMENU
277 // LPSTR lpItem - String contain the filename to add
280 // TRUE - Function run successfully
281 // FALSE - Function don't run successfully
285 // Used when used open a file (using File Open common
286 // dialog, Drag and drop or MRU)
288 // History: Date Author Comment
289 // 09/24/94 G. Vollant Created
291 //*************************************************************
292 void AddNewItem (LPMRUMENU lpMruMenu,LPSTR lpItem)
295 for (i=0;i<lpMruMenu->wNbItemFill;i++)
296 if (lstrcmpi(lpItem,(lpMruMenu->lpMRU) +
297 ((lpMruMenu->wMaxSizeLruItem) * (UINT)i)) == 0)
299 // Shift the other items
301 lstrcpy((lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)j),
302 (lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)(j-1)));
303 _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1);
306 lpMruMenu->wNbItemFill = min(lpMruMenu->wNbItemFill+1,lpMruMenu->wNbLruMenu);
307 for (i=lpMruMenu->wNbItemFill-1;i>0;i--)
308 lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i),
309 lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i-1)));
310 _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1);
313 //*************************************************************
321 // LPMRUMENU lpMruMenu - pointer on MRUMENU
322 // WORD wItem - Number of Item to set, zero based
323 // BOOL fIDMBased - TRUE : wItem is based on ID menu item
324 // FALSE : wItem is zero-based
327 // TRUE - Function run successfully
328 // FALSE - Function don't run successfully
332 // Used when used open a file, using MRU, and when an error
333 // occured (by example, when file was deleted)
335 // History: Date Author Comment
336 // 09/24/94 G. Vollant Created
338 //*************************************************************
339 BOOL DelMenuItem(LPMRUMENU lpMruMenu,WORD wItem,BOOL fIDMBased)
343 wItem -= (lpMruMenu->wIdMru + 1);
344 if (lpMruMenu->wNbItemFill <= wItem)
346 lpMruMenu->wNbItemFill--;
347 for (i=wItem;i<lpMruMenu->wNbItemFill;i++)
348 lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i),
349 lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i+1)));
353 //*************************************************************
355 // PlaceMenuMRUItem()
358 // Add MRU at the end of a menu
361 // LPMRUMENU lpMruMenu - pointer on MRUMENU
362 // HMENU hMenu - Handle of menu where MRU must be added
363 // UINT uiItem - Item of menu entry where MRU must be added
369 // Used MRU is modified, for refresh the File menu
371 // History: Date Author Comment
372 // 09/24/94 G. Vollant Created
374 //*************************************************************
375 void PlaceMenuMRUItem(LPMRUMENU lpMruMenu,HMENU hMenu,UINT uiItem)
381 // remove old MRU in menu
382 for (i=0;i<=(int)(lpMruMenu->wNbLruMenu);i++)
383 RemoveMenu(hMenu,i+lpMruMenu->wIdMru,MF_BYCOMMAND);
385 if (lpMruMenu->wNbItemFill == 0)
388 // If they are item, insert a separator before the files
389 InsertMenu(hMenu,uiItem,MF_SEPARATOR,lpMruMenu->wIdMru,NULL);
391 wNbShow = min(lpMruMenu->wNbItemFill,lpMruMenu->wNbLruShow);
392 for (i=(int)wNbShow-1;i>=0;i--)
395 if (lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20))
397 wsprintf(lpTxt,"&%lu %s",
398 (DWORD)(i+1),lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem*(UINT)i));
399 InsertMenu(hMenu,(((WORD)i)!=(wNbShow-1)) ? (lpMruMenu->wIdMru+i+2) : lpMruMenu->wIdMru,
400 MF_STRING,lpMruMenu->wIdMru+i+1,lpTxt);
401 GlobalFreePtr(lpTxt);
407 ///////////////////////////////////////////
411 //*************************************************************
416 // Save MRU in a private .INI
419 // LPMRUMENU lpMruMenu - pointer on MRUMENU
420 // LPSTR lpszSection - Points to a null-terminated string containing
421 // the name of the section
422 // LPSTR lpszFile - Points to a null-terminated string that names
423 // the initialization file.
426 // TRUE - Function run successfully
427 // FALSE - Function don't run successfully
431 // See WritePrivateProfileString API for more info on lpszSection and lpszFile
433 // History: Date Author Comment
434 // 09/24/94 G. Vollant Created
436 //*************************************************************
437 BOOL SaveMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile)
442 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
446 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
449 wsprintf(szEntry,"File%lu",(DWORD)i+1);
450 if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10))
452 WritePrivateProfileString(lpszSection,szEntry,lpTxt,lpszFile);
454 GlobalFreePtr(lpTxt);
455 WritePrivateProfileString(NULL,NULL,NULL,lpszFile); // flush cache
460 //*************************************************************
465 // Load MRU from a private .INI
468 // LPMRUMENU lpMruMenu - pointer on MRUMENU
469 // LPSTR lpszSection - Points to a null-terminated string containing
470 // the name of the section
471 // LPSTR lpszFile - Points to a null-terminated string that names
472 // the initialization file.
475 // TRUE - Function run successfully
476 // FALSE - Function don't run successfully
480 // See GetPrivateProfileString API for more info on lpszSection and lpszFile
482 // History: Date Author Comment
483 // 09/24/94 G. Vollant Created
485 //*************************************************************
486 BOOL LoadMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile)
490 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
494 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
498 wsprintf(szEntry,"File%lu",(DWORD)i+1);
499 GetPrivateProfileString(lpszSection,szEntry,"",lpTxt,
500 lpMruMenu->wMaxSizeLruItem + 10,lpszFile);
503 SetMenuItem(lpMruMenu,i,lpTxt);
505 GlobalFreePtr(lpTxt);
511 BOOL IsWin395OrHigher(void)
515 wVer = LOWORD(GetVersion());
516 wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer);
518 return (wVer >= 0x035F); // 5F = 95 dec
522 //*************************************************************
527 // Save MRU in the registry
530 // LPMRUMENU lpMruMenu - pointer on MRUMENU
531 // LPSTR lpszKey - Points to a null-terminated string
532 // specifying the name of a key that
533 // this function opens or creates.
536 // TRUE - Function run successfully
537 // FALSE - Function don't run successfully
541 // Win32 function designed for Windows NT and Windows 95
542 // See RegCreateKeyEx API for more info on lpszKey
544 // History: Date Author Comment
545 // 09/24/94 G. Vollant Created
547 //*************************************************************
548 BOOL SaveMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey)
555 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
559 RegCreateKeyEx(HKEY_CURRENT_USER,lpszKey,0,NULL,
560 REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hCurKey,&dwDisp);
562 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
565 wsprintf(szEntry,"File%lu",(DWORD)i+1);
566 if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10))
568 RegSetValueEx(hCurKey,szEntry,0,REG_SZ,lpTxt,lstrlen(lpTxt));
570 RegCloseKey(hCurKey);
571 GlobalFreePtr(lpTxt);
575 //*************************************************************
580 // Load MRU from the registry
583 // LPMRUMENU lpMruMenu - pointer on MRUMENU
584 // LPSTR lpszKey - Points to a null-terminated string
585 // specifying the name of a key that
586 // this function opens or creates.
589 // TRUE - Function run successfully
590 // FALSE - Function don't run successfully
594 // Win32 function designed for Windows NT and Windows 95
595 // See RegOpenKeyEx API for more info on lpszKey
597 // History: Date Author Comment
598 // 09/24/94 G. Vollant Created
600 //*************************************************************
601 BOOL LoadMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey)
607 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
611 RegOpenKeyEx(HKEY_CURRENT_USER,lpszKey,0,KEY_READ,&hCurKey);
614 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
618 wsprintf(szEntry,"File%lu",(DWORD)i+1);
620 dwSizeBuf = lpMruMenu->wMaxSizeLruItem + 10;
621 RegQueryValueEx(hCurKey,szEntry,NULL,&dwType,(LPBYTE)lpTxt,&dwSizeBuf);
622 *(lpTxt+dwSizeBuf)='\0';
625 SetMenuItem(lpMruMenu,i,lpTxt);
627 RegCloseKey(hCurKey);
628 GlobalFreePtr(lpTxt);
633 //*************************************************************
638 // Get the Win32 platform
642 // Return: (WIN32KIND)
643 // WINNT - Run under Windows NT
644 // WIN32S - Run under Windows 3.1x + Win32s
645 // WIN95ORGREATHER - Run under Windows 95
649 // Win32 function designed for Windows NT and Windows 95
650 // See RegOpenKeyEx API for more info on lpszKey
652 // History: Date Author Comment
653 // 09/24/94 G. Vollant Created
655 //*************************************************************
656 WIN32KIND GetWin32Kind()
658 BOOL IsWin395OrHigher(void);
662 if ((GetVersion() & 0x80000000) == 0)
664 wVer = LOWORD(GetVersion());
665 wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer);
668 return WIN95ORGREATHER;