home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 February / Chip_2001-02_cd1.bin / sharewar / vecad / source / mru.cpp < prev    next >
C/C++ Source or Header  |  2000-06-23  |  5KB  |  213 lines

  1. /********************************************************************
  2. * Project: VeCAD ver.5.1
  3. * Copyright (C) 1999-2000 by Oleg Kolbaskin.
  4. * All rights reserved.
  5. *
  6. * Most Recent Files (MRU)
  7. ********************************************************************/
  8. #include <windows.h>
  9. #include <tchar.h>
  10. #include "mru.h"
  11. #include "vecres.h"
  12.  
  13. extern HWND  ghwMain;    // Main App window
  14.  
  15. bool ModifyMenuItem (HMENU hMenu, UINT Cmd, LPCTSTR Text);
  16. static int  _cdecl CmpMruFile (const void* e1, const void* e2);
  17.  
  18.  
  19. //-------------------------------------
  20. CMruFile::CMruFile ()
  21. {
  22.   ::ZeroMemory( szName, sizeof(szName) );
  23.   OpenTime = 0;
  24. }
  25.  
  26.  
  27. //-------------------------------------
  28. void CMruFile::SetName (LPCTSTR szStr)
  29. {
  30.   _tcsncpy( szName, szStr, SZ_MRUFILENAME );
  31.   szName[SZ_MRUFILENAME-1] = 0;
  32.   _tcslwr( szName );
  33. }
  34.  
  35.  
  36.  
  37. //*******************************************************************
  38. CMruList::CMruList ()
  39. {
  40.   n_file = 0;
  41. }
  42.  
  43.  
  44. //-------------------------------------
  45. void CMruList::Add (LPCTSTR szFileName)
  46. {
  47.   int  i;
  48.   bool bExist = false;
  49.  
  50.   for (i=0; i<n_file; i++){
  51.     if (_tcsicmp( szFileName, File[i].GetName())==0){
  52.       File[i].SetTime();
  53.       bExist = true;
  54.       break;  // file already exist in the list
  55.     }
  56.   }
  57.   if (bExist==false){
  58.     if (n_file<MAX_MRU){
  59.       i = n_file++;
  60.     }else{
  61.       i = n_file - 1;
  62.     }
  63.     File[i].SetName( szFileName );
  64.   }
  65.   // sort list and update main menu
  66.   qsort( File, n_file, sizeof(CMruFile), CmpMruFile );
  67.   UpdateMenu();
  68. }
  69.  
  70.  
  71. //-------------------------------------
  72. LPCTSTR CMruList::Get (int Index, bool bSetTime)
  73. {
  74.   static TCHAR szBuf[256];
  75.   ::ZeroMemory( szBuf, sizeof(szBuf) );
  76.   if (0<=Index && Index<n_file){
  77.     _tcscpy( szBuf, File[Index].GetName() );
  78.     if (bSetTime){
  79.       File[Index].SetTime();
  80.       // sort list and update main menu
  81.       qsort( File, n_file, sizeof(CMruFile), CmpMruFile );
  82.       UpdateMenu();
  83.     }
  84.     return szBuf;
  85.   }
  86.   return NULL;
  87. }
  88.  
  89.  
  90. //-------------------------------------
  91. bool CMruList::Load (CConfig& Cfg)
  92. {
  93.   TCHAR  szKey[64], szVal[256];
  94.   HANDLE hFile;
  95.   WIN32_FIND_DATA FindFileData;
  96.   int i,j;
  97.     
  98.   n_file = 0;
  99.   for (i=0; i<MAX_MRU; i++){
  100.     _stprintf( szKey, _T("MRU%02d"), i );
  101.     if (Cfg.GetValue( szKey, szVal )){
  102.       for (j=0; j<n_file; j++){
  103.         if (_tcsicmp( szVal, File[j].GetName())==0){
  104.           j = 1000;  // filename already exist
  105.           break;
  106.         }
  107.       }
  108.       if (j!=1000){
  109.         hFile = ::FindFirstFile( szVal, &FindFileData );
  110.         if (hFile!=INVALID_HANDLE_VALUE){
  111.           FindClose( hFile );
  112.           if (n_file<MAX_MRU){
  113.             File[n_file].SetName( szVal );
  114.             File[n_file].SetTime( MAX_MRU-n_file );
  115.             n_file++;
  116.           }
  117.         }
  118.       }
  119.     }
  120.   }
  121.  
  122.   UpdateMenu();
  123.   return true;
  124. }
  125.  
  126.  
  127. //-------------------------------------
  128. bool CMruList::Save (CConfig& Cfg)
  129. {
  130.   TCHAR szKey[64];
  131.   ::ZeroMemory( szKey, sizeof(szKey) );
  132.  
  133.   qsort( File, n_file, sizeof(CMruFile), CmpMruFile );
  134.   for (int i=0; i<n_file; i++){
  135.     _stprintf( szKey, _T("MRU%02d"), i );
  136.     Cfg.SetValue( szKey, File[i].GetName() );
  137.   }
  138.   return true;
  139. }
  140.  
  141.  
  142. //-------------------------------------
  143. bool CMruList::UpdateMenu ()
  144. {
  145.   int ItemPos = 4; // position of item "Recent" in the "File" popup menu
  146.   HMENU hMainMenu = ::GetMenu( ghwMain );
  147.   int i;
  148.   for (i=0; i<MAX_MRU; i++){
  149.     ::DeleteMenu( hMainMenu, CM_MRU_01+i, MF_BYCOMMAND );
  150.   }
  151.   HMENU hMnu = ::GetSubMenu( hMainMenu, 0 );  // 0 - index of "File" item in main menu
  152.   HMENU hMnu2 = ::GetSubMenu( hMnu, ItemPos ); 
  153.   if (n_file==0){
  154.     ::EnableMenuItem( hMnu, 2, MF_BYPOSITION | MF_GRAYED | MF_DISABLED );
  155.   }else{
  156.     ::EnableMenuItem( hMnu, 2, MF_BYPOSITION | MF_ENABLED );
  157.     if (hMnu2){
  158.       for (i=0; i<n_file; i++){
  159.         ::InsertMenu( hMnu2, i, MF_BYPOSITION, CM_MRU_01+i, _T("!") );
  160.       }
  161.       for (i=0; i<n_file; i++){
  162.         ::ModifyMenuItem( hMainMenu, CM_MRU_01+i, File[i].GetName() );
  163.       }
  164.     }
  165.   }
  166.  
  167.   // update changes of main menu
  168.   ::DrawMenuBar( ghwMain );
  169.  
  170.   return true;
  171. }
  172.  
  173.  
  174.  
  175. //***********************************************
  176. static int _cdecl CmpMruFile (const void* e1, const void* e2)
  177. {
  178.   time_t t1 = ((CMruFile*)e1)->GetTime();
  179.   time_t t2 = ((CMruFile*)e2)->GetTime();
  180.   if (t1<t2) return 1;
  181.   if (t1>t2) return -1;
  182.   return 0;
  183. }
  184.  
  185.  
  186. //***********************************************
  187. bool ModifyMenuItem (HMENU hMenu, UINT Cmd, LPCTSTR Text)
  188. {
  189.   HMENU hSub;
  190.   UINT Id;
  191.   int  i,n;
  192.  
  193.   n=::GetMenuItemCount(hMenu);
  194.   if (n>0){
  195.     for (i=0; i<n; i++){
  196.       hSub=::GetSubMenu(hMenu,i);
  197.       if (hSub){
  198.         if (ModifyMenuItem( hSub, Cmd, Text )){
  199.           return true;
  200.         }
  201.       }else{
  202.         Id=::GetMenuItemID(hMenu,i);
  203.         if (Id==Cmd){
  204.           ::ModifyMenu( hMenu, i, MF_BYPOSITION, Cmd, Text );
  205.           return true;
  206.         }
  207.       }
  208.     }
  209.   }
  210.   return false;
  211. }
  212.  
  213.