display the computer selection dialog for remote registry administration
[reactos.git] / reactos / subsys / system / 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 <windows.h>
22 #include <tchar.h>
23 #include <commctrl.h>
24 #include <commdlg.h>
25 #include <cderr.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <shellapi.h>
29 #include <objsel.h>
30
31 #include "main.h"
32 #include "regproc.h"
33
34 /********************************************************************************
35 * Global and Local Variables:
36 */
37
38 static BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
39
40 /*******************************************************************************
41 * Local module support methods
42 */
43
44 static void resize_frame_rect(HWND hWnd, PRECT prect)
45 {
46 RECT rt;
47 /*
48 if (IsWindowVisible(hToolBar)) {
49 SendMessage(hToolBar, WM_SIZE, 0, 0);
50 GetClientRect(hToolBar, &rt);
51 prect->top = rt.bottom+3;
52 prect->bottom -= rt.bottom+3;
53 }
54 */
55 if (IsWindowVisible(hStatusBar)) {
56 SetupStatusBar(hWnd, TRUE);
57 GetClientRect(hStatusBar, &rt);
58 prect->bottom -= rt.bottom;
59 }
60 MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
61 }
62
63 static void resize_frame_client(HWND hWnd)
64 {
65 RECT rect;
66
67 GetClientRect(hWnd, &rect);
68 resize_frame_rect(hWnd, &rect);
69 }
70
71 /********************************************************************************/
72
73 static void OnEnterMenuLoop(HWND hWnd)
74 {
75 int nParts;
76
77 /* Update the status bar pane sizes */
78 nParts = -1;
79 SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
80 bInMenuLoop = TRUE;
81 SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
82 }
83
84 static void OnExitMenuLoop(HWND hWnd)
85 {
86 bInMenuLoop = FALSE;
87 /* Update the status bar pane sizes*/
88 SetupStatusBar(hWnd, TRUE);
89 UpdateStatusBar();
90 }
91
92 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
93 {
94 TCHAR str[100];
95
96 _tcscpy(str, _T(""));
97 if (nFlags & MF_POPUP) {
98 if (hSysMenu != GetMenu(hWnd)) {
99 if (nItemID == 2) nItemID = 5;
100 }
101 }
102 if (LoadString(hInst, nItemID, str, 100)) {
103 /* load appropriate string*/
104 LPTSTR lpsz = str;
105 /* first newline terminates actual string*/
106 lpsz = _tcschr(lpsz, '\n');
107 if (lpsz != NULL)
108 *lpsz = '\0';
109 }
110 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)str);
111 }
112
113 void SetupStatusBar(HWND hWnd, BOOL bResize)
114 {
115 RECT rc;
116 int nParts;
117 GetClientRect(hWnd, &rc);
118 nParts = rc.right;
119 /* nParts = -1;*/
120 if (bResize)
121 SendMessage(hStatusBar, WM_SIZE, 0, 0);
122 SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
123 }
124
125 void UpdateStatusBar(void)
126 {
127 TCHAR text[260];
128 DWORD size;
129
130 size = sizeof(text)/sizeof(TCHAR);
131 GetComputerName(text, &size);
132 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)text);
133 }
134
135 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
136 {
137 BOOL vis = IsWindowVisible(hchild);
138 HMENU hMenuView = GetSubMenu(hMenuFrame, ID_VIEW_MENU);
139
140 CheckMenuItem(hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
141 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
142 resize_frame_client(hWnd);
143 }
144
145 static BOOL CheckCommDlgError(HWND hWnd)
146 {
147 DWORD dwErrorCode = CommDlgExtendedError();
148 switch (dwErrorCode) {
149 case CDERR_DIALOGFAILURE:
150 break;
151 case CDERR_FINDRESFAILURE:
152 break;
153 case CDERR_NOHINSTANCE:
154 break;
155 case CDERR_INITIALIZATION:
156 break;
157 case CDERR_NOHOOK:
158 break;
159 case CDERR_LOCKRESFAILURE:
160 break;
161 case CDERR_NOTEMPLATE:
162 break;
163 case CDERR_LOADRESFAILURE:
164 break;
165 case CDERR_STRUCTSIZE:
166 break;
167 case CDERR_LOADSTRFAILURE:
168 break;
169 case FNERR_BUFFERTOOSMALL:
170 break;
171 case CDERR_MEMALLOCFAILURE:
172 break;
173 case FNERR_INVALIDFILENAME:
174 break;
175 case CDERR_MEMLOCKFAILURE:
176 break;
177 case FNERR_SUBCLASSFAILURE:
178 break;
179 default:
180 break;
181 }
182 return TRUE;
183 }
184
185 #define MAX_CUSTOM_FILTER_SIZE 50
186 TCHAR CustomFilterBuffer[MAX_CUSTOM_FILTER_SIZE];
187 TCHAR FileNameBuffer[_MAX_PATH];
188 TCHAR FileTitleBuffer[_MAX_PATH];
189
190 typedef struct
191 {
192 UINT DisplayID;
193 UINT FilterID;
194 } FILTERPAIR, *PFILTERPAIR;
195
196 void
197 BuildFilterStrings(TCHAR *Filter, PFILTERPAIR Pairs, int PairCount)
198 {
199 int i, c;
200
201 c = 0;
202 for(i = 0; i < PairCount; i++)
203 {
204 c += LoadString(hInst, Pairs[i].DisplayID, &Filter[c], 255 * sizeof(TCHAR));
205 Filter[++c] = '\0';
206 c += LoadString(hInst, Pairs[i].FilterID, &Filter[c], 255 * sizeof(TCHAR));
207 Filter[++c] = '\0';
208 }
209 Filter[++c] = '\0';
210 }
211
212 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
213 {
214 FILTERPAIR FilterPairs[3];
215 static TCHAR Filter[1024];
216
217 memset(pofn, 0, sizeof(OPENFILENAME));
218 pofn->lStructSize = sizeof(OPENFILENAME);
219 pofn->hwndOwner = hWnd;
220 pofn->hInstance = hInst;
221
222 /* create filter string */
223 FilterPairs[0].DisplayID = IDS_FLT_REGFILES;
224 FilterPairs[0].FilterID = IDS_FLT_REGFILES_FLT;
225 FilterPairs[1].DisplayID = IDS_FLT_REGEDIT4;
226 FilterPairs[1].FilterID = IDS_FLT_REGEDIT4_FLT;
227 FilterPairs[2].DisplayID = IDS_FLT_ALLFILES;
228 FilterPairs[2].FilterID = IDS_FLT_ALLFILES_FLT;
229 BuildFilterStrings(Filter, FilterPairs, sizeof(FilterPairs) / sizeof(FILTERPAIR));
230
231 pofn->lpstrFilter = Filter;
232 pofn->lpstrCustomFilter = CustomFilterBuffer;
233 pofn->nMaxCustFilter = MAX_CUSTOM_FILTER_SIZE;
234 pofn->nFilterIndex = 0;
235 pofn->lpstrFile = FileNameBuffer;
236 pofn->nMaxFile = _MAX_PATH;
237 pofn->lpstrFileTitle = FileTitleBuffer;
238 pofn->nMaxFileTitle = _MAX_PATH;
239 /* pofn->lpstrInitialDir = _T("");*/
240 /* pofn->lpstrTitle = _T("Import Registry File");*/
241 /* pofn->Flags = OFN_ENABLETEMPLATE + OFN_EXPLORER + OFN_ENABLESIZING;*/
242 pofn->Flags = OFN_HIDEREADONLY;
243 /* pofn->nFileOffset = ;*/
244 /* pofn->nFileExtension = ;*/
245 /* pofn->lpstrDefExt = _T("");*/
246 /* pofn->lCustData = ;*/
247 /* pofn->lpfnHook = ImportRegistryFile_OFNHookProc;*/
248 /* pofn->lpTemplateName = _T("ID_DLG_IMPORT_REGFILE");*/
249 /* pofn->lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);*/
250 /* pofn->FlagsEx = ;*/
251 return TRUE;
252 }
253
254 static BOOL ImportRegistryFile(HWND hWnd)
255 {
256 OPENFILENAME ofn;
257 TCHAR Caption[128];
258
259 InitOpenFileName(hWnd, &ofn);
260 LoadString(hInst, IDS_IMPORT_REG_FILE, Caption, sizeof(Caption)/sizeof(TCHAR));
261 ofn.lpstrTitle = Caption;
262 /* ofn.lCustData = ;*/
263 if (GetOpenFileName(&ofn)) {
264 /* FIXME - convert to ascii */
265 if (!import_registry_file((LPSTR)ofn.lpstrFile)) {
266 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
267 return FALSE;
268 }
269 #if 0
270 get_file_name(&s, filename, MAX_PATH);
271 if (!filename[0]) {
272 printf("No file name is specified\n%s", usage);
273 return FALSE;
274 /*exit(1);*/
275 }
276 while (filename[0]) {
277 if (!import_registry_file(filename)) {
278 perror("");
279 printf("Can't open file \"%s\"\n", filename);
280 return FALSE;
281 /*exit(1);*/
282 }
283 get_file_name(&s, filename, MAX_PATH);
284 }
285 #endif
286
287 } else {
288 CheckCommDlgError(hWnd);
289 }
290 return TRUE;
291 }
292
293
294 static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
295 {
296 HWND hControl;
297 UINT_PTR iResult = 0;
298
299 switch(uiMsg) {
300 case WM_INITDIALOG:
301 hControl = GetDlgItem(hdlg, IDC_EXPORT_ALL);
302 if (hControl)
303 {
304 EnableWindow(hControl, FALSE);
305 SendMessage(hControl, BM_SETCHECK, BST_CHECKED, 0);
306 }
307
308 hControl = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
309 if (hControl)
310 {
311 EnableWindow(hControl, FALSE);
312 SendMessage(hControl, BM_SETCHECK, BST_UNCHECKED, 0);
313 }
314
315 hControl = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
316 if (hControl)
317 {
318 EnableWindow(hControl, FALSE);
319 }
320 break;
321 }
322 return iResult;
323 }
324
325 static BOOL ExportRegistryFile(HWND hWnd)
326 {
327 OPENFILENAME ofn;
328 TCHAR ExportKeyPath[_MAX_PATH];
329 TCHAR Caption[128];
330
331 ExportKeyPath[0] = _T('\0');
332 InitOpenFileName(hWnd, &ofn);
333 LoadString(hInst, IDS_EXPORT_REG_FILE, Caption, sizeof(Caption)/sizeof(TCHAR));
334 ofn.lpstrTitle = Caption;
335 /* ofn.lCustData = ;*/
336 ofn.Flags = OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLEHOOK;
337 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
338 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORTRANGE);
339 if (GetSaveFileName(&ofn)) {
340 BOOL result;
341 /* FIXME - convert strings to ascii! */
342 result = export_registry_key((CHAR*)ofn.lpstrFile, (CHAR*)ExportKeyPath);
343 /*result = export_registry_key(ofn.lpstrFile, NULL);*/
344 /*if (!export_registry_key(ofn.lpstrFile, NULL)) {*/
345 if (!result) {
346 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
347 return FALSE;
348 }
349 #if 0
350 TCHAR filename[MAX_PATH];
351 filename[0] = '\0';
352 get_file_name(&s, filename, MAX_PATH);
353 if (!filename[0]) {
354 printf("No file name is specified\n%s", usage);
355 return FALSE;
356 /*exit(1);*/
357 }
358 if (s[0]) {
359 TCHAR reg_key_name[KEY_MAX_LEN];
360 get_file_name(&s, reg_key_name, KEY_MAX_LEN);
361 export_registry_key((CHAR)filename, reg_key_name);
362 } else {
363 export_registry_key(filename, NULL);
364 }
365 #endif
366
367 } else {
368 CheckCommDlgError(hWnd);
369 }
370 return TRUE;
371 }
372
373 BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
374 {
375 #if 1
376 PRINTDLG pd;
377
378 ZeroMemory(&pd, sizeof(PRINTDLG));
379 pd.lStructSize = sizeof(PRINTDLG);
380 pd.hwndOwner = hWnd;
381 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
382 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
383 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
384 pd.nCopies = 1;
385 pd.nFromPage = 0xFFFF;
386 pd.nToPage = 0xFFFF;
387 pd.nMinPage = 1;
388 pd.nMaxPage = 0xFFFF;
389 if (PrintDlg(&pd)) {
390 /* GDI calls to render output. */
391 DeleteDC(pd.hDC); /* Delete DC when done.*/
392 }
393 #else
394 HRESULT hResult;
395 PRINTDLGEX pd;
396
397 hResult = PrintDlgEx(&pd);
398 if (hResult == S_OK) {
399 switch (pd.dwResultAction) {
400 case PD_RESULT_APPLY:
401 /*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. */
402 break;
403 case PD_RESULT_CANCEL:
404 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
405 break;
406 case PD_RESULT_PRINT:
407 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
408 break;
409 default:
410 break;
411 }
412 } else {
413 switch (hResult) {
414 case E_OUTOFMEMORY:
415 /*Insufficient memory. */
416 break;
417 case E_INVALIDARG:
418 /* One or more arguments are invalid. */
419 break;
420 case E_POINTER:
421 /*Invalid pointer. */
422 break;
423 case E_HANDLE:
424 /*Invalid handle. */
425 break;
426 case E_FAIL:
427 /*Unspecified error. */
428 break;
429 default:
430 break;
431 }
432 return FALSE;
433 }
434 #endif
435 return TRUE;
436 }
437
438 static BOOL CopyKeyName(HWND hWnd, LPCTSTR keyName)
439 {
440 BOOL result;
441
442 result = OpenClipboard(hWnd);
443 if (result) {
444 result = EmptyClipboard();
445 if (result) {
446
447 /*HANDLE hClipData;*/
448 /*hClipData = SetClipboardData(UINT uFormat, HANDLE hMem);*/
449
450 } else {
451 /* error emptying clipboard*/
452 /* DWORD dwError = GetLastError(); */
453 ;
454 }
455 if (!CloseClipboard()) {
456 /* error closing clipboard*/
457 /* DWORD dwError = GetLastError(); */
458 ;
459 }
460 } else {
461 /* error opening clipboard*/
462 /* DWORD dwError = GetLastError(); */
463 ;
464 }
465 return result;
466 }
467
468 static BOOL CreateNewValue(HKEY hRootKey, LPCTSTR pszKeyPath, DWORD dwType)
469 {
470 TCHAR szNewValueFormat[128];
471 TCHAR szNewValue[128];
472 int iIndex = 1;
473 BYTE data[128];
474 DWORD dwExistingType, cbData;
475 LONG lResult;
476 HKEY hKey;
477 LVFINDINFO lvfi;
478
479 if (RegOpenKey(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
480 return FALSE;
481
482 LoadString(hInst, IDS_NEW_VALUE, szNewValueFormat, sizeof(szNewValueFormat)
483 / sizeof(szNewValueFormat[0]));
484
485 do
486 {
487 _sntprintf(szNewValue, sizeof(szNewValue) / sizeof(szNewValue[0]),
488 szNewValueFormat, iIndex++);
489
490 cbData = sizeof(data);
491 lResult = RegQueryValueEx(hKey, szNewValue, NULL, &dwExistingType, data, &cbData);
492 }
493 while(lResult == ERROR_SUCCESS);
494
495 switch(dwType) {
496 case REG_DWORD:
497 cbData = sizeof(DWORD);
498 break;
499 case REG_SZ:
500 case REG_EXPAND_SZ:
501 cbData = sizeof(TCHAR);
502 break;
503 case REG_MULTI_SZ:
504 cbData = sizeof(TCHAR) * 2;
505 break;
506 case REG_QWORD:
507 cbData = sizeof(DWORD) * 2;
508 break;
509 default:
510 cbData = 0;
511 break;
512 }
513 memset(data, 0, cbData);
514 lResult = RegSetValueEx(hKey, szNewValue, 0, dwType, data, cbData);
515 if (lResult != ERROR_SUCCESS)
516 return FALSE;
517
518 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
519
520 /* locate the newly added value, and get ready to rename it */
521 memset(&lvfi, 0, sizeof(lvfi));
522 lvfi.flags = LVFI_STRING;
523 lvfi.psz = szNewValue;
524 iIndex = ListView_FindItem(g_pChildWnd->hListWnd, -1, &lvfi);
525 if (iIndex >= 0)
526 ListView_EditLabel(g_pChildWnd->hListWnd, iIndex);
527
528 return TRUE;
529 }
530
531 static HRESULT
532 InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker)
533 {
534 HRESULT hRet;
535
536 *pDsObjectPicker = NULL;
537
538 hRet = CoCreateInstance(&CLSID_DsObjectPicker,
539 NULL,
540 CLSCTX_INPROC_SERVER,
541 &IID_IDsObjectPicker,
542 (LPVOID*)pDsObjectPicker);
543 if (SUCCEEDED(hRet))
544 {
545 DSOP_INIT_INFO InitInfo;
546 DSOP_SCOPE_INIT_INFO Scopes[] =
547 {
548 {
549 sizeof(DSOP_SCOPE_INIT_INFO),
550 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE |
551 DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
552 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP |
553 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN,
554 0,
555 {
556 {
557 DSOP_FILTER_COMPUTERS,
558 0,
559 0
560 },
561 DSOP_DOWNLEVEL_FILTER_COMPUTERS |
562 DSOP_DOWNLEVEL_FILTER_GLOBAL_GROUPS | DSOP_DOWNLEVEL_FILTER_ALL_WELLKNOWN_SIDS
563 },
564 NULL,
565 NULL,
566 S_OK
567 },
568 };
569
570 InitInfo.cbSize = sizeof(InitInfo);
571 InitInfo.pwzTargetComputer = NULL;
572 InitInfo.cDsScopeInfos = sizeof(Scopes) / sizeof(Scopes[0]);
573 InitInfo.aDsScopeInfos = Scopes;
574 InitInfo.flOptions = DSOP_SCOPE_TYPE_TARGET_COMPUTER;
575 InitInfo.cAttributesToFetch = 0;
576 InitInfo.apwzAttributeNames = NULL;
577
578 hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker,
579 &InitInfo);
580
581 if (FAILED(hRet))
582 {
583 /* delete the object picker in case initialization failed! */
584 (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker);
585 }
586 }
587
588 return hRet;
589 }
590
591 static HRESULT
592 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
593 IN HWND hwndParent OPTIONAL,
594 OUT LPWSTR lpBuffer,
595 IN UINT uSize)
596 {
597 IDataObject *pdo = NULL;
598 HRESULT hRet;
599
600 hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker,
601 hwndParent,
602 &pdo);
603 if (hRet == S_OK)
604 {
605 STGMEDIUM stm;
606 FORMATETC fe;
607
608 fe.cfFormat = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
609 fe.ptd = NULL;
610 fe.dwAspect = DVASPECT_CONTENT;
611 fe.lindex = -1;
612 fe.tymed = TYMED_HGLOBAL;
613
614 hRet = pdo->lpVtbl->GetData(pdo,
615 &fe,
616 &stm);
617 if (SUCCEEDED(hRet))
618 {
619 PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal);
620 if (SelectionList != NULL)
621 {
622 if (SelectionList->cItems == 1)
623 {
624 UINT nlen = wcslen(SelectionList->aDsSelection[0].pwzName);
625 if (nlen >= uSize)
626 {
627 nlen = uSize - 1;
628 }
629
630 memcpy(lpBuffer,
631 SelectionList->aDsSelection[0].pwzName,
632 nlen * sizeof(WCHAR));
633 lpBuffer[nlen] = L'\0';
634 }
635
636 GlobalUnlock(stm.hGlobal);
637 }
638
639 ReleaseStgMedium(&stm);
640 }
641
642 pdo->lpVtbl->Release(pdo);
643 }
644
645 return hRet;
646 }
647
648 static VOID
649 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
650 {
651 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
652 }
653
654 /*******************************************************************************
655 *
656 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
657 *
658 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
659 *
660 */
661 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
662 {
663 HKEY hKeyRoot = 0, hKey = 0;
664 LPCTSTR keyPath;
665 LPCTSTR valueName;
666 BOOL result = TRUE;
667 REGSAM regsam = KEY_READ;
668 LONG lRet;
669 int item;
670
671 switch (LOWORD(wParam)) {
672 case ID_REGISTRY_IMPORTREGISTRYFILE:
673 ImportRegistryFile(hWnd);
674 return TRUE;
675 case ID_REGISTRY_EXPORTREGISTRYFILE:
676 ExportRegistryFile(hWnd);
677 return TRUE;
678 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
679 {
680 IDsObjectPicker *ObjectPicker;
681 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
682 HRESULT hRet;
683
684 hRet = InitializeRemoteRegistryPicker(&ObjectPicker);
685 if (SUCCEEDED(hRet))
686 {
687 hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker,
688 hWnd,
689 szComputerName,
690 sizeof(szComputerName) / sizeof(szComputerName[0]));
691 if (hRet == S_OK)
692 {
693 /* FIXME - connect to the registry */
694 }
695
696 FreeObjectPicker(ObjectPicker);
697 }
698
699 return TRUE;
700 }
701 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
702 return TRUE;
703 case ID_REGISTRY_PRINT:
704 PrintRegistryHive(hWnd, _T(""));
705 return TRUE;
706 case ID_REGISTRY_EXIT:
707 DestroyWindow(hWnd);
708 return TRUE;
709 case ID_VIEW_STATUSBAR:
710 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
711 return TRUE;
712 case ID_HELP_HELPTOPICS:
713 WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
714 return TRUE;
715 case ID_HELP_ABOUT:
716 ShowAboutBox(hWnd);
717 return TRUE;
718 case ID_VIEW_SPLIT:
719 {
720 RECT rt;
721 POINT pt, pts;
722 GetClientRect(g_pChildWnd->hWnd, &rt);
723 pt.x = rt.left + g_pChildWnd->nSplitPos;
724 pt.y = (rt.bottom / 2);
725 pts = pt;
726 if(ClientToScreen(g_pChildWnd->hWnd, &pts))
727 {
728 SetCursorPos(pts.x, pts.y);
729 SetCursor(LoadCursor(0, IDC_SIZEWE));
730 SendMessage(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
731 }
732 return TRUE;
733 }
734 case ID_EDIT_RENAME:
735 case ID_EDIT_MODIFY:
736 case ID_EDIT_MODIFY_BIN:
737 case ID_EDIT_DELETE:
738 regsam |= KEY_WRITE;
739 break;
740 }
741
742 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
743 valueName = GetValueName(g_pChildWnd->hListWnd, -1);
744 if (keyPath) {
745 lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, regsam, &hKey);
746 if (lRet != ERROR_SUCCESS) hKey = 0;
747 }
748
749 switch (LOWORD(wParam)) {
750 case ID_EDIT_MODIFY:
751 if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE))
752 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
753 break;
754 case ID_EDIT_MODIFY_BIN:
755 if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE))
756 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
757 break;
758 case ID_EDIT_RENAME:
759 if(ListView_GetSelectedCount(g_pChildWnd->hListWnd) == 1)
760 {
761 item = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
762 if(item > -1)
763 {
764 ListView_EditLabel(g_pChildWnd->hListWnd, item);
765 }
766 }
767 break;
768 case ID_EDIT_DELETE:
769 {
770 UINT nSelected = ListView_GetSelectedCount(g_pChildWnd->hListWnd);
771 if(nSelected >= 1)
772 {
773 TCHAR msg[128], caption[128];
774 LoadString(hInst, IDS_QUERY_DELETE_CONFIRM, caption, sizeof(caption)/sizeof(TCHAR));
775 LoadString(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, sizeof(msg)/sizeof(TCHAR));
776 if(MessageBox(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES)
777 {
778 int ni, errs;
779
780 item = -1;
781 errs = 0;
782 while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1)
783 {
784 valueName = GetValueName(g_pChildWnd->hListWnd, item);
785 if(RegDeleteValue(hKey, valueName) != ERROR_SUCCESS)
786 {
787 errs++;
788 }
789 item = ni;
790 }
791
792 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
793 if(errs > 0)
794 {
795 LoadString(hInst, IDS_ERR_DELVAL_CAPTION, caption, sizeof(caption)/sizeof(TCHAR));
796 LoadString(hInst, IDS_ERR_DELETEVALUE, msg, sizeof(msg)/sizeof(TCHAR));
797 MessageBox(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP);
798 }
799 }
800 }
801 break;
802 case ID_EDIT_NEW_STRINGVALUE:
803 CreateNewValue(hKeyRoot, keyPath, REG_SZ);
804 break;
805 case ID_EDIT_NEW_BINARYVALUE:
806 CreateNewValue(hKeyRoot, keyPath, REG_BINARY);
807 break;
808 case ID_EDIT_NEW_DWORDVALUE:
809 CreateNewValue(hKeyRoot, keyPath, REG_DWORD);
810 break;
811 }
812 case ID_EDIT_COPYKEYNAME:
813 CopyKeyName(hWnd, _T(""));
814 break;
815 case ID_EDIT_PERMISSIONS:
816 if(keyPath != NULL && _tcslen(keyPath) > 0)
817 {
818 RegKeyEditPermissions(hWnd, hKey, NULL, keyPath);
819 }
820 else
821 {
822 MessageBeep(MB_ICONASTERISK);
823 }
824 break;
825 case ID_REGISTRY_PRINTERSETUP:
826 /*PRINTDLG pd;*/
827 /*PrintDlg(&pd);*/
828 /*PAGESETUPDLG psd;*/
829 /*PageSetupDlg(&psd);*/
830 break;
831 case ID_REGISTRY_OPENLOCAL:
832 break;
833
834 case ID_VIEW_REFRESH:
835 RefreshTreeView(g_pChildWnd->hTreeWnd);
836 /*RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL); */
837 break;
838 /*case ID_OPTIONS_TOOLBAR:*/
839 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
840 /* break;*/
841 case ID_EDIT_NEW_KEY:
842 CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd));
843 break;
844 default:
845 result = FALSE;
846 }
847
848 if(hKey)
849 RegCloseKey(hKey);
850 return result;
851 }
852
853 /********************************************************************************
854 *
855 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
856 *
857 * PURPOSE: Processes messages for the main frame window.
858 *
859 * WM_COMMAND - process the application menu
860 * WM_DESTROY - post a quit message and return
861 *
862 */
863
864 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
865 {
866 switch (message) {
867 case WM_CREATE:
868 CreateWindowEx(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE,
869 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
870 hWnd, (HMENU)0, hInst, 0);
871 break;
872 case WM_COMMAND:
873 if (!_CmdWndProc(hWnd, message, wParam, lParam))
874 return DefWindowProc(hWnd, message, wParam, lParam);
875 break;
876 case WM_ACTIVATE:
877 if (LOWORD(hWnd))
878 SetFocus(g_pChildWnd->hWnd);
879 break;
880 case WM_SIZE:
881 resize_frame_client(hWnd);
882 break;
883 case WM_TIMER:
884 break;
885 case WM_ENTERMENULOOP:
886 OnEnterMenuLoop(hWnd);
887 break;
888 case WM_EXITMENULOOP:
889 OnExitMenuLoop(hWnd);
890 break;
891 case WM_MENUSELECT:
892 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
893 break;
894 case WM_DESTROY:
895 WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
896 PostQuitMessage(0);
897 default:
898 return DefWindowProc(hWnd, message, wParam, lParam);
899 }
900 return 0;
901 }