don't use invalid options in the DSOP_INIT_INFO structure of the computer selection...
[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(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 hwndExportAll;
298 HWND hwndExportBranch;
299 HWND hwndExportBranchText;
300 UINT_PTR iResult = 0;
301 OPENFILENAME *pOfn;
302 LPTSTR pszSelectedKey;
303 OFNOTIFY *pOfnNotify;
304
305 switch(uiMsg) {
306 case WM_INITDIALOG:
307 pOfn = (OPENFILENAME *) lParam;
308 pszSelectedKey = (LPTSTR) pOfn->lCustData;
309
310 hwndExportAll = GetDlgItem(hdlg, IDC_EXPORT_ALL);
311 if (hwndExportAll)
312 SendMessage(hwndExportAll, BM_SETCHECK, pszSelectedKey[0] ? BST_UNCHECKED : BST_CHECKED, 0);
313
314 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
315 if (hwndExportBranch)
316 SendMessage(hwndExportBranch, BM_SETCHECK, pszSelectedKey[0] ? BST_CHECKED : BST_UNCHECKED, 0);
317
318 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
319 if (hwndExportBranchText)
320 SetWindowText(hwndExportBranchText, pszSelectedKey);
321 break;
322
323 case WM_NOTIFY:
324 if (((NMHDR *) lParam)->code == CDN_FILEOK)
325 {
326 pOfnNotify = (OFNOTIFY *) lParam;
327 pszSelectedKey = (LPTSTR) pOfnNotify->lpOFN->lCustData;
328
329 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
330 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
331 if (hwndExportBranch && hwndExportBranchText
332 && (SendMessage(hwndExportBranch, BM_GETCHECK, 0, 0) == BST_CHECKED))
333 {
334 GetWindowText(hwndExportBranchText, pszSelectedKey, _MAX_PATH);
335 }
336 else
337 {
338 pszSelectedKey[0] = '\0';
339 }
340 }
341 break;
342 }
343 return iResult;
344 }
345
346 static BOOL ExportRegistryFile(HWND hWnd)
347 {
348 OPENFILENAME ofn;
349 TCHAR ExportKeyPath[_MAX_PATH];
350 TCHAR Caption[128];
351 HKEY hKeyRoot;
352 LPCTSTR pszKeyPath;
353
354 /* Figure out which key path we are exporting */
355 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
356 RegKeyGetName(ExportKeyPath, sizeof(ExportKeyPath) / sizeof(ExportKeyPath[0]),
357 hKeyRoot, pszKeyPath);
358
359 InitOpenFileName(hWnd, &ofn);
360 LoadString(hInst, IDS_EXPORT_REG_FILE, Caption, sizeof(Caption)/sizeof(TCHAR));
361 ofn.lpstrTitle = Caption;
362 ofn.lCustData = (LPARAM) ExportKeyPath;
363 ofn.Flags = OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLEHOOK;
364 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
365 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORTRANGE);
366 if (GetSaveFileName(&ofn)) {
367 BOOL result;
368 /* FIXME - convert strings to ascii! */
369 result = export_registry_key((CHAR*)ofn.lpstrFile, (CHAR*)ExportKeyPath);
370 /*result = export_registry_key(ofn.lpstrFile, NULL);*/
371 /*if (!export_registry_key(ofn.lpstrFile, NULL)) {*/
372 if (!result) {
373 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
374 return FALSE;
375 }
376 #if 0
377 TCHAR filename[MAX_PATH];
378 filename[0] = '\0';
379 get_file_name(&s, filename, MAX_PATH);
380 if (!filename[0]) {
381 printf("No file name is specified\n%s", usage);
382 return FALSE;
383 /*exit(1);*/
384 }
385 if (s[0]) {
386 TCHAR reg_key_name[KEY_MAX_LEN];
387 get_file_name(&s, reg_key_name, KEY_MAX_LEN);
388 export_registry_key((CHAR)filename, reg_key_name);
389 } else {
390 export_registry_key(filename, NULL);
391 }
392 #endif
393
394 } else {
395 CheckCommDlgError(hWnd);
396 }
397 return TRUE;
398 }
399
400 BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
401 {
402 #if 1
403 PRINTDLG pd;
404
405 ZeroMemory(&pd, sizeof(PRINTDLG));
406 pd.lStructSize = sizeof(PRINTDLG);
407 pd.hwndOwner = hWnd;
408 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
409 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
410 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
411 pd.nCopies = 1;
412 pd.nFromPage = 0xFFFF;
413 pd.nToPage = 0xFFFF;
414 pd.nMinPage = 1;
415 pd.nMaxPage = 0xFFFF;
416 if (PrintDlg(&pd)) {
417 /* GDI calls to render output. */
418 DeleteDC(pd.hDC); /* Delete DC when done.*/
419 }
420 #else
421 HRESULT hResult;
422 PRINTDLGEX pd;
423
424 hResult = PrintDlgEx(&pd);
425 if (hResult == S_OK) {
426 switch (pd.dwResultAction) {
427 case PD_RESULT_APPLY:
428 /*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. */
429 break;
430 case PD_RESULT_CANCEL:
431 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
432 break;
433 case PD_RESULT_PRINT:
434 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
435 break;
436 default:
437 break;
438 }
439 } else {
440 switch (hResult) {
441 case E_OUTOFMEMORY:
442 /*Insufficient memory. */
443 break;
444 case E_INVALIDARG:
445 /* One or more arguments are invalid. */
446 break;
447 case E_POINTER:
448 /*Invalid pointer. */
449 break;
450 case E_HANDLE:
451 /*Invalid handle. */
452 break;
453 case E_FAIL:
454 /*Unspecified error. */
455 break;
456 default:
457 break;
458 }
459 return FALSE;
460 }
461 #endif
462 return TRUE;
463 }
464
465 static BOOL CopyKeyName(HWND hWnd, LPCTSTR keyName)
466 {
467 BOOL result;
468
469 result = OpenClipboard(hWnd);
470 if (result) {
471 result = EmptyClipboard();
472 if (result) {
473
474 /*HANDLE hClipData;*/
475 /*hClipData = SetClipboardData(UINT uFormat, HANDLE hMem);*/
476
477 } else {
478 /* error emptying clipboard*/
479 /* DWORD dwError = GetLastError(); */
480 ;
481 }
482 if (!CloseClipboard()) {
483 /* error closing clipboard*/
484 /* DWORD dwError = GetLastError(); */
485 ;
486 }
487 } else {
488 /* error opening clipboard*/
489 /* DWORD dwError = GetLastError(); */
490 ;
491 }
492 return result;
493 }
494
495 static BOOL CreateNewValue(HKEY hRootKey, LPCTSTR pszKeyPath, DWORD dwType)
496 {
497 TCHAR szNewValueFormat[128];
498 TCHAR szNewValue[128];
499 int iIndex = 1;
500 BYTE data[128];
501 DWORD dwExistingType, cbData;
502 LONG lResult;
503 HKEY hKey;
504 LVFINDINFO lvfi;
505
506 if (RegOpenKey(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
507 return FALSE;
508
509 LoadString(hInst, IDS_NEW_VALUE, szNewValueFormat, sizeof(szNewValueFormat)
510 / sizeof(szNewValueFormat[0]));
511
512 do
513 {
514 _sntprintf(szNewValue, sizeof(szNewValue) / sizeof(szNewValue[0]),
515 szNewValueFormat, iIndex++);
516
517 cbData = sizeof(data);
518 lResult = RegQueryValueEx(hKey, szNewValue, NULL, &dwExistingType, data, &cbData);
519 }
520 while(lResult == ERROR_SUCCESS);
521
522 switch(dwType) {
523 case REG_DWORD:
524 cbData = sizeof(DWORD);
525 break;
526 case REG_SZ:
527 case REG_EXPAND_SZ:
528 cbData = sizeof(TCHAR);
529 break;
530 case REG_MULTI_SZ:
531 cbData = sizeof(TCHAR) * 2;
532 break;
533 case REG_QWORD:
534 cbData = sizeof(DWORD) * 2;
535 break;
536 default:
537 cbData = 0;
538 break;
539 }
540 memset(data, 0, cbData);
541 lResult = RegSetValueEx(hKey, szNewValue, 0, dwType, data, cbData);
542 if (lResult != ERROR_SUCCESS)
543 return FALSE;
544
545 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
546
547 /* locate the newly added value, and get ready to rename it */
548 memset(&lvfi, 0, sizeof(lvfi));
549 lvfi.flags = LVFI_STRING;
550 lvfi.psz = szNewValue;
551 iIndex = ListView_FindItem(g_pChildWnd->hListWnd, -1, &lvfi);
552 if (iIndex >= 0)
553 ListView_EditLabel(g_pChildWnd->hListWnd, iIndex);
554
555 return TRUE;
556 }
557
558 static HRESULT
559 InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker)
560 {
561 HRESULT hRet;
562
563 *pDsObjectPicker = NULL;
564
565 hRet = CoCreateInstance(&CLSID_DsObjectPicker,
566 NULL,
567 CLSCTX_INPROC_SERVER,
568 &IID_IDsObjectPicker,
569 (LPVOID*)pDsObjectPicker);
570 if (SUCCEEDED(hRet))
571 {
572 DSOP_INIT_INFO InitInfo;
573 static DSOP_SCOPE_INIT_INFO Scopes[] =
574 {
575 {
576 sizeof(DSOP_SCOPE_INIT_INFO),
577 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE |
578 DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
579 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP |
580 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN,
581 0,
582 {
583 {
584 DSOP_FILTER_COMPUTERS,
585 0,
586 0
587 },
588 DSOP_DOWNLEVEL_FILTER_COMPUTERS
589 },
590 NULL,
591 NULL,
592 S_OK
593 },
594 };
595
596 InitInfo.cbSize = sizeof(InitInfo);
597 InitInfo.pwzTargetComputer = NULL;
598 InitInfo.cDsScopeInfos = sizeof(Scopes) / sizeof(Scopes[0]);
599 InitInfo.aDsScopeInfos = Scopes;
600 InitInfo.flOptions = 0;
601 InitInfo.cAttributesToFetch = 0;
602 InitInfo.apwzAttributeNames = NULL;
603
604 hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker,
605 &InitInfo);
606
607 if (FAILED(hRet))
608 {
609 /* delete the object picker in case initialization failed! */
610 (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker);
611 }
612 }
613
614 return hRet;
615 }
616
617 static HRESULT
618 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
619 IN HWND hwndParent OPTIONAL,
620 OUT LPTSTR lpBuffer,
621 IN UINT uSize)
622 {
623 IDataObject *pdo = NULL;
624 HRESULT hRet;
625
626 hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker,
627 hwndParent,
628 &pdo);
629 if (hRet == S_OK)
630 {
631 STGMEDIUM stm;
632 FORMATETC fe;
633
634 fe.cfFormat = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
635 fe.ptd = NULL;
636 fe.dwAspect = DVASPECT_CONTENT;
637 fe.lindex = -1;
638 fe.tymed = TYMED_HGLOBAL;
639
640 hRet = pdo->lpVtbl->GetData(pdo,
641 &fe,
642 &stm);
643 if (SUCCEEDED(hRet))
644 {
645 PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal);
646 if (SelectionList != NULL)
647 {
648 if (SelectionList->cItems == 1)
649 {
650 UINT nlen = wcslen(SelectionList->aDsSelection[0].pwzName);
651 if (nlen >= uSize)
652 {
653 nlen = uSize - 1;
654 }
655 #if UNICODE
656 memcpy(lpBuffer,
657 SelectionList->aDsSelection[0].pwzName,
658 nlen * sizeof(WCHAR));
659 #else
660 WideCharToMultiByte(CP_ACP,
661 0,
662 SelectionList->aDsSelection[0].pwzName,
663 nlen,
664 lpBuffer,
665 uSize,
666 NULL,
667 NULL);
668 #endif
669 lpBuffer[nlen] = L'\0';
670 }
671
672 GlobalUnlock(stm.hGlobal);
673 }
674
675 ReleaseStgMedium(&stm);
676 }
677
678 pdo->lpVtbl->Release(pdo);
679 }
680
681 return hRet;
682 }
683
684 static VOID
685 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
686 {
687 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
688 }
689
690 /*******************************************************************************
691 *
692 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
693 *
694 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
695 *
696 */
697 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
698 {
699 HKEY hKeyRoot = 0, hKey = 0;
700 LPCTSTR keyPath;
701 LPCTSTR valueName;
702 BOOL result = TRUE;
703 REGSAM regsam = KEY_READ;
704 LONG lRet;
705 int item;
706
707 switch (LOWORD(wParam)) {
708 case ID_REGISTRY_IMPORTREGISTRYFILE:
709 ImportRegistryFile(hWnd);
710 return TRUE;
711 case ID_REGISTRY_EXPORTREGISTRYFILE:
712 ExportRegistryFile(hWnd);
713 return TRUE;
714 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
715 {
716 IDsObjectPicker *ObjectPicker;
717 TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
718 HRESULT hRet;
719
720 hRet = CoInitialize(NULL);
721 if (SUCCEEDED(hRet))
722 {
723 hRet = InitializeRemoteRegistryPicker(&ObjectPicker);
724 if (SUCCEEDED(hRet))
725 {
726 hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker,
727 hWnd,
728 szComputerName,
729 sizeof(szComputerName) / sizeof(szComputerName[0]));
730 if (hRet == S_OK)
731 {
732 /* FIXME - connect to the registry */
733 }
734
735 FreeObjectPicker(ObjectPicker);
736 }
737
738 CoUninitialize();
739 }
740
741 return TRUE;
742 }
743 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
744 return TRUE;
745 case ID_REGISTRY_PRINT:
746 PrintRegistryHive(hWnd, _T(""));
747 return TRUE;
748 case ID_REGISTRY_EXIT:
749 DestroyWindow(hWnd);
750 return TRUE;
751 case ID_VIEW_STATUSBAR:
752 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
753 return TRUE;
754 case ID_HELP_HELPTOPICS:
755 WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
756 return TRUE;
757 case ID_HELP_ABOUT:
758 ShowAboutBox(hWnd);
759 return TRUE;
760 case ID_VIEW_SPLIT:
761 {
762 RECT rt;
763 POINT pt, pts;
764 GetClientRect(g_pChildWnd->hWnd, &rt);
765 pt.x = rt.left + g_pChildWnd->nSplitPos;
766 pt.y = (rt.bottom / 2);
767 pts = pt;
768 if(ClientToScreen(g_pChildWnd->hWnd, &pts))
769 {
770 SetCursorPos(pts.x, pts.y);
771 SetCursor(LoadCursor(0, IDC_SIZEWE));
772 SendMessage(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
773 }
774 return TRUE;
775 }
776 case ID_EDIT_RENAME:
777 case ID_EDIT_MODIFY:
778 case ID_EDIT_MODIFY_BIN:
779 case ID_EDIT_DELETE:
780 regsam |= KEY_WRITE;
781 break;
782 }
783
784 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
785 valueName = GetValueName(g_pChildWnd->hListWnd, -1);
786 if (keyPath) {
787 lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, regsam, &hKey);
788 if (lRet != ERROR_SUCCESS) hKey = 0;
789 }
790
791 switch (LOWORD(wParam)) {
792 case ID_EDIT_MODIFY:
793 if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE))
794 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
795 break;
796 case ID_EDIT_MODIFY_BIN:
797 if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE))
798 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
799 break;
800 case ID_EDIT_RENAME:
801 if(ListView_GetSelectedCount(g_pChildWnd->hListWnd) == 1)
802 {
803 item = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
804 if(item > -1)
805 {
806 ListView_EditLabel(g_pChildWnd->hListWnd, item);
807 }
808 }
809 break;
810 case ID_EDIT_DELETE:
811 {
812 UINT nSelected = ListView_GetSelectedCount(g_pChildWnd->hListWnd);
813 if(nSelected >= 1)
814 {
815 TCHAR msg[128], caption[128];
816 LoadString(hInst, IDS_QUERY_DELETE_CONFIRM, caption, sizeof(caption)/sizeof(TCHAR));
817 LoadString(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, sizeof(msg)/sizeof(TCHAR));
818 if(MessageBox(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES)
819 {
820 int ni, errs;
821
822 item = -1;
823 errs = 0;
824 while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1)
825 {
826 valueName = GetValueName(g_pChildWnd->hListWnd, item);
827 if(RegDeleteValue(hKey, valueName) != ERROR_SUCCESS)
828 {
829 errs++;
830 }
831 item = ni;
832 }
833
834 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
835 if(errs > 0)
836 {
837 LoadString(hInst, IDS_ERR_DELVAL_CAPTION, caption, sizeof(caption)/sizeof(TCHAR));
838 LoadString(hInst, IDS_ERR_DELETEVALUE, msg, sizeof(msg)/sizeof(TCHAR));
839 MessageBox(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP);
840 }
841 }
842 }
843 break;
844 case ID_EDIT_NEW_STRINGVALUE:
845 CreateNewValue(hKeyRoot, keyPath, REG_SZ);
846 break;
847 case ID_EDIT_NEW_BINARYVALUE:
848 CreateNewValue(hKeyRoot, keyPath, REG_BINARY);
849 break;
850 case ID_EDIT_NEW_DWORDVALUE:
851 CreateNewValue(hKeyRoot, keyPath, REG_DWORD);
852 break;
853 }
854 case ID_EDIT_COPYKEYNAME:
855 CopyKeyName(hWnd, _T(""));
856 break;
857 case ID_EDIT_PERMISSIONS:
858 if(keyPath != NULL && _tcslen(keyPath) > 0)
859 {
860 RegKeyEditPermissions(hWnd, hKey, NULL, keyPath);
861 }
862 else
863 {
864 MessageBeep(MB_ICONASTERISK);
865 }
866 break;
867 case ID_REGISTRY_PRINTERSETUP:
868 /*PRINTDLG pd;*/
869 /*PrintDlg(&pd);*/
870 /*PAGESETUPDLG psd;*/
871 /*PageSetupDlg(&psd);*/
872 break;
873 case ID_REGISTRY_OPENLOCAL:
874 break;
875
876 case ID_VIEW_REFRESH:
877 RefreshTreeView(g_pChildWnd->hTreeWnd);
878 /*RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL); */
879 break;
880 /*case ID_OPTIONS_TOOLBAR:*/
881 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
882 /* break;*/
883 case ID_EDIT_NEW_KEY:
884 CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd));
885 break;
886 default:
887 result = FALSE;
888 }
889
890 if(hKey)
891 RegCloseKey(hKey);
892 return result;
893 }
894
895 /********************************************************************************
896 *
897 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
898 *
899 * PURPOSE: Processes messages for the main frame window.
900 *
901 * WM_COMMAND - process the application menu
902 * WM_DESTROY - post a quit message and return
903 *
904 */
905
906 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
907 {
908 switch (message) {
909 case WM_CREATE:
910 CreateWindowEx(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE,
911 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
912 hWnd, (HMENU)0, hInst, 0);
913 break;
914 case WM_COMMAND:
915 if (!_CmdWndProc(hWnd, message, wParam, lParam))
916 return DefWindowProc(hWnd, message, wParam, lParam);
917 break;
918 case WM_ACTIVATE:
919 if (LOWORD(hWnd))
920 SetFocus(g_pChildWnd->hWnd);
921 break;
922 case WM_SIZE:
923 resize_frame_client(hWnd);
924 break;
925 case WM_TIMER:
926 break;
927 case WM_ENTERMENULOOP:
928 OnEnterMenuLoop(hWnd);
929 break;
930 case WM_EXITMENULOOP:
931 OnExitMenuLoop(hWnd);
932 break;
933 case WM_MENUSELECT:
934 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
935 break;
936 case WM_DESTROY:
937 WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
938 PostQuitMessage(0);
939 default:
940 return DefWindowProc(hWnd, message, wParam, lParam);
941 }
942 return 0;
943 }