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 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 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 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 65 static BOOL QueryDword(HKEY hKey, LPCTSTR pszValueName, DWORD *pdwResult) 66 { 67 return QueryGeneric(hKey, pszValueName, REG_DWORD, pdwResult, sizeof(*pdwResult)); 68 } 69 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 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 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 */ 105 void NOTEPAD_LoadSettingsFromRegistry(void) 106 { 107 HKEY hKey; 108 HFONT hFont; 109 DWORD dwPointSize, cx, cy; 110 DWORD cxScreen = GetSystemMetrics(SM_CXSCREEN), cyScreen = GetSystemMetrics(SM_CYSCREEN); 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 Globals.main_rect.left = CW_USEDEFAULT; 122 Globals.main_rect.top = CW_USEDEFAULT; 123 cx = min((cxScreen * 3) / 4, 640); 124 cy = min((cyScreen * 3) / 4, 480); 125 126 /* FIXME: Globals.fSaveWindowPositions = FALSE; */ 127 /* FIXME: Globals.fMLE_is_broken = FALSE; */ 128 129 /* Open the target registry key */ 130 if (RegOpenKey(HKEY_CURRENT_USER, s_szRegistryKey, &hKey) != ERROR_SUCCESS) 131 hKey = NULL; 132 133 /* Load the values from registry */ 134 if (hKey) 135 { 136 QueryByte(hKey, _T("lfCharSet"), &Globals.lfFont.lfCharSet); 137 QueryByte(hKey, _T("lfClipPrecision"), &Globals.lfFont.lfClipPrecision); 138 QueryDword(hKey, _T("lfEscapement"), (DWORD*)&Globals.lfFont.lfEscapement); 139 QueryByte(hKey, _T("lfItalic"), &Globals.lfFont.lfItalic); 140 QueryDword(hKey, _T("lfOrientation"), (DWORD*)&Globals.lfFont.lfOrientation); 141 QueryByte(hKey, _T("lfOutPrecision"), &Globals.lfFont.lfOutPrecision); 142 QueryByte(hKey, _T("lfPitchAndFamily"), &Globals.lfFont.lfPitchAndFamily); 143 QueryByte(hKey, _T("lfQuality"), &Globals.lfFont.lfQuality); 144 QueryByte(hKey, _T("lfStrikeOut"), &Globals.lfFont.lfStrikeOut); 145 QueryByte(hKey, _T("lfUnderline"), &Globals.lfFont.lfUnderline); 146 QueryDword(hKey, _T("lfWeight"), (DWORD*)&Globals.lfFont.lfWeight); 147 QueryDword(hKey, _T("iPointSize"), &dwPointSize); 148 149 QueryBool(hKey, _T("fWrap"), &Globals.bWrapLongLines); 150 QueryBool(hKey, _T("fStatusBar"), &Globals.bShowStatusBar); 151 152 QueryDword(hKey, _T("iMarginLeft"), (DWORD*)&Globals.lMargins.left); 153 QueryDword(hKey, _T("iMarginTop"), (DWORD*)&Globals.lMargins.top); 154 QueryDword(hKey, _T("iMarginRight"), (DWORD*)&Globals.lMargins.right); 155 QueryDword(hKey, _T("iMarginBottom"), (DWORD*)&Globals.lMargins.bottom); 156 157 QueryDword(hKey, _T("iWindowPosX"), (DWORD*)&Globals.main_rect.left); 158 QueryDword(hKey, _T("iWindowPosY"), (DWORD*)&Globals.main_rect.top); 159 QueryDword(hKey, _T("iWindowPosDX"), &cx); 160 QueryDword(hKey, _T("iWindowPosDY"), &cy); 161 162 QueryString(hKey, _T("searchString"), Globals.szFindText, _countof(Globals.szFindText)); 163 QueryString(hKey, _T("replaceString"), Globals.szReplaceText, _countof(Globals.szReplaceText)); 164 } 165 166 Globals.lfFont.lfHeight = HeightFromPointSize(dwPointSize); 167 Globals.main_rect.right = Globals.main_rect.left + cx; 168 Globals.main_rect.bottom = Globals.main_rect.top + cy; 169 170 if (!hKey || !QueryString(hKey, _T("lfFaceName"), 171 Globals.lfFont.lfFaceName, _countof(Globals.lfFont.lfFaceName))) 172 { 173 LoadString(Globals.hInstance, STRING_DEFAULTFONT, Globals.lfFont.lfFaceName, 174 _countof(Globals.lfFont.lfFaceName)); 175 } 176 177 if (!hKey || !QueryString(hKey, _T("szHeader"), Globals.szHeader, _countof(Globals.szHeader))) 178 { 179 LoadString(Globals.hInstance, STRING_PAGESETUP_HEADERVALUE, Globals.szHeader, 180 _countof(Globals.szHeader)); 181 } 182 183 if (!hKey || !QueryString(hKey, _T("szTrailer"), Globals.szFooter, _countof(Globals.szFooter))) 184 { 185 LoadString(Globals.hInstance, STRING_PAGESETUP_FOOTERVALUE, Globals.szFooter, 186 _countof(Globals.szFooter)); 187 } 188 189 if (hKey) 190 RegCloseKey(hKey); 191 192 /* WORKAROUND: Far East Asian users may not have suitable fixed-pitch fonts. */ 193 switch (PRIMARYLANGID(GetUserDefaultLangID())) 194 { 195 case LANG_CHINESE: 196 case LANG_JAPANESE: 197 case LANG_KOREAN: 198 Globals.lfFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; 199 break; 200 } 201 202 hFont = CreateFontIndirect(&Globals.lfFont); 203 SendMessage(Globals.hEdit, WM_SETFONT, (WPARAM)hFont, TRUE); 204 if (hFont) 205 { 206 if (Globals.hFont) 207 DeleteObject(Globals.hFont); 208 Globals.hFont = hFont; 209 } 210 } 211 212 static BOOL SaveDword(HKEY hKey, LPCTSTR pszValueNameT, DWORD dwValue) 213 { 214 return RegSetValueEx(hKey, pszValueNameT, 0, REG_DWORD, (LPBYTE) &dwValue, sizeof(dwValue)) == ERROR_SUCCESS; 215 } 216 217 static BOOL SaveString(HKEY hKey, LPCTSTR pszValueNameT, LPCTSTR pszValue) 218 { 219 return RegSetValueEx(hKey, pszValueNameT, 0, REG_SZ, (LPBYTE) pszValue, (DWORD) _tcslen(pszValue) * sizeof(*pszValue)) == ERROR_SUCCESS; 220 } 221 222 /*********************************************************************** 223 * NOTEPAD_SaveSettingsToRegistry 224 * 225 * Save settings to registry HKCU\Software\Microsoft\Notepad. 226 */ 227 void NOTEPAD_SaveSettingsToRegistry(void) 228 { 229 HKEY hKey; 230 DWORD dwDisposition; 231 232 GetWindowRect(Globals.hMainWnd, &Globals.main_rect); 233 234 if (RegCreateKeyEx(HKEY_CURRENT_USER, s_szRegistryKey, 235 0, NULL, 0, KEY_SET_VALUE, NULL, 236 &hKey, &dwDisposition) == ERROR_SUCCESS) 237 { 238 SaveDword(hKey, _T("lfCharSet"), Globals.lfFont.lfCharSet); 239 SaveDword(hKey, _T("lfClipPrecision"), Globals.lfFont.lfClipPrecision); 240 SaveDword(hKey, _T("lfEscapement"), Globals.lfFont.lfEscapement); 241 SaveString(hKey, _T("lfFaceName"), Globals.lfFont.lfFaceName); 242 SaveDword(hKey, _T("lfItalic"), Globals.lfFont.lfItalic); 243 SaveDword(hKey, _T("lfOrientation"), Globals.lfFont.lfOrientation); 244 SaveDword(hKey, _T("lfOutPrecision"), Globals.lfFont.lfOutPrecision); 245 SaveDword(hKey, _T("lfPitchAndFamily"), Globals.lfFont.lfPitchAndFamily); 246 SaveDword(hKey, _T("lfQuality"), Globals.lfFont.lfQuality); 247 SaveDword(hKey, _T("lfStrikeOut"), Globals.lfFont.lfStrikeOut); 248 SaveDword(hKey, _T("lfUnderline"), Globals.lfFont.lfUnderline); 249 SaveDword(hKey, _T("lfWeight"), Globals.lfFont.lfWeight); 250 SaveDword(hKey, _T("iPointSize"), PointSizeFromHeight(Globals.lfFont.lfHeight)); 251 SaveDword(hKey, _T("fWrap"), Globals.bWrapLongLines ? 1 : 0); 252 SaveDword(hKey, _T("fStatusBar"), Globals.bShowStatusBar ? 1 : 0); 253 SaveString(hKey, _T("szHeader"), Globals.szHeader); 254 SaveString(hKey, _T("szTrailer"), Globals.szFooter); 255 SaveDword(hKey, _T("iMarginLeft"), Globals.lMargins.left); 256 SaveDword(hKey, _T("iMarginTop"), Globals.lMargins.top); 257 SaveDword(hKey, _T("iMarginRight"), Globals.lMargins.right); 258 SaveDword(hKey, _T("iMarginBottom"), Globals.lMargins.bottom); 259 SaveDword(hKey, _T("iWindowPosX"), Globals.main_rect.left); 260 SaveDword(hKey, _T("iWindowPosY"), Globals.main_rect.top); 261 SaveDword(hKey, _T("iWindowPosDX"), Globals.main_rect.right - Globals.main_rect.left); 262 SaveDword(hKey, _T("iWindowPosDY"), Globals.main_rect.bottom - Globals.main_rect.top); 263 SaveString(hKey, _T("searchString"), Globals.szFindText); 264 SaveString(hKey, _T("replaceString"), Globals.szReplaceText); 265 266 RegCloseKey(hKey); 267 } 268 } 269