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