- Create KD branch. All debugging support is removed in this branch (no symbols,...
[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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <regedit.h>
22
23 /********************************************************************************
24 * Global and Local Variables:
25 */
26
27 #define FAVORITES_MENU_POSITION 3
28
29 static TCHAR s_szFavoritesRegKey[] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Favorites");
30
31 static BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
32
33 /*******************************************************************************
34 * Local module support methods
35 */
36
37 static void resize_frame_rect(HWND hWnd, PRECT prect)
38 {
39 RECT rt;
40 /*
41 if (IsWindowVisible(hToolBar)) {
42 SendMessage(hToolBar, WM_SIZE, 0, 0);
43 GetClientRect(hToolBar, &rt);
44 prect->top = rt.bottom+3;
45 prect->bottom -= rt.bottom+3;
46 }
47 */
48 if (IsWindowVisible(hStatusBar)) {
49 SetupStatusBar(hWnd, TRUE);
50 GetClientRect(hStatusBar, &rt);
51 prect->bottom -= rt.bottom;
52 }
53 MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
54 }
55
56 static void resize_frame_client(HWND hWnd)
57 {
58 RECT rect;
59
60 GetClientRect(hWnd, &rect);
61 resize_frame_rect(hWnd, &rect);
62 }
63
64 /********************************************************************************/
65
66 static void OnInitMenu(HWND hWnd)
67 {
68 LONG lResult;
69 HKEY hKey = NULL;
70 DWORD dwIndex, cbValueName, cbValueData, dwType;
71 TCHAR szValueName[256];
72 BYTE abValueData[256];
73 static int s_nFavoriteMenuSubPos = -1;
74 HMENU hMenu;
75 BOOL bDisplayedAny = FALSE;
76
77 /* Find Favorites menu and clear it out */
78 hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION);
79 if (!hMenu)
80 goto done;
81 if (s_nFavoriteMenuSubPos < 0)
82 {
83 s_nFavoriteMenuSubPos = GetMenuItemCount(hMenu);
84 }
85 else
86 {
87 while(RemoveMenu(hMenu, s_nFavoriteMenuSubPos, MF_BYPOSITION))
88 ;
89 }
90
91 lResult = RegOpenKey(HKEY_CURRENT_USER, s_szFavoritesRegKey, &hKey);
92 if (lResult != ERROR_SUCCESS)
93 goto done;
94
95 dwIndex = 0;
96 do
97 {
98 cbValueName = sizeof(szValueName) / sizeof(szValueName[0]);
99 cbValueData = sizeof(abValueData);
100 lResult = RegEnumValue(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 SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
127 bInMenuLoop = TRUE;
128 SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
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 TCHAR str[100];
142
143 _tcscpy(str, _T(""));
144 if (nFlags & MF_POPUP) {
145 if (hSysMenu != GetMenu(hWnd)) {
146 if (nItemID == 2) nItemID = 5;
147 }
148 }
149 if (LoadString(hInst, nItemID, str, 100)) {
150 /* load appropriate string*/
151 LPTSTR lpsz = str;
152 /* first newline terminates actual string*/
153 lpsz = _tcschr(lpsz, '\n');
154 if (lpsz != NULL)
155 *lpsz = '\0';
156 }
157 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)str);
158 }
159
160 void SetupStatusBar(HWND hWnd, BOOL bResize)
161 {
162 RECT rc;
163 int nParts;
164 GetClientRect(hWnd, &rc);
165 nParts = rc.right;
166 /* nParts = -1;*/
167 if (bResize)
168 SendMessage(hStatusBar, WM_SIZE, 0, 0);
169 SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
170 }
171
172 void UpdateStatusBar(void)
173 {
174 TCHAR text[260];
175 DWORD size;
176
177 size = sizeof(text)/sizeof(TCHAR);
178 GetComputerName(text, &size);
179 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)text);
180 }
181
182 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
183 {
184 BOOL vis = IsWindowVisible(hchild);
185 HMENU hMenuView = GetSubMenu(hMenuFrame, ID_VIEW_MENU);
186
187 CheckMenuItem(hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
188 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
189 resize_frame_client(hWnd);
190 }
191
192 static BOOL CheckCommDlgError(HWND hWnd)
193 {
194 DWORD dwErrorCode = CommDlgExtendedError();
195 UNREFERENCED_PARAMETER(hWnd);
196 switch (dwErrorCode) {
197 case CDERR_DIALOGFAILURE:
198 break;
199 case CDERR_FINDRESFAILURE:
200 break;
201 case CDERR_NOHINSTANCE:
202 break;
203 case CDERR_INITIALIZATION:
204 break;
205 case CDERR_NOHOOK:
206 break;
207 case CDERR_LOCKRESFAILURE:
208 break;
209 case CDERR_NOTEMPLATE:
210 break;
211 case CDERR_LOADRESFAILURE:
212 break;
213 case CDERR_STRUCTSIZE:
214 break;
215 case CDERR_LOADSTRFAILURE:
216 break;
217 case FNERR_BUFFERTOOSMALL:
218 break;
219 case CDERR_MEMALLOCFAILURE:
220 break;
221 case FNERR_INVALIDFILENAME:
222 break;
223 case CDERR_MEMLOCKFAILURE:
224 break;
225 case FNERR_SUBCLASSFAILURE:
226 break;
227 default:
228 break;
229 }
230 return TRUE;
231 }
232
233 #define MAX_CUSTOM_FILTER_SIZE 50
234 TCHAR CustomFilterBuffer[MAX_CUSTOM_FILTER_SIZE];
235 TCHAR FileNameBuffer[_MAX_PATH];
236 TCHAR FileTitleBuffer[_MAX_PATH];
237
238 typedef struct
239 {
240 UINT DisplayID;
241 UINT FilterID;
242 } FILTERPAIR, *PFILTERPAIR;
243
244 void
245 BuildFilterStrings(TCHAR *Filter, PFILTERPAIR Pairs, int PairCount)
246 {
247 int i, c;
248
249 c = 0;
250 for(i = 0; i < PairCount; i++)
251 {
252 c += LoadString(hInst, Pairs[i].DisplayID, &Filter[c], 255 * sizeof(TCHAR));
253 Filter[++c] = '\0';
254 c += LoadString(hInst, Pairs[i].FilterID, &Filter[c], 255 * sizeof(TCHAR));
255 Filter[++c] = '\0';
256 }
257 Filter[++c] = '\0';
258 }
259
260 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
261 {
262 FILTERPAIR FilterPairs[3];
263 static TCHAR 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_REGEDIT4;
274 FilterPairs[1].FilterID = IDS_FLT_REGEDIT4_FLT;
275 FilterPairs[2].DisplayID = IDS_FLT_ALLFILES;
276 FilterPairs[2].FilterID = IDS_FLT_ALLFILES_FLT;
277 BuildFilterStrings(Filter, FilterPairs, sizeof(FilterPairs) / sizeof(FILTERPAIR));
278
279 pofn->lpstrFilter = Filter;
280 pofn->lpstrCustomFilter = CustomFilterBuffer;
281 pofn->nMaxCustFilter = MAX_CUSTOM_FILTER_SIZE;
282 pofn->nFilterIndex = 0;
283 pofn->lpstrFile = FileNameBuffer;
284 pofn->nMaxFile = _MAX_PATH;
285 pofn->lpstrFileTitle = FileTitleBuffer;
286 pofn->nMaxFileTitle = _MAX_PATH;
287 /* pofn->lpstrInitialDir = _T("");*/
288 /* pofn->lpstrTitle = _T("Import Registry File");*/
289 /* pofn->Flags = OFN_ENABLETEMPLATE + OFN_EXPLORER + OFN_ENABLESIZING;*/
290 pofn->Flags = OFN_HIDEREADONLY;
291 /* pofn->nFileOffset = ;*/
292 /* pofn->nFileExtension = ;*/
293 /* pofn->lpstrDefExt = _T("");*/
294 /* pofn->lCustData = ;*/
295 /* pofn->lpfnHook = ImportRegistryFile_OFNHookProc;*/
296 /* pofn->lpTemplateName = _T("ID_DLG_IMPORT_REGFILE");*/
297 /* pofn->lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);*/
298 /* pofn->FlagsEx = ;*/
299 return TRUE;
300 }
301
302 static BOOL ImportRegistryFile(HWND hWnd)
303 {
304 OPENFILENAME ofn;
305 TCHAR Caption[128];
306
307 InitOpenFileName(hWnd, &ofn);
308 LoadString(hInst, IDS_IMPORT_REG_FILE, Caption, sizeof(Caption)/sizeof(TCHAR));
309 ofn.lpstrTitle = Caption;
310 /* ofn.lCustData = ;*/
311 if (GetOpenFileName(&ofn)) {
312 /* FIXME - convert to ascii */
313 if (!import_registry_file(ofn.lpstrFile)) {
314 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
315 return FALSE;
316 }
317 #if 0
318 get_file_name(&s, filename, MAX_PATH);
319 if (!filename[0]) {
320 printf("No file name is specified\n%s", usage);
321 return FALSE;
322 /*exit(1);*/
323 }
324 while (filename[0]) {
325 if (!import_registry_file(filename)) {
326 perror("");
327 printf("Can't open file \"%s\"\n", filename);
328 return FALSE;
329 /*exit(1);*/
330 }
331 get_file_name(&s, filename, MAX_PATH);
332 }
333 #endif
334
335 } else {
336 CheckCommDlgError(hWnd);
337 }
338 return TRUE;
339 }
340
341
342 static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
343 {
344 HWND hwndExportAll;
345 HWND hwndExportBranch;
346 HWND hwndExportBranchText;
347 UINT_PTR iResult = 0;
348 OPENFILENAME *pOfn;
349 LPTSTR pszSelectedKey;
350 OFNOTIFY *pOfnNotify;
351
352 UNREFERENCED_PARAMETER(wParam);
353
354 switch(uiMsg) {
355 case WM_INITDIALOG:
356 pOfn = (OPENFILENAME *) lParam;
357 pszSelectedKey = (LPTSTR) pOfn->lCustData;
358
359 hwndExportAll = GetDlgItem(hdlg, IDC_EXPORT_ALL);
360 if (hwndExportAll)
361 SendMessage(hwndExportAll, BM_SETCHECK, pszSelectedKey[0] ? BST_UNCHECKED : BST_CHECKED, 0);
362
363 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
364 if (hwndExportBranch)
365 SendMessage(hwndExportBranch, BM_SETCHECK, pszSelectedKey[0] ? BST_CHECKED : BST_UNCHECKED, 0);
366
367 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
368 if (hwndExportBranchText)
369 SetWindowText(hwndExportBranchText, pszSelectedKey);
370 break;
371
372 case WM_NOTIFY:
373 if (((NMHDR *) lParam)->code == CDN_FILEOK)
374 {
375 pOfnNotify = (OFNOTIFY *) lParam;
376 pszSelectedKey = (LPTSTR) pOfnNotify->lpOFN->lCustData;
377
378 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
379 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
380 if (hwndExportBranch && hwndExportBranchText
381 && (SendMessage(hwndExportBranch, BM_GETCHECK, 0, 0) == BST_CHECKED))
382 {
383 GetWindowText(hwndExportBranchText, pszSelectedKey, _MAX_PATH);
384 }
385 else
386 {
387 pszSelectedKey[0] = '\0';
388 }
389 }
390 break;
391 }
392 return iResult;
393 }
394
395 BOOL ExportRegistryFile(HWND hWnd)
396 {
397 OPENFILENAME ofn;
398 TCHAR ExportKeyPath[_MAX_PATH];
399 TCHAR Caption[128];
400 HKEY hKeyRoot;
401 LPCTSTR pszKeyPath;
402
403 /* Figure out which key path we are exporting */
404 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
405 RegKeyGetName(ExportKeyPath, sizeof(ExportKeyPath) / sizeof(ExportKeyPath[0]),
406 hKeyRoot, pszKeyPath);
407
408 InitOpenFileName(hWnd, &ofn);
409 LoadString(hInst, IDS_EXPORT_REG_FILE, Caption, sizeof(Caption)/sizeof(TCHAR));
410 ofn.lpstrTitle = Caption;
411 ofn.lCustData = (LPARAM) ExportKeyPath;
412 ofn.Flags = OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLEHOOK;
413 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
414 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORTRANGE);
415 if (GetSaveFileName(&ofn)) {
416 BOOL result;
417 LPSTR pszExportKeyPath;
418 #ifdef UNICODE
419 CHAR buffer[_MAX_PATH];
420
421 WideCharToMultiByte(CP_ACP, 0, ExportKeyPath, -1, buffer, sizeof(buffer), NULL, NULL);
422 pszExportKeyPath = buffer;
423 #else
424 pszExportKeyPath = ExportKeyPath;
425 #endif
426
427 result = export_registry_key(ofn.lpstrFile, pszExportKeyPath);
428 if (!result) {
429 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
430 return FALSE;
431 }
432 #if 0
433 TCHAR filename[MAX_PATH];
434 filename[0] = '\0';
435 get_file_name(&s, filename, MAX_PATH);
436 if (!filename[0]) {
437 printf("No file name is specified\n%s", usage);
438 return FALSE;
439 /*exit(1);*/
440 }
441 if (s[0]) {
442 TCHAR reg_key_name[KEY_MAX_LEN];
443 get_file_name(&s, reg_key_name, KEY_MAX_LEN);
444 export_registry_key((CHAR)filename, reg_key_name);
445 } else {
446 export_registry_key(filename, NULL);
447 }
448 #endif
449
450 } else {
451 CheckCommDlgError(hWnd);
452 }
453 return TRUE;
454 }
455
456 BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
457 {
458 #if 1
459 PRINTDLG pd;
460 UNREFERENCED_PARAMETER(path);
461
462 ZeroMemory(&pd, sizeof(PRINTDLG));
463 pd.lStructSize = sizeof(PRINTDLG);
464 pd.hwndOwner = hWnd;
465 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
466 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
467 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
468 pd.nCopies = 1;
469 pd.nFromPage = 0xFFFF;
470 pd.nToPage = 0xFFFF;
471 pd.nMinPage = 1;
472 pd.nMaxPage = 0xFFFF;
473 if (PrintDlg(&pd)) {
474 /* GDI calls to render output. */
475 DeleteDC(pd.hDC); /* Delete DC when done.*/
476 }
477 #else
478 HRESULT hResult;
479 PRINTDLGEX pd;
480
481 hResult = PrintDlgEx(&pd);
482 if (hResult == S_OK) {
483 switch (pd.dwResultAction) {
484 case PD_RESULT_APPLY:
485 /*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. */
486 break;
487 case PD_RESULT_CANCEL:
488 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
489 break;
490 case PD_RESULT_PRINT:
491 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
492 break;
493 default:
494 break;
495 }
496 } else {
497 switch (hResult) {
498 case E_OUTOFMEMORY:
499 /*Insufficient memory. */
500 break;
501 case E_INVALIDARG:
502 /* One or more arguments are invalid. */
503 break;
504 case E_POINTER:
505 /*Invalid pointer. */
506 break;
507 case E_HANDLE:
508 /*Invalid handle. */
509 break;
510 case E_FAIL:
511 /*Unspecified error. */
512 break;
513 default:
514 break;
515 }
516 return FALSE;
517 }
518 #endif
519 return TRUE;
520 }
521
522 static void ChooseFavorite(LPCTSTR pszFavorite)
523 {
524 HKEY hKey = NULL;
525 TCHAR szFavoritePath[512];
526 DWORD cbData, dwType;
527
528 if (RegOpenKeyEx(HKEY_CURRENT_USER, s_szFavoritesRegKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
529 goto done;
530
531 cbData = (sizeof(szFavoritePath) / sizeof(szFavoritePath[0])) - 1;
532 memset(szFavoritePath, 0, sizeof(szFavoritePath));
533 if (RegQueryValueEx(hKey, pszFavorite, NULL, &dwType, (LPBYTE) szFavoritePath, &cbData) != ERROR_SUCCESS)
534 goto done;
535
536 if (dwType == REG_SZ)
537 SelectNode(g_pChildWnd->hTreeWnd, szFavoritePath);
538
539 done:
540 if (hKey)
541 RegCloseKey(hKey);
542 }
543
544 BOOL CopyKeyName(HWND hWnd, HKEY hRootKey, LPCTSTR keyName)
545 {
546 BOOL bClipboardOpened = FALSE;
547 BOOL bSuccess = FALSE;
548 TCHAR szBuffer[512];
549 HGLOBAL hGlobal;
550 LPTSTR s;
551
552 if (!OpenClipboard(hWnd))
553 goto done;
554 bClipboardOpened = TRUE;
555
556 if (!EmptyClipboard())
557 goto done;
558
559 if (!RegKeyGetName(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), hRootKey, keyName))
560 goto done;
561
562 hGlobal = GlobalAlloc(GMEM_MOVEABLE, (_tcslen(szBuffer) + 1) * sizeof(TCHAR));
563 if (!hGlobal)
564 goto done;
565
566 s = GlobalLock(hGlobal);
567 _tcscpy(s, szBuffer);
568 GlobalUnlock(hGlobal);
569
570 #ifdef UNICODE
571 SetClipboardData(CF_UNICODETEXT, hGlobal);
572 #else
573 SetClipboardData(CF_TEXT, hGlobal);
574 #endif
575 bSuccess = TRUE;
576
577 done:
578 if (bClipboardOpened)
579 CloseClipboard();
580 return bSuccess;
581 }
582
583 static BOOL CreateNewValue(HKEY hRootKey, LPCTSTR pszKeyPath, DWORD dwType)
584 {
585 TCHAR szNewValueFormat[128];
586 TCHAR szNewValue[128];
587 int iIndex = 1;
588 BYTE data[128];
589 DWORD dwExistingType, cbData;
590 LONG lResult;
591 HKEY hKey;
592 LVFINDINFO lvfi;
593
594 if (RegOpenKey(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
595 return FALSE;
596
597 LoadString(hInst, IDS_NEW_VALUE, szNewValueFormat, sizeof(szNewValueFormat)
598 / sizeof(szNewValueFormat[0]));
599
600 do
601 {
602 _sntprintf(szNewValue, sizeof(szNewValue) / sizeof(szNewValue[0]),
603 szNewValueFormat, iIndex++);
604
605 cbData = sizeof(data);
606 lResult = RegQueryValueEx(hKey, szNewValue, NULL, &dwExistingType, data, &cbData);
607 }
608 while(lResult == ERROR_SUCCESS);
609
610 switch(dwType) {
611 case REG_DWORD:
612 cbData = sizeof(DWORD);
613 break;
614 case REG_SZ:
615 case REG_EXPAND_SZ:
616 cbData = sizeof(TCHAR);
617 break;
618 case REG_MULTI_SZ:
619 cbData = sizeof(TCHAR) * 2;
620 break;
621 case REG_QWORD:
622 cbData = sizeof(DWORD) * 2;
623 break;
624 default:
625 cbData = 0;
626 break;
627 }
628 memset(data, 0, cbData);
629 lResult = RegSetValueEx(hKey, szNewValue, 0, dwType, data, cbData);
630 if (lResult != ERROR_SUCCESS)
631 return FALSE;
632
633 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
634
635 /* locate the newly added value, and get ready to rename it */
636 memset(&lvfi, 0, sizeof(lvfi));
637 lvfi.flags = LVFI_STRING;
638 lvfi.psz = szNewValue;
639 iIndex = ListView_FindItem(g_pChildWnd->hListWnd, -1, &lvfi);
640 if (iIndex >= 0)
641 (void)ListView_EditLabel(g_pChildWnd->hListWnd, iIndex);
642
643 return TRUE;
644 }
645
646 static HRESULT
647 InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker)
648 {
649 HRESULT hRet;
650
651 *pDsObjectPicker = NULL;
652
653 hRet = CoCreateInstance(&CLSID_DsObjectPicker,
654 NULL,
655 CLSCTX_INPROC_SERVER,
656 &IID_IDsObjectPicker,
657 (LPVOID*)pDsObjectPicker);
658 if (SUCCEEDED(hRet))
659 {
660 DSOP_INIT_INFO InitInfo;
661 static DSOP_SCOPE_INIT_INFO Scopes[] =
662 {
663 {
664 sizeof(DSOP_SCOPE_INIT_INFO),
665 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE |
666 DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
667 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP |
668 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN,
669 0,
670 {
671 {
672 DSOP_FILTER_COMPUTERS,
673 0,
674 0
675 },
676 DSOP_DOWNLEVEL_FILTER_COMPUTERS
677 },
678 NULL,
679 NULL,
680 S_OK
681 },
682 };
683
684 InitInfo.cbSize = sizeof(InitInfo);
685 InitInfo.pwzTargetComputer = NULL;
686 InitInfo.cDsScopeInfos = sizeof(Scopes) / sizeof(Scopes[0]);
687 InitInfo.aDsScopeInfos = Scopes;
688 InitInfo.flOptions = 0;
689 InitInfo.cAttributesToFetch = 0;
690 InitInfo.apwzAttributeNames = NULL;
691
692 hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker,
693 &InitInfo);
694
695 if (FAILED(hRet))
696 {
697 /* delete the object picker in case initialization failed! */
698 (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker);
699 }
700 }
701
702 return hRet;
703 }
704
705 static HRESULT
706 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
707 IN HWND hwndParent OPTIONAL,
708 OUT LPTSTR lpBuffer,
709 IN UINT uSize)
710 {
711 IDataObject *pdo = NULL;
712 HRESULT hRet;
713
714 hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker,
715 hwndParent,
716 &pdo);
717 if (hRet == S_OK)
718 {
719 STGMEDIUM stm;
720 FORMATETC fe;
721
722 fe.cfFormat = (CLIPFORMAT) RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
723 fe.ptd = NULL;
724 fe.dwAspect = DVASPECT_CONTENT;
725 fe.lindex = -1;
726 fe.tymed = TYMED_HGLOBAL;
727
728 hRet = pdo->lpVtbl->GetData(pdo,
729 &fe,
730 &stm);
731 if (SUCCEEDED(hRet))
732 {
733 PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal);
734 if (SelectionList != NULL)
735 {
736 if (SelectionList->cItems == 1)
737 {
738 size_t nlen = wcslen(SelectionList->aDsSelection[0].pwzName);
739 if (nlen >= uSize)
740 {
741 nlen = uSize - 1;
742 }
743 #if UNICODE
744 memcpy(lpBuffer,
745 SelectionList->aDsSelection[0].pwzName,
746 nlen * sizeof(WCHAR));
747 #else
748 WideCharToMultiByte(CP_ACP,
749 0,
750 SelectionList->aDsSelection[0].pwzName,
751 nlen,
752 lpBuffer,
753 uSize,
754 NULL,
755 NULL);
756 #endif
757 lpBuffer[nlen] = L'\0';
758 }
759
760 GlobalUnlock(stm.hGlobal);
761 }
762
763 ReleaseStgMedium(&stm);
764 }
765
766 pdo->lpVtbl->Release(pdo);
767 }
768
769 return hRet;
770 }
771
772 static VOID
773 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
774 {
775 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
776 }
777
778 /*******************************************************************************
779 *
780 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
781 *
782 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
783 *
784 */
785 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
786 {
787 HKEY hKeyRoot = 0, hKey = 0;
788 LPCTSTR keyPath;
789 LPCTSTR valueName;
790 BOOL result = TRUE;
791 REGSAM regsam = KEY_READ;
792 LONG lRet;
793 int item;
794
795 UNREFERENCED_PARAMETER(lParam);
796 UNREFERENCED_PARAMETER(message);
797
798 switch (LOWORD(wParam)) {
799 case ID_REGISTRY_IMPORTREGISTRYFILE:
800 ImportRegistryFile(hWnd);
801 return TRUE;
802 case ID_REGISTRY_EXPORTREGISTRYFILE:
803 ExportRegistryFile(hWnd);
804 return TRUE;
805 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
806 {
807 IDsObjectPicker *ObjectPicker;
808 TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
809 HRESULT hRet;
810
811 hRet = CoInitialize(NULL);
812 if (SUCCEEDED(hRet))
813 {
814 hRet = InitializeRemoteRegistryPicker(&ObjectPicker);
815 if (SUCCEEDED(hRet))
816 {
817 hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker,
818 hWnd,
819 szComputerName,
820 sizeof(szComputerName) / sizeof(szComputerName[0]));
821 if (hRet == S_OK)
822 {
823 /* FIXME - connect to the registry */
824 }
825
826 FreeObjectPicker(ObjectPicker);
827 }
828
829 CoUninitialize();
830 }
831
832 return TRUE;
833 }
834 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
835 return TRUE;
836 case ID_REGISTRY_PRINT:
837 PrintRegistryHive(hWnd, _T(""));
838 return TRUE;
839 case ID_REGISTRY_EXIT:
840 DestroyWindow(hWnd);
841 return TRUE;
842 case ID_VIEW_STATUSBAR:
843 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
844 return TRUE;
845 case ID_HELP_HELPTOPICS:
846 WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
847 return TRUE;
848 case ID_HELP_ABOUT:
849 ShowAboutBox(hWnd);
850 return TRUE;
851 case ID_VIEW_SPLIT:
852 {
853 RECT rt;
854 POINT pt, pts;
855 GetClientRect(g_pChildWnd->hWnd, &rt);
856 pt.x = rt.left + g_pChildWnd->nSplitPos;
857 pt.y = (rt.bottom / 2);
858 pts = pt;
859 if(ClientToScreen(g_pChildWnd->hWnd, &pts))
860 {
861 SetCursorPos(pts.x, pts.y);
862 SetCursor(LoadCursor(0, IDC_SIZEWE));
863 SendMessage(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
864 }
865 return TRUE;
866 }
867 case ID_EDIT_RENAME:
868 case ID_EDIT_MODIFY:
869 case ID_EDIT_MODIFY_BIN:
870 case ID_EDIT_DELETE:
871 regsam |= KEY_WRITE;
872 break;
873 }
874
875 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
876 valueName = GetValueName(g_pChildWnd->hListWnd, -1);
877 if (keyPath) {
878 lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, regsam, &hKey);
879 if (lRet != ERROR_SUCCESS) hKey = 0;
880 }
881
882 switch (LOWORD(wParam)) {
883 case ID_EDIT_MODIFY:
884 if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE))
885 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
886 break;
887 case ID_EDIT_MODIFY_BIN:
888 if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE))
889 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
890 break;
891 case ID_EDIT_RENAME:
892 if(ListView_GetSelectedCount(g_pChildWnd->hListWnd) == 1)
893 {
894 item = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
895 if(item > -1)
896 {
897 (void)ListView_EditLabel(g_pChildWnd->hListWnd, item);
898 }
899 }
900 break;
901 case ID_EDIT_DELETE:
902 {
903 if (GetFocus() == g_pChildWnd->hListWnd)
904 {
905 UINT nSelected = ListView_GetSelectedCount(g_pChildWnd->hListWnd);
906 if(nSelected >= 1)
907 {
908 TCHAR msg[128], caption[128];
909 LoadString(hInst, IDS_QUERY_DELETE_CONFIRM, caption, sizeof(caption)/sizeof(TCHAR));
910 LoadString(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, sizeof(msg)/sizeof(TCHAR));
911 if(MessageBox(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES)
912 {
913 int ni, errs;
914
915 item = -1;
916 errs = 0;
917 while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1)
918 {
919 valueName = GetValueName(g_pChildWnd->hListWnd, item);
920 if(RegDeleteValue(hKey, valueName) != ERROR_SUCCESS)
921 {
922 errs++;
923 }
924 item = ni;
925 }
926
927 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
928 if(errs > 0)
929 {
930 LoadString(hInst, IDS_ERR_DELVAL_CAPTION, caption, sizeof(caption)/sizeof(TCHAR));
931 LoadString(hInst, IDS_ERR_DELETEVALUE, msg, sizeof(msg)/sizeof(TCHAR));
932 MessageBox(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP);
933 }
934 }
935 }
936 } else
937 if (GetFocus() == g_pChildWnd->hTreeWnd)
938 {
939 if (keyPath == 0 || *keyPath == 0)
940 {
941 MessageBeep(MB_ICONHAND);
942 } else
943 if (DeleteKey(hWnd, hKeyRoot, keyPath))
944 DeleteNode(g_pChildWnd->hTreeWnd, 0);
945 }
946 break;
947 case ID_EDIT_NEW_STRINGVALUE:
948 CreateNewValue(hKeyRoot, keyPath, REG_SZ);
949 break;
950 case ID_EDIT_NEW_BINARYVALUE:
951 CreateNewValue(hKeyRoot, keyPath, REG_BINARY);
952 break;
953 case ID_EDIT_NEW_DWORDVALUE:
954 CreateNewValue(hKeyRoot, keyPath, REG_DWORD);
955 break;
956 case ID_EDIT_NEW_MULTISTRINGVALUE:
957 CreateNewValue(hKeyRoot, keyPath, REG_MULTI_SZ);
958 break;
959 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE:
960 CreateNewValue(hKeyRoot, keyPath, REG_EXPAND_SZ);
961 break;
962
963 }
964 case ID_EDIT_FIND:
965 FindDialog(hWnd);
966 break;
967 case ID_EDIT_FINDNEXT:
968 FindNext(hWnd);
969 break;
970 case ID_EDIT_COPYKEYNAME:
971 CopyKeyName(hWnd, hKeyRoot, keyPath);
972 break;
973 case ID_EDIT_PERMISSIONS:
974 RegKeyEditPermissions(hWnd, hKeyRoot, NULL, keyPath);
975 break;
976 case ID_REGISTRY_PRINTERSETUP:
977 /*PRINTDLG pd;*/
978 /*PrintDlg(&pd);*/
979 /*PAGESETUPDLG psd;*/
980 /*PageSetupDlg(&psd);*/
981 break;
982 case ID_REGISTRY_OPENLOCAL:
983 break;
984
985 case ID_VIEW_REFRESH:
986 RefreshTreeView(g_pChildWnd->hTreeWnd);
987 /*RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL); */
988 break;
989 /*case ID_OPTIONS_TOOLBAR:*/
990 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
991 /* break;*/
992 case ID_EDIT_NEW_KEY:
993 CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd));
994 break;
995 default:
996 if ((LOWORD(wParam) >= ID_FAVORITES_MIN) && (LOWORD(wParam) <= ID_FAVORITES_MAX))
997 {
998 HMENU hMenu;
999 MENUITEMINFO mii;
1000 TCHAR szFavorite[512];
1001
1002 hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION);
1003
1004 memset(&mii, 0, sizeof(mii));
1005 mii.cbSize = sizeof(mii);
1006 mii.fMask = MIIM_TYPE;
1007 mii.fType = MFT_STRING;
1008 mii.dwTypeData = szFavorite;
1009 mii.cch = sizeof(szFavorite) / sizeof(szFavorite[0]);
1010
1011 if (GetMenuItemInfo(hMenu, LOWORD(wParam) - ID_FAVORITES_MIN, TRUE, &mii))
1012 {
1013 ChooseFavorite(szFavorite);
1014 }
1015 }
1016 else
1017 {
1018 result = FALSE;
1019 }
1020 break;
1021 }
1022
1023 if(hKey)
1024 RegCloseKey(hKey);
1025 return result;
1026 }
1027
1028 /********************************************************************************
1029 *
1030 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1031 *
1032 * PURPOSE: Processes messages for the main frame window.
1033 *
1034 * WM_COMMAND - process the application menu
1035 * WM_DESTROY - post a quit message and return
1036 *
1037 */
1038
1039 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1040 {
1041 switch (message) {
1042 case WM_CREATE:
1043 CreateWindowEx(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE,
1044 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
1045 hWnd, (HMENU)0, hInst, 0);
1046 break;
1047 case WM_COMMAND:
1048 if (!_CmdWndProc(hWnd, message, wParam, lParam))
1049 return DefWindowProc(hWnd, message, wParam, lParam);
1050 break;
1051 case WM_ACTIVATE:
1052 if (LOWORD(hWnd))
1053 SetFocus(g_pChildWnd->hWnd);
1054 break;
1055 case WM_SIZE:
1056 resize_frame_client(hWnd);
1057 break;
1058 case WM_TIMER:
1059 break;
1060 case WM_INITMENU:
1061 OnInitMenu(hWnd);
1062 break;
1063 case WM_ENTERMENULOOP:
1064 OnEnterMenuLoop(hWnd);
1065 break;
1066 case WM_EXITMENULOOP:
1067 OnExitMenuLoop(hWnd);
1068 break;
1069 case WM_MENUSELECT:
1070 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
1071 break;
1072 case WM_DESTROY:
1073 WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
1074 PostQuitMessage(0);
1075 default:
1076 return DefWindowProc(hWnd, message, wParam, lParam);
1077 }
1078 return 0;
1079 }