wine/programs/wordpad/registry.c
Dylan Smith 3355be3e5d wordpad: Number of preview pages to show when unzoomed is persistent.
Either one or two pages may be shown in print preview when zoomed out.
This value is stored in the registry in native wordpad, and preserved
while opening and closing the print preview.  Zooming in will only show one
page, but the pages shown value must be saved because it will return to the
preview pages shown value after unzooming completely. If two pages should
be shown when there is only one page of text, then a second blank page is
shown.
2010-02-24 15:12:30 +01:00

413 lines
12 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_settings[] = {'S','e','t','t','i','n','g','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 const WCHAR var_maximized[] = {'M','a','x','i','m','i','z','e','d',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 = 0;
DWORD action;
if(registry_get_handle(&hKey, &action, key_options) == ERROR_SUCCESS)
{
WINDOWPLACEMENT wp;
DWORD isMaximized;
wp.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(hMainWnd, &wp);
isMaximized = (wp.showCmd == SW_SHOWMAXIMIZED);
RegSetValueExW(hKey, var_framerect, 0, REG_BINARY, (LPBYTE)&wp.rcNormalPosition, sizeof(RECT));
RegSetValueExW(hKey, var_maximized, 0, REG_DWORD, (LPBYTE)&isMaximized, sizeof(DWORD));
registry_set_pagemargins(hKey);
RegCloseKey(hKey);
}
if(registry_get_handle(&hKey, &action, key_settings) == ERROR_SUCCESS)
{
registry_set_previewpages(hKey);
RegCloseKey(hKey);
}
}
void registry_read_winrect(RECT* rc)
{
HKEY hKey = 0;
DWORD size = sizeof(RECT);
if(registry_get_handle(&hKey, 0, 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);
}
void registry_read_maximized(DWORD *bMaximized)
{
HKEY hKey = 0;
DWORD size = sizeof(DWORD);
if(registry_get_handle(&hKey, 0, key_options) != ERROR_SUCCESS ||
RegQueryValueExW(hKey, var_maximized, 0, NULL, (LPBYTE)bMaximized, &size) !=
ERROR_SUCCESS || size != sizeof(DWORD))
{
*bMaximized = FALSE;
}
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 = (ULONG_PTR)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; 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, (const BYTE*)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);
}
if(registry_get_handle(&hKey, 0, key_settings) != ERROR_SUCCESS) {
registry_read_previewpages(NULL);
} else {
registry_read_previewpages(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_NONE;
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);
}