Maintain MRU List

Category: Application Features

Date: 02-16-2022

Return to Index


 
'A MRU (most recently used) list contains the last files opened
'or saved by an application.  The list is often displayed as submenus
'under the File menu, or as a drop down list in the toolbar under an
'Open button.  The list is usually saved between sessions in a simple text file,
'the Windows Registry, or an INI file.
 
'This compilable example places the entries below "Exit" in the File
'menu and stores values between sessions in an INI file. During program
'execution, the list is maintained in an array. In this example, an Opened
'file is added to the top of the list, with up to 10 MRU entries.
'The MRU list is read on startup and saved when the app ends.
 
'Primary Code:
'The heart of the MRU code is in these 4 Sub procedures.
'1. AddFileToOpenMRUArray  - adds Opened file, removes duplicates
'2. ClearOpenMRUList - clears array and menu entries
'3. PutOpenMURListInFileMenu - clears menu entries, then reloads array of MRUs
'4. Settings_INI - read MRU list on startup, save on exit
 
Sub AddFileToOpenMRUArray(NewPath$)
   Local i As Long
   NewPath$ = LCase$(NewPath$)              'work in lower case
   Array Scan OpenMRU(), = NewPath$,  To i  'scan for duplicate of NewPath$
   If i Then Array Delete OpenMRU(i-1)      'remove duplicate, if found
      Array Insert OpenMRU(0), NewPath$     'put newpath$ at top of array OpenMRU()
End Sub
 
Sub ClearOpenMRUList
   Local i As Long
   ReDim OpenMRU(9)              'clear the array containing OpenMRU file names
   Menu Delete hMenuFile, 5      'remove the separator after Exit
   For i = 0 To 9 : Menu Delete hMenuFile, ByCmd 251+i : Next i 'remove the hMenu items
      PutMRUInLabel
End Sub
 
Sub PutOpenMRUListInFileMenu
   Local i As Long, OneTime As Long
   Menu Delete hMenuFile, 5                                           'remove existing separator after Exit
   For i = 0 To 9 : Menu Delete hMenuFile, ByCmd 251+i : Next i       'remove existing MRU entries
      If OpenMRU(0) <> "Then Menu Add String, hMenuFile, "-", 0, 0  'add sep after Exit only if MRUs exist
         For i = 0 To 9
            If OpenMRU(i) <> "Then
               Menu Add String, hMenuFile, OpenMRU(i), 251+i, %MF_Enabled
            End If
         Next i
End Sub
 
Sub Settings_INI(Task$)
   Local i As Long, tempASCIIZ As Asciiz * %Max_Path, INIFileName As Asciiz * %Max_Path
   INIFileName = Exe.Path$ + "mru.ini"
   Select Case task$
      Case "get"
         For i = 0 To 9
            Getprivateprofilestring "OpenMRU", "OpenMRU" + Format$(i,"00"), "", tempASCIIZ, %Max_Path, INIFileName
            OpenMRU(i) = tempASCIIZ
         Next i
      Case "save"
         For i = 0 To 9
            tempASCIIZ = OpenMRU(i)
            WritePrivateProfileString "OpenMRU", "OpenMRU" + Format$(i,"00"), tempASCIIZ, INIFileName
         Next i
   End Select
End Sub
 
 
'Compilable Example:  (Jose Includes)
'this example includes an Open menu item. It doesn't actually open anything, just
'captures the name of the file selected and adds it to the MRU list.
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "Win32api.inc"
%IDM_Open = 400 : %IDM_ClearOpenMRU = 401 : %IDM_Exit = 403
%IDM_Cut = 500  : %IDM_Copy = 502         : %IDM_Paste = 503
%IDM_Sep = 250  : %IDC_Label = 700
 
Global hDlg As DWord, OpenMRU() As String, CurrentFileName$
Global hMenu As DWord, hMenuFile As DWord, hMenuEdit As DWord
 
Function PBMain()
   ReDim OpenMRU(9)
   Dialog New Pixels, 0, "MRU Demo",300,300,500,300, %WS_OverlappedWindow To hDlg
   Control Add Label, hDlg, %IDC_Label, "<MRU Entries>", 20,20,460,240, %WS_Border
   AddMenu
   Dialog Show Modal hDlg Call DlgProc()
End Function
 
CallBack Function DlgProc() As Long
   Local temp$
   Select Case CB.Msg
      Case %WM_InitDialog
         Settings_INI "get"
         PutOpenMRUListInFileMenu     'ID 251-260 reserved for MRU items
         PutMRUInLabel
      Case %WM_Destroy
         Settings_INI "save"
      Case %WM_Command
         Select Case CB.Ctl
            Case %IDM_Open         : SelectFileToOpen
            Case %IDM_ClearOpenMRU : ClearOpenMRUList
            Case %IDM_Exit         : Dialog End hDlg
            Case %IDM_Cut          'no action - just for display
            Case %IDM_Copy         'no action - just for display
            Case %IDM_Paste        'no action - just for display
            Case 251 To 260        'the 10 Open MRU entries under the File menu
               If CB.Ctlmsg = %BN_Clicked Then         '%ID values 251-260 used for MRU list
                  Menu Get Text hMenuFile, ByCmd CB.Ctl To temp$
                  AddFileToOpenMRUArray temp$   'moves to top of list
                  PutOpenMRUListInFileMenu      'reload Menu items
                  PutMRUInLabel
                  MsgBox "Request to open:" + $crlf + $crlf + temp$
               End If
         End Select
   End Select
End Function
 
Sub AddFileToOpenMRUArray(NewPath$)
   Local i As Long
   NewPath$ = LCase$(NewPath$)              'work in lower case
   Array Scan OpenMRU(), = NewPath$,  To i  'scan for duplicate of NewPath$
   If i Then Array Delete OpenMRU(i-1)      'remove duplicate, if found
   Array Insert OpenMRU(0), NewPath$        'put newpath$ at top of array OpenMRU()
End Sub
 
Sub ClearOpenMRUList
   Local i As Long
   ReDim OpenMRU(9)              'clear the array containing OpenMRU file names
   Menu Delete hMenuFile, 5      'remove the separator after Exit
   For i = 0 To 9 : Menu Delete hMenuFile, ByCmd 251+i : Next i 'remove the hMenu items
   PutMRUInLabel
End Sub
 
Sub PutOpenMRUListInFileMenu
   Local i As Long, OneTime As Long
   Menu Delete hMenuFile, 5                                     'remove existing separator after Exit
   For i = 0 To 9 : Menu Delete hMenuFile, ByCmd 251+i : Next i 'remove existing MRU entries
   If OpenMRU(0) <> "Then Menu Add String, hMenuFile, "-", 0, 0  'add sep after Exit only if MRUs exist
   For i = 0 To 9
      If OpenMRU(i) <> "Then
         Menu Add String, hMenuFile, OpenMRU(i), 251+i, %MF_Enabled
      End If
   Next i
End Sub
 
Sub Settings_INI(Task$)
   Local i As Long, tempASCIIZ As Asciiz * %Max_Path, INIFileName As Asciiz * %Max_Path
   INIFileName = Exe.Path$ + "mru.ini"
   Select Case task$
      Case "get"
         For i = 0 To 9
            Getprivateprofilestring "OpenMRU", "OpenMRU" + Format$(i,"00"), "", tempASCIIZ, %Max_Path, INIFileName
            OpenMRU(i) = tempASCIIZ
         Next i
      Case "save"
         For i = 0 To 9
            tempASCIIZ = OpenMRU(i)
            WritePrivateProfileString "OpenMRU", "OpenMRU" + Format$(i,"00"), tempASCIIZ, INIFileName
         Next i
   End Select
End Sub
 
Sub SelectFileToOpen
   Local title$, filter$, startfile$, startfolder$
   Local defaultext$, flags&, filevar$, countvar&
   filter$ = Chr$("Data",0,"*.txt",0)
   startfolder$ = CurrentFileName$     'initial folder to be displayed
   startfile$ = CurrentFileName$       'name to be used as initial selection
   defaultext$ = "txt"                 'default extension to append to selection if user does not enter it
   flags& = %OFN_Explorer Or %OFN_FileMustExist Or %OFN_HideReadOnly
   Display OpenFile hDlg, 100, 100, "", startfolder$, filter$, startfile$, _
      defaultext$, flags& To filevar$, countvar&
   If IsFile(filevar$) Then
      CurrentFileName$ = filevar$
      AddFileToOpenMRUArray CurrentFileName$
      PutOpenMRUListInFileMenu      'reload Menu items
      PutMRUInLabel
   End If
End Sub
 
Sub AddMenu()
   Menu New Bar To hMenu
   Menu New Popup To hMenuEdit
   Menu New Popup To hMenuFile
 
   'Create File + Children -------------------------
   Menu Add Popup, hMenu, "&File", hMenuFile, %MF_Enabled
   Menu Add String, hMenuFile, "&Open" + $Tab + "Ctrl-O", %IDM_Open, %MF_Enabled
   Menu Add String, hMenuFile, "&Clear MRU" + $Tab + "Ctrl-O", %IDM_ClearOpenMRU, %MF_Enabled
   Menu Add String, hMenuFile, "-", %IDM_Sep, 0
   Menu Add String, hMenuFile, "E&xit", %IDM_Exit, %MF_Enabled
 
   'Create Edit + Children -------------------------
   Menu Add Popup, hMenu, "&Edit", hMenuEdit, %MF_Enabled
   Menu Add String, hMenuEdit, "&Cut", %IDM_Cut, %MF_Enabled
   Menu Add String, hMenuEdit, "C&opy", %IDM_Copy, %MF_Enabled
   Menu Add String, hMenuEdit, "&Paste", %IDM_Paste, %MF_Enabled
   Menu Attach hMenu, hDlg
End Sub
 
Sub PutMRUInLabel
   If OpenMRU(0) = "Then
      Control Set Text hDlg, %IDC_Label, "MRU List Empty"
   Else
      Control Set Text hDlg, %IDC_Label, "MRU List  (see File Menu for clickable list): " + Join$(OpenMRU(), $CrLf)
   End If
End Sub
 
'gbs_00046
'Date: 03-10-2012


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm