7a1050953b690c586761e43420956fc23d2c7b11
[reactos.git] / reactos / base / applications / regedit / framewnd.c
1 /*
2 * Regedit frame window
3 *
4 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include "regedit.h"
22
23 #include <commdlg.h>
24 #include <cderr.h>
25 #include <objsel.h>
26
27 /********************************************************************************
28 * Global and Local Variables:
29 */
30
31 #define FAVORITES_MENU_POSITION 3
32
33 static WCHAR s_szFavoritesRegKey[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Favorites";
34
35 static BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
36
37 /*******************************************************************************
38 * Local module support methods
39 */
40
41 static void resize_frame_rect(HWND hWnd, PRECT prect)
42 {
43 RECT rt;
44 /*
45 if (IsWindowVisible(hToolBar)) {
46 SendMessageW(hToolBar, WM_SIZE, 0, 0);
47 GetClientRect(hToolBar, &rt);
48 prect->top = rt.bottom+3;
49 prect->bottom -= rt.bottom+3;
50 }
51 */
52 if (IsWindowVisible(hStatusBar))
53 {
54 SetupStatusBar(hWnd, TRUE);
55 GetClientRect(hStatusBar, &rt);
56 prect->bottom -= rt.bottom;
57 }
58 MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
59 }
60
61 static void resize_frame_client(HWND hWnd)
62 {
63 RECT rect;
64
65 GetClientRect(hWnd, &rect);
66 resize_frame_rect(hWnd, &rect);
67 }
68
69 /********************************************************************************/
70
71 static void OnInitMenu(HWND hWnd)
72 {
73 LONG lResult;
74 HKEY hKey = NULL;
75 DWORD dwIndex, cbValueName, cbValueData, dwType;
76 WCHAR szValueName[256];
77 BYTE abValueData[256];
78 static int s_nFavoriteMenuSubPos = -1;
79 HMENU hMenu;
80 BOOL bDisplayedAny = FALSE;
81
82 /* Find Favorites menu and clear it out */
83 hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION);
84 if (!hMenu)
85 goto done;
86 if (s_nFavoriteMenuSubPos < 0)
87 {
88 s_nFavoriteMenuSubPos = GetMenuItemCount(hMenu);
89 }
90 else
91 {
92 while(RemoveMenu(hMenu, s_nFavoriteMenuSubPos, MF_BYPOSITION)) ;
93 }
94
95 lResult = RegOpenKeyW(HKEY_CURRENT_USER, s_szFavoritesRegKey, &hKey);
96 if (lResult != ERROR_SUCCESS)
97 goto done;
98
99 dwIndex = 0;
100 do
101 {
102 cbValueName = COUNT_OF(szValueName);
103 cbValueData = sizeof(abValueData);
104 lResult = RegEnumValueW(hKey, dwIndex, szValueName, &cbValueName, NULL, &dwType, abValueData, &cbValueData);
105 if ((lResult == ERROR_SUCCESS) && (dwType == REG_SZ))
106 {
107 if (!bDisplayedAny)
108 {
109 AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
110 bDisplayedAny = TRUE;
111 }
112 AppendMenu(hMenu, 0, ID_FAVORITES_MIN + GetMenuItemCount(hMenu), szValueName);
113 }
114 dwIndex++;
115 }
116 while(lResult == ERROR_SUCCESS);
117
118 done:
119 if (hKey)
120 RegCloseKey(hKey);
121 }
122
123 static void OnEnterMenuLoop(HWND hWnd)
124 {
125 int nParts;
126 UNREFERENCED_PARAMETER(hWnd);
127
128 /* Update the status bar pane sizes */
129 nParts = -1;
130 SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
131 bInMenuLoop = TRUE;
132 SendMessageW(hStatusBar, SB_SETTEXTW, (WPARAM)0, (LPARAM)L"");
133 }
134
135 static void OnExitMenuLoop(HWND hWnd)
136 {
137 bInMenuLoop = FALSE;
138 /* Update the status bar pane sizes*/
139 SetupStatusBar(hWnd, TRUE);
140 UpdateStatusBar();
141 }
142
143 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
144 {
145 WCHAR str[100];
146
147 wcscpy(str, L"");
148 if (nFlags & MF_POPUP)
149 {
150 if (hSysMenu != GetMenu(hWnd))
151 {
152 if (nItemID == 2) nItemID = 5;
153 }
154 }
155 if (LoadStringW(hInst, nItemID, str, 100))
156 {
157 /* load appropriate string*/
158 LPWSTR lpsz = str;
159 /* first newline terminates actual string*/
160 lpsz = wcschr(lpsz, L'\n');
161 if (lpsz != NULL)
162 *lpsz = L'\0';
163 }
164 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)str);
165 }
166
167 void SetupStatusBar(HWND hWnd, BOOL bResize)
168 {
169 RECT rc;
170 int nParts;
171 GetClientRect(hWnd, &rc);
172 nParts = rc.right;
173 /* nParts = -1;*/
174 if (bResize)
175 SendMessageW(hStatusBar, WM_SIZE, 0, 0);
176 SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
177 }
178
179 void UpdateStatusBar(void)
180 {
181 HKEY hKeyRoot;
182 LPCWSTR pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
183
184 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)pszKeyPath);
185 }
186
187 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
188 {
189 BOOL vis = IsWindowVisible(hchild);
190 HMENU hMenuView = GetSubMenu(hMenuFrame, ID_VIEW_MENU);
191
192 CheckMenuItem(hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
193 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
194 resize_frame_client(hWnd);
195 }
196
197 static BOOL CheckCommDlgError(HWND hWnd)
198 {
199 DWORD dwErrorCode = CommDlgExtendedError();
200 UNREFERENCED_PARAMETER(hWnd);
201 switch (dwErrorCode)
202 {
203 case CDERR_DIALOGFAILURE:
204 break;
205 case CDERR_FINDRESFAILURE:
206 break;
207 case CDERR_NOHINSTANCE:
208 break;
209 case CDERR_INITIALIZATION:
210 break;
211 case CDERR_NOHOOK:
212 break;
213 case CDERR_LOCKRESFAILURE:
214 break;
215 case CDERR_NOTEMPLATE:
216 break;
217 case CDERR_LOADRESFAILURE:
218 break;
219 case CDERR_STRUCTSIZE:
220 break;
221 case CDERR_LOADSTRFAILURE:
222 break;
223 case FNERR_BUFFERTOOSMALL:
224 break;
225 case CDERR_MEMALLOCFAILURE:
226 break;
227 case FNERR_INVALIDFILENAME:
228 break;
229 case CDERR_MEMLOCKFAILURE:
230 break;
231 case FNERR_SUBCLASSFAILURE:
232 break;
233 default:
234 break;
235 }
236 return TRUE;
237 }
238
239 WCHAR FileNameBuffer[_MAX_PATH];
240 WCHAR FileTitleBuffer[_MAX_PATH];
241
242 typedef struct
243 {
244 UINT DisplayID;
245 UINT FilterID;
246 } FILTERPAIR, *PFILTERPAIR;
247
248 void
249 BuildFilterStrings(WCHAR *Filter, PFILTERPAIR Pairs, int PairCount)
250 {
251 int i, c;
252
253 c = 0;
254 for(i = 0; i < PairCount; i++)
255 {
256 c += LoadStringW(hInst, Pairs[i].DisplayID, &Filter[c], 255);
257 Filter[++c] = L'\0';
258 c += LoadStringW(hInst, Pairs[i].FilterID, &Filter[c], 255);
259 Filter[++c] = L'\0';
260 }
261 Filter[++c] = L'\0';
262 }
263
264 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
265 {
266 FILTERPAIR FilterPairs[4];
267 static WCHAR Filter[1024];
268
269 memset(pofn, 0, sizeof(OPENFILENAME));
270 pofn->lStructSize = sizeof(OPENFILENAME);
271 pofn->hwndOwner = hWnd;
272 pofn->hInstance = hInst;
273
274 /* create filter string */
275 FilterPairs[0].DisplayID = IDS_FLT_REGFILES;
276 FilterPairs[0].FilterID = IDS_FLT_REGFILES_FLT;
277 FilterPairs[1].DisplayID = IDS_FLT_HIVFILES;
278 FilterPairs[1].FilterID = IDS_FLT_HIVFILES_FLT;
279 FilterPairs[2].DisplayID = IDS_FLT_REGEDIT4;
280 FilterPairs[2].FilterID = IDS_FLT_REGEDIT4_FLT;
281 FilterPairs[3].DisplayID = IDS_FLT_ALLFILES;
282 FilterPairs[3].FilterID = IDS_FLT_ALLFILES_FLT;
283 BuildFilterStrings(Filter, FilterPairs, COUNT_OF(FilterPairs));
284
285 pofn->lpstrFilter = Filter;
286 pofn->lpstrFile = FileNameBuffer;
287 pofn->nMaxFile = _MAX_PATH;
288 pofn->lpstrFileTitle = FileTitleBuffer;
289 pofn->nMaxFileTitle = _MAX_PATH;
290 pofn->Flags = OFN_HIDEREADONLY;
291 pofn->lpstrDefExt = L"reg";
292 return TRUE;
293 }
294
295 #define LOADHIVE_KEYNAMELENGTH 128
296
297 static INT_PTR CALLBACK LoadHive_KeyNameInHookProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
298 {
299 static LPWSTR sKey = NULL;
300 switch(uMsg)
301 {
302 case WM_INITDIALOG:
303 sKey = (LPWSTR)lParam;
304 break;
305 case WM_COMMAND:
306 switch(LOWORD(wParam))
307 {
308 case IDOK:
309 if(GetDlgItemTextW(hWndDlg, IDC_EDIT_KEY, sKey, LOADHIVE_KEYNAMELENGTH))
310 return EndDialog(hWndDlg, -1);
311 else
312 return EndDialog(hWndDlg, 0);
313 case IDCANCEL:
314 return EndDialog(hWndDlg, 0);
315 }
316 break;
317 }
318 return FALSE;
319 }
320
321 static BOOL EnablePrivilege(LPCWSTR lpszPrivilegeName, LPCWSTR lpszSystemName, BOOL bEnablePrivilege)
322 {
323 BOOL bRet = FALSE;
324 HANDLE hToken = NULL;
325
326 if (OpenProcessToken(GetCurrentProcess(),
327 TOKEN_ADJUST_PRIVILEGES,
328 &hToken))
329 {
330 TOKEN_PRIVILEGES tp;
331
332 tp.PrivilegeCount = 1;
333 tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0);
334
335 if (LookupPrivilegeValueW(lpszSystemName,
336 lpszPrivilegeName,
337 &tp.Privileges[0].Luid))
338 {
339 bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
340
341 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
342 bRet = FALSE;
343 }
344
345 CloseHandle(hToken);
346 }
347
348 return bRet;
349 }
350
351 static BOOL LoadHive(HWND hWnd)
352 {
353 OPENFILENAME ofn;
354 WCHAR Caption[128];
355 LPCWSTR pszKeyPath;
356 WCHAR xPath[LOADHIVE_KEYNAMELENGTH];
357 HKEY hRootKey;
358 WCHAR Filter[1024];
359 FILTERPAIR filter;
360 /* get the item key to load the hive in */
361 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
362 /* initialize the "open file" dialog */
363 InitOpenFileName(hWnd, &ofn);
364 /* build the "All Files" filter up */
365 filter.DisplayID = IDS_FLT_ALLFILES;
366 filter.FilterID = IDS_FLT_ALLFILES_FLT;
367 BuildFilterStrings(Filter, &filter, 1);
368 ofn.lpstrFilter = Filter;
369 /* load and set the caption and flags for dialog */
370 LoadStringW(hInst, IDS_LOAD_HIVE, Caption, COUNT_OF(Caption));
371 ofn.lpstrTitle = Caption;
372 ofn.Flags |= OFN_ENABLESIZING;
373 /* ofn.lCustData = ;*/
374 /* now load the hive */
375 if (GetOpenFileName(&ofn))
376 {
377 if (DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_LOADHIVE), hWnd,
378 &LoadHive_KeyNameInHookProc, (LPARAM)xPath))
379 {
380 LONG regLoadResult;
381
382 /* Enable the 'restore' privilege, load the hive, disable the privilege */
383 EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE);
384 regLoadResult = RegLoadKeyW(hRootKey, xPath, ofn.lpstrFile);
385 EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE);
386
387 if(regLoadResult == ERROR_SUCCESS)
388 {
389 /* refresh tree and list views */
390 RefreshTreeView(g_pChildWnd->hTreeWnd);
391 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
392 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
393 }
394 else
395 {
396 ErrorMessageBox(hWnd, Caption, regLoadResult);
397 return FALSE;
398 }
399 }
400 }
401 else
402 {
403 CheckCommDlgError(hWnd);
404 }
405 return TRUE;
406 }
407
408 static BOOL UnloadHive(HWND hWnd)
409 {
410 WCHAR Caption[128];
411 LPCWSTR pszKeyPath;
412 HKEY hRootKey;
413 LONG regUnloadResult;
414
415 /* get the item key to unload */
416 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
417 /* load and set the caption and flags for dialog */
418 LoadStringW(hInst, IDS_UNLOAD_HIVE, Caption, COUNT_OF(Caption));
419
420 /* Enable the 'restore' privilege, unload the hive, disable the privilege */
421 EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE);
422 regUnloadResult = RegUnLoadKeyW(hRootKey, pszKeyPath);
423 EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE);
424
425 if(regUnloadResult == ERROR_SUCCESS)
426 {
427 /* refresh tree and list views */
428 RefreshTreeView(g_pChildWnd->hTreeWnd);
429 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
430 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
431 }
432 else
433 {
434 ErrorMessageBox(hWnd, Caption, regUnloadResult);
435 return FALSE;
436 }
437 return TRUE;
438 }
439
440 static BOOL ImportRegistryFile(HWND hWnd)
441 {
442 BOOL bRet = FALSE;
443 OPENFILENAME ofn;
444 WCHAR Caption[128], szTitle[512], szText[512];
445 HKEY hKeyRoot;
446 LPCWSTR pszKeyPath;
447
448 /* Figure out in which key path we are importing */
449 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
450
451 InitOpenFileName(hWnd, &ofn);
452 LoadStringW(hInst, IDS_IMPORT_REG_FILE, Caption, COUNT_OF(Caption));
453 ofn.lpstrTitle = Caption;
454 ofn.Flags |= OFN_ENABLESIZING;
455 /* ofn.lCustData = ;*/
456 if (GetOpenFileName(&ofn))
457 {
458 /* Look at the extension of the file to determine its type */
459 if (ofn.nFileExtension >= 1 &&
460 _wcsicmp(ofn.lpstrFile + ofn.nFileExtension, L"reg") == 0) /* REGEDIT4 or Windows Registry Editor Version 5.00 */
461 {
462 /* Open the file */
463 FILE* fp = _wfopen(ofn.lpstrFile, L"r");
464
465 /* Import it */
466 if (fp == NULL || !import_registry_file(fp))
467 {
468 /* Error opening the file */
469 LoadStringW(hInst, IDS_APP_TITLE, szTitle, COUNT_OF(szTitle));
470 LoadStringW(hInst, IDS_IMPORT_ERROR, szText, COUNT_OF(szText));
471 InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, szText, ofn.lpstrFile);
472 bRet = FALSE;
473 }
474 else
475 {
476 /* Show successful import */
477 LoadStringW(hInst, IDS_APP_TITLE, szTitle, COUNT_OF(szTitle));
478 LoadStringW(hInst, IDS_IMPORT_OK, szText, COUNT_OF(szText));
479 InfoMessageBox(hWnd, MB_OK | MB_ICONINFORMATION, szTitle, szText, ofn.lpstrFile);
480 bRet = TRUE;
481 }
482
483 /* Close the file */
484 if (fp) fclose(fp);
485 }
486 else /* Registry Hive Files */
487 {
488 LoadStringW(hInst, IDS_QUERY_IMPORT_HIVE_CAPTION, szTitle, COUNT_OF(szTitle));
489 LoadStringW(hInst, IDS_QUERY_IMPORT_HIVE_MSG, szText, COUNT_OF(szText));
490
491 /* Display a confirmation message */
492 if (MessageBoxW(g_pChildWnd->hWnd, szText, szTitle, MB_ICONWARNING | MB_YESNO) == IDYES)
493 {
494 LONG lResult;
495 HKEY hSubKey;
496
497 /* Open the subkey */
498 lResult = RegOpenKeyExW(hKeyRoot, pszKeyPath, 0, KEY_WRITE, &hSubKey);
499 if (lResult == ERROR_SUCCESS)
500 {
501 /* Enable the 'restore' privilege, restore the hive then disable the privilege */
502 EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE);
503 lResult = RegRestoreKey(hSubKey, ofn.lpstrFile, REG_FORCE_RESTORE);
504 EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE);
505
506 /* Flush the subkey and close it */
507 RegFlushKey(hSubKey);
508 RegCloseKey(hSubKey);
509 }
510
511 /* Set the return value */
512 bRet = (lResult == ERROR_SUCCESS);
513
514 /* Display error, if any */
515 if (!bRet) ErrorMessageBox(hWnd, Caption, lResult);
516 }
517 }
518 }
519 else
520 {
521 CheckCommDlgError(hWnd);
522 }
523
524 /* refresh tree and list views */
525 RefreshTreeView(g_pChildWnd->hTreeWnd);
526 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
527 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, pszKeyPath);
528
529 return bRet;
530 }
531
532 static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
533 {
534 HWND hwndExportAll;
535 HWND hwndExportBranch;
536 HWND hwndExportBranchText;
537 UINT_PTR iResult = 0;
538 OPENFILENAME *pOfn;
539 LPWSTR pszSelectedKey;
540 OFNOTIFY *pOfnNotify;
541
542 UNREFERENCED_PARAMETER(wParam);
543
544 switch(uiMsg)
545 {
546 case WM_INITDIALOG:
547 pOfn = (OPENFILENAME *) lParam;
548 pszSelectedKey = (LPWSTR) pOfn->lCustData;
549
550 hwndExportAll = GetDlgItem(hdlg, IDC_EXPORT_ALL);
551 if (hwndExportAll)
552 SendMessageW(hwndExportAll, BM_SETCHECK, pszSelectedKey ? BST_UNCHECKED : BST_CHECKED, 0);
553
554 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
555 if (hwndExportBranch)
556 SendMessageW(hwndExportBranch, BM_SETCHECK, pszSelectedKey ? BST_CHECKED : BST_UNCHECKED, 0);
557
558 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
559 if (hwndExportBranchText)
560 SetWindowTextW(hwndExportBranchText, pszSelectedKey);
561 break;
562
563 case WM_NOTIFY:
564 if (((NMHDR *) lParam)->code == CDN_FILEOK)
565 {
566 pOfnNotify = (OFNOTIFY *) lParam;
567 pszSelectedKey = (LPWSTR) pOfnNotify->lpOFN->lCustData;
568
569 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
570 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
571 if (hwndExportBranch && hwndExportBranchText
572 && (SendMessageW(hwndExportBranch, BM_GETCHECK, 0, 0) == BST_CHECKED))
573 {
574 GetWindowTextW(hwndExportBranchText, pszSelectedKey, _MAX_PATH);
575 }
576 else
577 {
578 pszSelectedKey[0] = L'\0';
579 }
580 }
581 break;
582 }
583 return iResult;
584 }
585
586 BOOL ExportRegistryFile(HWND hWnd)
587 {
588 BOOL bRet = FALSE;
589 OPENFILENAME ofn;
590 WCHAR ExportKeyPath[_MAX_PATH] = {0};
591 WCHAR Caption[128], szTitle[512], szText[512];
592 HKEY hKeyRoot;
593 LPCWSTR pszKeyPath;
594
595 /* Figure out which key path we are exporting */
596 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
597 GetKeyName(ExportKeyPath, COUNT_OF(ExportKeyPath), hKeyRoot, pszKeyPath);
598
599 InitOpenFileName(hWnd, &ofn);
600 LoadStringW(hInst, IDS_EXPORT_REG_FILE, Caption, COUNT_OF(Caption));
601 ofn.lpstrTitle = Caption;
602
603 /* Only set the path if a key (not the root node) is selected */
604 if (hKeyRoot != 0)
605 {
606 ofn.lCustData = (LPARAM) ExportKeyPath;
607 }
608 ofn.Flags = OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_OVERWRITEPROMPT;
609 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
610 ofn.lpTemplateName = MAKEINTRESOURCEW(IDD_EXPORTRANGE);
611 if (GetSaveFileName(&ofn))
612 {
613 switch (ofn.nFilterIndex)
614 {
615 case 2: /* Registry Hive Files */
616 {
617 LONG lResult;
618 HKEY hSubKey;
619
620 /* Open the subkey */
621 lResult = RegOpenKeyExW(hKeyRoot, pszKeyPath, 0, KEY_READ, &hSubKey);
622 if (lResult == ERROR_SUCCESS)
623 {
624 /* Enable the 'backup' privilege, save the hive then disable the privilege */
625 EnablePrivilege(SE_BACKUP_NAME, NULL, TRUE);
626 lResult = RegSaveKeyW(hSubKey, ofn.lpstrFile, NULL);
627 if (lResult == ERROR_ALREADY_EXISTS)
628 {
629 /*
630 * We are here, that means that we already said "yes" to the confirmation dialog.
631 * So we absolutely want to replace the hive file.
632 */
633 if (DeleteFileW(ofn.lpstrFile))
634 {
635 /* Try again */
636 lResult = RegSaveKeyW(hSubKey, ofn.lpstrFile, NULL);
637 }
638 }
639 EnablePrivilege(SE_BACKUP_NAME, NULL, FALSE);
640
641 if (lResult != ERROR_SUCCESS)
642 {
643 /*
644 * If we are here, it's because RegSaveKeyW has failed for any reason.
645 * The problem is that even if it has failed, it has created or
646 * replaced the exported hive file with a new empty file. We don't
647 * want to keep this file, so we delete it.
648 */
649 DeleteFileW(ofn.lpstrFile);
650 }
651
652 /* Close the subkey */
653 RegCloseKey(hSubKey);
654 }
655
656 /* Set the return value */
657 bRet = (lResult == ERROR_SUCCESS);
658
659 /* Display error, if any */
660 if (!bRet) ErrorMessageBox(hWnd, Caption, lResult);
661
662 break;
663 }
664
665 case 1: /* Windows Registry Editor Version 5.00 */
666 case 3: /* REGEDIT4 */
667 default: /* All files ==> use Windows Registry Editor Version 5.00 */
668 {
669 if (!export_registry_key(ofn.lpstrFile, ExportKeyPath,
670 (ofn.nFilterIndex == 3 ? REG_FORMAT_4
671 : REG_FORMAT_5)))
672 {
673 /* Error creating the file */
674 LoadStringW(hInst, IDS_APP_TITLE, szTitle, COUNT_OF(szTitle));
675 LoadStringW(hInst, IDS_EXPORT_ERROR, szText, COUNT_OF(szText));
676 InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, szText, ofn.lpstrFile);
677 bRet = FALSE;
678 }
679 else
680 {
681 bRet = TRUE;
682 }
683
684 break;
685 }
686 }
687 }
688 else
689 {
690 CheckCommDlgError(hWnd);
691 }
692
693 return bRet;
694 }
695
696 BOOL PrintRegistryHive(HWND hWnd, LPWSTR path)
697 {
698 #if 1
699 PRINTDLG pd;
700 UNREFERENCED_PARAMETER(path);
701
702 ZeroMemory(&pd, sizeof(PRINTDLG));
703 pd.lStructSize = sizeof(PRINTDLG);
704 pd.hwndOwner = hWnd;
705 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
706 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
707 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
708 pd.nCopies = 1;
709 pd.nFromPage = 0xFFFF;
710 pd.nToPage = 0xFFFF;
711 pd.nMinPage = 1;
712 pd.nMaxPage = 0xFFFF;
713 if (PrintDlg(&pd))
714 {
715 /* GDI calls to render output. */
716 DeleteDC(pd.hDC); /* Delete DC when done.*/
717 }
718 #else
719 HRESULT hResult;
720 PRINTDLGEX pd;
721
722 hResult = PrintDlgEx(&pd);
723 if (hResult == S_OK)
724 {
725 switch (pd.dwResultAction)
726 {
727 case PD_RESULT_APPLY:
728 /*The user clicked the Apply button and later clicked the Cancel button. This indicates that the user wants to apply the changes made in the property sheet, but does not yet want to print. The PRINTDLGEX structure contains the information specified by the user at the time the Apply button was clicked. */
729 break;
730 case PD_RESULT_CANCEL:
731 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
732 break;
733 case PD_RESULT_PRINT:
734 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
735 break;
736 default:
737 break;
738 }
739 }
740 else
741 {
742 switch (hResult)
743 {
744 case E_OUTOFMEMORY:
745 /*Insufficient memory. */
746 break;
747 case E_INVALIDARG:
748 /* One or more arguments are invalid. */
749 break;
750 case E_POINTER:
751 /*Invalid pointer. */
752 break;
753 case E_HANDLE:
754 /*Invalid handle. */
755 break;
756 case E_FAIL:
757 /*Unspecified error. */
758 break;
759 default:
760 break;
761 }
762 return FALSE;
763 }
764 #endif
765 return TRUE;
766 }
767
768 static void ChooseFavorite(LPCWSTR pszFavorite)
769 {
770 HKEY hKey = NULL;
771 WCHAR szFavoritePath[512];
772 DWORD cbData, dwType;
773
774 if (RegOpenKeyExW(HKEY_CURRENT_USER, s_szFavoritesRegKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
775 goto done;
776
777 cbData = sizeof(szFavoritePath);
778 memset(szFavoritePath, 0, sizeof(szFavoritePath));
779 if (RegQueryValueExW(hKey, pszFavorite, NULL, &dwType, (LPBYTE) szFavoritePath, &cbData) != ERROR_SUCCESS)
780 goto done;
781
782 if (dwType == REG_SZ)
783 SelectNode(g_pChildWnd->hTreeWnd, szFavoritePath);
784
785 done:
786 if (hKey)
787 RegCloseKey(hKey);
788 }
789
790 BOOL CopyKeyName(HWND hWnd, HKEY hRootKey, LPCWSTR keyName)
791 {
792 BOOL bClipboardOpened = FALSE;
793 BOOL bSuccess = FALSE;
794 WCHAR szBuffer[512];
795 HGLOBAL hGlobal;
796 LPWSTR s;
797
798 if (!OpenClipboard(hWnd))
799 goto done;
800 bClipboardOpened = TRUE;
801
802 if (!EmptyClipboard())
803 goto done;
804
805 if (!GetKeyName(szBuffer, COUNT_OF(szBuffer), hRootKey, keyName))
806 goto done;
807
808 hGlobal = GlobalAlloc(GMEM_MOVEABLE, (wcslen(szBuffer) + 1) * sizeof(WCHAR));
809 if (!hGlobal)
810 goto done;
811
812 s = GlobalLock(hGlobal);
813 wcscpy(s, szBuffer);
814 GlobalUnlock(hGlobal);
815
816 SetClipboardData(CF_UNICODETEXT, hGlobal);
817 bSuccess = TRUE;
818
819 done:
820 if (bClipboardOpened)
821 CloseClipboard();
822 return bSuccess;
823 }
824
825 static BOOL CreateNewValue(HKEY hRootKey, LPCWSTR pszKeyPath, DWORD dwType)
826 {
827 WCHAR szNewValueFormat[128];
828 WCHAR szNewValue[128];
829 int iIndex = 1;
830 BYTE data[128];
831 DWORD dwExistingType, cbData;
832 LONG lResult;
833 HKEY hKey;
834 LVFINDINFO lvfi;
835
836 if (RegOpenKeyExW(hRootKey, pszKeyPath, 0, KEY_QUERY_VALUE | KEY_SET_VALUE,
837 &hKey) != ERROR_SUCCESS)
838 return FALSE;
839
840 LoadStringW(hInst, IDS_NEW_VALUE, szNewValueFormat, COUNT_OF(szNewValueFormat));
841
842 do
843 {
844 wsprintf(szNewValue, szNewValueFormat, iIndex++);
845 cbData = sizeof(data);
846 lResult = RegQueryValueExW(hKey, szNewValue, NULL, &dwExistingType, data, &cbData);
847 }
848 while(lResult == ERROR_SUCCESS);
849
850 switch(dwType)
851 {
852 case REG_DWORD:
853 cbData = sizeof(DWORD);
854 break;
855 case REG_SZ:
856 case REG_EXPAND_SZ:
857 cbData = sizeof(WCHAR);
858 break;
859 case REG_MULTI_SZ:
860 /*
861 * WARNING: An empty multi-string has only one null char.
862 * Indeed, multi-strings are built in the following form:
863 * str1\0str2\0...strN\0\0
864 * where each strI\0 is a null-terminated string, and it
865 * ends with a terminating empty string.
866 * Therefore an empty multi-string contains only the terminating
867 * empty string, that is, one null char.
868 */
869 cbData = sizeof(WCHAR);
870 break;
871 case REG_QWORD: /* REG_QWORD_LITTLE_ENDIAN */
872 cbData = sizeof(DWORDLONG); // == sizeof(DWORD) * 2;
873 break;
874 default:
875 cbData = 0;
876 break;
877 }
878 memset(data, 0, cbData);
879 lResult = RegSetValueExW(hKey, szNewValue, 0, dwType, data, cbData);
880 RegCloseKey(hKey);
881 if (lResult != ERROR_SUCCESS)
882 {
883 return FALSE;
884 }
885
886 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
887
888 /* locate the newly added value, and get ready to rename it */
889 memset(&lvfi, 0, sizeof(lvfi));
890 lvfi.flags = LVFI_STRING;
891 lvfi.psz = szNewValue;
892 iIndex = ListView_FindItem(g_pChildWnd->hListWnd, -1, &lvfi);
893 if (iIndex >= 0)
894 (void)ListView_EditLabel(g_pChildWnd->hListWnd, iIndex);
895
896 return TRUE;
897 }
898
899 static HRESULT
900 InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker)
901 {
902 HRESULT hRet;
903
904 *pDsObjectPicker = NULL;
905
906 hRet = CoCreateInstance(&CLSID_DsObjectPicker,
907 NULL,
908 CLSCTX_INPROC_SERVER,
909 &IID_IDsObjectPicker,
910 (LPVOID*)pDsObjectPicker);
911 if (SUCCEEDED(hRet))
912 {
913 DSOP_INIT_INFO InitInfo;
914 static DSOP_SCOPE_INIT_INFO Scopes[] =
915 {
916 {
917 sizeof(DSOP_SCOPE_INIT_INFO),
918 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE |
919 DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
920 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP |
921 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN,
922 0,
923 {
924 {
925 DSOP_FILTER_COMPUTERS,
926 0,
927 0
928 },
929 DSOP_DOWNLEVEL_FILTER_COMPUTERS
930 },
931 NULL,
932 NULL,
933 S_OK
934 },
935 };
936
937 InitInfo.cbSize = sizeof(InitInfo);
938 InitInfo.pwzTargetComputer = NULL;
939 InitInfo.cDsScopeInfos = COUNT_OF(Scopes);
940 InitInfo.aDsScopeInfos = Scopes;
941 InitInfo.flOptions = 0;
942 InitInfo.cAttributesToFetch = 0;
943 InitInfo.apwzAttributeNames = NULL;
944
945 hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker,
946 &InitInfo);
947
948 if (FAILED(hRet))
949 {
950 /* delete the object picker in case initialization failed! */
951 (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker);
952 }
953 }
954
955 return hRet;
956 }
957
958 static HRESULT
959 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
960 IN HWND hwndParent OPTIONAL,
961 OUT LPWSTR lpBuffer,
962 IN UINT uSize)
963 {
964 IDataObject *pdo = NULL;
965 HRESULT hRet;
966
967 hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker,
968 hwndParent,
969 &pdo);
970 if (hRet == S_OK)
971 {
972 STGMEDIUM stm;
973 FORMATETC fe;
974
975 fe.cfFormat = (CLIPFORMAT) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST);
976 fe.ptd = NULL;
977 fe.dwAspect = DVASPECT_CONTENT;
978 fe.lindex = -1;
979 fe.tymed = TYMED_HGLOBAL;
980
981 hRet = pdo->lpVtbl->GetData(pdo,
982 &fe,
983 &stm);
984 if (SUCCEEDED(hRet))
985 {
986 PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal);
987 if (SelectionList != NULL)
988 {
989 if (SelectionList->cItems == 1)
990 {
991 size_t nlen = wcslen(SelectionList->aDsSelection[0].pwzName);
992 if (nlen >= uSize)
993 {
994 nlen = uSize - 1;
995 }
996
997 memcpy(lpBuffer,
998 SelectionList->aDsSelection[0].pwzName,
999 nlen * sizeof(WCHAR));
1000
1001 lpBuffer[nlen] = L'\0';
1002 }
1003
1004 GlobalUnlock(stm.hGlobal);
1005 }
1006
1007 ReleaseStgMedium(&stm);
1008 }
1009
1010 pdo->lpVtbl->Release(pdo);
1011 }
1012
1013 return hRet;
1014 }
1015
1016 static VOID
1017 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
1018 {
1019 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
1020 }
1021
1022 /*******************************************************************************
1023 *
1024 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
1025 *
1026 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
1027 *
1028 */
1029 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1030 {
1031 HKEY hKeyRoot = 0, hKey = 0;
1032 LPCWSTR keyPath;
1033 LPCWSTR valueName;
1034 BOOL result = TRUE;
1035 REGSAM regsam = KEY_READ;
1036 LONG lRet;
1037 int item;
1038
1039 UNREFERENCED_PARAMETER(lParam);
1040 UNREFERENCED_PARAMETER(message);
1041
1042 switch (LOWORD(wParam))
1043 {
1044 case ID_REGISTRY_LOADHIVE:
1045 LoadHive(hWnd);
1046 return TRUE;
1047 case ID_REGISTRY_UNLOADHIVE:
1048 UnloadHive(hWnd);
1049 return TRUE;
1050 case ID_REGISTRY_IMPORTREGISTRYFILE:
1051 ImportRegistryFile(hWnd);
1052 return TRUE;
1053 case ID_REGISTRY_EXPORTREGISTRYFILE:
1054 ExportRegistryFile(hWnd);
1055 return TRUE;
1056 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
1057 {
1058 IDsObjectPicker *ObjectPicker;
1059 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1060 HRESULT hRet;
1061
1062 hRet = CoInitialize(NULL);
1063 if (SUCCEEDED(hRet))
1064 {
1065 hRet = InitializeRemoteRegistryPicker(&ObjectPicker);
1066 if (SUCCEEDED(hRet))
1067 {
1068 hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker,
1069 hWnd,
1070 szComputerName,
1071 COUNT_OF(szComputerName));
1072 if (hRet == S_OK)
1073 {
1074 /* FIXME - connect to the registry */
1075 }
1076
1077 FreeObjectPicker(ObjectPicker);
1078 }
1079
1080 CoUninitialize();
1081 }
1082
1083 return TRUE;
1084 }
1085 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
1086 return TRUE;
1087 case ID_REGISTRY_PRINT:
1088 PrintRegistryHive(hWnd, L"");
1089 return TRUE;
1090 case ID_REGISTRY_EXIT:
1091 DestroyWindow(hWnd);
1092 return TRUE;
1093 case ID_VIEW_STATUSBAR:
1094 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
1095 return TRUE;
1096 case ID_HELP_HELPTOPICS:
1097 WinHelpW(hWnd, getAppName(), HELP_FINDER, 0);
1098 return TRUE;
1099 case ID_HELP_ABOUT:
1100 ShowAboutBox(hWnd);
1101 return TRUE;
1102 case ID_VIEW_SPLIT:
1103 {
1104 RECT rt;
1105 POINT pt, pts;
1106 GetClientRect(g_pChildWnd->hWnd, &rt);
1107 pt.x = rt.left + g_pChildWnd->nSplitPos;
1108 pt.y = (rt.bottom / 2);
1109 pts = pt;
1110 if(ClientToScreen(g_pChildWnd->hWnd, &pts))
1111 {
1112 SetCursorPos(pts.x, pts.y);
1113 SetCursor(LoadCursorW(0, IDC_SIZEWE));
1114 SendMessageW(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
1115 }
1116 return TRUE;
1117 }
1118 case ID_EDIT_RENAME:
1119 case ID_EDIT_MODIFY:
1120 case ID_EDIT_MODIFY_BIN:
1121 case ID_EDIT_DELETE:
1122 regsam |= KEY_WRITE;
1123 break;
1124 }
1125
1126 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
1127 valueName = GetValueName(g_pChildWnd->hListWnd, -1);
1128
1129 if (!keyPath)
1130 return TRUE;
1131
1132 lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, regsam, &hKey);
1133 if (lRet != ERROR_SUCCESS)
1134 hKey = 0;
1135
1136 switch (LOWORD(wParam))
1137 {
1138 case ID_EDIT_MODIFY:
1139 if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE))
1140 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1141 break;
1142 case ID_EDIT_MODIFY_BIN:
1143 if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE))
1144 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1145 break;
1146 case ID_EDIT_RENAME:
1147 if (GetFocus() == g_pChildWnd->hListWnd)
1148 {
1149 if(ListView_GetSelectedCount(g_pChildWnd->hListWnd) == 1)
1150 {
1151 item = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
1152 if(item > -1)
1153 {
1154 (void)ListView_EditLabel(g_pChildWnd->hListWnd, item);
1155 }
1156 }
1157 }
1158 else if (GetFocus() == g_pChildWnd->hTreeWnd)
1159 {
1160 /* Get focused entry of treeview (if any) */
1161 HTREEITEM hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
1162 if (hItem != NULL)
1163 (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, hItem);
1164 }
1165 break;
1166 case ID_EDIT_DELETE:
1167 {
1168 if (GetFocus() == g_pChildWnd->hListWnd)
1169 {
1170 UINT nSelected = ListView_GetSelectedCount(g_pChildWnd->hListWnd);
1171 if(nSelected >= 1)
1172 {
1173 WCHAR msg[128], caption[128];
1174 LoadStringW(hInst, IDS_QUERY_DELETE_CONFIRM, caption, COUNT_OF(caption));
1175 LoadStringW(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, COUNT_OF(msg));
1176 if(MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES)
1177 {
1178 int ni, errs;
1179
1180 item = -1;
1181 errs = 0;
1182 while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1)
1183 {
1184 valueName = GetValueName(g_pChildWnd->hListWnd, item);
1185 if(RegDeleteValueW(hKey, valueName) != ERROR_SUCCESS)
1186 {
1187 errs++;
1188 }
1189 item = ni;
1190 }
1191
1192 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1193 if(errs > 0)
1194 {
1195 LoadStringW(hInst, IDS_ERR_DELVAL_CAPTION, caption, COUNT_OF(caption));
1196 LoadStringW(hInst, IDS_ERR_DELETEVALUE, msg, COUNT_OF(msg));
1197 MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP);
1198 }
1199 }
1200 }
1201 }
1202 else if (GetFocus() == g_pChildWnd->hTreeWnd)
1203 {
1204 if (keyPath == 0 || *keyPath == 0)
1205 {
1206 MessageBeep(MB_ICONHAND);
1207 }
1208 else if (DeleteKey(hWnd, hKeyRoot, keyPath))
1209 {
1210 DeleteNode(g_pChildWnd->hTreeWnd, 0);
1211 RefreshTreeView(g_pChildWnd->hTreeWnd);
1212 }
1213 }
1214 break;
1215 }
1216 case ID_EDIT_NEW_STRINGVALUE:
1217 CreateNewValue(hKeyRoot, keyPath, REG_SZ);
1218 break;
1219 case ID_EDIT_NEW_BINARYVALUE:
1220 CreateNewValue(hKeyRoot, keyPath, REG_BINARY);
1221 break;
1222 case ID_EDIT_NEW_DWORDVALUE:
1223 CreateNewValue(hKeyRoot, keyPath, REG_DWORD);
1224 break;
1225 case ID_EDIT_NEW_MULTISTRINGVALUE:
1226 CreateNewValue(hKeyRoot, keyPath, REG_MULTI_SZ);
1227 break;
1228 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE:
1229 CreateNewValue(hKeyRoot, keyPath, REG_EXPAND_SZ);
1230 break;
1231 case ID_EDIT_FIND:
1232 FindDialog(hWnd);
1233 break;
1234 case ID_EDIT_FINDNEXT:
1235 FindNext(hWnd);
1236 break;
1237 case ID_EDIT_COPYKEYNAME:
1238 CopyKeyName(hWnd, hKeyRoot, keyPath);
1239 break;
1240 case ID_EDIT_PERMISSIONS:
1241 RegKeyEditPermissions(hWnd, hKeyRoot, NULL, keyPath);
1242 break;
1243 case ID_REGISTRY_PRINTERSETUP:
1244 /*PRINTDLG pd;*/
1245 /*PrintDlg(&pd);*/
1246 /*PAGESETUPDLG psd;*/
1247 /*PageSetupDlg(&psd);*/
1248 break;
1249 case ID_REGISTRY_OPENLOCAL:
1250 break;
1251
1252 case ID_VIEW_REFRESH:
1253 RefreshTreeView(g_pChildWnd->hTreeWnd);
1254 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
1255 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1256 break;
1257 /*case ID_OPTIONS_TOOLBAR:*/
1258 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1259 /* break;*/
1260 case ID_EDIT_NEW_KEY:
1261 CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd));
1262 break;
1263 default:
1264 if ((LOWORD(wParam) >= ID_FAVORITES_MIN) && (LOWORD(wParam) <= ID_FAVORITES_MAX))
1265 {
1266 HMENU hMenu;
1267 MENUITEMINFOW mii;
1268 WCHAR szFavorite[512];
1269
1270 hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION);
1271
1272 memset(&mii, 0, sizeof(mii));
1273 mii.cbSize = sizeof(mii);
1274 mii.fMask = MIIM_TYPE;
1275 mii.fType = MFT_STRING;
1276 mii.dwTypeData = szFavorite;
1277 mii.cch = COUNT_OF(szFavorite);
1278
1279 if (GetMenuItemInfo(hMenu, LOWORD(wParam) - ID_FAVORITES_MIN, TRUE, &mii))
1280 {
1281 ChooseFavorite(szFavorite);
1282 }
1283 }
1284 else
1285 {
1286 result = FALSE;
1287 }
1288 break;
1289 }
1290
1291 if(hKey)
1292 RegCloseKey(hKey);
1293 return result;
1294 }
1295
1296 /********************************************************************************
1297 *
1298 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1299 *
1300 * PURPOSE: Processes messages for the main frame window.
1301 *
1302 * WM_COMMAND - process the application menu
1303 * WM_DESTROY - post a quit message and return
1304 *
1305 */
1306
1307 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1308 {
1309 switch (message)
1310 {
1311 case WM_CREATE:
1312 CreateWindowExW(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE,
1313 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
1314 hWnd, (HMENU)0, hInst, 0);
1315 break;
1316 case WM_COMMAND:
1317 if (!_CmdWndProc(hWnd, message, wParam, lParam))
1318 return DefWindowProcW(hWnd, message, wParam, lParam);
1319 break;
1320 case WM_ACTIVATE:
1321 if (LOWORD(hWnd) && g_pChildWnd)
1322 SetFocus(g_pChildWnd->hWnd);
1323 break;
1324 case WM_SIZE:
1325 resize_frame_client(hWnd);
1326 break;
1327 case WM_TIMER:
1328 break;
1329 case WM_INITMENU:
1330 OnInitMenu(hWnd);
1331 break;
1332 case WM_ENTERMENULOOP:
1333 OnEnterMenuLoop(hWnd);
1334 break;
1335 case WM_EXITMENULOOP:
1336 OnExitMenuLoop(hWnd);
1337 break;
1338 case WM_MENUSELECT:
1339 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
1340 break;
1341 case WM_SYSCOLORCHANGE:
1342 /* Forward WM_SYSCOLORCHANGE to common controls */
1343 SendMessageW(g_pChildWnd->hListWnd, WM_SYSCOLORCHANGE, 0, 0);
1344 SendMessageW(g_pChildWnd->hTreeWnd, WM_SYSCOLORCHANGE, 0, 0);
1345 break;
1346 case WM_DESTROY:
1347 WinHelpW(hWnd, getAppName(), HELP_QUIT, 0);
1348 SaveSettings();
1349 PostQuitMessage(0);
1350 default:
1351 return DefWindowProcW(hWnd, message, wParam, lParam);
1352 }
1353 return 0;
1354 }