2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../../idlib/precompiled.h"
35 //*************************************************************
40 // Routines for MRU support
44 // Gilles Vollant (100144.2636@compuserve.com)
46 //*************************************************************
49 // CreateMruMenu : MRUMENU constructor
50 // wNbLruShowInit : nb of item showed in menu
51 // wNbLruMenuInit : nb of item stored in memory
52 // wMaxSizeLruItemInit : size max. of filename
55 //*************************************************************
61 // Allocate and Initialize an MRU and return a pointer on it
66 // WORD wNbLruShowInit - Maximum number of item displayed on menu
67 // WORD wNbLruMenuInit - Maximum number of item stored in memory
68 // WORD wMaxSizeLruItemInit - Maximum size of an item (ie size of pathname)
69 // WORD wIdMruInit - ID of the first item in the menu (default:IDMRU)
72 // Return: (LPMRUMENU)
74 // Pointer on a MRUMENU structure, used by other function
78 // wNbLruShowInit <= wNbLruMenuInit
81 // History: Date Author Comment
82 // 09/24/94 G. Vollant Created
84 //*************************************************************
86 LPMRUMENU CreateMruMenu (WORD wNbLruShowInit,
87 WORD wNbLruMenuInit,WORD wMaxSizeLruItemInit,WORD wIdMruInit)
90 lpMruMenu = (LPMRUMENU)GlobalAllocPtr(GHND,sizeof(MRUMENU));
92 lpMruMenu->wNbItemFill = 0;
93 lpMruMenu->wNbLruMenu = wNbLruMenuInit;
94 lpMruMenu->wNbLruShow = wNbLruShowInit;
95 lpMruMenu->wIdMru = wIdMruInit;
96 lpMruMenu->wMaxSizeLruItem = wMaxSizeLruItemInit;
97 lpMruMenu->lpMRU = (LPSTR)GlobalAllocPtr(GHND,
98 lpMruMenu->wNbLruMenu*(UINT)lpMruMenu->wMaxSizeLruItem);
99 if (lpMruMenu->lpMRU == NULL)
101 GlobalFreePtr(lpMruMenu);
107 //*************************************************************
109 // CreateMruMenuDefault()
113 // Allocate and Initialize an MRU and return a pointer on it
114 // Use default parameter
120 // Return: (LPMRUMENU)
122 // Pointer on a MRUMENU structure, used by other function
128 // History: Date Author Comment
129 // 09/24/94 G. Vollant Created
131 //*************************************************************
133 LPMRUMENU CreateMruMenuDefault()
135 return CreateMruMenu (NBMRUMENUSHOW,NBMRUMENU,MAXSIZEMRUITEM,IDMRU);
139 //*************************************************************
145 // Clean and free a MRUMENU structure
149 // LPMRUMENU lpMruMenu - pointer on MRUMENU, allocated
150 // by CreateMruMenu() or CreateMruMenuDefault()
159 // History: Date Author Comment
160 // 09/24/94 G. Vollant Created
162 //*************************************************************
163 void DeleteMruMenu(LPMRUMENU lpMruMenu)
165 GlobalFreePtr(lpMruMenu->lpMRU);
166 GlobalFreePtr(lpMruMenu);
169 //*************************************************************
174 // Change the maximum number of item displayed on menu
177 // LPMRUMENU lpMruMenu - pointer on MRUMENU
178 // WORD wNbLruShowInit - Maximum number of item displayed on menu
187 // History: Date Author Comment
188 // 09/24/94 G. Vollant Created
190 //*************************************************************
191 void SetNbLruShow (LPMRUMENU lpMruMenu,WORD wNbLruShowInit)
193 lpMruMenu->wNbLruShow = min(wNbLruShowInit,lpMruMenu->wNbLruMenu);
196 //*************************************************************
201 // Set the filename of an item
204 // LPMRUMENU lpMruMenu - pointer on MRUMENU
205 // WORD wItem - Number of Item to set, zero based
206 // LPSTR lpItem - String, contain the filename of the item
210 // TRUE - Function run successfully
211 // FALSE - Function don't run successfully
215 // used when load .INI or reg database
217 // History: Date Author Comment
218 // 09/24/94 G. Vollant Created
220 //*************************************************************
221 BOOL SetMenuItem (LPMRUMENU lpMruMenu,WORD wItem,LPSTR lpItem)
223 if (wItem >= NBMRUMENU)
225 _fstrncpy((lpMruMenu->lpMRU) +
226 ((lpMruMenu->wMaxSizeLruItem) * (UINT)wItem),
227 lpItem,lpMruMenu->wMaxSizeLruItem-1);
228 lpMruMenu->wNbItemFill = max(lpMruMenu->wNbItemFill,wItem+1);
232 //*************************************************************
237 // Get the filename of an item
240 // LPMRUMENU lpMruMenu - pointer on MRUMENU
241 // WORD wItem - Number of Item to set, zero based
242 // BOOL fIDMBased - TRUE : wItem is based on ID menu item
243 // FALSE : wItem is zero-based
244 // LPSTR lpItem - String where the filename of the item will be
245 // stored by GetMenuItem()
246 // UINT uiSize - Size of the lpItem buffer
250 // TRUE - Function run successfully
251 // FALSE - Function don't run successfully
255 // Used for saving in .INI or reg database, or when user select
256 // an MRU in File menu
258 // History: Date Author Comment
259 // 09/24/94 G. Vollant Created
261 //*************************************************************
262 BOOL GetMenuItem (LPMRUMENU lpMruMenu,WORD wItem,
263 BOOL fIDMBased,LPSTR lpItem,UINT uiSize)
266 wItem -= (lpMruMenu->wIdMru + 1);
267 if (wItem >= lpMruMenu->wNbItemFill)
269 _fstrncpy(lpItem,(lpMruMenu->lpMRU) +
270 ((lpMruMenu->wMaxSizeLruItem) * (UINT)(wItem)),uiSize);
271 *(lpItem+uiSize-1) = '\0';
275 //*************************************************************
280 // Add an item at the begin of the list
283 // LPMRUMENU lpMruMenu - pointer on MRUMENU
284 // LPSTR lpItem - String contain the filename to add
287 // TRUE - Function run successfully
288 // FALSE - Function don't run successfully
292 // Used when used open a file (using File Open common
293 // dialog, Drag and drop or MRU)
295 // History: Date Author Comment
296 // 09/24/94 G. Vollant Created
298 //*************************************************************
299 void AddNewItem (LPMRUMENU lpMruMenu,LPSTR lpItem)
302 for (i=0;i<lpMruMenu->wNbItemFill;i++)
303 if (lstrcmpi(lpItem,(lpMruMenu->lpMRU) +
304 ((lpMruMenu->wMaxSizeLruItem) * (UINT)i)) == 0)
306 // Shift the other items
308 lstrcpy((lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)j),
309 (lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)(j-1)));
310 _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1);
313 lpMruMenu->wNbItemFill = min(lpMruMenu->wNbItemFill+1,lpMruMenu->wNbLruMenu);
314 for (i=lpMruMenu->wNbItemFill-1;i>0;i--)
315 lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i),
316 lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i-1)));
317 _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1);
320 //*************************************************************
328 // LPMRUMENU lpMruMenu - pointer on MRUMENU
329 // WORD wItem - Number of Item to set, zero based
330 // BOOL fIDMBased - TRUE : wItem is based on ID menu item
331 // FALSE : wItem is zero-based
334 // TRUE - Function run successfully
335 // FALSE - Function don't run successfully
339 // Used when used open a file, using MRU, and when an error
340 // occured (by example, when file was deleted)
342 // History: Date Author Comment
343 // 09/24/94 G. Vollant Created
345 //*************************************************************
346 BOOL DelMenuItem(LPMRUMENU lpMruMenu,WORD wItem,BOOL fIDMBased)
350 wItem -= (lpMruMenu->wIdMru + 1);
351 if (lpMruMenu->wNbItemFill <= wItem)
353 lpMruMenu->wNbItemFill--;
354 for (i=wItem;i<lpMruMenu->wNbItemFill;i++)
355 lstrcpy(lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)i),
356 lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem * (UINT)(i+1)));
360 //*************************************************************
362 // PlaceMenuMRUItem()
365 // Add MRU at the end of a menu
368 // LPMRUMENU lpMruMenu - pointer on MRUMENU
369 // HMENU hMenu - Handle of menu where MRU must be added
370 // UINT uiItem - Item of menu entry where MRU must be added
376 // Used MRU is modified, for refresh the File menu
378 // History: Date Author Comment
379 // 09/24/94 G. Vollant Created
381 //*************************************************************
382 void PlaceMenuMRUItem(LPMRUMENU lpMruMenu,HMENU hMenu,UINT uiItem)
388 // remove old MRU in menu
389 for (i=0;i<=(int)(lpMruMenu->wNbLruMenu);i++)
390 RemoveMenu(hMenu,i+lpMruMenu->wIdMru,MF_BYCOMMAND);
392 if (lpMruMenu->wNbItemFill == 0)
395 // If they are item, insert a separator before the files
396 InsertMenu(hMenu,uiItem,MF_SEPARATOR,lpMruMenu->wIdMru,NULL);
398 wNbShow = min(lpMruMenu->wNbItemFill,lpMruMenu->wNbLruShow);
399 for (i=(int)wNbShow-1;i>=0;i--)
402 if (lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20))
404 wsprintf(lpTxt,"&%lu %s",
405 (DWORD)(i+1),lpMruMenu->lpMRU + (lpMruMenu->wMaxSizeLruItem*(UINT)i));
406 InsertMenu(hMenu,(((WORD)i)!=(wNbShow-1)) ? (lpMruMenu->wIdMru+i+2) : lpMruMenu->wIdMru,
407 MF_STRING,lpMruMenu->wIdMru+i+1,lpTxt);
408 GlobalFreePtr(lpTxt);
414 ///////////////////////////////////////////
418 //*************************************************************
423 // Save MRU in a private .INI
426 // LPMRUMENU lpMruMenu - pointer on MRUMENU
427 // LPSTR lpszSection - Points to a null-terminated string containing
428 // the name of the section
429 // LPSTR lpszFile - Points to a null-terminated string that names
430 // the initialization file.
433 // TRUE - Function run successfully
434 // FALSE - Function don't run successfully
438 // See WritePrivateProfileString API for more info on lpszSection and lpszFile
440 // History: Date Author Comment
441 // 09/24/94 G. Vollant Created
443 //*************************************************************
444 BOOL SaveMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile)
449 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
453 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
456 wsprintf(szEntry,"File%lu",(DWORD)i+1);
457 if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10))
459 WritePrivateProfileString(lpszSection,szEntry,lpTxt,lpszFile);
461 GlobalFreePtr(lpTxt);
462 WritePrivateProfileString(NULL,NULL,NULL,lpszFile); // flush cache
467 //*************************************************************
472 // Load MRU from a private .INI
475 // LPMRUMENU lpMruMenu - pointer on MRUMENU
476 // LPSTR lpszSection - Points to a null-terminated string containing
477 // the name of the section
478 // LPSTR lpszFile - Points to a null-terminated string that names
479 // the initialization file.
482 // TRUE - Function run successfully
483 // FALSE - Function don't run successfully
487 // See GetPrivateProfileString API for more info on lpszSection and lpszFile
489 // History: Date Author Comment
490 // 09/24/94 G. Vollant Created
492 //*************************************************************
493 BOOL LoadMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile)
497 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
501 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
505 wsprintf(szEntry,"File%lu",(DWORD)i+1);
506 GetPrivateProfileString(lpszSection,szEntry,"",lpTxt,
507 lpMruMenu->wMaxSizeLruItem + 10,lpszFile);
510 SetMenuItem(lpMruMenu,i,lpTxt);
512 GlobalFreePtr(lpTxt);
518 BOOL IsWin395OrHigher(void)
522 wVer = LOWORD(GetVersion());
523 wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer);
525 return (wVer >= 0x035F); // 5F = 95 dec
529 //*************************************************************
534 // Save MRU in the registry
537 // LPMRUMENU lpMruMenu - pointer on MRUMENU
538 // LPSTR lpszKey - Points to a null-terminated string
539 // specifying the name of a key that
540 // this function opens or creates.
543 // TRUE - Function run successfully
544 // FALSE - Function don't run successfully
548 // Win32 function designed for Windows NT and Windows 95
549 // See RegCreateKeyEx API for more info on lpszKey
551 // History: Date Author Comment
552 // 09/24/94 G. Vollant Created
554 //*************************************************************
555 BOOL SaveMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey)
562 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
566 RegCreateKeyEx(HKEY_CURRENT_USER,lpszKey,0,NULL,
567 REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hCurKey,&dwDisp);
569 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
572 wsprintf(szEntry,"File%lu",(DWORD)i+1);
573 if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10))
575 RegSetValueEx(hCurKey,szEntry,0,REG_SZ,(unsigned char*)lpTxt,lstrlen(lpTxt));
577 RegCloseKey(hCurKey);
578 GlobalFreePtr(lpTxt);
582 //*************************************************************
587 // Load MRU from the registry
590 // LPMRUMENU lpMruMenu - pointer on MRUMENU
591 // LPSTR lpszKey - Points to a null-terminated string
592 // specifying the name of a key that
593 // this function opens or creates.
596 // TRUE - Function run successfully
597 // FALSE - Function don't run successfully
601 // Win32 function designed for Windows NT and Windows 95
602 // See RegOpenKeyEx API for more info on lpszKey
604 // History: Date Author Comment
605 // 09/24/94 G. Vollant Created
607 //*************************************************************
608 BOOL LoadMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey)
614 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20);
618 RegOpenKeyEx(HKEY_CURRENT_USER,lpszKey,0,KEY_READ,&hCurKey);
621 for (i=0;i<lpMruMenu->wNbLruMenu;i++)
625 wsprintf(szEntry,"File%lu",(DWORD)i+1);
627 dwSizeBuf = lpMruMenu->wMaxSizeLruItem + 10;
628 RegQueryValueEx(hCurKey,szEntry,NULL,&dwType,(LPBYTE)lpTxt,&dwSizeBuf);
629 *(lpTxt+dwSizeBuf)='\0';
632 SetMenuItem(lpMruMenu,i,lpTxt);
634 RegCloseKey(hCurKey);
635 GlobalFreePtr(lpTxt);
640 //*************************************************************
645 // Get the Win32 platform
649 // Return: (WIN32KIND)
650 // WINNT - Run under Windows NT
651 // WIN32S - Run under Windows 3.1x + Win32s
652 // WIN95ORGREATHER - Run under Windows 95
656 // Win32 function designed for Windows NT and Windows 95
657 // See RegOpenKeyEx API for more info on lpszKey
659 // History: Date Author Comment
660 // 09/24/94 G. Vollant Created
662 //*************************************************************
663 WIN32KIND GetWin32Kind()
665 BOOL IsWin395OrHigher(void);
669 if ((GetVersion() & 0x80000000) == 0)
671 wVer = LOWORD(GetVersion());
672 wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer);
675 return WIN95ORGREATHER;