MRU.CPP (19370B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena 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. 11 12 Quake III Arena 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. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 //************************************************************* 23 // File name: mru.c 24 // 25 // Description: 26 // 27 // Routines for MRU support 28 // 29 // Development Team: 30 // 31 // Gilles Vollant (100144.2636@compuserve.com) 32 // 33 //************************************************************* 34 35 #include "stdafx.h" 36 #include <windows.h> 37 #include <windowsx.h> 38 #include <string.h> 39 40 #include "mru.h" 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 45 46 47 //************************************************************* 48 // 49 // CreateMruMenu() 50 // 51 // Purpose: 52 // 53 // Allocate and Initialize an MRU and return a pointer on it 54 // 55 // 56 // Parameters: 57 // 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) 62 // 63 // 64 // Return: (LPMRUMENU) 65 // 66 // Pointer on a MRUMENU structure, used by other function 67 // 68 // 69 // Comments: 70 // wNbLruShowInit <= wNbLruMenuInit 71 // 72 // 73 // History: Date Author Comment 74 // 09/24/94 G. Vollant Created 75 // 76 //************************************************************* 77 78 LPMRUMENU CreateMruMenu (WORD wNbLruShowInit, 79 WORD wNbLruMenuInit,WORD wMaxSizeLruItemInit,WORD wIdMruInit) 80 { 81 LPMRUMENU lpMruMenu; 82 lpMruMenu = (LPMRUMENU)GlobalAllocPtr(GHND,sizeof(MRUMENU)); 83 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) 92 { 93 GlobalFreePtr(lpMruMenu); 94 lpMruMenu = NULL; 95 } 96 return lpMruMenu; 97 } 98 99 //************************************************************* 100 // 101 // CreateMruMenuDefault() 102 // 103 // Purpose: 104 // 105 // Allocate and Initialize an MRU and return a pointer on it 106 // Use default parameter 107 // 108 // 109 // Parameters: 110 // 111 // 112 // Return: (LPMRUMENU) 113 // 114 // Pointer on a MRUMENU structure, used by other function 115 // 116 // 117 // Comments: 118 // 119 // 120 // History: Date Author Comment 121 // 09/24/94 G. Vollant Created 122 // 123 //************************************************************* 124 125 LPMRUMENU CreateMruMenuDefault() 126 { 127 return CreateMruMenu (NBMRUMENUSHOW,NBMRUMENU,MAXSIZEMRUITEM,IDMRU); 128 } 129 130 131 //************************************************************* 132 // 133 // DeleteMruMenu() 134 // 135 // Purpose: 136 // Destructor : 137 // Clean and free a MRUMENU structure 138 // 139 // Parameters: 140 // 141 // LPMRUMENU lpMruMenu - pointer on MRUMENU, allocated 142 // by CreateMruMenu() or CreateMruMenuDefault() 143 // 144 // 145 // Return: void 146 // 147 // 148 // Comments: 149 // 150 // 151 // History: Date Author Comment 152 // 09/24/94 G. Vollant Created 153 // 154 //************************************************************* 155 void DeleteMruMenu(LPMRUMENU lpMruMenu) 156 { 157 GlobalFreePtr(lpMruMenu->lpMRU); 158 GlobalFreePtr(lpMruMenu); 159 } 160 161 //************************************************************* 162 // 163 // SetNbLruShow() 164 // 165 // Purpose: 166 // Change the maximum number of item displayed on menu 167 // 168 // Parameters: 169 // LPMRUMENU lpMruMenu - pointer on MRUMENU 170 // WORD wNbLruShowInit - Maximum number of item displayed on menu 171 // 172 // 173 // Return: void 174 // 175 // 176 // Comments: 177 // 178 // 179 // History: Date Author Comment 180 // 09/24/94 G. Vollant Created 181 // 182 //************************************************************* 183 void SetNbLruShow (LPMRUMENU lpMruMenu,WORD wNbLruShowInit) 184 { 185 lpMruMenu->wNbLruShow = min(wNbLruShowInit,lpMruMenu->wNbLruMenu); 186 } 187 188 //************************************************************* 189 // 190 // SetMenuItem() 191 // 192 // Purpose: 193 // Set the filename of an item 194 // 195 // Parameters: 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 199 // 200 // 201 // Return: (BOOL) 202 // TRUE - Function run successfully 203 // FALSE - Function don't run successfully 204 // 205 // 206 // Comments: 207 // used when load .INI or reg database 208 // 209 // History: Date Author Comment 210 // 09/24/94 G. Vollant Created 211 // 212 //************************************************************* 213 BOOL SetMenuItem (LPMRUMENU lpMruMenu,WORD wItem,LPSTR lpItem) 214 { 215 if (wItem >= NBMRUMENU) 216 return FALSE; 217 _fstrncpy((lpMruMenu->lpMRU) + 218 ((lpMruMenu->wMaxSizeLruItem) * (UINT)wItem), 219 lpItem,lpMruMenu->wMaxSizeLruItem-1); 220 lpMruMenu->wNbItemFill = max(lpMruMenu->wNbItemFill,wItem+1); 221 return TRUE; 222 } 223 224 //************************************************************* 225 // 226 // GetMenuItem() 227 // 228 // Purpose: 229 // Get the filename of an item 230 // 231 // Parameters: 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 239 // 240 // 241 // Return: (BOOL) 242 // TRUE - Function run successfully 243 // FALSE - Function don't run successfully 244 // 245 // 246 // Comments: 247 // Used for saving in .INI or reg database, or when user select 248 // an MRU in File menu 249 // 250 // History: Date Author Comment 251 // 09/24/94 G. Vollant Created 252 // 253 //************************************************************* 254 BOOL GetMenuItem (LPMRUMENU lpMruMenu,WORD wItem, 255 BOOL fIDMBased,LPSTR lpItem,UINT uiSize) 256 { 257 if (fIDMBased) 258 wItem -= (lpMruMenu->wIdMru + 1); 259 if (wItem >= lpMruMenu->wNbItemFill) 260 return FALSE; 261 _fstrncpy(lpItem,(lpMruMenu->lpMRU) + 262 ((lpMruMenu->wMaxSizeLruItem) * (UINT)(wItem)),uiSize); 263 *(lpItem+uiSize-1) = '\0'; 264 return TRUE; 265 } 266 267 //************************************************************* 268 // 269 // AddNewItem() 270 // 271 // Purpose: 272 // Add an item at the begin of the list 273 // 274 // Parameters: 275 // LPMRUMENU lpMruMenu - pointer on MRUMENU 276 // LPSTR lpItem - String contain the filename to add 277 // 278 // Return: (BOOL) 279 // TRUE - Function run successfully 280 // FALSE - Function don't run successfully 281 // 282 // 283 // Comments: 284 // Used when used open a file (using File Open common 285 // dialog, Drag and drop or MRU) 286 // 287 // History: Date Author Comment 288 // 09/24/94 G. Vollant Created 289 // 290 //************************************************************* 291 void AddNewItem (LPMRUMENU lpMruMenu,LPSTR lpItem) 292 { 293 WORD i,j; 294 for (i=0;i<lpMruMenu->wNbItemFill;i++) 295 if (lstrcmpi(lpItem,(lpMruMenu->lpMRU) + 296 ((lpMruMenu->wMaxSizeLruItem) * (UINT)i)) == 0) 297 { 298 // Shift the other items 299 for (j=i;j>0;j--) 300 lstrcpy((lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)j), 301 (lpMruMenu->lpMRU) + (lpMruMenu->wMaxSizeLruItem * (UINT)(j-1))); 302 _fstrncpy(lpMruMenu->lpMRU,lpItem,lpMruMenu->wMaxSizeLruItem-1); 303 return ; 304 } 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); 310 } 311 312 //************************************************************* 313 // 314 // DelMenuItem() 315 // 316 // Purpose: 317 // Delete an item 318 // 319 // Parameters: 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 324 // 325 // Return: (BOOL) 326 // TRUE - Function run successfully 327 // FALSE - Function don't run successfully 328 // 329 // 330 // Comments: 331 // Used when used open a file, using MRU, and when an error 332 // occured (by example, when file was deleted) 333 // 334 // History: Date Author Comment 335 // 09/24/94 G. Vollant Created 336 // 337 //************************************************************* 338 BOOL DelMenuItem(LPMRUMENU lpMruMenu,WORD wItem,BOOL fIDMBased) 339 { 340 WORD i; 341 if (fIDMBased) 342 wItem -= (lpMruMenu->wIdMru + 1); 343 if (lpMruMenu->wNbItemFill <= wItem) 344 return FALSE; 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))); 349 return TRUE; 350 } 351 352 //************************************************************* 353 // 354 // PlaceMenuMRUItem() 355 // 356 // Purpose: 357 // Add MRU at the end of a menu 358 // 359 // Parameters: 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 363 // 364 // Return: void 365 // 366 // 367 // Comments: 368 // Used MRU is modified, for refresh the File menu 369 // 370 // History: Date Author Comment 371 // 09/24/94 G. Vollant Created 372 // 373 //************************************************************* 374 void PlaceMenuMRUItem(LPMRUMENU lpMruMenu,HMENU hMenu,UINT uiItem) 375 { 376 int i; 377 WORD wNbShow; 378 if (hMenu == NULL) 379 return; 380 // remove old MRU in menu 381 for (i=0;i<=(int)(lpMruMenu->wNbLruMenu);i++) 382 RemoveMenu(hMenu,i+lpMruMenu->wIdMru,MF_BYCOMMAND); 383 384 if (lpMruMenu->wNbItemFill == 0) 385 return; 386 387 // If they are item, insert a separator before the files 388 InsertMenu(hMenu,uiItem,MF_SEPARATOR,lpMruMenu->wIdMru,NULL); 389 390 wNbShow = min(lpMruMenu->wNbItemFill,lpMruMenu->wNbLruShow); 391 for (i=(int)wNbShow-1;i>=0;i--) 392 { 393 LPSTR lpTxt; 394 if (lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20)) 395 { 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); 401 } 402 } 403 404 } 405 406 /////////////////////////////////////////// 407 408 409 410 //************************************************************* 411 // 412 // SaveMruInIni() 413 // 414 // Purpose: 415 // Save MRU in a private .INI 416 // 417 // Parameters: 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. 423 // 424 // Return: (BOOL) 425 // TRUE - Function run successfully 426 // FALSE - Function don't run successfully 427 // 428 // 429 // Comments: 430 // See WritePrivateProfileString API for more info on lpszSection and lpszFile 431 // 432 // History: Date Author Comment 433 // 09/24/94 G. Vollant Created 434 // 435 //************************************************************* 436 BOOL SaveMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile) 437 { 438 LPSTR lpTxt; 439 WORD i; 440 441 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); 442 if (lpTxt == NULL) 443 return FALSE; 444 445 for (i=0;i<lpMruMenu->wNbLruMenu;i++) 446 { 447 char szEntry[16]; 448 wsprintf(szEntry,"File%lu",(DWORD)i+1); 449 if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10)) 450 *lpTxt = '\0'; 451 WritePrivateProfileString(lpszSection,szEntry,lpTxt,lpszFile); 452 } 453 GlobalFreePtr(lpTxt); 454 WritePrivateProfileString(NULL,NULL,NULL,lpszFile); // flush cache 455 return TRUE; 456 } 457 458 459 //************************************************************* 460 // 461 // LoadMruInIni() 462 // 463 // Purpose: 464 // Load MRU from a private .INI 465 // 466 // Parameters: 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. 472 // 473 // Return: (BOOL) 474 // TRUE - Function run successfully 475 // FALSE - Function don't run successfully 476 // 477 // 478 // Comments: 479 // See GetPrivateProfileString API for more info on lpszSection and lpszFile 480 // 481 // History: Date Author Comment 482 // 09/24/94 G. Vollant Created 483 // 484 //************************************************************* 485 BOOL LoadMruInIni(LPMRUMENU lpMruMenu,LPSTR lpszSection,LPSTR lpszFile) 486 { 487 LPSTR lpTxt; 488 WORD i; 489 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); 490 if (lpTxt == NULL) 491 return FALSE; 492 493 for (i=0;i<lpMruMenu->wNbLruMenu;i++) 494 { 495 char szEntry[16]; 496 497 wsprintf(szEntry,"File%lu",(DWORD)i+1); 498 GetPrivateProfileString(lpszSection,szEntry,"",lpTxt, 499 lpMruMenu->wMaxSizeLruItem + 10,lpszFile); 500 if (*lpTxt == '\0') 501 break; 502 SetMenuItem(lpMruMenu,i,lpTxt); 503 } 504 GlobalFreePtr(lpTxt); 505 return TRUE; 506 } 507 508 #ifdef WIN32 509 510 BOOL IsWin395OrHigher(void) 511 { 512 WORD wVer; 513 514 wVer = LOWORD(GetVersion()); 515 wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer); 516 517 return (wVer >= 0x035F); // 5F = 95 dec 518 } 519 520 521 //************************************************************* 522 // 523 // SaveMruInReg() 524 // 525 // Purpose: 526 // Save MRU in the registry 527 // 528 // Parameters: 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. 533 // 534 // Return: (BOOL) 535 // TRUE - Function run successfully 536 // FALSE - Function don't run successfully 537 // 538 // 539 // Comments: 540 // Win32 function designed for Windows NT and Windows 95 541 // See RegCreateKeyEx API for more info on lpszKey 542 // 543 // History: Date Author Comment 544 // 09/24/94 G. Vollant Created 545 // 546 //************************************************************* 547 BOOL SaveMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey) 548 { 549 LPSTR lpTxt; 550 WORD i; 551 HKEY hCurKey; 552 DWORD dwDisp; 553 554 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); 555 if (lpTxt == NULL) 556 return FALSE; 557 558 RegCreateKeyEx(HKEY_CURRENT_USER,lpszKey,0,NULL, 559 REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hCurKey,&dwDisp); 560 561 for (i=0;i<lpMruMenu->wNbLruMenu;i++) 562 { 563 char szEntry[16]; 564 wsprintf(szEntry,"File%lu",(DWORD)i+1); 565 if (!GetMenuItem(lpMruMenu,i,FALSE,lpTxt,lpMruMenu->wMaxSizeLruItem + 10)) 566 *lpTxt = '\0'; 567 RegSetValueEx(hCurKey,szEntry,0,REG_SZ,(unsigned char*)lpTxt,lstrlen(lpTxt)); 568 } 569 RegCloseKey(hCurKey); 570 GlobalFreePtr(lpTxt); 571 return TRUE; 572 } 573 574 //************************************************************* 575 // 576 // LoadMruInReg() 577 // 578 // Purpose: 579 // Load MRU from the registry 580 // 581 // Parameters: 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. 586 // 587 // Return: (BOOL) 588 // TRUE - Function run successfully 589 // FALSE - Function don't run successfully 590 // 591 // 592 // Comments: 593 // Win32 function designed for Windows NT and Windows 95 594 // See RegOpenKeyEx API for more info on lpszKey 595 // 596 // History: Date Author Comment 597 // 09/24/94 G. Vollant Created 598 // 599 //************************************************************* 600 BOOL LoadMruInReg(LPMRUMENU lpMruMenu,LPSTR lpszKey) 601 { 602 LPSTR lpTxt; 603 WORD i; 604 HKEY hCurKey; 605 DWORD dwType; 606 lpTxt = (LPSTR)GlobalAllocPtr(GHND,lpMruMenu->wMaxSizeLruItem + 20); 607 if (lpTxt == NULL) 608 return FALSE; 609 610 RegOpenKeyEx(HKEY_CURRENT_USER,lpszKey,0,KEY_READ,&hCurKey); 611 612 613 for (i=0;i<lpMruMenu->wNbLruMenu;i++) 614 { 615 char szEntry[16]; 616 DWORD dwSizeBuf; 617 wsprintf(szEntry,"File%lu",(DWORD)i+1); 618 *lpTxt = '\0'; 619 dwSizeBuf = lpMruMenu->wMaxSizeLruItem + 10; 620 RegQueryValueEx(hCurKey,szEntry,NULL,&dwType,(LPBYTE)lpTxt,&dwSizeBuf); 621 *(lpTxt+dwSizeBuf)='\0'; 622 if (*lpTxt == '\0') 623 break; 624 SetMenuItem(lpMruMenu,i,lpTxt); 625 } 626 RegCloseKey(hCurKey); 627 GlobalFreePtr(lpTxt); 628 return TRUE; 629 } 630 631 632 //************************************************************* 633 // 634 // GetWin32Kind() 635 // 636 // Purpose: 637 // Get the Win32 platform 638 // 639 // Parameters: 640 // 641 // Return: (WIN32KIND) 642 // WINNT - Run under Windows NT 643 // WIN32S - Run under Windows 3.1x + Win32s 644 // WIN95ORGREATHER - Run under Windows 95 645 // 646 // 647 // Comments: 648 // Win32 function designed for Windows NT and Windows 95 649 // See RegOpenKeyEx API for more info on lpszKey 650 // 651 // History: Date Author Comment 652 // 09/24/94 G. Vollant Created 653 // 654 //************************************************************* 655 WIN32KIND GetWin32Kind() 656 { 657 BOOL IsWin395OrHigher(void); 658 659 WORD wVer; 660 661 if ((GetVersion() & 0x80000000) == 0) 662 return WINNT; 663 wVer = LOWORD(GetVersion()); 664 wVer = (((WORD)LOBYTE(wVer)) << 8) | (WORD)HIBYTE(wVer); 665 666 if (wVer >= 0x035F) 667 return WIN95ORGREATHER; 668 else 669 return WIN32S; 670 } 671 #endif