Sync with trunk r58740.
[reactos.git] / 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 #define LOADHIVE_KEYNAMELENGTH 128
292
293 static INT_PTR CALLBACK LoadHive_KeyNameInHookProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
294 {
295 static LPWSTR sKey = NULL;
296 switch(uMsg)
297 {
298 case WM_INITDIALOG:
299 sKey = (LPWSTR)lParam;
300 break;
301 case WM_COMMAND:
302 switch(LOWORD(wParam))
303 {
304 case IDOK:
305 if(GetDlgItemTextW(hWndDlg, IDC_EDIT_KEY, sKey, LOADHIVE_KEYNAMELENGTH))
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(LPCWSTR lpszPrivilegeName, LPCWSTR 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 (LookupPrivilegeValueW(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 WCHAR Caption[128];
351 LPCWSTR pszKeyPath;
352 WCHAR xPath[LOADHIVE_KEYNAMELENGTH];
353 HKEY hRootKey;
354 WCHAR 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 LoadStringW(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 (DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_LOADHIVE), hWnd,
374 &LoadHive_KeyNameInHookProc, (LPARAM)xPath))
375 {
376 LONG regLoadResult;
377
378 /* Enable the 'restore' privilege, load the hive, disable the privilege */
379 EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE);
380 regLoadResult = RegLoadKeyW(hRootKey, xPath, ofn.lpstrFile);
381 EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE);
382
383 if(regLoadResult == ERROR_SUCCESS)
384 {
385 /* refresh tree and list views */
386 RefreshTreeView(g_pChildWnd->hTreeWnd);
387 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
388 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
389 }
390 else
391 {
392 ErrorMessageBox(hWnd, Caption, regLoadResult);
393 return FALSE;
394 }
395 }
396 }
397 else
398 {
399 CheckCommDlgError(hWnd);
400 }
401 return TRUE;
402 }
403
404 static BOOL UnloadHive(HWND hWnd)
405 {
406 WCHAR Caption[128];
407 LPCWSTR pszKeyPath;
408 HKEY hRootKey;
409 LONG regUnloadResult;
410
411 /* get the item key to unload */
412 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
413 /* load and set the caption and flags for dialog */
414 LoadStringW(hInst, IDS_UNLOAD_HIVE, Caption, COUNT_OF(Caption));
415
416 /* Enable the 'restore' privilege, unload the hive, disable the privilege */
417 EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE);
418 regUnloadResult = RegUnLoadKeyW(hRootKey, pszKeyPath);
419 EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE);
420
421 if(regUnloadResult == ERROR_SUCCESS)
422 {
423 /* refresh tree and list views */
424 RefreshTreeView(g_pChildWnd->hTreeWnd);
425 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
426 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
427 }
428 else
429 {
430 ErrorMessageBox(hWnd, Caption, regUnloadResult);
431 return FALSE;
432 }
433 return TRUE;
434 }
435
436 static BOOL ImportRegistryFile(HWND hWnd)
437 {
438 BOOL bRet = FALSE;
439 OPENFILENAME ofn;
440 WCHAR Caption[128], szTitle[512], szText[512];
441 HKEY hKeyRoot;
442 LPCWSTR pszKeyPath;
443
444 /* Figure out in which key path we are importing */
445 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
446
447 InitOpenFileName(hWnd, &ofn);
448 LoadStringW(hInst, IDS_IMPORT_REG_FILE, Caption, COUNT_OF(Caption));
449 ofn.lpstrTitle = Caption;
450 ofn.Flags |= OFN_ENABLESIZING;
451 /* ofn.lCustData = ;*/
452 if (GetOpenFileName(&ofn))
453 {
454 /* Look at the extension of the file to determine its type */
455 if (ofn.nFileExtension >= 1 &&
456 _wcsicmp(ofn.lpstrFile + ofn.nFileExtension, L"reg") == 0) /* REGEDIT4 or Windows Registry Editor Version 5.00 */
457 {
458 /* Open the file */
459 FILE* fp = _wfopen(ofn.lpstrFile, L"r");
460
461 /* Import it */
462 if (fp == NULL || !import_registry_file(fp))
463 {
464 /* Error opening the file */
465 LoadStringW(hInst, IDS_APP_TITLE, szTitle, COUNT_OF(szTitle));
466 LoadStringW(hInst, IDS_IMPORT_ERROR, szText, COUNT_OF(szText));
467 InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, szText, ofn.lpstrFile);
468 bRet = FALSE;
469 }
470 else
471 {
472 /* Show successful import */
473 LoadStringW(hInst, IDS_APP_TITLE, szTitle, COUNT_OF(szTitle));
474 LoadStringW(hInst, IDS_IMPORT_OK, szText, COUNT_OF(szText));
475 InfoMessageBox(hWnd, MB_OK | MB_ICONINFORMATION, szTitle, szText, ofn.lpstrFile);
476 bRet = TRUE;
477 }
478
479 /* Close the file */
480 if (fp) fclose(fp);
481 }
482 else /* Registry Hive Files */
483 {
484 LoadStringW(hInst, IDS_QUERY_IMPORT_HIVE_CAPTION, szTitle, COUNT_OF(szTitle));
485 LoadStringW(hInst, IDS_QUERY_IMPORT_HIVE_MSG, szText, COUNT_OF(szText));
486
487 /* Display a confirmation message */
488 if (MessageBoxW(g_pChildWnd->hWnd, szText, szTitle, MB_ICONWARNING | MB_YESNO) == IDYES)
489 {
490 LONG lResult;
491 HKEY hSubKey;
492
493 /* Open the subkey */
494 lResult = RegOpenKeyExW(hKeyRoot, pszKeyPath, 0, KEY_WRITE, &hSubKey);
495 if (lResult == ERROR_SUCCESS)
496 {
497 /* Enable the 'restore' privilege, restore the hive then disable the privilege */
498 EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE);
499 lResult = RegRestoreKey(hSubKey, ofn.lpstrFile, REG_FORCE_RESTORE);
500 EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE);
501
502 /* Flush the subkey and close it */
503 RegFlushKey(hSubKey);
504 RegCloseKey(hSubKey);
505 }
506
507 /* Set the return value */
508 bRet = (lResult == ERROR_SUCCESS);
509
510 /* Display error, if any */
511 if (!bRet) ErrorMessageBox(hWnd, Caption, lResult);
512 }
513 }
514 }
515 else
516 {
517 CheckCommDlgError(hWnd);
518 }
519
520 /* refresh tree and list views */
521 RefreshTreeView(g_pChildWnd->hTreeWnd);
522 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
523 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, pszKeyPath);
524
525 return bRet;
526 }
527
528 static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
529 {
530 HWND hwndExportAll;
531 HWND hwndExportBranch;
532 HWND hwndExportBranchText;
533 UINT_PTR iResult = 0;
534 OPENFILENAME *pOfn;
535 LPWSTR pszSelectedKey;
536 OFNOTIFY *pOfnNotify;
537
538 UNREFERENCED_PARAMETER(wParam);
539
540 switch(uiMsg)
541 {
542 case WM_INITDIALOG:
543 pOfn = (OPENFILENAME *) lParam;
544 pszSelectedKey = (LPWSTR) pOfn->lCustData;
545
546 hwndExportAll = GetDlgItem(hdlg, IDC_EXPORT_ALL);
547 if (hwndExportAll)
548 SendMessageW(hwndExportAll, BM_SETCHECK, pszSelectedKey ? BST_UNCHECKED : BST_CHECKED, 0);
549
550 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
551 if (hwndExportBranch)
552 SendMessageW(hwndExportBranch, BM_SETCHECK, pszSelectedKey ? BST_CHECKED : BST_UNCHECKED, 0);
553
554 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
555 if (hwndExportBranchText)
556 SetWindowTextW(hwndExportBranchText, pszSelectedKey);
557 break;
558
559 case WM_NOTIFY:
560 if (((NMHDR *) lParam)->code == CDN_FILEOK)
561 {
562 pOfnNotify = (OFNOTIFY *) lParam;
563 pszSelectedKey = (LPWSTR) pOfnNotify->lpOFN->lCustData;
564
565 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
566 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
567 if (hwndExportBranch && hwndExportBranchText
568 && (SendMessageW(hwndExportBranch, BM_GETCHECK, 0, 0) == BST_CHECKED))
569 {
570 GetWindowTextW(hwndExportBranchText, pszSelectedKey, _MAX_PATH);
571 }
572 else
573 {
574 pszSelectedKey[0] = L'\0';
575 }
576 }
577 break;
578 }
579 return iResult;
580 }
581
582 BOOL ExportRegistryFile(HWND hWnd)
583 {
584 BOOL bRet = FALSE;
585 OPENFILENAME ofn;
586 WCHAR ExportKeyPath[_MAX_PATH];
587 WCHAR Caption[128], szTitle[512], szText[512];
588 HKEY hKeyRoot;
589 LPCWSTR pszKeyPath;
590
591 /* Figure out which key path we are exporting */
592 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
593 GetKeyName(ExportKeyPath, COUNT_OF(ExportKeyPath), hKeyRoot, pszKeyPath);
594
595 InitOpenFileName(hWnd, &ofn);
596 LoadStringW(hInst, IDS_EXPORT_REG_FILE, Caption, COUNT_OF(Caption));
597 ofn.lpstrTitle = Caption;
598
599 /* Only set the path if a key (not the root node) is selected */
600 if (hKeyRoot != 0)
601 {
602 ofn.lCustData = (LPARAM) ExportKeyPath;
603 }
604 ofn.Flags = OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_OVERWRITEPROMPT;
605 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
606 ofn.lpTemplateName = MAKEINTRESOURCEW(IDD_EXPORTRANGE);
607 if (GetSaveFileName(&ofn))
608 {
609 switch (ofn.nFilterIndex)
610 {
611 case 2: /* Registry Hive Files */
612 {
613 LONG lResult;
614 HKEY hSubKey;
615
616 /* Open the subkey */
617 lResult = RegOpenKeyExW(hKeyRoot, pszKeyPath, 0, KEY_READ, &hSubKey);
618 if (lResult == ERROR_SUCCESS)
619 {
620 /* Enable the 'backup' privilege, save the hive then disable the privilege */
621 EnablePrivilege(SE_BACKUP_NAME, NULL, TRUE);
622 lResult = RegSaveKeyW(hSubKey, ofn.lpstrFile, NULL);
623 if (lResult == ERROR_ALREADY_EXISTS)
624 {
625 /*
626 * We are here, that means that we already said "yes" to the confirmation dialog.
627 * So we absolutely want to replace the hive file.
628 */
629 if (DeleteFileW(ofn.lpstrFile))
630 {
631 /* Try again */
632 lResult = RegSaveKeyW(hSubKey, ofn.lpstrFile, NULL);
633 }
634 }
635 EnablePrivilege(SE_BACKUP_NAME, NULL, FALSE);
636
637 if (lResult != ERROR_SUCCESS)
638 {
639 /*
640 * If we are here, it's because RegSaveKeyW has failed for any reason.
641 * The problem is that even if it has failed, it has created or
642 * replaced the exported hive file with a new empty file. We don't
643 * want to keep this file, so we delete it.
644 */
645 DeleteFileW(ofn.lpstrFile);
646 }
647
648 /* Close the subkey */
649 RegCloseKey(hSubKey);
650 }
651
652 /* Set the return value */
653 bRet = (lResult == ERROR_SUCCESS);
654
655 /* Display error, if any */
656 if (!bRet) ErrorMessageBox(hWnd, Caption, lResult);
657
658 break;
659 }
660
661 case 1: /* Windows Registry Editor Version 5.00 */
662 case 3: /* REGEDIT4 */
663 default: /* All files ==> use Windows Registry Editor Version 5.00 */
664 {
665 if (!export_registry_key(ofn.lpstrFile, ExportKeyPath,
666 (ofn.nFilterIndex == 3 ? REG_FORMAT_4
667 : REG_FORMAT_5)))
668 {
669 /* Error creating the file */
670 LoadStringW(hInst, IDS_APP_TITLE, szTitle, COUNT_OF(szTitle));
671 LoadStringW(hInst, IDS_EXPORT_ERROR, szText, COUNT_OF(szText));
672 InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, szText, ofn.lpstrFile);
673 bRet = FALSE;
674 }
675 else
676 {
677 bRet = TRUE;
678 }
679
680 break;
681 }
682 }
683 }
684 else
685 {
686 CheckCommDlgError(hWnd);
687 }
688
689 return bRet;
690 }
691
692 BOOL PrintRegistryHive(HWND hWnd, LPWSTR path)
693 {
694 #if 1
695 PRINTDLG pd;
696 UNREFERENCED_PARAMETER(path);
697
698 ZeroMemory(&pd, sizeof(PRINTDLG));
699 pd.lStructSize = sizeof(PRINTDLG);
700 pd.hwndOwner = hWnd;
701 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
702 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
703 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
704 pd.nCopies = 1;
705 pd.nFromPage = 0xFFFF;
706 pd.nToPage = 0xFFFF;
707 pd.nMinPage = 1;
708 pd.nMaxPage = 0xFFFF;
709 if (PrintDlg(&pd))
710 {
711 /* GDI calls to render output. */
712 DeleteDC(pd.hDC); /* Delete DC when done.*/
713 }
714 #else
715 HRESULT hResult;
716 PRINTDLGEX pd;
717
718 hResult = PrintDlgEx(&pd);
719 if (hResult == S_OK)
720 {
721 switch (pd.dwResultAction)
722 {
723 case PD_RESULT_APPLY:
724 /*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. */
725 break;
726 case PD_RESULT_CANCEL:
727 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
728 break;
729 case PD_RESULT_PRINT:
730 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
731 break;
732 default:
733 break;
734 }
735 }
736 else
737 {
738 switch (hResult)
739 {
740 case E_OUTOFMEMORY:
741 /*Insufficient memory. */
742 break;
743 case E_INVALIDARG:
744 /* One or more arguments are invalid. */
745 break;
746 case E_POINTER:
747 /*Invalid pointer. */
748 break;
749 case E_HANDLE:
750 /*Invalid handle. */
751 break;
752 case E_FAIL:
753 /*Unspecified error. */
754 break;
755 default:
756 break;
757 }
758 return FALSE;
759 }
760 #endif
761 return TRUE;
762 }
763
764 static void ChooseFavorite(LPCWSTR pszFavorite)
765 {
766 HKEY hKey = NULL;
767 WCHAR szFavoritePath[512];
768 DWORD cbData, dwType;
769
770 if (RegOpenKeyExW(HKEY_CURRENT_USER, s_szFavoritesRegKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
771 goto done;
772
773 cbData = (sizeof(szFavoritePath) / sizeof(szFavoritePath[0])) - 1;
774 memset(szFavoritePath, 0, sizeof(szFavoritePath));
775 if (RegQueryValueExW(hKey, pszFavorite, NULL, &dwType, (LPBYTE) szFavoritePath, &cbData) != ERROR_SUCCESS)
776 goto done;
777
778 if (dwType == REG_SZ)
779 SelectNode(g_pChildWnd->hTreeWnd, szFavoritePath);
780
781 done:
782 if (hKey)
783 RegCloseKey(hKey);
784 }
785
786 BOOL CopyKeyName(HWND hWnd, HKEY hRootKey, LPCWSTR keyName)
787 {
788 BOOL bClipboardOpened = FALSE;
789 BOOL bSuccess = FALSE;
790 WCHAR szBuffer[512];
791 HGLOBAL hGlobal;
792 LPWSTR s;
793
794 if (!OpenClipboard(hWnd))
795 goto done;
796 bClipboardOpened = TRUE;
797
798 if (!EmptyClipboard())
799 goto done;
800
801 if (!GetKeyName(szBuffer, COUNT_OF(szBuffer), hRootKey, keyName))
802 goto done;
803
804 hGlobal = GlobalAlloc(GMEM_MOVEABLE, (wcslen(szBuffer) + 1) * sizeof(WCHAR));
805 if (!hGlobal)
806 goto done;
807
808 s = GlobalLock(hGlobal);
809 wcscpy(s, szBuffer);
810 GlobalUnlock(hGlobal);
811
812 SetClipboardData(CF_UNICODETEXT, hGlobal);
813 bSuccess = TRUE;
814
815 done:
816 if (bClipboardOpened)
817 CloseClipboard();
818 return bSuccess;
819 }
820
821 static BOOL CreateNewValue(HKEY hRootKey, LPCWSTR pszKeyPath, DWORD dwType)
822 {
823 WCHAR szNewValueFormat[128];
824 WCHAR szNewValue[128];
825 int iIndex = 1;
826 BYTE data[128];
827 DWORD dwExistingType, cbData;
828 LONG lResult;
829 HKEY hKey;
830 LVFINDINFO lvfi;
831
832 if (RegOpenKeyExW(hRootKey, pszKeyPath, 0, KEY_QUERY_VALUE | KEY_SET_VALUE,
833 &hKey) != ERROR_SUCCESS)
834 return FALSE;
835
836 LoadStringW(hInst, IDS_NEW_VALUE, szNewValueFormat, COUNT_OF(szNewValueFormat));
837
838 do
839 {
840 wsprintf(szNewValue, szNewValueFormat, iIndex++);
841 cbData = sizeof(data);
842 lResult = RegQueryValueExW(hKey, szNewValue, NULL, &dwExistingType, data, &cbData);
843 }
844 while(lResult == ERROR_SUCCESS);
845
846 switch(dwType)
847 {
848 case REG_DWORD:
849 cbData = sizeof(DWORD);
850 break;
851 case REG_SZ:
852 case REG_EXPAND_SZ:
853 cbData = sizeof(WCHAR);
854 break;
855 case REG_MULTI_SZ:
856 cbData = sizeof(WCHAR) * 2;
857 break;
858 case REG_QWORD:
859 cbData = sizeof(DWORD) * 2;
860 break;
861 default:
862 cbData = 0;
863 break;
864 }
865 memset(data, 0, cbData);
866 lResult = RegSetValueExW(hKey, szNewValue, 0, dwType, data, cbData);
867 RegCloseKey(hKey);
868 if (lResult != ERROR_SUCCESS)
869 {
870 return FALSE;
871 }
872
873 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
874
875 /* locate the newly added value, and get ready to rename it */
876 memset(&lvfi, 0, sizeof(lvfi));
877 lvfi.flags = LVFI_STRING;
878 lvfi.psz = szNewValue;
879 iIndex = ListView_FindItem(g_pChildWnd->hListWnd, -1, &lvfi);
880 if (iIndex >= 0)
881 (void)ListView_EditLabel(g_pChildWnd->hListWnd, iIndex);
882
883 return TRUE;
884 }
885
886 static HRESULT
887 InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker)
888 {
889 HRESULT hRet;
890
891 *pDsObjectPicker = NULL;
892
893 hRet = CoCreateInstance(&CLSID_DsObjectPicker,
894 NULL,
895 CLSCTX_INPROC_SERVER,
896 &IID_IDsObjectPicker,
897 (LPVOID*)pDsObjectPicker);
898 if (SUCCEEDED(hRet))
899 {
900 DSOP_INIT_INFO InitInfo;
901 static DSOP_SCOPE_INIT_INFO Scopes[] =
902 {
903 {
904 sizeof(DSOP_SCOPE_INIT_INFO),
905 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE |
906 DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
907 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP |
908 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN,
909 0,
910 {
911 {
912 DSOP_FILTER_COMPUTERS,
913 0,
914 0
915 },
916 DSOP_DOWNLEVEL_FILTER_COMPUTERS
917 },
918 NULL,
919 NULL,
920 S_OK
921 },
922 };
923
924 InitInfo.cbSize = sizeof(InitInfo);
925 InitInfo.pwzTargetComputer = NULL;
926 InitInfo.cDsScopeInfos = COUNT_OF(Scopes);
927 InitInfo.aDsScopeInfos = Scopes;
928 InitInfo.flOptions = 0;
929 InitInfo.cAttributesToFetch = 0;
930 InitInfo.apwzAttributeNames = NULL;
931
932 hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker,
933 &InitInfo);
934
935 if (FAILED(hRet))
936 {
937 /* delete the object picker in case initialization failed! */
938 (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker);
939 }
940 }
941
942 return hRet;
943 }
944
945 static HRESULT
946 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
947 IN HWND hwndParent OPTIONAL,
948 OUT LPWSTR lpBuffer,
949 IN UINT uSize)
950 {
951 IDataObject *pdo = NULL;
952 HRESULT hRet;
953
954 hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker,
955 hwndParent,
956 &pdo);
957 if (hRet == S_OK)
958 {
959 STGMEDIUM stm;
960 FORMATETC fe;
961
962 fe.cfFormat = (CLIPFORMAT) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST);
963 fe.ptd = NULL;
964 fe.dwAspect = DVASPECT_CONTENT;
965 fe.lindex = -1;
966 fe.tymed = TYMED_HGLOBAL;
967
968 hRet = pdo->lpVtbl->GetData(pdo,
969 &fe,
970 &stm);
971 if (SUCCEEDED(hRet))
972 {
973 PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal);
974 if (SelectionList != NULL)
975 {
976 if (SelectionList->cItems == 1)
977 {
978 size_t nlen = wcslen(SelectionList->aDsSelection[0].pwzName);
979 if (nlen >= uSize)
980 {
981 nlen = uSize - 1;
982 }
983
984 memcpy(lpBuffer,
985 SelectionList->aDsSelection[0].pwzName,
986 nlen * sizeof(WCHAR));
987
988 lpBuffer[nlen] = L'\0';
989 }
990
991 GlobalUnlock(stm.hGlobal);
992 }
993
994 ReleaseStgMedium(&stm);
995 }
996
997 pdo->lpVtbl->Release(pdo);
998 }
999
1000 return hRet;
1001 }
1002
1003 static VOID
1004 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
1005 {
1006 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
1007 }
1008
1009 /*******************************************************************************
1010 *
1011 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
1012 *
1013 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
1014 *
1015 */
1016 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1017 {
1018 HKEY hKeyRoot = 0, hKey = 0;
1019 LPCWSTR keyPath;
1020 LPCWSTR valueName;
1021 BOOL result = TRUE;
1022 REGSAM regsam = KEY_READ;
1023 LONG lRet;
1024 int item;
1025
1026 UNREFERENCED_PARAMETER(lParam);
1027 UNREFERENCED_PARAMETER(message);
1028
1029 switch (LOWORD(wParam))
1030 {
1031 case ID_REGISTRY_LOADHIVE:
1032 LoadHive(hWnd);
1033 return TRUE;
1034 case ID_REGISTRY_UNLOADHIVE:
1035 UnloadHive(hWnd);
1036 return TRUE;
1037 case ID_REGISTRY_IMPORTREGISTRYFILE:
1038 ImportRegistryFile(hWnd);
1039 return TRUE;
1040 case ID_REGISTRY_EXPORTREGISTRYFILE:
1041 ExportRegistryFile(hWnd);
1042 return TRUE;
1043 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
1044 {
1045 IDsObjectPicker *ObjectPicker;
1046 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1047 HRESULT hRet;
1048
1049 hRet = CoInitialize(NULL);
1050 if (SUCCEEDED(hRet))
1051 {
1052 hRet = InitializeRemoteRegistryPicker(&ObjectPicker);
1053 if (SUCCEEDED(hRet))
1054 {
1055 hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker,
1056 hWnd,
1057 szComputerName,
1058 COUNT_OF(szComputerName));
1059 if (hRet == S_OK)
1060 {
1061 /* FIXME - connect to the registry */
1062 }
1063
1064 FreeObjectPicker(ObjectPicker);
1065 }
1066
1067 CoUninitialize();
1068 }
1069
1070 return TRUE;
1071 }
1072 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
1073 return TRUE;
1074 case ID_REGISTRY_PRINT:
1075 PrintRegistryHive(hWnd, L"");
1076 return TRUE;
1077 case ID_REGISTRY_EXIT:
1078 DestroyWindow(hWnd);
1079 return TRUE;
1080 case ID_VIEW_STATUSBAR:
1081 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
1082 return TRUE;
1083 case ID_HELP_HELPTOPICS:
1084 WinHelpW(hWnd, getAppName(), HELP_FINDER, 0);
1085 return TRUE;
1086 case ID_HELP_ABOUT:
1087 ShowAboutBox(hWnd);
1088 return TRUE;
1089 case ID_VIEW_SPLIT:
1090 {
1091 RECT rt;
1092 POINT pt, pts;
1093 GetClientRect(g_pChildWnd->hWnd, &rt);
1094 pt.x = rt.left + g_pChildWnd->nSplitPos;
1095 pt.y = (rt.bottom / 2);
1096 pts = pt;
1097 if(ClientToScreen(g_pChildWnd->hWnd, &pts))
1098 {
1099 SetCursorPos(pts.x, pts.y);
1100 SetCursor(LoadCursorW(0, IDC_SIZEWE));
1101 SendMessageW(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
1102 }
1103 return TRUE;
1104 }
1105 case ID_EDIT_RENAME:
1106 case ID_EDIT_MODIFY:
1107 case ID_EDIT_MODIFY_BIN:
1108 case ID_EDIT_DELETE:
1109 regsam |= KEY_WRITE;
1110 break;
1111 }
1112
1113 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
1114 valueName = GetValueName(g_pChildWnd->hListWnd, -1);
1115 if (keyPath)
1116 {
1117 lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, regsam, &hKey);
1118 if (lRet != ERROR_SUCCESS) hKey = 0;
1119 }
1120
1121 switch (LOWORD(wParam))
1122 {
1123 case ID_EDIT_MODIFY:
1124 if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE))
1125 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1126 break;
1127 case ID_EDIT_MODIFY_BIN:
1128 if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE))
1129 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1130 break;
1131 case ID_EDIT_RENAME:
1132 if (GetFocus() == g_pChildWnd->hListWnd)
1133 {
1134 if(ListView_GetSelectedCount(g_pChildWnd->hListWnd) == 1)
1135 {
1136 item = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
1137 if(item > -1)
1138 {
1139 (void)ListView_EditLabel(g_pChildWnd->hListWnd, item);
1140 }
1141 }
1142 }
1143 else if (GetFocus() == g_pChildWnd->hTreeWnd)
1144 {
1145 /* Get focused entry of treeview (if any) */
1146 HTREEITEM hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
1147 if (hItem != NULL)
1148 (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, hItem);
1149 }
1150 break;
1151 case ID_EDIT_DELETE:
1152 {
1153 if (GetFocus() == g_pChildWnd->hListWnd)
1154 {
1155 UINT nSelected = ListView_GetSelectedCount(g_pChildWnd->hListWnd);
1156 if(nSelected >= 1)
1157 {
1158 WCHAR msg[128], caption[128];
1159 LoadStringW(hInst, IDS_QUERY_DELETE_CONFIRM, caption, COUNT_OF(caption));
1160 LoadStringW(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, COUNT_OF(msg));
1161 if(MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES)
1162 {
1163 int ni, errs;
1164
1165 item = -1;
1166 errs = 0;
1167 while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1)
1168 {
1169 valueName = GetValueName(g_pChildWnd->hListWnd, item);
1170 if(RegDeleteValueW(hKey, valueName) != ERROR_SUCCESS)
1171 {
1172 errs++;
1173 }
1174 item = ni;
1175 }
1176
1177 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1178 if(errs > 0)
1179 {
1180 LoadStringW(hInst, IDS_ERR_DELVAL_CAPTION, caption, COUNT_OF(caption));
1181 LoadStringW(hInst, IDS_ERR_DELETEVALUE, msg, COUNT_OF(msg));
1182 MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP);
1183 }
1184 }
1185 }
1186 }
1187 else if (GetFocus() == g_pChildWnd->hTreeWnd)
1188 {
1189 if (keyPath == 0 || *keyPath == 0)
1190 {
1191 MessageBeep(MB_ICONHAND);
1192 }
1193 else if (DeleteKey(hWnd, hKeyRoot, keyPath))
1194 {
1195 DeleteNode(g_pChildWnd->hTreeWnd, 0);
1196 RefreshTreeView(g_pChildWnd->hTreeWnd);
1197 }
1198 }
1199 break;
1200 }
1201 case ID_EDIT_NEW_STRINGVALUE:
1202 CreateNewValue(hKeyRoot, keyPath, REG_SZ);
1203 break;
1204 case ID_EDIT_NEW_BINARYVALUE:
1205 CreateNewValue(hKeyRoot, keyPath, REG_BINARY);
1206 break;
1207 case ID_EDIT_NEW_DWORDVALUE:
1208 CreateNewValue(hKeyRoot, keyPath, REG_DWORD);
1209 break;
1210 case ID_EDIT_NEW_MULTISTRINGVALUE:
1211 CreateNewValue(hKeyRoot, keyPath, REG_MULTI_SZ);
1212 break;
1213 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE:
1214 CreateNewValue(hKeyRoot, keyPath, REG_EXPAND_SZ);
1215 break;
1216 case ID_EDIT_FIND:
1217 FindDialog(hWnd);
1218 break;
1219 case ID_EDIT_FINDNEXT:
1220 FindNext(hWnd);
1221 break;
1222 case ID_EDIT_COPYKEYNAME:
1223 CopyKeyName(hWnd, hKeyRoot, keyPath);
1224 break;
1225 case ID_EDIT_PERMISSIONS:
1226 RegKeyEditPermissions(hWnd, hKeyRoot, NULL, keyPath);
1227 break;
1228 case ID_REGISTRY_PRINTERSETUP:
1229 /*PRINTDLG pd;*/
1230 /*PrintDlg(&pd);*/
1231 /*PAGESETUPDLG psd;*/
1232 /*PageSetupDlg(&psd);*/
1233 break;
1234 case ID_REGISTRY_OPENLOCAL:
1235 break;
1236
1237 case ID_VIEW_REFRESH:
1238 RefreshTreeView(g_pChildWnd->hTreeWnd);
1239 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
1240 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1241 break;
1242 /*case ID_OPTIONS_TOOLBAR:*/
1243 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1244 /* break;*/
1245 case ID_EDIT_NEW_KEY:
1246 CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd));
1247 break;
1248 default:
1249 if ((LOWORD(wParam) >= ID_FAVORITES_MIN) && (LOWORD(wParam) <= ID_FAVORITES_MAX))
1250 {
1251 HMENU hMenu;
1252 MENUITEMINFOW mii;
1253 WCHAR szFavorite[512];
1254
1255 hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION);
1256
1257 memset(&mii, 0, sizeof(mii));
1258 mii.cbSize = sizeof(mii);
1259 mii.fMask = MIIM_TYPE;
1260 mii.fType = MFT_STRING;
1261 mii.dwTypeData = szFavorite;
1262 mii.cch = COUNT_OF(szFavorite);
1263
1264 if (GetMenuItemInfo(hMenu, LOWORD(wParam) - ID_FAVORITES_MIN, TRUE, &mii))
1265 {
1266 ChooseFavorite(szFavorite);
1267 }
1268 }
1269 else
1270 {
1271 result = FALSE;
1272 }
1273 break;
1274 }
1275
1276 if(hKey)
1277 RegCloseKey(hKey);
1278 return result;
1279 }
1280
1281 /********************************************************************************
1282 *
1283 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1284 *
1285 * PURPOSE: Processes messages for the main frame window.
1286 *
1287 * WM_COMMAND - process the application menu
1288 * WM_DESTROY - post a quit message and return
1289 *
1290 */
1291
1292 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1293 {
1294 switch (message)
1295 {
1296 case WM_CREATE:
1297 CreateWindowExW(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE,
1298 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
1299 hWnd, (HMENU)0, hInst, 0);
1300 break;
1301 case WM_COMMAND:
1302 if (!_CmdWndProc(hWnd, message, wParam, lParam))
1303 return DefWindowProcW(hWnd, message, wParam, lParam);
1304 break;
1305 case WM_ACTIVATE:
1306 if (LOWORD(hWnd))
1307 SetFocus(g_pChildWnd->hWnd);
1308 break;
1309 case WM_SIZE:
1310 resize_frame_client(hWnd);
1311 break;
1312 case WM_TIMER:
1313 break;
1314 case WM_INITMENU:
1315 OnInitMenu(hWnd);
1316 break;
1317 case WM_ENTERMENULOOP:
1318 OnEnterMenuLoop(hWnd);
1319 break;
1320 case WM_EXITMENULOOP:
1321 OnExitMenuLoop(hWnd);
1322 break;
1323 case WM_MENUSELECT:
1324 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
1325 break;
1326 case WM_SYSCOLORCHANGE:
1327 /* Forward WM_SYSCOLORCHANGE to common controls */
1328 SendMessageW(g_pChildWnd->hListWnd, WM_SYSCOLORCHANGE, 0, 0);
1329 SendMessageW(g_pChildWnd->hTreeWnd, WM_SYSCOLORCHANGE, 0, 0);
1330 break;
1331 case WM_DESTROY:
1332 WinHelpW(hWnd, getAppName(), HELP_QUIT, 0);
1333 SaveSettings();
1334 PostQuitMessage(0);
1335 default:
1336 return DefWindowProcW(hWnd, message, wParam, lParam);
1337 }
1338 return 0;
1339 }