1 /*
2 * PROJECT: ReactOS Notepad
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Providing a Windows-compatible simple text editor for ReactOS
5 * COPYRIGHT: Copyright 1998,99 Marcel Baur <mbaur@g26.ethz.ch>
6 * Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
7 * Copyright 2002 Andriy Palamarchuk
8 */
9
10 #include "notepad.h"
11
12 #include <winreg.h>
13
14 static LPCTSTR s_szRegistryKey = _T("Software\\Microsoft\\Notepad");
15
16
HeightFromPointSize(DWORD dwPointSize)17 static LONG HeightFromPointSize(DWORD dwPointSize)
18 {
19 LONG lHeight;
20 HDC hDC;
21
22 hDC = GetDC(NULL);
23 lHeight = -MulDiv(dwPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 720);
24 ReleaseDC(NULL, hDC);
25
26 return lHeight;
27 }
28
PointSizeFromHeight(LONG lHeight)29 static DWORD PointSizeFromHeight(LONG lHeight)
30 {
31 DWORD dwPointSize;
32 HDC hDC;
33
34 hDC = GetDC(NULL);
35 dwPointSize = -MulDiv(lHeight, 720, GetDeviceCaps(hDC, LOGPIXELSY));
36 ReleaseDC(NULL, hDC);
37
38 /* round to nearest multiple of 10 */
39 dwPointSize += 5;
40 dwPointSize -= dwPointSize % 10;
41
42 return dwPointSize;
43 }
44
45 static BOOL
QueryGeneric(HKEY hKey,LPCTSTR pszValueNameT,DWORD dwExpectedType,LPVOID pvResult,DWORD dwResultSize)46 QueryGeneric(HKEY hKey, LPCTSTR pszValueNameT, DWORD dwExpectedType,
47 LPVOID pvResult, DWORD dwResultSize)
48 {
49 DWORD dwType, cbData;
50 LPVOID *pTemp = _alloca(dwResultSize);
51
52 ZeroMemory(pTemp, dwResultSize);
53
54 cbData = dwResultSize;
55 if (RegQueryValueEx(hKey, pszValueNameT, NULL, &dwType, (LPBYTE) pTemp, &cbData) != ERROR_SUCCESS)
56 return FALSE;
57
58 if (dwType != dwExpectedType)
59 return FALSE;
60
61 memcpy(pvResult, pTemp, cbData);
62 return TRUE;
63 }
64
QueryDword(HKEY hKey,LPCTSTR pszValueName,DWORD * pdwResult)65 static BOOL QueryDword(HKEY hKey, LPCTSTR pszValueName, DWORD *pdwResult)
66 {
67 return QueryGeneric(hKey, pszValueName, REG_DWORD, pdwResult, sizeof(*pdwResult));
68 }
69
QueryByte(HKEY hKey,LPCTSTR pszValueName,BYTE * pbResult)70 static BOOL QueryByte(HKEY hKey, LPCTSTR pszValueName, BYTE *pbResult)
71 {
72 DWORD dwResult;
73 if (!QueryGeneric(hKey, pszValueName, REG_DWORD, &dwResult, sizeof(dwResult)))
74 return FALSE;
75 if (dwResult >= 0x100)
76 return FALSE;
77 *pbResult = (BYTE) dwResult;
78 return TRUE;
79 }
80
QueryBool(HKEY hKey,LPCTSTR pszValueName,BOOL * pbResult)81 static BOOL QueryBool(HKEY hKey, LPCTSTR pszValueName, BOOL *pbResult)
82 {
83 DWORD dwResult;
84 if (!QueryDword(hKey, pszValueName, &dwResult))
85 return FALSE;
86 *pbResult = dwResult ? TRUE : FALSE;
87 return TRUE;
88 }
89
QueryString(HKEY hKey,LPCTSTR pszValueName,LPTSTR pszResult,DWORD dwResultLength)90 static BOOL QueryString(HKEY hKey, LPCTSTR pszValueName, LPTSTR pszResult, DWORD dwResultLength)
91 {
92 if (dwResultLength == 0)
93 return FALSE;
94 if (!QueryGeneric(hKey, pszValueName, REG_SZ, pszResult, dwResultLength * sizeof(TCHAR)))
95 return FALSE;
96 pszResult[dwResultLength - 1] = 0; /* Avoid buffer overrun */
97 return TRUE;
98 }
99
100 /***********************************************************************
101 * NOTEPAD_LoadSettingsFromRegistry
102 *
103 * Load settings from registry HKCU\Software\Microsoft\Notepad.
104 */
NOTEPAD_LoadSettingsFromRegistry(PWINDOWPLACEMENT pWP)105 void NOTEPAD_LoadSettingsFromRegistry(PWINDOWPLACEMENT pWP)
106 {
107 HKEY hKey;
108 HFONT hFont;
109 DWORD dwPointSize;
110 DWORD x = CW_USEDEFAULT, y = CW_USEDEFAULT, cx = 0, cy = 0;
111
112 /* Set the default values */
113 Globals.bShowStatusBar = TRUE;
114 Globals.bWrapLongLines = FALSE;
115 SetRect(&Globals.lMargins, 750, 1000, 750, 1000);
116 ZeroMemory(&Globals.lfFont, sizeof(Globals.lfFont));
117 Globals.lfFont.lfCharSet = DEFAULT_CHARSET;
118 dwPointSize = 100;
119 Globals.lfFont.lfWeight = FW_NORMAL;
120 Globals.lfFont.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
121
122 /* FIXME: Globals.fSaveWindowPositions = FALSE; */
123 /* FIXME: Globals.fMLE_is_broken = FALSE; */
124
125 /* Open the target registry key */
126 if (RegOpenKey(HKEY_CURRENT_USER, s_szRegistryKey, &hKey) != ERROR_SUCCESS)
127 hKey = NULL;
128
129 /* Load the values from registry */
130 if (hKey)
131 {
132 QueryByte(hKey, _T("lfCharSet"), &Globals.lfFont.lfCharSet);
133 QueryByte(hKey, _T("lfClipPrecision"), &Globals.lfFont.lfClipPrecision);
134 QueryDword(hKey, _T("lfEscapement"), (DWORD*)&Globals.lfFont.lfEscapement);
135 QueryByte(hKey, _T("lfItalic"), &Globals.lfFont.lfItalic);
136 QueryDword(hKey, _T("lfOrientation"), (DWORD*)&Globals.lfFont.lfOrientation);
137 QueryByte(hKey, _T("lfOutPrecision"), &Globals.lfFont.lfOutPrecision);
138 QueryByte(hKey, _T("lfPitchAndFamily"), &Globals.lfFont.lfPitchAndFamily);
139 QueryByte(hKey, _T("lfQuality"), &Globals.lfFont.lfQuality);
140 QueryByte(hKey, _T("lfStrikeOut"), &Globals.lfFont.lfStrikeOut);
141 QueryByte(hKey, _T("lfUnderline"), &Globals.lfFont.lfUnderline);
142 QueryDword(hKey, _T("lfWeight"), (DWORD*)&Globals.lfFont.lfWeight);
143 QueryDword(hKey, _T("iPointSize"), &dwPointSize);
144
145 QueryBool(hKey, _T("fWrap"), &Globals.bWrapLongLines);
146 QueryBool(hKey, _T("fStatusBar"), &Globals.bShowStatusBar);
147
148 QueryDword(hKey, _T("iMarginLeft"), (DWORD*)&Globals.lMargins.left);
149 QueryDword(hKey, _T("iMarginTop"), (DWORD*)&Globals.lMargins.top);
150 QueryDword(hKey, _T("iMarginRight"), (DWORD*)&Globals.lMargins.right);
151 QueryDword(hKey, _T("iMarginBottom"), (DWORD*)&Globals.lMargins.bottom);
152
153 QueryDword(hKey, _T("iWindowPosX"), &x);
154 QueryDword(hKey, _T("iWindowPosY"), &y);
155 QueryDword(hKey, _T("iWindowPosDX"), &cx);
156 QueryDword(hKey, _T("iWindowPosDY"), &cy);
157
158 QueryString(hKey, _T("searchString"), Globals.szFindText, _countof(Globals.szFindText));
159 QueryString(hKey, _T("replaceString"), Globals.szReplaceText, _countof(Globals.szReplaceText));
160 }
161
162 pWP->length = sizeof(*pWP);
163 pWP->flags = 0;
164 pWP->showCmd = SW_SHOWDEFAULT;
165 if (cy & 0x80000000)
166 {
167 cy &= ~0x80000000;
168 pWP->flags |= WPF_RESTORETOMAXIMIZED;
169 pWP->showCmd = SW_SHOWMAXIMIZED;
170 }
171 pWP->rcNormalPosition.left = x;
172 pWP->rcNormalPosition.right = x + cx;
173 pWP->rcNormalPosition.top = y;
174 pWP->rcNormalPosition.bottom = y + cy;
175 pWP->ptMaxPosition.x = x;
176 pWP->ptMaxPosition.y = y;
177
178 Globals.lfFont.lfHeight = HeightFromPointSize(dwPointSize);
179 if (!hKey || !QueryString(hKey, _T("lfFaceName"),
180 Globals.lfFont.lfFaceName, _countof(Globals.lfFont.lfFaceName)))
181 {
182 LoadString(Globals.hInstance, STRING_DEFAULTFONT, Globals.lfFont.lfFaceName,
183 _countof(Globals.lfFont.lfFaceName));
184 }
185
186 if (!hKey || !QueryString(hKey, _T("szHeader"), Globals.szHeader, _countof(Globals.szHeader)))
187 {
188 LoadString(Globals.hInstance, STRING_PAGESETUP_HEADERVALUE, Globals.szHeader,
189 _countof(Globals.szHeader));
190 }
191
192 if (!hKey || !QueryString(hKey, _T("szTrailer"), Globals.szFooter, _countof(Globals.szFooter)))
193 {
194 LoadString(Globals.hInstance, STRING_PAGESETUP_FOOTERVALUE, Globals.szFooter,
195 _countof(Globals.szFooter));
196 }
197
198 if (hKey)
199 RegCloseKey(hKey);
200
201 /* WORKAROUND: Far East Asian users may not have suitable fixed-pitch fonts. */
202 switch (PRIMARYLANGID(GetUserDefaultLangID()))
203 {
204 case LANG_CHINESE:
205 case LANG_JAPANESE:
206 case LANG_KOREAN:
207 Globals.lfFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
208 break;
209 }
210
211 hFont = CreateFontIndirect(&Globals.lfFont);
212 SendMessage(Globals.hEdit, WM_SETFONT, (WPARAM)hFont, TRUE);
213 if (hFont)
214 {
215 if (Globals.hFont)
216 DeleteObject(Globals.hFont);
217 Globals.hFont = hFont;
218 }
219 }
220
SaveDword(HKEY hKey,LPCTSTR pszValueNameT,DWORD dwValue)221 static BOOL SaveDword(HKEY hKey, LPCTSTR pszValueNameT, DWORD dwValue)
222 {
223 return RegSetValueEx(hKey, pszValueNameT, 0, REG_DWORD, (LPBYTE) &dwValue, sizeof(dwValue)) == ERROR_SUCCESS;
224 }
225
SaveString(HKEY hKey,LPCTSTR pszValueNameT,LPCTSTR pszValue)226 static BOOL SaveString(HKEY hKey, LPCTSTR pszValueNameT, LPCTSTR pszValue)
227 {
228 return RegSetValueEx(hKey, pszValueNameT, 0, REG_SZ, (LPBYTE) pszValue, (DWORD) _tcslen(pszValue) * sizeof(*pszValue)) == ERROR_SUCCESS;
229 }
230
231 /***********************************************************************
232 * NOTEPAD_SaveSettingsToRegistry
233 *
234 * Save settings to registry HKCU\Software\Microsoft\Notepad.
235 */
NOTEPAD_SaveSettingsToRegistry(void)236 void NOTEPAD_SaveSettingsToRegistry(void)
237 {
238 HKEY hKey;
239 DWORD dwDisposition;
240 WINDOWPLACEMENT wp;
241 UINT x, y, cx, cy;
242
243 wp.length = sizeof(wp);
244 GetWindowPlacement(Globals.hMainWnd, &wp);
245 x = wp.rcNormalPosition.left;
246 y = wp.rcNormalPosition.top;
247 cx = wp.rcNormalPosition.right - x;
248 cy = wp.rcNormalPosition.bottom - y;
249 if (wp.flags & WPF_RESTORETOMAXIMIZED)
250 cy |= 0x80000000;
251
252
253 if (RegCreateKeyEx(HKEY_CURRENT_USER, s_szRegistryKey,
254 0, NULL, 0, KEY_SET_VALUE, NULL,
255 &hKey, &dwDisposition) == ERROR_SUCCESS)
256 {
257 SaveDword(hKey, _T("lfCharSet"), Globals.lfFont.lfCharSet);
258 SaveDword(hKey, _T("lfClipPrecision"), Globals.lfFont.lfClipPrecision);
259 SaveDword(hKey, _T("lfEscapement"), Globals.lfFont.lfEscapement);
260 SaveString(hKey, _T("lfFaceName"), Globals.lfFont.lfFaceName);
261 SaveDword(hKey, _T("lfItalic"), Globals.lfFont.lfItalic);
262 SaveDword(hKey, _T("lfOrientation"), Globals.lfFont.lfOrientation);
263 SaveDword(hKey, _T("lfOutPrecision"), Globals.lfFont.lfOutPrecision);
264 SaveDword(hKey, _T("lfPitchAndFamily"), Globals.lfFont.lfPitchAndFamily);
265 SaveDword(hKey, _T("lfQuality"), Globals.lfFont.lfQuality);
266 SaveDword(hKey, _T("lfStrikeOut"), Globals.lfFont.lfStrikeOut);
267 SaveDword(hKey, _T("lfUnderline"), Globals.lfFont.lfUnderline);
268 SaveDword(hKey, _T("lfWeight"), Globals.lfFont.lfWeight);
269 SaveDword(hKey, _T("iPointSize"), PointSizeFromHeight(Globals.lfFont.lfHeight));
270 SaveDword(hKey, _T("fWrap"), Globals.bWrapLongLines ? 1 : 0);
271 SaveDword(hKey, _T("fStatusBar"), Globals.bShowStatusBar ? 1 : 0);
272 SaveString(hKey, _T("szHeader"), Globals.szHeader);
273 SaveString(hKey, _T("szTrailer"), Globals.szFooter);
274 SaveDword(hKey, _T("iMarginLeft"), Globals.lMargins.left);
275 SaveDword(hKey, _T("iMarginTop"), Globals.lMargins.top);
276 SaveDword(hKey, _T("iMarginRight"), Globals.lMargins.right);
277 SaveDword(hKey, _T("iMarginBottom"), Globals.lMargins.bottom);
278 SaveDword(hKey, _T("iWindowPosX"), x);
279 SaveDword(hKey, _T("iWindowPosY"), y);
280 SaveDword(hKey, _T("iWindowPosDX"), cx);
281 SaveDword(hKey, _T("iWindowPosDY"), cy);
282 SaveString(hKey, _T("searchString"), Globals.szFindText);
283 SaveString(hKey, _T("replaceString"), Globals.szReplaceText);
284
285 RegCloseKey(hKey);
286 }
287 }
288