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