2024-03-20 07:46:28 +01:00
|
|
|
|
/*
|
|
|
|
|
* mru.c
|
|
|
|
|
*
|
|
|
|
|
* This file is part of Emu48
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) 2007 Christoph Gie<EFBFBD>elink
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
#include "pch.h"
|
|
|
|
|
#include "resource.h"
|
|
|
|
|
#include "Emu48.h"
|
|
|
|
|
|
|
|
|
|
static TCHAR szOriginal[MAX_PATH] = _T("");
|
|
|
|
|
|
|
|
|
|
static LPTSTR *ppszFiles = NULL; // pointer to MRU table
|
|
|
|
|
static INT nEntry = 0; // no. of MRU entries
|
|
|
|
|
|
|
|
|
|
static HMENU hMruMenu = NULL; // menu handle for MRU list
|
|
|
|
|
static INT nMruPos; // insert position for MRU list
|
|
|
|
|
|
|
|
|
|
static BOOL GetMenuPosForId(HMENU hMenu, UINT nItem)
|
|
|
|
|
{
|
|
|
|
|
HMENU hSubMenu;
|
|
|
|
|
UINT nID;
|
|
|
|
|
INT i,nMaxID;
|
|
|
|
|
|
|
|
|
|
nMaxID = GetMenuItemCount(hMenu);
|
|
|
|
|
for (i = 0; i < nMaxID; ++i)
|
|
|
|
|
{
|
|
|
|
|
nID = GetMenuItemID(hMenu,i); // get ID
|
|
|
|
|
|
|
|
|
|
if (nID == 0) continue; // separator or invalid command
|
|
|
|
|
|
|
|
|
|
if (nID == (UINT)-1) // possibly a popup menu
|
|
|
|
|
{
|
|
|
|
|
hSubMenu = GetSubMenu(hMenu,i); // try to get handle to popup menu
|
|
|
|
|
if (hSubMenu != NULL) // it's a popup menu
|
|
|
|
|
{
|
|
|
|
|
// recursive search
|
|
|
|
|
if (GetMenuPosForId(hSubMenu,nItem))
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nID == nItem) // found ID
|
|
|
|
|
{
|
|
|
|
|
hMruMenu = hMenu; // remember menu and position
|
|
|
|
|
nMruPos = i;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL MruInit(INT nNum)
|
|
|
|
|
{
|
|
|
|
|
HMENU hMenu = GetMenu(hWnd); // main menu
|
|
|
|
|
|
|
|
|
|
_ASSERT(ppszFiles == NULL); // MRU already initialized
|
|
|
|
|
|
|
|
|
|
if (*szOriginal == 0) // get orginal value of first MRU entry
|
|
|
|
|
{
|
|
|
|
|
VERIFY(GetMenuString(hMenu,ID_FILE_MRU_FILE1,szOriginal,ARRAYSIZEOF(szOriginal),MF_BYCOMMAND));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// no. of files in MRU list
|
|
|
|
|
nEntry = ReadSettingsInt(_T("MRU"),_T("FileCount"),nNum);
|
|
|
|
|
|
|
|
|
|
// look for menu position of ID_FILE_MRU_FILE1
|
|
|
|
|
VERIFY(GetMenuPosForId(hMenu,ID_FILE_MRU_FILE1));
|
|
|
|
|
|
|
|
|
|
if (nEntry > 0) // allocate MRU table
|
|
|
|
|
{
|
|
|
|
|
// create MRU table
|
|
|
|
|
if ((ppszFiles = HeapAlloc(hHeap,0,nEntry * sizeof(*ppszFiles))) == NULL)
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
|
|
// fill each entry
|
|
|
|
|
for (nNum = 0; nNum < nEntry; ++nNum)
|
|
|
|
|
ppszFiles[nNum] = NULL;
|
|
|
|
|
|
|
|
|
|
MruReadList(); // read actual MRU list
|
|
|
|
|
MruUpdateMenu(); // update menu
|
|
|
|
|
}
|
|
|
|
|
else // kill MRU menu entries
|
|
|
|
|
{
|
|
|
|
|
// delete MRU menu
|
|
|
|
|
DeleteMenu(hMruMenu,nMruPos,MF_BYPOSITION);
|
|
|
|
|
|
|
|
|
|
// delete following separator
|
|
|
|
|
_ASSERT((GetMenuState(hMruMenu,nMruPos,MF_BYPOSITION) & MF_SEPARATOR) != 0);
|
|
|
|
|
DeleteMenu(hMruMenu,nMruPos,MF_BYPOSITION);
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID MruCleanup(VOID)
|
|
|
|
|
{
|
|
|
|
|
INT i;
|
|
|
|
|
|
|
|
|
|
MruWriteList(); // write actual MRU list
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < nEntry; ++i) // cleanup each entry
|
|
|
|
|
{
|
|
|
|
|
if (ppszFiles[i] != NULL)
|
|
|
|
|
HeapFree(hHeap,0,ppszFiles[i]); // cleanup entry
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ppszFiles != NULL) // table defined
|
|
|
|
|
{
|
|
|
|
|
HeapFree(hHeap,0,ppszFiles); // free table
|
|
|
|
|
ppszFiles = NULL;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID MruAdd(LPCTSTR lpszEntry)
|
|
|
|
|
{
|
|
|
|
|
TCHAR szFilename[MAX_PATH];
|
|
|
|
|
LPTSTR lpFilePart;
|
|
|
|
|
INT i;
|
|
|
|
|
|
|
|
|
|
if (nEntry == 0) return; // no entries
|
|
|
|
|
|
|
|
|
|
// get full path name
|
|
|
|
|
GetFullPathName(lpszEntry,ARRAYSIZEOF(szFilename),szFilename,&lpFilePart);
|
|
|
|
|
|
|
|
|
|
// look if entry is already in table
|
|
|
|
|
for (i = 0; i < nEntry; ++i)
|
|
|
|
|
{
|
|
|
|
|
// already in table -> quit
|
|
|
|
|
if ( ppszFiles[i] != NULL
|
|
|
|
|
&& lstrcmpi(ppszFiles[i],szFilename) == 0)
|
|
|
|
|
{
|
2024-03-20 07:46:28 +01:00
|
|
|
|
MruMoveTop(i); // move to top and update menu
|
2024-03-20 07:46:28 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = nEntry - 1; // last index
|
|
|
|
|
if (ppszFiles[i] != NULL)
|
|
|
|
|
HeapFree(hHeap,0,ppszFiles[i]); // free oldest entry
|
|
|
|
|
|
|
|
|
|
for (; i > 0; --i) // move old entries 1 line down
|
|
|
|
|
{
|
|
|
|
|
ppszFiles[i] = ppszFiles[i-1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// add new entry to top
|
|
|
|
|
ppszFiles[0] = DuplicateString(szFilename);
|
|
|
|
|
|
|
|
|
|
MruUpdateMenu(); // update menu
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID MruRemove(INT nIndex)
|
|
|
|
|
{
|
|
|
|
|
HeapFree(hHeap,0,ppszFiles[nIndex]); // free entry
|
|
|
|
|
|
2024-03-20 07:46:28 +01:00
|
|
|
|
for (; nIndex < nEntry - 1; ++nIndex) // move below entries 1 line up
|
2024-03-20 07:46:28 +01:00
|
|
|
|
{
|
|
|
|
|
ppszFiles[nIndex] = ppszFiles[nIndex+1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ppszFiles[nIndex] = NULL; // clear last line
|
|
|
|
|
|
|
|
|
|
MruUpdateMenu(); // update menu
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-20 07:46:28 +01:00
|
|
|
|
VOID MruMoveTop(INT nIndex)
|
|
|
|
|
{
|
|
|
|
|
LPTSTR lpszEntry = ppszFiles[nIndex]; // remember selected entry
|
|
|
|
|
|
|
|
|
|
for (; nIndex > 0; --nIndex) // move above entries 1 line down
|
|
|
|
|
{
|
|
|
|
|
ppszFiles[nIndex] = ppszFiles[nIndex-1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ppszFiles[0] = lpszEntry; // insert entry on top
|
|
|
|
|
|
|
|
|
|
MruUpdateMenu(); // update menu
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-20 07:46:28 +01:00
|
|
|
|
INT MruEntries(VOID)
|
|
|
|
|
{
|
|
|
|
|
return nEntry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LPCTSTR MruFilename(INT nIndex)
|
|
|
|
|
{
|
|
|
|
|
_ASSERT(ppszFiles != NULL); // MRU not initialized
|
|
|
|
|
_ASSERT(nIndex >= 0 && nIndex < nEntry); // inside range
|
|
|
|
|
return ppszFiles[nIndex];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID MruUpdateMenu(VOID)
|
|
|
|
|
{
|
|
|
|
|
TCHAR szCurPath[MAX_PATH];
|
|
|
|
|
HANDLE hMenu;
|
|
|
|
|
BOOL bEmpty;
|
|
|
|
|
INT i;
|
|
|
|
|
|
|
|
|
|
if (nEntry == 0) return; // no entries
|
|
|
|
|
|
|
|
|
|
_ASSERT(ppszFiles != NULL); // MRU not initialized
|
|
|
|
|
_ASSERT(hWnd != NULL);
|
|
|
|
|
VERIFY(hMenu = GetMenu(hWnd)); // main menu
|
|
|
|
|
|
|
|
|
|
bEmpty = TRUE; // MRU list empty
|
|
|
|
|
for (i = 0; i < nEntry; ++i) // delete all menu entries
|
|
|
|
|
{
|
|
|
|
|
DeleteMenu(hMenu,ID_FILE_MRU_FILE1+i,MF_BYCOMMAND);
|
|
|
|
|
|
|
|
|
|
if (ppszFiles[i] != NULL) // valid entry
|
|
|
|
|
bEmpty = FALSE; // MRU list not empty
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bEmpty) // empty MRU list
|
|
|
|
|
{
|
|
|
|
|
// fill with orginal string
|
|
|
|
|
VERIFY(InsertMenu(hMruMenu,nMruPos,MF_STRING|MF_BYPOSITION|MF_GRAYED,ID_FILE_MRU_FILE1,szOriginal));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// current directory
|
|
|
|
|
GetCurrentDirectory(ARRAYSIZEOF(szCurPath),szCurPath);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < nEntry; ++i) // add menu entries
|
|
|
|
|
{
|
|
|
|
|
if (ppszFiles[i] != NULL) // valid entry
|
|
|
|
|
{
|
|
|
|
|
TCHAR szMenuname[2*MAX_PATH+3];
|
|
|
|
|
TCHAR szFilename[MAX_PATH];
|
|
|
|
|
LPTSTR lpFilePart,lpszPtr;
|
|
|
|
|
|
|
|
|
|
// check if file path and current path is identical
|
|
|
|
|
if (GetFullPathName(ppszFiles[i],ARRAYSIZEOF(szFilename),szFilename,&lpFilePart))
|
|
|
|
|
{
|
|
|
|
|
TCHAR szCutname[MAX_PATH];
|
|
|
|
|
|
|
|
|
|
*(lpFilePart-1) = 0; // devide path and name
|
|
|
|
|
|
|
|
|
|
// name is current directory -> use only name
|
|
|
|
|
if (lstrcmpi(szCurPath,szFilename) == 0)
|
|
|
|
|
{
|
|
|
|
|
// short name view
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// full name view
|
|
|
|
|
lpFilePart = ppszFiles[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// cut filename to fit into menu
|
|
|
|
|
GetCutPathName(lpFilePart,szCutname,ARRAYSIZEOF(szCutname),36);
|
|
|
|
|
lpFilePart = szCutname;
|
|
|
|
|
|
|
|
|
|
lpszPtr = szMenuname; // adding accelerator key
|
|
|
|
|
*lpszPtr++ = _T('&');
|
|
|
|
|
*lpszPtr++ = _T('0') + ((i + 1) % 10);
|
|
|
|
|
*lpszPtr++ = _T(' ');
|
|
|
|
|
|
|
|
|
|
// copy file to view buffer and expand & to &&
|
|
|
|
|
while (*lpFilePart != 0)
|
|
|
|
|
{
|
|
|
|
|
if (*lpFilePart == _T('&'))
|
|
|
|
|
{
|
|
|
|
|
*lpszPtr++ = *lpFilePart;
|
|
|
|
|
}
|
|
|
|
|
*lpszPtr++ = *lpFilePart++;
|
|
|
|
|
}
|
|
|
|
|
*lpszPtr = 0;
|
|
|
|
|
|
|
|
|
|
VERIFY(InsertMenu(hMruMenu,nMruPos+i,MF_STRING|MF_BYPOSITION,ID_FILE_MRU_FILE1+i,szMenuname));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID MruWriteList(VOID)
|
|
|
|
|
{
|
|
|
|
|
TCHAR szItemname[32];
|
|
|
|
|
INT i;
|
|
|
|
|
|
|
|
|
|
// no. of files in MRU list
|
|
|
|
|
WriteSettingsInt(_T("MRU"),_T("FileCount"),nEntry);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < nEntry; ++i) // add menu entries
|
|
|
|
|
{
|
|
|
|
|
_ASSERT(ppszFiles != NULL); // MRU not initialized
|
|
|
|
|
wsprintf(szItemname,_T("File%d"),i+1);
|
|
|
|
|
if (ppszFiles[i] != NULL)
|
|
|
|
|
{
|
|
|
|
|
WriteSettingsString(_T("MRU"),szItemname,ppszFiles[i]);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DelSettingsKey(_T("MRU"),szItemname);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID MruReadList(VOID)
|
|
|
|
|
{
|
|
|
|
|
TCHAR szFilename[MAX_PATH];
|
|
|
|
|
TCHAR szItemname[32];
|
|
|
|
|
LPTSTR lpszValue;
|
|
|
|
|
INT i;
|
|
|
|
|
|
|
|
|
|
_ASSERT(ppszFiles != NULL); // MRU not initialized
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < nEntry; ++i) // add menu entries
|
|
|
|
|
{
|
|
|
|
|
wsprintf(szItemname,_T("File%d"),i+1);
|
|
|
|
|
ReadSettingsString(_T("MRU"),szItemname,_T(""),szFilename,ARRAYSIZEOF(szFilename));
|
|
|
|
|
|
|
|
|
|
if (ppszFiles[i] != NULL) // already filled
|
|
|
|
|
{
|
|
|
|
|
HeapFree(hHeap,0,ppszFiles[i]); // free entry
|
|
|
|
|
ppszFiles[i] = NULL; // clear last line
|
|
|
|
|
lpszValue = _T("");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (*szFilename) // read a valid entry
|
|
|
|
|
{
|
|
|
|
|
ppszFiles[i] = DuplicateString(szFilename);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|