wordpad: Add recent file list.
This commit is contained in:
parent
e5e41191b3
commit
07d60bc727
|
@ -22,11 +22,17 @@
|
|||
#define ID_FILE_NEW 1003
|
||||
#define ID_FILE_SAVEAS 1004
|
||||
|
||||
#define ID_PRINT 1005
|
||||
#define ID_PREVIEW 1006
|
||||
#define ID_FILE_RECENT1 1005
|
||||
#define ID_FILE_RECENT2 1006
|
||||
#define ID_FILE_RECENT3 1007
|
||||
#define ID_FILE_RECENT4 1008
|
||||
#define ID_FILE_RECENT_SEPARATOR 1009
|
||||
|
||||
#define ID_FIND 1007
|
||||
#define ID_FIND_NEXT 1008
|
||||
#define ID_PRINT 1010
|
||||
#define ID_PREVIEW 1011
|
||||
|
||||
#define ID_FIND 1012
|
||||
#define ID_FIND_NEXT 1013
|
||||
|
||||
#define ID_ALIGN_LEFT 1100
|
||||
#define ID_ALIGN_CENTER 1101
|
||||
|
@ -62,6 +68,9 @@
|
|||
#define BANDID_TOOLBAR 0
|
||||
#define BANDID_FORMATBAR 1
|
||||
|
||||
#define FILELIST_ENTRIES 4
|
||||
#define FILELIST_ENTRY_LENGTH 33
|
||||
|
||||
#define ID_DATETIME 1600
|
||||
|
||||
#define IDC_STATUSBAR 2000
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <richedit.h>
|
||||
#include <commctrl.h>
|
||||
#include <commdlg.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
|
@ -43,6 +44,11 @@ static const WCHAR wszRichEditClass[] = {'R','I','C','H','E','D','I','T','2','0'
|
|||
static const WCHAR wszMainWndClass[] = {'W','O','R','D','P','A','D','T','O','P',0};
|
||||
static const WCHAR wszAppTitle[] = {'W','i','n','e',' ','W','o','r','d','p','a','d',0};
|
||||
|
||||
static const WCHAR key_recentfiles[] = {'R','e','c','e','n','t',' ','f','i','l','e',
|
||||
' ','l','i','s','t',0};
|
||||
|
||||
static const WCHAR var_file[] = {'F','i','l','e','%','d',0};
|
||||
|
||||
static HWND hMainWnd;
|
||||
static HWND hEditorWnd;
|
||||
static HWND hFindWnd;
|
||||
|
@ -142,6 +148,22 @@ static DWORD CALLBACK stream_out(DWORD_PTR cookie, LPBYTE buffer, LONG cb, LONG
|
|||
return 0;
|
||||
}
|
||||
|
||||
static LPWSTR file_basename(LPWSTR path)
|
||||
{
|
||||
LPWSTR pos = path + lstrlenW(path);
|
||||
|
||||
while(pos > path)
|
||||
{
|
||||
if(*pos == '\\' || *pos == '/')
|
||||
{
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
pos--;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
static WCHAR wszFileName[MAX_PATH];
|
||||
|
||||
static void set_caption(LPCWSTR wszNewFileName)
|
||||
|
@ -170,6 +192,238 @@ static void set_caption(LPCWSTR wszNewFileName)
|
|||
HeapFree(GetProcessHeap(), 0, wszCaption);
|
||||
}
|
||||
|
||||
static LRESULT registry_get_handle(HKEY *hKey, LPDWORD action, LPCWSTR subKey)
|
||||
{
|
||||
LONG ret;
|
||||
static const WCHAR wszProgramKey[] = {'S','o','f','t','w','a','r','e','\\',
|
||||
'M','i','c','r','o','s','o','f','t','\\',
|
||||
'W','i','n','d','o','w','s','\\',
|
||||
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
|
||||
'A','p','p','l','e','t','s','\\',
|
||||
'W','o','r','d','p','a','d',0};
|
||||
LPWSTR key = (LPWSTR)wszProgramKey;
|
||||
|
||||
if(subKey)
|
||||
{
|
||||
WCHAR backslash[] = {'\\',0};
|
||||
key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
(lstrlenW(wszProgramKey)+lstrlenW(subKey)+lstrlenW(backslash)+1)
|
||||
*sizeof(WCHAR));
|
||||
|
||||
if(!key)
|
||||
return 1;
|
||||
|
||||
lstrcpyW(key, wszProgramKey);
|
||||
lstrcatW(key, backslash);
|
||||
lstrcatW(key, subKey);
|
||||
}
|
||||
|
||||
if(action)
|
||||
{
|
||||
ret = RegCreateKeyExW(HKEY_CURRENT_USER, key, 0, NULL, REG_OPTION_NON_VOLATILE,
|
||||
KEY_READ | KEY_WRITE, NULL, hKey, action);
|
||||
} else
|
||||
{
|
||||
ret = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ | KEY_WRITE, hKey);
|
||||
}
|
||||
|
||||
if(subKey)
|
||||
HeapFree(GetProcessHeap(), 0, key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void truncate_path(LPWSTR file, LPWSTR out, LPWSTR pos1, LPWSTR pos2)
|
||||
{
|
||||
static const WCHAR dots[] = {'.','.','.',0};
|
||||
|
||||
*++pos1 = 0;
|
||||
|
||||
lstrcatW(out, file);
|
||||
lstrcatW(out, dots);
|
||||
lstrcatW(out, pos2);
|
||||
}
|
||||
|
||||
static void format_filelist_filename(LPWSTR file, LPWSTR out)
|
||||
{
|
||||
LPWSTR pos_basename;
|
||||
LPWSTR truncpos1, truncpos2;
|
||||
WCHAR myDocs[MAX_STRING_LEN];
|
||||
|
||||
SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, (LPWSTR)&myDocs);
|
||||
pos_basename = file_basename(file);
|
||||
truncpos1 = NULL;
|
||||
truncpos2 = NULL;
|
||||
|
||||
*(pos_basename-1) = 0;
|
||||
if(!lstrcmpiW(file, myDocs) || (lstrlenW(pos_basename) > FILELIST_ENTRY_LENGTH))
|
||||
{
|
||||
truncpos1 = pos_basename;
|
||||
*(pos_basename-1) = '\\';
|
||||
} else
|
||||
{
|
||||
LPWSTR pos;
|
||||
BOOL morespace = FALSE;
|
||||
|
||||
*(pos_basename-1) = '\\';
|
||||
|
||||
for(pos = file; pos < pos_basename; pos++)
|
||||
{
|
||||
if(*pos == '\\' || *pos == '/')
|
||||
{
|
||||
if(truncpos1)
|
||||
{
|
||||
if((pos - file + lstrlenW(pos_basename)) > FILELIST_ENTRY_LENGTH)
|
||||
break;
|
||||
|
||||
truncpos1 = pos;
|
||||
morespace = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if((pos - file + lstrlenW(pos_basename)) > FILELIST_ENTRY_LENGTH)
|
||||
break;
|
||||
|
||||
truncpos1 = pos;
|
||||
}
|
||||
}
|
||||
|
||||
if(morespace)
|
||||
{
|
||||
for(pos = pos_basename; pos >= truncpos1; pos--)
|
||||
{
|
||||
if(*pos == '\\' || *pos == '/')
|
||||
{
|
||||
if((truncpos1 - file + lstrlenW(pos_basename) + pos_basename - pos) > FILELIST_ENTRY_LENGTH)
|
||||
break;
|
||||
|
||||
truncpos2 = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(truncpos1 == pos_basename)
|
||||
lstrcatW(out, pos_basename);
|
||||
else if(truncpos1 == truncpos2 || !truncpos2)
|
||||
lstrcatW(out, file);
|
||||
else
|
||||
truncate_path(file, out, truncpos1, truncpos2 ? truncpos2 : (pos_basename-1));
|
||||
}
|
||||
|
||||
static void registry_read_filelist(HWND hMainWnd)
|
||||
{
|
||||
HKEY hFileKey;
|
||||
|
||||
if(registry_get_handle(&hFileKey, 0, key_recentfiles) == ERROR_SUCCESS)
|
||||
{
|
||||
WCHAR itemText[MAX_PATH+3], buffer[MAX_PATH];
|
||||
/* The menu item name is not the same as the file name, so we need to store
|
||||
the file name here */
|
||||
static WCHAR file1[MAX_PATH], file2[MAX_PATH], file3[MAX_PATH], file4[MAX_PATH];
|
||||
WCHAR numFormat[] = {'&','%','d',' ',0};
|
||||
LPWSTR pFile[] = {file1, file2, file3, file4};
|
||||
DWORD pathSize = MAX_PATH*sizeof(WCHAR);
|
||||
int i;
|
||||
WCHAR key[6];
|
||||
MENUITEMINFOW mi;
|
||||
HMENU hMenu = GetMenu(hMainWnd);
|
||||
|
||||
mi.cbSize = sizeof(MENUITEMINFOW);
|
||||
mi.fMask = MIIM_ID | MIIM_DATA | MIIM_STRING | MIIM_FTYPE;
|
||||
mi.fType = MFT_STRING;
|
||||
mi.dwTypeData = itemText;
|
||||
mi.wID = ID_FILE_RECENT1;
|
||||
|
||||
RemoveMenu(hMenu, ID_FILE_RECENT_SEPARATOR, MF_BYCOMMAND);
|
||||
for(i = 0; i < FILELIST_ENTRIES; i++)
|
||||
{
|
||||
wsprintfW(key, var_file, i+1);
|
||||
RemoveMenu(hMenu, ID_FILE_RECENT1+i, MF_BYCOMMAND);
|
||||
if(RegQueryValueExW(hFileKey, (LPWSTR)key, 0, NULL, (LPBYTE)pFile[i], &pathSize)
|
||||
!= ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
mi.dwItemData = (DWORD)pFile[i];
|
||||
wsprintfW(itemText, numFormat, i+1);
|
||||
|
||||
lstrcpyW(buffer, pFile[i]);
|
||||
|
||||
format_filelist_filename(buffer, itemText);
|
||||
|
||||
InsertMenuItemW(hMenu, ID_FILE_EXIT, FALSE, &mi);
|
||||
mi.wID++;
|
||||
pathSize = MAX_PATH*sizeof(WCHAR);
|
||||
}
|
||||
mi.fType = MFT_SEPARATOR;
|
||||
mi.fMask = MIIM_FTYPE | MIIM_ID;
|
||||
InsertMenuItemW(hMenu, ID_FILE_EXIT, FALSE, &mi);
|
||||
|
||||
RegCloseKey(hFileKey);
|
||||
}
|
||||
}
|
||||
|
||||
static void registry_set_filelist(LPCWSTR newFile)
|
||||
{
|
||||
HKEY hKey;
|
||||
DWORD action;
|
||||
|
||||
if(registry_get_handle(&hKey, &action, key_recentfiles) == ERROR_SUCCESS)
|
||||
{
|
||||
LPCWSTR pFiles[FILELIST_ENTRIES];
|
||||
int i;
|
||||
HMENU hMenu = GetMenu(hMainWnd);
|
||||
MENUITEMINFOW mi;
|
||||
WCHAR buffer[6];
|
||||
|
||||
mi.cbSize = sizeof(MENUITEMINFOW);
|
||||
mi.fMask = MIIM_DATA;
|
||||
|
||||
for(i = 0; i < FILELIST_ENTRIES; i++)
|
||||
pFiles[i] = NULL;
|
||||
|
||||
for(i = 0; GetMenuItemInfoW(hMenu, ID_FILE_RECENT1+i, FALSE, &mi); i++)
|
||||
pFiles[i] = (LPWSTR)mi.dwItemData;
|
||||
|
||||
if(lstrcmpiW(newFile, pFiles[0]))
|
||||
{
|
||||
for(i = 0; pFiles[i] && i < FILELIST_ENTRIES; i++)
|
||||
{
|
||||
if(!lstrcmpiW(pFiles[i], newFile))
|
||||
{
|
||||
int j;
|
||||
for(j = 0; pFiles[j] && j < i; j++)
|
||||
{
|
||||
pFiles[i-j] = pFiles[i-j-1];
|
||||
}
|
||||
pFiles[0] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!pFiles[0])
|
||||
{
|
||||
pFiles[0] = newFile;
|
||||
} else
|
||||
{
|
||||
for(i = 0; pFiles[i] && i < FILELIST_ENTRIES-1; i++)
|
||||
pFiles[FILELIST_ENTRIES-1-i] = pFiles[FILELIST_ENTRIES-2-i];
|
||||
|
||||
pFiles[0] = newFile;
|
||||
}
|
||||
|
||||
for(i = 0; pFiles[i] && i < FILELIST_ENTRIES; i++)
|
||||
{
|
||||
wsprintfW(buffer, var_file, i+1);
|
||||
RegSetValueExW(hKey, (LPWSTR)&buffer, 0, REG_SZ, (LPBYTE)pFiles[i],
|
||||
(lstrlenW(pFiles[i])+1)*sizeof(WCHAR));
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
registry_read_filelist(hMainWnd);
|
||||
}
|
||||
|
||||
static void DoOpenFile(LPCWSTR szOpenFileName)
|
||||
{
|
||||
HANDLE hFile;
|
||||
|
@ -194,6 +448,7 @@ static void DoOpenFile(LPCWSTR szOpenFileName)
|
|||
|
||||
lstrcpyW(wszFileName, szOpenFileName);
|
||||
SendMessageW(hEditorWnd, EM_SETMODIFY, FALSE, 0);
|
||||
registry_set_filelist(szOpenFileName);
|
||||
}
|
||||
|
||||
static void DoSaveFile(LPCWSTR wszSaveFileName)
|
||||
|
@ -710,6 +965,8 @@ static LRESULT OnCreate( HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
ID_FINDMSGSTRING = RegisterWindowMessageW(FINDMSGSTRINGW);
|
||||
|
||||
registry_read_filelist(hWnd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -831,6 +1088,21 @@ static LRESULT OnCommand( HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||
DialogSaveFile();
|
||||
break;
|
||||
|
||||
case ID_FILE_RECENT1:
|
||||
case ID_FILE_RECENT2:
|
||||
case ID_FILE_RECENT3:
|
||||
case ID_FILE_RECENT4:
|
||||
{
|
||||
HMENU hMenu = GetMenu(hWnd);
|
||||
MENUITEMINFOW mi;
|
||||
|
||||
mi.cbSize = sizeof(MENUITEMINFOW);
|
||||
mi.fMask = MIIM_DATA;
|
||||
if(GetMenuItemInfoW(hMenu, LOWORD(wParam), FALSE, &mi))
|
||||
DoOpenFile((LPWSTR)mi.dwItemData);
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_FIND:
|
||||
dialog_find(&findreplace);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue