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