379 lines
11 KiB
C
379 lines
11 KiB
C
/*
|
|
* Wordpad implementation - Registry functions
|
|
*
|
|
* Copyright 2007 by Alexander N. Sørnes <alex@thehandofagony.com>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <windows.h>
|
|
#include <shlobj.h>
|
|
#include <richedit.h>
|
|
|
|
#include "wordpad.h"
|
|
|
|
static const WCHAR key_recentfiles[] = {'R','e','c','e','n','t',' ','f','i','l','e',
|
|
' ','l','i','s','t',0};
|
|
static const WCHAR key_options[] = {'O','p','t','i','o','n','s',0};
|
|
static const WCHAR key_rtf[] = {'R','T','F',0};
|
|
static const WCHAR key_text[] = {'T','e','x','t',0};
|
|
|
|
static const WCHAR var_file[] = {'F','i','l','e','%','d',0};
|
|
static const WCHAR var_framerect[] = {'F','r','a','m','e','R','e','c','t',0};
|
|
static const WCHAR var_barstate0[] = {'B','a','r','S','t','a','t','e','0',0};
|
|
|
|
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;
|
|
}
|
|
|
|
void registry_set_options(HWND hMainWnd)
|
|
{
|
|
HKEY hKey;
|
|
DWORD action;
|
|
|
|
if(registry_get_handle(&hKey, &action, (LPWSTR)key_options) == ERROR_SUCCESS)
|
|
{
|
|
RECT rc;
|
|
|
|
GetWindowRect(hMainWnd, &rc);
|
|
|
|
RegSetValueExW(hKey, var_framerect, 0, REG_BINARY, (LPBYTE)&rc, sizeof(RECT));
|
|
|
|
registry_set_pagemargins(hKey);
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
void registry_read_winrect(RECT* rc)
|
|
{
|
|
HKEY hKey;
|
|
DWORD size = sizeof(RECT);
|
|
|
|
if(registry_get_handle(&hKey, 0, (LPWSTR)key_options) != ERROR_SUCCESS ||
|
|
RegQueryValueExW(hKey, var_framerect, 0, NULL, (LPBYTE)rc, &size) !=
|
|
ERROR_SUCCESS || size != sizeof(RECT))
|
|
{
|
|
rc->top = 0;
|
|
rc->left = 0;
|
|
rc->bottom = 300;
|
|
rc->right = 600;
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
void registry_set_filelist(LPCWSTR newFile, HWND hMainWnd)
|
|
{
|
|
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);
|
|
}
|
|
|
|
int reg_formatindex(WPARAM format)
|
|
{
|
|
return (format & SF_TEXT) ? 1 : 0;
|
|
}
|
|
|
|
void registry_read_options(void)
|
|
{
|
|
HKEY hKey;
|
|
|
|
if(registry_get_handle(&hKey, 0, key_options) != ERROR_SUCCESS)
|
|
registry_read_pagemargins(NULL);
|
|
else
|
|
registry_read_pagemargins(hKey);
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
static void registry_read_formatopts(int index, LPCWSTR key, DWORD barState[], DWORD wordWrap[])
|
|
{
|
|
HKEY hKey;
|
|
DWORD action = 0;
|
|
BOOL fetched = FALSE;
|
|
barState[index] = 0;
|
|
wordWrap[index] = 0;
|
|
|
|
if(registry_get_handle(&hKey, &action, key) != ERROR_SUCCESS)
|
|
return;
|
|
|
|
if(action == REG_OPENED_EXISTING_KEY)
|
|
{
|
|
DWORD size = sizeof(DWORD);
|
|
|
|
if(RegQueryValueExW(hKey, var_barstate0, 0, NULL, (LPBYTE)&barState[index],
|
|
&size) == ERROR_SUCCESS)
|
|
fetched = TRUE;
|
|
}
|
|
|
|
if(!fetched)
|
|
barState[index] = (1 << BANDID_TOOLBAR) | (1 << BANDID_FORMATBAR) | (1 << BANDID_RULER) | (1 << BANDID_STATUSBAR);
|
|
|
|
if(index == reg_formatindex(SF_RTF))
|
|
wordWrap[index] = ID_WORDWRAP_WINDOW;
|
|
else if(index == reg_formatindex(SF_TEXT))
|
|
wordWrap[index] = ID_WORDWRAP_WINDOW; /* FIXME: should be ID_WORDWRAP_NONE once we support it */
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
void registry_read_formatopts_all(DWORD barState[], DWORD wordWrap[])
|
|
{
|
|
registry_read_formatopts(reg_formatindex(SF_RTF), key_rtf, barState, wordWrap);
|
|
registry_read_formatopts(reg_formatindex(SF_TEXT), key_text, barState, wordWrap);
|
|
}
|
|
|
|
static void registry_set_formatopts(int index, LPCWSTR key, DWORD barState[])
|
|
{
|
|
HKEY hKey;
|
|
DWORD action = 0;
|
|
|
|
if(registry_get_handle(&hKey, &action, key) == ERROR_SUCCESS)
|
|
{
|
|
RegSetValueExW(hKey, var_barstate0, 0, REG_DWORD, (LPBYTE)&barState[index],
|
|
sizeof(DWORD));
|
|
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
|
|
void registry_set_formatopts_all(DWORD barState[])
|
|
{
|
|
registry_set_formatopts(reg_formatindex(SF_RTF), key_rtf, barState);
|
|
registry_set_formatopts(reg_formatindex(SF_TEXT), key_text, barState);
|
|
}
|