1 /*
2  * PROJECT:    PAINT for ReactOS
3  * LICENSE:    LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4  * PURPOSE:    Offering functions dealing with registry values
5  * COPYRIGHT:  Copyright 2015 Benedikt Freisen <b.freisen@gmx.net>
6  *             Copyright 2020 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7  */
8 
9 #include "precomp.h"
10 #include <winreg.h>
11 #include <wincon.h>
12 #include <shlobj.h>
13 
14 RegistrySettings registrySettings;
15 
16 /* FUNCTIONS ********************************************************/
17 
ReadDWORD(CRegKey & key,LPCWSTR lpName,DWORD & dwValue)18 static void ReadDWORD(CRegKey &key, LPCWSTR lpName, DWORD &dwValue)
19 {
20     DWORD dwTemp;
21     if (key.QueryDWORDValue(lpName, dwTemp) == ERROR_SUCCESS)
22         dwValue = dwTemp;
23 }
24 
ReadString(CRegKey & key,LPCWSTR lpName,CStringW & strValue,LPCWSTR lpDefault=L"")25 static void ReadString(CRegKey &key, LPCWSTR lpName, CStringW &strValue, LPCWSTR lpDefault = L"")
26 {
27     CStringW strTemp;
28     ULONG nChars = MAX_PATH;
29     LPWSTR psz = strTemp.GetBuffer(nChars);
30     LONG error = key.QueryStringValue(lpName, psz, &nChars);
31     strTemp.ReleaseBuffer();
32 
33     if (error == ERROR_SUCCESS)
34         strValue = strTemp;
35     else
36         strValue = lpDefault;
37 }
38 
SetWallpaper(LPCWSTR szFileName,RegistrySettings::WallpaperStyle style)39 void RegistrySettings::SetWallpaper(LPCWSTR szFileName, RegistrySettings::WallpaperStyle style)
40 {
41     // Build the local path to the converted cached BMP wallpaper
42     HRESULT hr;
43     WCHAR szWallpaper[MAX_PATH];
44     hr = SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szWallpaper);
45     if (FAILED(hr))
46         return;
47     hr = StringCchCatW(szWallpaper, _countof(szWallpaper), TEXT("\\Wallpaper1.bmp"));
48     if (FAILED(hr))
49         return;
50 
51     // Save the converted wallpaper BMP
52     CImageDx img;
53     HBITMAP hbmLocked = imageModel.LockBitmap();
54     img.Attach(hbmLocked);
55     hr = img.SaveDx(szWallpaper);
56     img.Detach();
57     imageModel.UnlockBitmap(hbmLocked);
58     if (FAILED(hr))
59         return;
60 
61     // Write the wallpaper settings to the registry
62     CRegKey desktop;
63     if (desktop.Open(HKEY_CURRENT_USER, L"Control Panel\\Desktop") == ERROR_SUCCESS)
64     {
65         desktop.SetStringValue(L"Wallpaper", szFileName);
66         desktop.SetStringValue(L"WallpaperStyle", (style == RegistrySettings::STRETCHED) ? L"2" : L"0");
67         desktop.SetStringValue(L"TileWallpaper", (style == RegistrySettings::TILED) ? L"1" : L"0");
68         desktop.SetStringValue(L"ConvertedWallpaper", szWallpaper);
69         desktop.SetStringValue(L"OriginalWallpaper", szFileName);
70     }
71 
72     // Set the desktop wallpaper
73     SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
74 }
75 
LoadPresets(INT nCmdShow)76 void RegistrySettings::LoadPresets(INT nCmdShow)
77 {
78     BMPHeight = GetSystemMetrics(SM_CYSCREEN) / 2;
79     BMPWidth = GetSystemMetrics(SM_CXSCREEN) / 2;
80     GridExtent = 1;
81     NoStretching = 0;
82     ShowThumbnail = 0;
83     SnapToGrid = 0;
84     ThumbHeight = 100;
85     ThumbWidth = 120;
86     ThumbXPos = 180;
87     ThumbYPos = 200;
88     UnitSetting = 0;
89     Bold = FALSE;
90     Italic = FALSE;
91     Underline = FALSE;
92     CharSet = DEFAULT_CHARSET;
93     PointSize = 14;
94     FontsPositionX = 0;
95     FontsPositionY = 0;
96     ShowTextTool = TRUE;
97     ShowStatusBar = TRUE;
98     ShowPalette = TRUE;
99     ShowToolBox = TRUE;
100     Bar1ID = BAR1ID_TOP;
101     Bar2ID = BAR2ID_LEFT;
102 
103     LOGFONTW lf;
104     ::GetObjectW(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
105     strFontName = lf.lfFaceName;
106 
107     ZeroMemory(&WindowPlacement, sizeof(WindowPlacement));
108     RECT& rc = WindowPlacement.rcNormalPosition;
109     rc.left = rc.top = CW_USEDEFAULT;
110     rc.right = rc.left + 544;
111     rc.bottom = rc.top + 375;
112     WindowPlacement.showCmd = nCmdShow;
113 }
114 
Load(INT nCmdShow)115 void RegistrySettings::Load(INT nCmdShow)
116 {
117     LoadPresets(nCmdShow);
118 
119     CRegKey paint;
120     if (paint.Open(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Paint", KEY_READ) != ERROR_SUCCESS)
121         return;
122 
123     CRegKey view;
124     if (view.Open(paint, L"View", KEY_READ) == ERROR_SUCCESS)
125     {
126         ReadDWORD(view, L"BMPHeight",     BMPHeight);
127         ReadDWORD(view, L"BMPWidth",      BMPWidth);
128         ReadDWORD(view, L"GridExtent",    GridExtent);
129         ReadDWORD(view, L"NoStretching",  NoStretching);
130         ReadDWORD(view, L"ShowThumbnail", ShowThumbnail);
131         ReadDWORD(view, L"SnapToGrid",    SnapToGrid);
132         ReadDWORD(view, L"ThumbHeight",   ThumbHeight);
133         ReadDWORD(view, L"ThumbWidth",    ThumbWidth);
134         ReadDWORD(view, L"ThumbXPos",     ThumbXPos);
135         ReadDWORD(view, L"ThumbYPos",     ThumbYPos);
136         ReadDWORD(view, L"UnitSetting",   UnitSetting);
137         ReadDWORD(view, L"ShowStatusBar", ShowStatusBar);
138 
139         ULONG pnBytes = sizeof(WINDOWPLACEMENT);
140         view.QueryBinaryValue(L"WindowPlacement", &WindowPlacement, &pnBytes);
141     }
142 
143     CRegKey files;
144     if (files.Open(paint, L"Recent File List", KEY_READ) == ERROR_SUCCESS)
145     {
146         WCHAR szName[64];
147         for (INT i = 0; i < MAX_RECENT_FILES; ++i)
148         {
149             StringCchPrintfW(szName, _countof(szName), L"File%u", i + 1);
150             ReadString(files, szName, strFiles[i]);
151         }
152     }
153 
154     CRegKey text;
155     if (text.Open(paint, L"Text", KEY_READ) == ERROR_SUCCESS)
156     {
157         ReadDWORD(text, L"Bold",         Bold);
158         ReadDWORD(text, L"Italic",       Italic);
159         ReadDWORD(text, L"Underline",    Underline);
160         ReadDWORD(text, L"CharSet",      CharSet);
161         ReadDWORD(text, L"PointSize",    PointSize);
162         ReadDWORD(text, L"PositionX",    FontsPositionX);
163         ReadDWORD(text, L"PositionY",    FontsPositionY);
164         ReadDWORD(text, L"ShowTextTool", ShowTextTool);
165         ReadString(text, L"TypeFaceName", strFontName, strFontName);
166     }
167 
168     CRegKey bar1;
169     if (bar1.Open(paint, L"General-Bar1", KEY_READ) == ERROR_SUCCESS)
170     {
171         ReadDWORD(bar1, L"BarID", Bar1ID);
172     }
173 
174     CRegKey bar2;
175     if (bar2.Open(paint, L"General-Bar2", KEY_READ) == ERROR_SUCCESS)
176     {
177         ReadDWORD(bar2, L"BarID", Bar2ID);
178     }
179 
180     CRegKey bar3;
181     if (bar3.Open(paint, L"General-Bar3", KEY_READ) == ERROR_SUCCESS)
182     {
183         ReadDWORD(bar3, L"Visible", ShowToolBox);
184     }
185 
186     CRegKey bar4;
187     if (bar4.Open(paint, L"General-Bar4", KEY_READ) == ERROR_SUCCESS)
188     {
189         ReadDWORD(bar4, L"Visible", ShowPalette);
190     }
191 
192     // Fix the bitmap size if too large
193     if (BMPWidth > 5000)
194         BMPWidth = (GetSystemMetrics(SM_CXSCREEN) * 6) / 10;
195     if (BMPHeight > 5000)
196         BMPHeight = (GetSystemMetrics(SM_CYSCREEN) * 6) / 10;
197 }
198 
Store()199 void RegistrySettings::Store()
200 {
201     BMPWidth = imageModel.GetWidth();
202     BMPHeight = imageModel.GetHeight();
203 
204     CRegKey paint;
205     if (paint.Create(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Paint") != ERROR_SUCCESS)
206         return;
207 
208     CRegKey view;
209     if (view.Create(paint, L"View") == ERROR_SUCCESS)
210     {
211         view.SetDWORDValue(L"BMPHeight",     BMPHeight);
212         view.SetDWORDValue(L"BMPWidth",      BMPWidth);
213         view.SetDWORDValue(L"GridExtent",    GridExtent);
214         view.SetDWORDValue(L"NoStretching",  NoStretching);
215         view.SetDWORDValue(L"ShowThumbnail", ShowThumbnail);
216         view.SetDWORDValue(L"SnapToGrid",    SnapToGrid);
217         view.SetDWORDValue(L"ThumbHeight",   ThumbHeight);
218         view.SetDWORDValue(L"ThumbWidth",    ThumbWidth);
219         view.SetDWORDValue(L"ThumbXPos",     ThumbXPos);
220         view.SetDWORDValue(L"ThumbYPos",     ThumbYPos);
221         view.SetDWORDValue(L"UnitSetting",   UnitSetting);
222         view.SetDWORDValue(L"ShowStatusBar", ShowStatusBar);
223 
224         view.SetBinaryValue(L"WindowPlacement", &WindowPlacement, sizeof(WINDOWPLACEMENT));
225     }
226 
227     CRegKey files;
228     if (files.Create(paint, L"Recent File List") == ERROR_SUCCESS)
229     {
230         WCHAR szName[64];
231         for (INT iFile = 0; iFile < MAX_RECENT_FILES; ++iFile)
232         {
233             StringCchPrintfW(szName, _countof(szName), L"File%u", iFile + 1);
234             files.SetStringValue(szName, strFiles[iFile]);
235         }
236     }
237 
238     CRegKey text;
239     if (text.Create(paint, L"Text") == ERROR_SUCCESS)
240     {
241         text.SetDWORDValue(L"Bold",          Bold);
242         text.SetDWORDValue(L"Italic",        Italic);
243         text.SetDWORDValue(L"Underline",     Underline);
244         text.SetDWORDValue(L"CharSet",       CharSet);
245         text.SetDWORDValue(L"PointSize",     PointSize);
246         text.SetDWORDValue(L"PositionX",     FontsPositionX);
247         text.SetDWORDValue(L"PositionY",     FontsPositionY);
248         text.SetDWORDValue(L"ShowTextTool",  ShowTextTool);
249         text.SetStringValue(L"TypeFaceName", strFontName);
250     }
251 
252     CRegKey bar1;
253     if (bar1.Create(paint, L"General-Bar1") == ERROR_SUCCESS)
254     {
255         bar1.SetDWORDValue(L"BarID", Bar1ID);
256     }
257 
258     CRegKey bar2;
259     if (bar2.Create(paint, L"General-Bar2") == ERROR_SUCCESS)
260     {
261         bar2.SetDWORDValue(L"BarID", Bar2ID);
262     }
263 
264     CRegKey bar3;
265     if (bar3.Create(paint, L"General-Bar3") == ERROR_SUCCESS)
266     {
267         bar3.SetDWORDValue(L"Visible", ShowToolBox);
268     }
269 
270     CRegKey bar4;
271     if (bar4.Create(paint, L"General-Bar4") == ERROR_SUCCESS)
272     {
273         bar4.SetDWORDValue(L"Visible", ShowPalette);
274     }
275 }
276 
SetMostRecentFile(LPCWSTR szPathName)277 void RegistrySettings::SetMostRecentFile(LPCWSTR szPathName)
278 {
279     // Register the file to the user's 'Recent' folder
280     if (szPathName && szPathName[0])
281         SHAddToRecentDocs(SHARD_PATHW, szPathName);
282 
283     // If szPathName is present in strFiles, move it to the top of the list
284     for (INT i = MAX_RECENT_FILES - 1, iFound = -1; i > 0; --i)
285     {
286         if (iFound < 0 && strFiles[i].CompareNoCase(szPathName) == 0)
287             iFound = i;
288 
289         if (iFound >= 0)
290             Swap(strFiles[i], strFiles[i - 1]);
291     }
292 
293     // If szPathName is not the first item in strFiles, insert it at the top of the list
294     if (strFiles[0].CompareNoCase(szPathName) != 0)
295     {
296         for (INT i = MAX_RECENT_FILES - 1; i > 0; --i)
297             strFiles[i] = strFiles[i - 1];
298 
299         strFiles[0] = szPathName;
300     }
301 }
302