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