Synchronize with trunk revision 59636 (just before Alex's CreateProcess revamp).
[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 /*
857 * WARNING: An empty multi-string has only one null char.
858 * Indeed, multi-strings are built in the following form:
859 * str1\0str2\0...strN\0\0
860 * where each strI\0 is a null-terminated string, and it
861 * ends with a terminating empty string.
862 * Therefore an empty multi-string contains only the terminating
863 * empty string, that is, one null char.
864 */
865 cbData = sizeof(WCHAR);
866 break;
867 case REG_QWORD: /* REG_QWORD_LITTLE_ENDIAN */
868 cbData = sizeof(DWORDLONG); // == sizeof(DWORD) * 2;
869 break;
870 default:
871 cbData = 0;
872 break;
873 }
874 memset(data, 0, cbData);
875 lResult = RegSetValueExW(hKey, szNewValue, 0, dwType, data, cbData);
876 RegCloseKey(hKey);
877 if (lResult != ERROR_SUCCESS)
878 {
879 return FALSE;
880 }
881
882 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
883
884 /* locate the newly added value, and get ready to rename it */
885 memset(&lvfi, 0, sizeof(lvfi));
886 lvfi.flags = LVFI_STRING;
887 lvfi.psz = szNewValue;
888 iIndex = ListView_FindItem(g_pChildWnd->hListWnd, -1, &lvfi);
889 if (iIndex >= 0)
890 (void)ListView_EditLabel(g_pChildWnd->hListWnd, iIndex);
891
892 return TRUE;
893 }
894
895 static HRESULT
896 InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker)
897 {
898 HRESULT hRet;
899
900 *pDsObjectPicker = NULL;
901
902 hRet = CoCreateInstance(&CLSID_DsObjectPicker,
903 NULL,
904 CLSCTX_INPROC_SERVER,
905 &IID_IDsObjectPicker,
906 (LPVOID*)pDsObjectPicker);
907 if (SUCCEEDED(hRet))
908 {
909 DSOP_INIT_INFO InitInfo;
910 static DSOP_SCOPE_INIT_INFO Scopes[] =
911 {
912 {
913 sizeof(DSOP_SCOPE_INIT_INFO),
914 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE |
915 DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
916 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP |
917 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN,
918 0,
919 {
920 {
921 DSOP_FILTER_COMPUTERS,
922 0,
923 0
924 },
925 DSOP_DOWNLEVEL_FILTER_COMPUTERS
926 },
927 NULL,
928 NULL,
929 S_OK
930 },
931 };
932
933 InitInfo.cbSize = sizeof(InitInfo);
934 InitInfo.pwzTargetComputer = NULL;
935 InitInfo.cDsScopeInfos = COUNT_OF(Scopes);
936 InitInfo.aDsScopeInfos = Scopes;
937 InitInfo.flOptions = 0;
938 InitInfo.cAttributesToFetch = 0;
939 InitInfo.apwzAttributeNames = NULL;
940
941 hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker,
942 &InitInfo);
943
944 if (FAILED(hRet))
945 {
946 /* delete the object picker in case initialization failed! */
947 (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker);
948 }
949 }
950
951 return hRet;
952 }
953
954 static HRESULT
955 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
956 IN HWND hwndParent OPTIONAL,
957 OUT LPWSTR lpBuffer,
958 IN UINT uSize)
959 {
960 IDataObject *pdo = NULL;
961 HRESULT hRet;
962
963 hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker,
964 hwndParent,
965 &pdo);
966 if (hRet == S_OK)
967 {
968 STGMEDIUM stm;
969 FORMATETC fe;
970
971 fe.cfFormat = (CLIPFORMAT) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST);
972 fe.ptd = NULL;
973 fe.dwAspect = DVASPECT_CONTENT;
974 fe.lindex = -1;
975 fe.tymed = TYMED_HGLOBAL;
976
977 hRet = pdo->lpVtbl->GetData(pdo,
978 &fe,
979 &stm);
980 if (SUCCEEDED(hRet))
981 {
982 PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal);
983 if (SelectionList != NULL)
984 {
985 if (SelectionList->cItems == 1)
986 {
987 size_t nlen = wcslen(SelectionList->aDsSelection[0].pwzName);
988 if (nlen >= uSize)
989 {
990 nlen = uSize - 1;
991 }
992
993 memcpy(lpBuffer,
994 SelectionList->aDsSelection[0].pwzName,
995 nlen * sizeof(WCHAR));
996
997 lpBuffer[nlen] = L'\0';
998 }
999
1000 GlobalUnlock(stm.hGlobal);
1001 }
1002
1003 ReleaseStgMedium(&stm);
1004 }
1005
1006 pdo->lpVtbl->Release(pdo);
1007 }
1008
1009 return hRet;
1010 }
1011
1012 static VOID
1013 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
1014 {
1015 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
1016 }
1017
1018 /*******************************************************************************
1019 *
1020 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
1021 *
1022 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
1023 *
1024 */
1025 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1026 {
1027 HKEY hKeyRoot = 0, hKey = 0;
1028 LPCWSTR keyPath;
1029 LPCWSTR valueName;
1030 BOOL result = TRUE;
1031 REGSAM regsam = KEY_READ;
1032 LONG lRet;
1033 int item;
1034
1035 UNREFERENCED_PARAMETER(lParam);
1036 UNREFERENCED_PARAMETER(message);
1037
1038 switch (LOWORD(wParam))
1039 {
1040 case ID_REGISTRY_LOADHIVE:
1041 LoadHive(hWnd);
1042 return TRUE;
1043 case ID_REGISTRY_UNLOADHIVE:
1044 UnloadHive(hWnd);
1045 return TRUE;
1046 case ID_REGISTRY_IMPORTREGISTRYFILE:
1047 ImportRegistryFile(hWnd);
1048 return TRUE;
1049 case ID_REGISTRY_EXPORTREGISTRYFILE:
1050 ExportRegistryFile(hWnd);
1051 return TRUE;
1052 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
1053 {
1054 IDsObjectPicker *ObjectPicker;
1055 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
1056 HRESULT hRet;
1057
1058 hRet = CoInitialize(NULL);
1059 if (SUCCEEDED(hRet))
1060 {
1061 hRet = InitializeRemoteRegistryPicker(&ObjectPicker);
1062 if (SUCCEEDED(hRet))
1063 {
1064 hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker,
1065 hWnd,
1066 szComputerName,
1067 COUNT_OF(szComputerName));
1068 if (hRet == S_OK)
1069 {
1070 /* FIXME - connect to the registry */
1071 }
1072
1073 FreeObjectPicker(ObjectPicker);
1074 }
1075
1076 CoUninitialize();
1077 }
1078
1079 return TRUE;
1080 }
1081 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
1082 return TRUE;
1083 case ID_REGISTRY_PRINT:
1084 PrintRegistryHive(hWnd, L"");
1085 return TRUE;
1086 case ID_REGISTRY_EXIT:
1087 DestroyWindow(hWnd);
1088 return TRUE;
1089 case ID_VIEW_STATUSBAR:
1090 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
1091 return TRUE;
1092 case ID_HELP_HELPTOPICS:
1093 WinHelpW(hWnd, getAppName(), HELP_FINDER, 0);
1094 return TRUE;
1095 case ID_HELP_ABOUT:
1096 ShowAboutBox(hWnd);
1097 return TRUE;
1098 case ID_VIEW_SPLIT:
1099 {
1100 RECT rt;
1101 POINT pt, pts;
1102 GetClientRect(g_pChildWnd->hWnd, &rt);
1103 pt.x = rt.left + g_pChildWnd->nSplitPos;
1104 pt.y = (rt.bottom / 2);
1105 pts = pt;
1106 if(ClientToScreen(g_pChildWnd->hWnd, &pts))
1107 {
1108 SetCursorPos(pts.x, pts.y);
1109 SetCursor(LoadCursorW(0, IDC_SIZEWE));
1110 SendMessageW(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
1111 }
1112 return TRUE;
1113 }
1114 case ID_EDIT_RENAME:
1115 case ID_EDIT_MODIFY:
1116 case ID_EDIT_MODIFY_BIN:
1117 case ID_EDIT_DELETE:
1118 regsam |= KEY_WRITE;
1119 break;
1120 }
1121
1122 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
1123 valueName = GetValueName(g_pChildWnd->hListWnd, -1);
1124 if (keyPath)
1125 {
1126 lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, regsam, &hKey);
1127 if (lRet != ERROR_SUCCESS) hKey = 0;
1128 }
1129
1130 switch (LOWORD(wParam))
1131 {
1132 case ID_EDIT_MODIFY:
1133 if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE))
1134 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1135 break;
1136 case ID_EDIT_MODIFY_BIN:
1137 if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE))
1138 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1139 break;
1140 case ID_EDIT_RENAME:
1141 if (GetFocus() == g_pChildWnd->hListWnd)
1142 {
1143 if(ListView_GetSelectedCount(g_pChildWnd->hListWnd) == 1)
1144 {
1145 item = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
1146 if(item > -1)
1147 {
1148 (void)ListView_EditLabel(g_pChildWnd->hListWnd, item);
1149 }
1150 }
1151 }
1152 else if (GetFocus() == g_pChildWnd->hTreeWnd)
1153 {
1154 /* Get focused entry of treeview (if any) */
1155 HTREEITEM hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
1156 if (hItem != NULL)
1157 (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, hItem);
1158 }
1159 break;
1160 case ID_EDIT_DELETE:
1161 {
1162 if (GetFocus() == g_pChildWnd->hListWnd)
1163 {
1164 UINT nSelected = ListView_GetSelectedCount(g_pChildWnd->hListWnd);
1165 if(nSelected >= 1)
1166 {
1167 WCHAR msg[128], caption[128];
1168 LoadStringW(hInst, IDS_QUERY_DELETE_CONFIRM, caption, COUNT_OF(caption));
1169 LoadStringW(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, COUNT_OF(msg));
1170 if(MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES)
1171 {
1172 int ni, errs;
1173
1174 item = -1;
1175 errs = 0;
1176 while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1)
1177 {
1178 valueName = GetValueName(g_pChildWnd->hListWnd, item);
1179 if(RegDeleteValueW(hKey, valueName) != ERROR_SUCCESS)
1180 {
1181 errs++;
1182 }
1183 item = ni;
1184 }
1185
1186 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1187 if(errs > 0)
1188 {
1189 LoadStringW(hInst, IDS_ERR_DELVAL_CAPTION, caption, COUNT_OF(caption));
1190 LoadStringW(hInst, IDS_ERR_DELETEVALUE, msg, COUNT_OF(msg));
1191 MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP);
1192 }
1193 }
1194 }
1195 }
1196 else if (GetFocus() == g_pChildWnd->hTreeWnd)
1197 {
1198 if (keyPath == 0 || *keyPath == 0)
1199 {
1200 MessageBeep(MB_ICONHAND);
1201 }
1202 else if (DeleteKey(hWnd, hKeyRoot, keyPath))
1203 {
1204 DeleteNode(g_pChildWnd->hTreeWnd, 0);
1205 RefreshTreeView(g_pChildWnd->hTreeWnd);
1206 }
1207 }
1208 break;
1209 }
1210 case ID_EDIT_NEW_STRINGVALUE:
1211 CreateNewValue(hKeyRoot, keyPath, REG_SZ);
1212 break;
1213 case ID_EDIT_NEW_BINARYVALUE:
1214 CreateNewValue(hKeyRoot, keyPath, REG_BINARY);
1215 break;
1216 case ID_EDIT_NEW_DWORDVALUE:
1217 CreateNewValue(hKeyRoot, keyPath, REG_DWORD);
1218 break;
1219 case ID_EDIT_NEW_MULTISTRINGVALUE:
1220 CreateNewValue(hKeyRoot, keyPath, REG_MULTI_SZ);
1221 break;
1222 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE:
1223 CreateNewValue(hKeyRoot, keyPath, REG_EXPAND_SZ);
1224 break;
1225 case ID_EDIT_FIND:
1226 FindDialog(hWnd);
1227 break;
1228 case ID_EDIT_FINDNEXT:
1229 FindNext(hWnd);
1230 break;
1231 case ID_EDIT_COPYKEYNAME:
1232 CopyKeyName(hWnd, hKeyRoot, keyPath);
1233 break;
1234 case ID_EDIT_PERMISSIONS:
1235 RegKeyEditPermissions(hWnd, hKeyRoot, NULL, keyPath);
1236 break;
1237 case ID_REGISTRY_PRINTERSETUP:
1238 /*PRINTDLG pd;*/
1239 /*PrintDlg(&pd);*/
1240 /*PAGESETUPDLG psd;*/
1241 /*PageSetupDlg(&psd);*/
1242 break;
1243 case ID_REGISTRY_OPENLOCAL:
1244 break;
1245
1246 case ID_VIEW_REFRESH:
1247 RefreshTreeView(g_pChildWnd->hTreeWnd);
1248 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
1249 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
1250 break;
1251 /*case ID_OPTIONS_TOOLBAR:*/
1252 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1253 /* break;*/
1254 case ID_EDIT_NEW_KEY:
1255 CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd));
1256 break;
1257 default:
1258 if ((LOWORD(wParam) >= ID_FAVORITES_MIN) && (LOWORD(wParam) <= ID_FAVORITES_MAX))
1259 {
1260 HMENU hMenu;
1261 MENUITEMINFOW mii;
1262 WCHAR szFavorite[512];
1263
1264 hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION);
1265
1266 memset(&mii, 0, sizeof(mii));
1267 mii.cbSize = sizeof(mii);
1268 mii.fMask = MIIM_TYPE;
1269 mii.fType = MFT_STRING;
1270 mii.dwTypeData = szFavorite;
1271 mii.cch = COUNT_OF(szFavorite);
1272
1273 if (GetMenuItemInfo(hMenu, LOWORD(wParam) - ID_FAVORITES_MIN, TRUE, &mii))
1274 {
1275 ChooseFavorite(szFavorite);
1276 }
1277 }
1278 else
1279 {
1280 result = FALSE;
1281 }
1282 break;
1283 }
1284
1285 if(hKey)
1286 RegCloseKey(hKey);
1287 return result;
1288 }
1289
1290 /********************************************************************************
1291 *
1292 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1293 *
1294 * PURPOSE: Processes messages for the main frame window.
1295 *
1296 * WM_COMMAND - process the application menu
1297 * WM_DESTROY - post a quit message and return
1298 *
1299 */
1300
1301 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1302 {
1303 switch (message)
1304 {
1305 case WM_CREATE:
1306 CreateWindowExW(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE,
1307 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
1308 hWnd, (HMENU)0, hInst, 0);
1309 break;
1310 case WM_COMMAND:
1311 if (!_CmdWndProc(hWnd, message, wParam, lParam))
1312 return DefWindowProcW(hWnd, message, wParam, lParam);
1313 break;
1314 case WM_ACTIVATE:
1315 if (LOWORD(hWnd))
1316 SetFocus(g_pChildWnd->hWnd);
1317 break;
1318 case WM_SIZE:
1319 resize_frame_client(hWnd);
1320 break;
1321 case WM_TIMER:
1322 break;
1323 case WM_INITMENU:
1324 OnInitMenu(hWnd);
1325 break;
1326 case WM_ENTERMENULOOP:
1327 OnEnterMenuLoop(hWnd);
1328 break;
1329 case WM_EXITMENULOOP:
1330 OnExitMenuLoop(hWnd);
1331 break;
1332 case WM_MENUSELECT:
1333 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
1334 break;
1335 case WM_SYSCOLORCHANGE:
1336 /* Forward WM_SYSCOLORCHANGE to common controls */
1337 SendMessageW(g_pChildWnd->hListWnd, WM_SYSCOLORCHANGE, 0, 0);
1338 SendMessageW(g_pChildWnd->hTreeWnd, WM_SYSCOLORCHANGE, 0, 0);
1339 break;
1340 case WM_DESTROY:
1341 WinHelpW(hWnd, getAppName(), HELP_QUIT, 0);
1342 SaveSettings();
1343 PostQuitMessage(0);
1344 default:
1345 return DefWindowProcW(hWnd, message, wParam, lParam);
1346 }
1347 return 0;
1348 }