1 /*
2  * Regedit settings
3  *
4  * Copyright 2012 Edijs Kolesnikovics <terminedijs@yahoo.com>
5  * Copyright 2012 Gr�gori Mac�rio Harbs <mysoft64bits@gmail.com>
6  * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
7  */
8 
9 #include "regedit.h"
10 
11 const WCHAR g_szGeneralRegKey[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit";
12 DECLSPEC_IMPORT ULONG WINAPIV DbgPrint(PCCH Format,...);
13 
14 /*
15 VV,VV,VV,VV,WA,WA,WA,WA,WB,WB,WB,WB,R1,R1,R1,R1
16 R2,R2,R2,R2,R3,R3,R3,R3,R4,R4,R4,r4,LL,LL,LL,LL
17 TT,TT,TT,TT,RR,RR,RR,RR,BB,BB,BB,BB,SS,SS,SS,SS
18 NN,NN,NN,NN,KK,KK,KK,KK,DD,DD,DD,DD,SB,SB,SB,SB
19 
20 VV = Version or Sanity? WINDOWPLACEMENT? (2C?)
21 WA = (0=restored / 1=maximized)
22 WB = (1=restored / 3=maximized)
23 R1 = ???? \
24 R2 = ???? | either those are reserved unused or they will
25 R3 = ???? | have IP/INFO if connected to remote registry
26 R4 = ???? /
27 LL = Left position of window
28 TT = top position of window
29 RR = right position of window
30 BB = bottom position of window
31 SS = size of key tree view (splitter)
32 NN = size of 'name' column
33 KK = size of 'type' column (kind)
34 DD = size of 'data' coumn
35 SB = status bar (1=visible / 0=hidden)
36 */
37 
38 typedef struct
39 {
40     WINDOWPLACEMENT tPlacement;
41     int             TreeViewSize;
42     int             NameColumnSize;
43     int             TypeColumnSize;
44     int             DataColumnSize;
45     BOOL            StatusBarVisible;
46 } RegistryBinaryConfig;
47 
LoadSettings(void)48 extern void LoadSettings(void)
49 {
50     HKEY hKey = NULL;
51     WCHAR szBuffer[MAX_PATH];
52 
53     if (RegOpenKeyW(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS)
54     {
55         RegistryBinaryConfig tConfig;
56         DWORD iBufferSize = sizeof(tConfig);
57         BOOL bVisible = FALSE;
58 
59         if (RegQueryValueExW(hKey, L"View", NULL, NULL, (LPBYTE)&tConfig, &iBufferSize) == ERROR_SUCCESS)
60         {
61             if (iBufferSize == sizeof(tConfig))
62             {
63                 RECT rcTemp;
64 
65                 /* Update status bar settings */
66                 CheckMenuItem(GetSubMenu(hMenuFrame, ID_VIEW_MENU), ID_VIEW_STATUSBAR, MF_BYCOMMAND | (tConfig.StatusBarVisible ? MF_CHECKED : MF_UNCHECKED));
67                 ShowWindow(hStatusBar, (tConfig.StatusBarVisible ? SW_SHOW : SW_HIDE));
68 
69                 /* Update listview column width */
70                 (void)ListView_SetColumnWidth(g_pChildWnd->hListWnd, 0, tConfig.NameColumnSize);
71                 (void)ListView_SetColumnWidth(g_pChildWnd->hListWnd, 1, tConfig.TypeColumnSize);
72                 (void)ListView_SetColumnWidth(g_pChildWnd->hListWnd, 2, tConfig.DataColumnSize);
73 
74                 /* Update treeview (splitter) */
75                 GetClientRect(hFrameWnd, &rcTemp);
76                 g_pChildWnd->nSplitPos = tConfig.TreeViewSize;
77                 ResizeWnd(rcTemp.right, rcTemp.bottom);
78 
79                 /* Apply program window settings */
80                 tConfig.tPlacement.length = sizeof(WINDOWPLACEMENT);
81                 bVisible = SetWindowPlacement(hFrameWnd, &tConfig.tPlacement);
82             }
83         }
84 
85         /* In case we fail to restore the window, or open the key, show normal */
86         if (!bVisible)
87             ShowWindow(hFrameWnd, SW_SHOWNORMAL);
88 
89         /* Restore key position */
90         if (QueryStringValue(HKEY_CURRENT_USER, g_szGeneralRegKey, L"LastKey", szBuffer, ARRAY_SIZE(szBuffer)) == ERROR_SUCCESS)
91         {
92             SelectNode(g_pChildWnd->hTreeWnd, szBuffer);
93         }
94 
95         RegCloseKey(hKey);
96     }
97     else
98     {
99         /* Failed to open key, show normal */
100         ShowWindow(hFrameWnd, SW_SHOWNORMAL);
101     }
102 }
103 
SaveSettings(void)104 extern void SaveSettings(void)
105 {
106     HKEY hKey = NULL;
107 
108     if (RegCreateKeyW(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS)
109     {
110         RegistryBinaryConfig tConfig;
111         DWORD iBufferSize = sizeof(tConfig);
112         WCHAR szBuffer[MAX_PATH]; /* FIXME: a complete registry path can be longer than that */
113         LPCWSTR keyPath, rootName;
114         HKEY hRootKey;
115 
116         /* Save key position */
117         keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
118         rootName = get_root_key_name(hRootKey);
119 
120         /* Load "My Computer" string and complete it */
121         if (LoadStringW(hInst, IDS_MY_COMPUTER, szBuffer, ARRAY_SIZE(szBuffer)) &&
122             SUCCEEDED(StringCbCatW(szBuffer, sizeof(szBuffer), L"\\")) &&
123             SUCCEEDED(StringCbCatW(szBuffer, sizeof(szBuffer), rootName)) &&
124             SUCCEEDED(StringCbCatW(szBuffer, sizeof(szBuffer), L"\\")))
125         {
126             HRESULT hr = S_OK;
127             if (keyPath)
128                 hr = StringCbCatW(szBuffer, sizeof(szBuffer), keyPath);
129             if (SUCCEEDED(hr))
130                 RegSetValueExW(hKey, L"LastKey", 0, REG_SZ, (LPBYTE)szBuffer, (DWORD)wcslen(szBuffer) * sizeof(WCHAR));
131             else
132                 DbgPrint("err: (%s:%d): Buffer not big enough for '%S + %S'\n", __FILE__, __LINE__, rootName, keyPath);
133         }
134         else
135         {
136             DbgPrint("err: (%s:%d): Buffer not big enough for '%S'\n", __FILE__, __LINE__, rootName);
137         }
138 
139         /* Get statusbar settings */
140         tConfig.StatusBarVisible = ((GetMenuState(GetSubMenu(hMenuFrame, ID_VIEW_MENU), ID_VIEW_STATUSBAR, MF_BYCOMMAND) & MF_CHECKED) ? 1 : 0);
141 
142         /* Get splitter position */
143         tConfig.TreeViewSize = g_pChildWnd->nSplitPos;
144 
145         /* Get list view column width*/
146         tConfig.NameColumnSize = ListView_GetColumnWidth(g_pChildWnd->hListWnd, 0);
147         tConfig.TypeColumnSize = ListView_GetColumnWidth(g_pChildWnd->hListWnd, 1);
148         tConfig.DataColumnSize = ListView_GetColumnWidth(g_pChildWnd->hListWnd, 2);
149 
150         /* Get program window settings */
151         tConfig.tPlacement.length = sizeof(WINDOWPLACEMENT);
152         GetWindowPlacement(hFrameWnd, &tConfig.tPlacement);
153 
154         /* Save all the data */
155         RegSetValueExW(hKey, L"View", 0, REG_BINARY, (LPBYTE)&tConfig, iBufferSize);
156 
157         RegCloseKey(hKey);
158     }
159 }
160 /* EOF */
161