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