Date: 02-16-2022
Return to Index
created by gbSnippets
'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
http://www.garybeene.com/sw/gbsnippets.htm