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 
18 static void ReadDWORD(CRegKey &key, LPCTSTR lpName, DWORD &dwValue)
19 {
20     DWORD dwTemp;
21     if (key.QueryDWORDValue(lpName, dwTemp) == ERROR_SUCCESS)
22         dwValue = dwTemp;
23 }
24 
25 static void ReadString(CRegKey &key, LPCTSTR lpName, CString &strValue, LPCTSTR lpDefault = TEXT(""))
26 {
27     CString strTemp;
28     ULONG nChars = MAX_PATH;
29     LPTSTR 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 
39 void RegistrySettings::SetWallpaper(LPCTSTR szFileName, RegistrySettings::WallpaperStyle style)
40 {
41     CRegKey desktop;
42     if (desktop.Open(HKEY_CURRENT_USER, _T("Control Panel\\Desktop")) == ERROR_SUCCESS)
43     {
44         desktop.SetStringValue(_T("Wallpaper"), szFileName);
45 
46         desktop.SetStringValue(_T("WallpaperStyle"), (style == RegistrySettings::STRETCHED) ? _T("2") : _T("0"));
47         desktop.SetStringValue(_T("TileWallpaper"), (style == RegistrySettings::TILED) ? _T("1") : _T("0"));
48     }
49 
50     SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID) szFileName, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
51 }
52 
53 void RegistrySettings::LoadPresets(INT nCmdShow)
54 {
55     BMPHeight = GetSystemMetrics(SM_CYSCREEN) / 2;
56     BMPWidth = GetSystemMetrics(SM_CXSCREEN) / 2;
57     GridExtent = 1;
58     NoStretching = 0;
59     ShowThumbnail = 0;
60     SnapToGrid = 0;
61     ThumbHeight = 100;
62     ThumbWidth = 120;
63     ThumbXPos = 180;
64     ThumbYPos = 200;
65     UnitSetting = 0;
66     Bold = FALSE;
67     Italic = FALSE;
68     Underline = FALSE;
69     CharSet = DEFAULT_CHARSET;
70     PointSize = 14;
71     FontsPositionX = 0;
72     FontsPositionY = 0;
73     ShowTextTool = TRUE;
74     ShowStatusBar = TRUE;
75     ShowPalette = TRUE;
76     ShowToolBox = TRUE;
77     Bar1ID = BAR1ID_TOP;
78     Bar2ID = BAR2ID_LEFT;
79 
80     LOGFONT lf;
81     GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
82     strFontName = lf.lfFaceName;
83 
84     ZeroMemory(&WindowPlacement, sizeof(WindowPlacement));
85     RECT& rc = WindowPlacement.rcNormalPosition;
86     rc.left = rc.top = CW_USEDEFAULT;
87     rc.right = rc.left + 544;
88     rc.bottom = rc.top + 375;
89     WindowPlacement.showCmd = nCmdShow;
90 }
91 
92 void RegistrySettings::Load(INT nCmdShow)
93 {
94     LoadPresets(nCmdShow);
95 
96     CRegKey paint;
97     if (paint.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Paint"), KEY_READ) != ERROR_SUCCESS)
98         return;
99 
100     CRegKey view;
101     if (view.Open(paint, _T("View"), KEY_READ) == ERROR_SUCCESS)
102     {
103         ReadDWORD(view, _T("BMPHeight"),     BMPHeight);
104         ReadDWORD(view, _T("BMPWidth"),      BMPWidth);
105         ReadDWORD(view, _T("GridExtent"),    GridExtent);
106         ReadDWORD(view, _T("NoStretching"),  NoStretching);
107         ReadDWORD(view, _T("ShowThumbnail"), ShowThumbnail);
108         ReadDWORD(view, _T("SnapToGrid"),    SnapToGrid);
109         ReadDWORD(view, _T("ThumbHeight"),   ThumbHeight);
110         ReadDWORD(view, _T("ThumbWidth"),    ThumbWidth);
111         ReadDWORD(view, _T("ThumbXPos"),     ThumbXPos);
112         ReadDWORD(view, _T("ThumbYPos"),     ThumbYPos);
113         ReadDWORD(view, _T("UnitSetting"),   UnitSetting);
114         ReadDWORD(view, _T("ShowStatusBar"), ShowStatusBar);
115 
116         ULONG pnBytes = sizeof(WINDOWPLACEMENT);
117         view.QueryBinaryValue(_T("WindowPlacement"), &WindowPlacement, &pnBytes);
118     }
119 
120     CRegKey files;
121     if (files.Open(paint, _T("Recent File List"), KEY_READ) == ERROR_SUCCESS)
122     {
123         TCHAR szName[64];
124         for (INT i = 0; i < MAX_RECENT_FILES; ++i)
125         {
126             wsprintf(szName, _T("File%u"), i + 1);
127             ReadString(files, szName, strFiles[i]);
128         }
129     }
130 
131     CRegKey text;
132     if (text.Open(paint, _T("Text"), KEY_READ) == ERROR_SUCCESS)
133     {
134         ReadDWORD(text, _T("Bold"),         Bold);
135         ReadDWORD(text, _T("Italic"),       Italic);
136         ReadDWORD(text, _T("Underline"),    Underline);
137         ReadDWORD(text, _T("CharSet"),      CharSet);
138         ReadDWORD(text, _T("PointSize"),    PointSize);
139         ReadDWORD(text, _T("PositionX"),    FontsPositionX);
140         ReadDWORD(text, _T("PositionY"),    FontsPositionY);
141         ReadDWORD(text, _T("ShowTextTool"), ShowTextTool);
142         ReadString(text, _T("TypeFaceName"), strFontName, strFontName);
143     }
144 
145     CRegKey bar1;
146     if (bar1.Open(paint, _T("General-Bar1"), KEY_READ) == ERROR_SUCCESS)
147     {
148         ReadDWORD(bar1, _T("BarID"), Bar1ID);
149     }
150 
151     CRegKey bar2;
152     if (bar2.Open(paint, _T("General-Bar2"), KEY_READ) == ERROR_SUCCESS)
153     {
154         ReadDWORD(bar2, _T("BarID"), Bar2ID);
155     }
156 
157     CRegKey bar3;
158     if (bar3.Open(paint, _T("General-Bar3"), KEY_READ) == ERROR_SUCCESS)
159     {
160         ReadDWORD(bar3, _T("Visible"), ShowToolBox);
161     }
162 
163     CRegKey bar4;
164     if (bar4.Open(paint, _T("General-Bar4"), KEY_READ) == ERROR_SUCCESS)
165     {
166         ReadDWORD(bar4, _T("Visible"), ShowPalette);
167     }
168 
169     // Fix the bitmap size if too large
170     if (BMPWidth > 5000)
171         BMPWidth = (GetSystemMetrics(SM_CXSCREEN) * 6) / 10;
172     if (BMPHeight > 5000)
173         BMPHeight = (GetSystemMetrics(SM_CYSCREEN) * 6) / 10;
174 }
175 
176 void RegistrySettings::Store()
177 {
178     BMPWidth = imageModel.GetWidth();
179     BMPHeight = imageModel.GetHeight();
180 
181     CRegKey paint;
182     if (paint.Create(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Paint")) != ERROR_SUCCESS)
183         return;
184 
185     CRegKey view;
186     if (view.Create(paint, _T("View")) == ERROR_SUCCESS)
187     {
188         view.SetDWORDValue(_T("BMPHeight"),     BMPHeight);
189         view.SetDWORDValue(_T("BMPWidth"),      BMPWidth);
190         view.SetDWORDValue(_T("GridExtent"),    GridExtent);
191         view.SetDWORDValue(_T("NoStretching"),  NoStretching);
192         view.SetDWORDValue(_T("ShowThumbnail"), ShowThumbnail);
193         view.SetDWORDValue(_T("SnapToGrid"),    SnapToGrid);
194         view.SetDWORDValue(_T("ThumbHeight"),   ThumbHeight);
195         view.SetDWORDValue(_T("ThumbWidth"),    ThumbWidth);
196         view.SetDWORDValue(_T("ThumbXPos"),     ThumbXPos);
197         view.SetDWORDValue(_T("ThumbYPos"),     ThumbYPos);
198         view.SetDWORDValue(_T("UnitSetting"),   UnitSetting);
199         view.SetDWORDValue(_T("ShowStatusBar"), ShowStatusBar);
200 
201         view.SetBinaryValue(_T("WindowPlacement"), &WindowPlacement, sizeof(WINDOWPLACEMENT));
202     }
203 
204     CRegKey files;
205     if (files.Create(paint, _T("Recent File List")) == ERROR_SUCCESS)
206     {
207         TCHAR szName[64];
208         for (INT iFile = 0; iFile < MAX_RECENT_FILES; ++iFile)
209         {
210             wsprintf(szName, _T("File%u"), iFile + 1);
211             files.SetStringValue(szName, strFiles[iFile]);
212         }
213     }
214 
215     CRegKey text;
216     if (text.Create(paint, _T("Text")) == ERROR_SUCCESS)
217     {
218         text.SetDWORDValue(_T("Bold"),          Bold);
219         text.SetDWORDValue(_T("Italic"),        Italic);
220         text.SetDWORDValue(_T("Underline"),     Underline);
221         text.SetDWORDValue(_T("CharSet"),       CharSet);
222         text.SetDWORDValue(_T("PointSize"),     PointSize);
223         text.SetDWORDValue(_T("PositionX"),     FontsPositionX);
224         text.SetDWORDValue(_T("PositionY"),     FontsPositionY);
225         text.SetDWORDValue(_T("ShowTextTool"),  ShowTextTool);
226         text.SetStringValue(_T("TypeFaceName"), strFontName);
227     }
228 
229     CRegKey bar1;
230     if (bar1.Create(paint, _T("General-Bar1")) == ERROR_SUCCESS)
231     {
232         bar1.SetDWORDValue(_T("BarID"), Bar1ID);
233     }
234 
235     CRegKey bar2;
236     if (bar2.Create(paint, _T("General-Bar2")) == ERROR_SUCCESS)
237     {
238         bar2.SetDWORDValue(_T("BarID"), Bar2ID);
239     }
240 
241     CRegKey bar3;
242     if (bar3.Create(paint, _T("General-Bar3")) == ERROR_SUCCESS)
243     {
244         bar3.SetDWORDValue(_T("Visible"), ShowToolBox);
245     }
246 
247     CRegKey bar4;
248     if (bar4.Create(paint, _T("General-Bar4")) == ERROR_SUCCESS)
249     {
250         bar4.SetDWORDValue(_T("Visible"), ShowPalette);
251     }
252 }
253 
254 void RegistrySettings::SetMostRecentFile(LPCTSTR szPathName)
255 {
256     // Register the file to the user's 'Recent' folder
257     if (szPathName && szPathName[0])
258         SHAddToRecentDocs(SHARD_PATHW, szPathName);
259 
260     // If szPathName is present in strFiles, move it to the top of the list
261     for (INT i = MAX_RECENT_FILES - 1, iFound = -1; i > 0; --i)
262     {
263         if (iFound < 0 && strFiles[i].CompareNoCase(szPathName) == 0)
264             iFound = i;
265 
266         if (iFound >= 0)
267         {
268             CString tmp = strFiles[i];
269             strFiles[i] = strFiles[i - 1];
270             strFiles[i - 1] = tmp;
271         }
272     }
273 
274     // If szPathName is not the first item in strFiles, insert it at the top of the list
275     if (strFiles[0].CompareNoCase(szPathName) != 0)
276     {
277         for (INT i = MAX_RECENT_FILES - 1; i > 0; --i)
278             strFiles[i] = strFiles[i - 1];
279 
280         strFiles[0] = szPathName;
281     }
282 }
283