msvcrt: Don't include MSVC 8.0+ time functions in SOs for older DLLs.
[wine.git] / programs / wordpad / registry.c
blob138111614bfbc71d3bc92d5f3f3183584f4b9c3d
1 /*
2 * Wordpad implementation - Registry functions
4 * Copyright 2007 by Alexander N. Sørnes <alex@thehandofagony.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <windows.h>
22 #include <shlobj.h>
23 #include <richedit.h>
25 #include "wordpad.h"
27 static const WCHAR key_recentfiles[] = {'R','e','c','e','n','t',' ','f','i','l','e',
28 ' ','l','i','s','t',0};
29 static const WCHAR key_options[] = {'O','p','t','i','o','n','s',0};
30 static const WCHAR key_settings[] = {'S','e','t','t','i','n','g','s',0};
31 static const WCHAR key_rtf[] = {'R','T','F',0};
32 static const WCHAR key_text[] = {'T','e','x','t',0};
34 static const WCHAR var_file[] = {'F','i','l','e','%','d',0};
35 static const WCHAR var_framerect[] = {'F','r','a','m','e','R','e','c','t',0};
36 static const WCHAR var_barstate0[] = {'B','a','r','S','t','a','t','e','0',0};
37 static const WCHAR var_wrap[] = {'W','r','a','p',0};
38 static const WCHAR var_maximized[] = {'M','a','x','i','m','i','z','e','d',0};
40 static LRESULT registry_get_handle(HKEY *hKey, LPDWORD action, LPCWSTR subKey)
42 LONG ret;
43 static const WCHAR wszProgramKey[] = {'S','o','f','t','w','a','r','e','\\',
44 'M','i','c','r','o','s','o','f','t','\\',
45 'W','i','n','d','o','w','s','\\',
46 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
47 'A','p','p','l','e','t','s','\\',
48 'W','o','r','d','p','a','d',0};
49 LPWSTR key = (LPWSTR)wszProgramKey;
51 if(subKey)
53 WCHAR backslash[] = {'\\',0};
54 key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
55 (lstrlenW(wszProgramKey)+lstrlenW(subKey)+lstrlenW(backslash)+1)
56 *sizeof(WCHAR));
58 if(!key)
59 return 1;
61 lstrcpyW(key, wszProgramKey);
62 lstrcatW(key, backslash);
63 lstrcatW(key, subKey);
66 if(action)
68 ret = RegCreateKeyExW(HKEY_CURRENT_USER, key, 0, NULL, REG_OPTION_NON_VOLATILE,
69 KEY_READ | KEY_WRITE, NULL, hKey, action);
70 } else
72 ret = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ | KEY_WRITE, hKey);
75 if(subKey)
76 HeapFree(GetProcessHeap(), 0, key);
78 return ret;
81 void registry_set_options(HWND hMainWnd)
83 HKEY hKey = 0;
84 DWORD action;
86 if(registry_get_handle(&hKey, &action, key_options) == ERROR_SUCCESS)
88 WINDOWPLACEMENT wp;
89 DWORD isMaximized;
91 wp.length = sizeof(WINDOWPLACEMENT);
92 GetWindowPlacement(hMainWnd, &wp);
93 isMaximized = (wp.showCmd == SW_SHOWMAXIMIZED);
95 RegSetValueExW(hKey, var_framerect, 0, REG_BINARY, (LPBYTE)&wp.rcNormalPosition, sizeof(RECT));
96 RegSetValueExW(hKey, var_maximized, 0, REG_DWORD, (LPBYTE)&isMaximized, sizeof(DWORD));
98 registry_set_pagemargins(hKey);
99 RegCloseKey(hKey);
102 if(registry_get_handle(&hKey, &action, key_settings) == ERROR_SUCCESS)
104 registry_set_previewpages(hKey);
105 RegCloseKey(hKey);
109 void registry_read_winrect(RECT* rc)
111 HKEY hKey = 0;
112 DWORD size = sizeof(RECT);
114 if(registry_get_handle(&hKey, 0, key_options) != ERROR_SUCCESS ||
115 RegQueryValueExW(hKey, var_framerect, 0, NULL, (LPBYTE)rc, &size) !=
116 ERROR_SUCCESS || size != sizeof(RECT))
117 SetRect(rc, 0, 0, 600, 300);
119 RegCloseKey(hKey);
122 void registry_read_maximized(DWORD *bMaximized)
124 HKEY hKey = 0;
125 DWORD size = sizeof(DWORD);
127 if(registry_get_handle(&hKey, 0, key_options) != ERROR_SUCCESS ||
128 RegQueryValueExW(hKey, var_maximized, 0, NULL, (LPBYTE)bMaximized, &size) !=
129 ERROR_SUCCESS || size != sizeof(DWORD))
131 *bMaximized = FALSE;
134 RegCloseKey(hKey);
137 static void truncate_path(LPWSTR file, LPWSTR out, LPWSTR pos1, LPWSTR pos2)
139 static const WCHAR dots[] = {'.','.','.',0};
141 *++pos1 = 0;
143 lstrcatW(out, file);
144 lstrcatW(out, dots);
145 lstrcatW(out, pos2);
148 static void format_filelist_filename(LPWSTR file, LPWSTR out)
150 LPWSTR pos_basename;
151 LPWSTR truncpos1, truncpos2;
152 WCHAR myDocs[MAX_PATH];
154 SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocs);
155 pos_basename = file_basename(file);
156 truncpos1 = NULL;
157 truncpos2 = NULL;
159 *(pos_basename-1) = 0;
160 if(!lstrcmpiW(file, myDocs) || (lstrlenW(pos_basename) > FILELIST_ENTRY_LENGTH))
162 truncpos1 = pos_basename;
163 *(pos_basename-1) = '\\';
164 } else
166 LPWSTR pos;
167 BOOL morespace = FALSE;
169 *(pos_basename-1) = '\\';
171 for(pos = file; pos < pos_basename; pos++)
173 if(*pos == '\\' || *pos == '/')
175 if(truncpos1)
177 if((pos - file + lstrlenW(pos_basename)) > FILELIST_ENTRY_LENGTH)
178 break;
180 truncpos1 = pos;
181 morespace = TRUE;
182 break;
185 if((pos - file + lstrlenW(pos_basename)) > FILELIST_ENTRY_LENGTH)
186 break;
188 truncpos1 = pos;
192 if(morespace)
194 for(pos = pos_basename; pos >= truncpos1; pos--)
196 if(*pos == '\\' || *pos == '/')
198 if((truncpos1 - file + lstrlenW(pos_basename) + pos_basename - pos) > FILELIST_ENTRY_LENGTH)
199 break;
201 truncpos2 = pos;
207 if(truncpos1 == pos_basename)
208 lstrcatW(out, pos_basename);
209 else if(truncpos1 == truncpos2 || !truncpos2)
210 lstrcatW(out, file);
211 else
212 truncate_path(file, out, truncpos1, truncpos2);
215 void registry_read_filelist(HWND hMainWnd)
217 HKEY hFileKey;
219 if(registry_get_handle(&hFileKey, 0, key_recentfiles) == ERROR_SUCCESS)
221 WCHAR itemText[MAX_PATH+3], buffer[MAX_PATH];
222 /* The menu item name is not the same as the file name, so we need to store
223 the file name here */
224 static WCHAR file1[MAX_PATH], file2[MAX_PATH], file3[MAX_PATH], file4[MAX_PATH];
225 WCHAR numFormat[] = {'&','%','d',' ',0};
226 LPWSTR pFile[] = {file1, file2, file3, file4};
227 DWORD pathSize = MAX_PATH*sizeof(WCHAR);
228 int i;
229 WCHAR key[6];
230 MENUITEMINFOW mi;
231 HMENU hMenu = GetMenu(hMainWnd);
233 mi.cbSize = sizeof(MENUITEMINFOW);
234 mi.fMask = MIIM_ID | MIIM_DATA | MIIM_STRING | MIIM_FTYPE;
235 mi.fType = MFT_STRING;
236 mi.dwTypeData = itemText;
237 mi.wID = ID_FILE_RECENT1;
239 RemoveMenu(hMenu, ID_FILE_RECENT_SEPARATOR, MF_BYCOMMAND);
240 for(i = 0; i < FILELIST_ENTRIES; i++)
242 wsprintfW(key, var_file, i+1);
243 RemoveMenu(hMenu, ID_FILE_RECENT1+i, MF_BYCOMMAND);
244 if(RegQueryValueExW(hFileKey, (LPWSTR)key, 0, NULL, (LPBYTE)pFile[i], &pathSize)
245 != ERROR_SUCCESS)
246 break;
248 mi.dwItemData = (ULONG_PTR)pFile[i];
249 wsprintfW(itemText, numFormat, i+1);
251 lstrcpyW(buffer, pFile[i]);
253 format_filelist_filename(buffer, itemText);
255 InsertMenuItemW(hMenu, ID_FILE_EXIT, FALSE, &mi);
256 mi.wID++;
257 pathSize = MAX_PATH*sizeof(WCHAR);
259 mi.fType = MFT_SEPARATOR;
260 mi.fMask = MIIM_FTYPE | MIIM_ID;
261 InsertMenuItemW(hMenu, ID_FILE_EXIT, FALSE, &mi);
263 RegCloseKey(hFileKey);
267 void registry_set_filelist(LPCWSTR newFile, HWND hMainWnd)
269 HKEY hKey;
270 DWORD action;
272 if(registry_get_handle(&hKey, &action, key_recentfiles) == ERROR_SUCCESS)
274 LPCWSTR pFiles[FILELIST_ENTRIES];
275 int i;
276 HMENU hMenu = GetMenu(hMainWnd);
277 MENUITEMINFOW mi;
278 WCHAR buffer[6];
280 mi.cbSize = sizeof(MENUITEMINFOW);
281 mi.fMask = MIIM_DATA;
283 for(i = 0; i < FILELIST_ENTRIES; i++)
284 pFiles[i] = NULL;
286 for(i = 0; i < FILELIST_ENTRIES && GetMenuItemInfoW(hMenu, ID_FILE_RECENT1+i, FALSE, &mi); i++)
287 pFiles[i] = (LPWSTR)mi.dwItemData;
289 if(lstrcmpiW(newFile, pFiles[0]))
291 for(i = 0; i < FILELIST_ENTRIES && pFiles[i]; i++)
293 if(!lstrcmpiW(pFiles[i], newFile))
295 int j;
296 for(j = 0; j < i; j++)
298 pFiles[i-j] = pFiles[i-j-1];
300 pFiles[0] = NULL;
301 break;
305 if(!pFiles[0])
307 pFiles[0] = newFile;
308 } else
310 for(i = 0; i < FILELIST_ENTRIES-1; i++)
311 pFiles[FILELIST_ENTRIES-1-i] = pFiles[FILELIST_ENTRIES-2-i];
313 pFiles[0] = newFile;
316 for(i = 0; i < FILELIST_ENTRIES && pFiles[i]; i++)
318 wsprintfW(buffer, var_file, i+1);
319 RegSetValueExW(hKey, (LPWSTR)&buffer, 0, REG_SZ, (const BYTE*)pFiles[i],
320 (lstrlenW(pFiles[i])+1)*sizeof(WCHAR));
323 RegCloseKey(hKey);
325 registry_read_filelist(hMainWnd);
328 int reg_formatindex(WPARAM format)
330 return (format & SF_TEXT) ? 1 : 0;
333 void registry_read_options(void)
335 HKEY hKey;
337 if(registry_get_handle(&hKey, 0, key_options) != ERROR_SUCCESS)
338 registry_read_pagemargins(NULL);
339 else
341 registry_read_pagemargins(hKey);
342 RegCloseKey(hKey);
345 if(registry_get_handle(&hKey, 0, key_settings) != ERROR_SUCCESS) {
346 registry_read_previewpages(NULL);
347 } else {
348 registry_read_previewpages(hKey);
349 RegCloseKey(hKey);
353 static void registry_read_formatopts(int index, LPCWSTR key, DWORD barState[], DWORD wordWrap[])
355 HKEY hKey;
356 DWORD action = 0;
357 BOOL fetched = FALSE;
358 barState[index] = 0;
359 wordWrap[index] = 0;
361 if(registry_get_handle(&hKey, &action, key) != ERROR_SUCCESS)
362 return;
364 if(action == REG_OPENED_EXISTING_KEY)
366 DWORD size = sizeof(DWORD);
368 if(RegQueryValueExW(hKey, var_barstate0, 0, NULL, (LPBYTE)&barState[index],
369 &size) == ERROR_SUCCESS)
370 fetched = TRUE;
373 if(!fetched)
374 barState[index] = (1 << BANDID_TOOLBAR) | (1 << BANDID_FORMATBAR) | (1 << BANDID_RULER) | (1 << BANDID_STATUSBAR);
376 fetched = FALSE;
377 if(action == REG_OPENED_EXISTING_KEY)
379 DWORD size = sizeof(DWORD);
380 if(RegQueryValueExW(hKey, var_wrap, 0, NULL, (LPBYTE)&wordWrap[index],
381 &size) == ERROR_SUCCESS)
382 fetched = TRUE;
385 if (!fetched)
387 if(index == reg_formatindex(SF_RTF))
388 wordWrap[index] = ID_WORDWRAP_WINDOW;
389 else if(index == reg_formatindex(SF_TEXT))
390 wordWrap[index] = ID_WORDWRAP_NONE;
393 RegCloseKey(hKey);
396 void registry_read_formatopts_all(DWORD barState[], DWORD wordWrap[])
398 registry_read_formatopts(reg_formatindex(SF_RTF), key_rtf, barState, wordWrap);
399 registry_read_formatopts(reg_formatindex(SF_TEXT), key_text, barState, wordWrap);
402 static void registry_set_formatopts(int index, LPCWSTR key, DWORD barState[], DWORD wordWrap[])
404 HKEY hKey;
405 DWORD action = 0;
407 if(registry_get_handle(&hKey, &action, key) == ERROR_SUCCESS)
409 RegSetValueExW(hKey, var_barstate0, 0, REG_DWORD, (LPBYTE)&barState[index],
410 sizeof(DWORD));
411 RegSetValueExW(hKey, var_wrap, 0, REG_DWORD, (LPBYTE)&wordWrap[index],
412 sizeof(DWORD));
413 RegCloseKey(hKey);
417 void registry_set_formatopts_all(DWORD barState[], DWORD wordWrap[])
419 registry_set_formatopts(reg_formatindex(SF_RTF), key_rtf, barState, wordWrap);
420 registry_set_formatopts(reg_formatindex(SF_TEXT), key_text, barState, wordWrap);