regedit: Implement deleting multiple values.
[wine/hacks.git] / programs / regedit / framewnd.c
blob5262e553faf6ae2d77f4690325e17185bf876688
1 /*
2 * Regedit frame window
4 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
23 #include <windows.h>
24 #include <tchar.h>
25 #include <commctrl.h>
26 #include <commdlg.h>
27 #include <cderr.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <shellapi.h>
32 #include "main.h"
33 #include "regproc.h"
35 /********************************************************************************
36 * Global and Local Variables:
39 static TCHAR favoritesKey[] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\RegEdit\\Favorites");
40 static BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
41 static TCHAR favoriteName[128];
42 static TCHAR searchString[128];
43 static int searchMask = SEARCH_KEYS | SEARCH_VALUES | SEARCH_CONTENT;
45 static TCHAR FileNameBuffer[_MAX_PATH];
46 static TCHAR FileTitleBuffer[_MAX_PATH];
47 static TCHAR FilterBuffer[_MAX_PATH];
49 /*******************************************************************************
50 * Local module support methods
53 static void resize_frame_rect(HWND hWnd, PRECT prect)
55 RECT rt;
57 if (IsWindowVisible(hToolBar)) {
58 SendMessage(hToolBar, WM_SIZE, 0, 0);
59 GetClientRect(hToolBar, &rt);
60 prect->top = rt.bottom+3;
61 prect->bottom -= rt.bottom+3;
64 if (IsWindowVisible(hStatusBar)) {
65 SetupStatusBar(hWnd, TRUE);
66 GetClientRect(hStatusBar, &rt);
67 prect->bottom -= rt.bottom;
69 MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
72 static void resize_frame_client(HWND hWnd)
74 RECT rect;
76 GetClientRect(hWnd, &rect);
77 resize_frame_rect(hWnd, &rect);
80 /********************************************************************************/
82 static void OnEnterMenuLoop(HWND hWnd)
84 int nParts;
86 /* Update the status bar pane sizes */
87 nParts = -1;
88 SendMessage(hStatusBar, SB_SETPARTS, 1, (long)&nParts);
89 bInMenuLoop = TRUE;
90 SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
93 static void OnExitMenuLoop(HWND hWnd)
95 bInMenuLoop = FALSE;
96 /* Update the status bar pane sizes*/
97 SetupStatusBar(hWnd, TRUE);
98 UpdateStatusBar();
101 static void UpdateMenuItems(HMENU hMenu) {
102 HWND hwndTV = g_pChildWnd->hTreeWnd;
103 BOOL bAllowEdit = FALSE;
104 HKEY hRootKey = NULL;
105 LPCTSTR keyName;
106 keyName = GetItemPath(hwndTV, TreeView_GetSelection(hwndTV), &hRootKey);
107 if (GetFocus() != hwndTV || (keyName && *keyName)) { /* can't modify root keys, but allow for their values */
108 bAllowEdit = TRUE;
110 EnableMenuItem(hMenu, ID_EDIT_FIND, MF_ENABLED | MF_BYCOMMAND);
111 EnableMenuItem(hMenu, ID_EDIT_FINDNEXT, MF_ENABLED | MF_BYCOMMAND);
112 EnableMenuItem(hMenu, ID_EDIT_MODIFY, (bAllowEdit ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
113 EnableMenuItem(hMenu, ID_EDIT_DELETE, (bAllowEdit ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
114 EnableMenuItem(hMenu, ID_EDIT_RENAME, (bAllowEdit ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
115 EnableMenuItem(hMenu, ID_FAVORITES_ADDTOFAVORITES, (hRootKey ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
116 EnableMenuItem(hMenu, ID_FAVORITES_REMOVEFAVORITE,
117 (GetMenuItemCount(hMenu)>2 ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
120 static void OnInitMenuPopup(HWND hWnd, HMENU hMenu, short wItem)
122 if (wItem == 3) {
123 HKEY hKey;
124 while(GetMenuItemCount(hMenu)>2)
125 DeleteMenu(hMenu, 2, MF_BYPOSITION);
126 if (RegOpenKeyEx(HKEY_CURRENT_USER, favoritesKey,
127 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
128 TCHAR namebuf[KEY_MAX_LEN];
129 BYTE valuebuf[4096];
130 int i = 0;
131 BOOL sep = FALSE;
132 DWORD ksize, vsize, type;
133 LONG error;
134 do {
135 ksize = KEY_MAX_LEN;
136 vsize = sizeof(valuebuf);
137 error = RegEnumValue(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
138 if (error != ERROR_SUCCESS)
139 break;
140 if (type == REG_SZ) {
141 if (!sep) {
142 AppendMenu(hMenu, MF_SEPARATOR, -1, NULL);
143 sep = TRUE;
145 AppendMenu(hMenu, MF_STRING, ID_FAVORITE_FIRST+i, namebuf);
147 i++;
148 } while(error == ERROR_SUCCESS);
149 RegCloseKey(hKey);
152 UpdateMenuItems(hMenu);
155 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
157 TCHAR str[100];
159 _tcscpy(str, _T(""));
160 if (nFlags & MF_POPUP) {
161 if (hSysMenu != GetMenu(hWnd)) {
162 if (nItemID == 2) nItemID = 5;
165 if (LoadString(hInst, nItemID, str, 100)) {
166 /* load appropriate string*/
167 LPTSTR lpsz = str;
168 /* first newline terminates actual string*/
169 lpsz = _tcschr(lpsz, '\n');
170 if (lpsz != NULL)
171 *lpsz = '\0';
173 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)str);
176 void SetupStatusBar(HWND hWnd, BOOL bResize)
178 RECT rc;
179 int nParts;
180 GetClientRect(hWnd, &rc);
181 nParts = rc.right;
182 /* nParts = -1;*/
183 if (bResize)
184 SendMessage(hStatusBar, WM_SIZE, 0, 0);
185 SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
186 UpdateStatusBar();
189 void UpdateStatusBar(void)
191 LPTSTR fullPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, TRUE);
192 SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath);
193 HeapFree(GetProcessHeap(), 0, fullPath);
196 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
198 BOOL vis = IsWindowVisible(hchild);
199 HMENU hMenuView = GetSubMenu(hMenuFrame, ID_VIEW_MENU);
201 CheckMenuItem(hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
202 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
203 resize_frame_client(hWnd);
206 static BOOL CheckCommDlgError(HWND hWnd)
208 DWORD dwErrorCode = CommDlgExtendedError();
209 switch (dwErrorCode) {
210 case CDERR_DIALOGFAILURE:
211 break;
212 case CDERR_FINDRESFAILURE:
213 break;
214 case CDERR_NOHINSTANCE:
215 break;
216 case CDERR_INITIALIZATION:
217 break;
218 case CDERR_NOHOOK:
219 break;
220 case CDERR_LOCKRESFAILURE:
221 break;
222 case CDERR_NOTEMPLATE:
223 break;
224 case CDERR_LOADRESFAILURE:
225 break;
226 case CDERR_STRUCTSIZE:
227 break;
228 case CDERR_LOADSTRFAILURE:
229 break;
230 case FNERR_BUFFERTOOSMALL:
231 break;
232 case CDERR_MEMALLOCFAILURE:
233 break;
234 case FNERR_INVALIDFILENAME:
235 break;
236 case CDERR_MEMLOCKFAILURE:
237 break;
238 case FNERR_SUBCLASSFAILURE:
239 break;
240 default:
241 break;
243 return TRUE;
246 static void ExportRegistryFile_StoreSelection(HWND hdlg, OPENFILENAME *pOpenFileName)
248 if (IsDlgButtonChecked(hdlg, IDC_EXPORT_SELECTED))
250 INT len = SendDlgItemMessage(hdlg, IDC_EXPORT_PATH, WM_GETTEXTLENGTH, 0, 0);
251 pOpenFileName->lCustData = (LPARAM)HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(TCHAR));
252 SendDlgItemMessage(hdlg, IDC_EXPORT_PATH, WM_GETTEXT, len+1, pOpenFileName->lCustData);
254 else
255 pOpenFileName->lCustData = (LPARAM)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TCHAR));
258 static UINT CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
260 static OPENFILENAME* pOpenFileName;
261 OFNOTIFY *pOfNotify;
262 LPTSTR path;
264 switch (uiMsg) {
265 case WM_INITDIALOG:
266 pOpenFileName = (OPENFILENAME*)lParam;
267 break;
268 case WM_COMMAND:
269 if (LOWORD(wParam) == IDC_EXPORT_PATH && HIWORD(wParam) == EN_UPDATE)
270 CheckRadioButton(hdlg, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, IDC_EXPORT_SELECTED);
271 break;
272 case WM_NOTIFY:
273 pOfNotify = (OFNOTIFY*)lParam;
274 switch (pOfNotify->hdr.code)
276 case CDN_INITDONE:
277 path = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
278 SendDlgItemMessage(hdlg, IDC_EXPORT_PATH, WM_SETTEXT, 0, (LPARAM)path);
279 HeapFree(GetProcessHeap(), 0, path);
280 CheckRadioButton(hdlg, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, pOpenFileName->lCustData ? IDC_EXPORT_SELECTED : IDC_EXPORT_ALL);
281 break;
282 case CDN_FILEOK:
283 ExportRegistryFile_StoreSelection(hdlg, pOpenFileName);
284 break;
286 break;
287 default:
288 break;
290 return 0L;
294 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME *pofn)
296 memset(pofn, 0, sizeof(OPENFILENAME));
297 pofn->lStructSize = sizeof(OPENFILENAME);
298 pofn->hwndOwner = hWnd;
299 pofn->hInstance = hInst;
301 if (FilterBuffer[0] == 0)
302 LoadString(hInst, IDS_FILEDIALOG_FILTER, FilterBuffer, _MAX_PATH);
303 pofn->lpstrFilter = FilterBuffer;
304 pofn->nFilterIndex = 1;
305 pofn->lpstrFile = FileNameBuffer;
306 pofn->nMaxFile = _MAX_PATH;
307 pofn->lpstrFileTitle = FileTitleBuffer;
308 pofn->nMaxFileTitle = _MAX_PATH;
309 pofn->Flags = OFN_HIDEREADONLY;
310 /* some other fields may be set by the caller */
311 return TRUE;
314 static BOOL import_registry_filename(LPTSTR filename)
316 FILE* reg_file = fopen(filename, "r");
318 if(!reg_file)
319 return FALSE;
321 return import_registry_file(reg_file);
324 static BOOL ImportRegistryFile(HWND hWnd)
326 OPENFILENAME ofn;
327 TCHAR title[128];
329 InitOpenFileName(hWnd, &ofn);
330 LoadString(hInst, IDS_FILEDIALOG_IMPORT_TITLE, title, COUNT_OF(title));
331 ofn.lpstrTitle = title;
332 if (GetOpenFileName(&ofn)) {
333 if (!import_registry_filename(ofn.lpstrFile)) {
334 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
335 return FALSE;
337 } else {
338 CheckCommDlgError(hWnd);
340 RefreshTreeView(g_pChildWnd->hTreeWnd);
341 return TRUE;
345 static BOOL ExportRegistryFile(HWND hWnd, BOOL export_branch)
347 OPENFILENAME ofn;
348 TCHAR ExportKeyPath[_MAX_PATH];
349 TCHAR title[128];
351 ExportKeyPath[0] = _T('\0');
352 InitOpenFileName(hWnd, &ofn);
353 LoadString(hInst, IDS_FILEDIALOG_EXPORT_TITLE, title, COUNT_OF(title));
354 ofn.lpstrTitle = title;
355 ofn.lCustData = export_branch;
356 ofn.Flags = OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
357 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
358 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORT_TEMPLATE);
359 if (GetSaveFileName(&ofn)) {
360 BOOL result;
361 result = export_registry_key(ofn.lpstrFile, (LPTSTR)ofn.lCustData);
362 if (!result) {
363 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
364 return FALSE;
366 } else {
367 CheckCommDlgError(hWnd);
369 return TRUE;
372 static BOOL PrintRegistryHive(HWND hWnd, LPCTSTR path)
374 #if 1
375 PRINTDLG pd;
377 ZeroMemory(&pd, sizeof(PRINTDLG));
378 pd.lStructSize = sizeof(PRINTDLG);
379 pd.hwndOwner = hWnd;
380 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
381 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
382 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
383 pd.nCopies = 1;
384 pd.nFromPage = 0xFFFF;
385 pd.nToPage = 0xFFFF;
386 pd.nMinPage = 1;
387 pd.nMaxPage = 0xFFFF;
388 if (PrintDlg(&pd)) {
389 /* GDI calls to render output. */
390 DeleteDC(pd.hDC); /* Delete DC when done.*/
392 #else
393 HRESULT hResult;
394 PRINTDLGEX pd;
396 hResult = PrintDlgEx(&pd);
397 if (hResult == S_OK) {
398 switch (pd.dwResultAction) {
399 case PD_RESULT_APPLY:
400 /*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. */
401 break;
402 case PD_RESULT_CANCEL:
403 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
404 break;
405 case PD_RESULT_PRINT:
406 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
407 break;
408 default:
409 break;
411 } else {
412 switch (hResult) {
413 case E_OUTOFMEMORY:
414 /*Insufficient memory. */
415 break;
416 case E_INVALIDARG:
417 /* One or more arguments are invalid. */
418 break;
419 case E_POINTER:
420 /*Invalid pointer. */
421 break;
422 case E_HANDLE:
423 /*Invalid handle. */
424 break;
425 case E_FAIL:
426 /*Unspecified error. */
427 break;
428 default:
429 break;
431 return FALSE;
433 #endif
434 return TRUE;
437 static BOOL CopyKeyName(HWND hWnd, LPCTSTR keyName)
439 BOOL result;
441 result = OpenClipboard(hWnd);
442 if (result) {
443 result = EmptyClipboard();
444 if (result) {
445 int len = (_tcslen(keyName)+1)*sizeof(TCHAR);
446 HANDLE hClipData = GlobalAlloc(GHND, len);
447 LPVOID pLoc = GlobalLock(hClipData);
448 _tcscpy(pLoc, keyName);
449 GlobalUnlock(hClipData);
450 hClipData = SetClipboardData(CF_TEXT, hClipData);
452 } else {
453 /* error emptying clipboard*/
454 /* DWORD dwError = GetLastError(); */
457 if (!CloseClipboard()) {
458 /* error closing clipboard*/
459 /* DWORD dwError = GetLastError(); */
462 } else {
463 /* error opening clipboard*/
464 /* DWORD dwError = GetLastError(); */
467 return result;
470 static INT_PTR CALLBACK find_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
472 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
474 switch(uMsg) {
475 case WM_INITDIALOG:
476 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
477 CheckDlgButton(hwndDlg, IDC_FIND_KEYS, searchMask&SEARCH_KEYS ? BST_CHECKED : BST_UNCHECKED);
478 CheckDlgButton(hwndDlg, IDC_FIND_VALUES, searchMask&SEARCH_VALUES ? BST_CHECKED : BST_UNCHECKED);
479 CheckDlgButton(hwndDlg, IDC_FIND_CONTENT, searchMask&SEARCH_CONTENT ? BST_CHECKED : BST_UNCHECKED);
480 CheckDlgButton(hwndDlg, IDC_FIND_WHOLE, searchMask&SEARCH_WHOLE ? BST_CHECKED : BST_UNCHECKED);
481 SendMessage(hwndValue, EM_SETLIMITTEXT, 127, 0);
482 SetWindowText(hwndValue, searchString);
483 return TRUE;
484 case WM_COMMAND:
485 switch(LOWORD(wParam)) {
486 case IDC_VALUE_NAME:
487 if (HIWORD(wParam) == EN_UPDATE) {
488 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLength(hwndValue)>0);
489 return TRUE;
491 break;
492 case IDOK:
493 if (GetWindowTextLength(hwndValue)>0) {
494 int mask = 0;
495 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_KEYS)) mask |= SEARCH_KEYS;
496 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_VALUES)) mask |= SEARCH_VALUES;
497 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_CONTENT)) mask |= SEARCH_CONTENT;
498 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_WHOLE)) mask |= SEARCH_WHOLE;
499 searchMask = mask;
500 GetWindowText(hwndValue, searchString, 128);
501 EndDialog(hwndDlg, IDOK);
503 return TRUE;
504 case IDCANCEL:
505 EndDialog(hwndDlg, IDCANCEL);
506 return TRUE;
508 break;
510 return FALSE;
513 static INT_PTR CALLBACK addtofavorites_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
515 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
517 switch(uMsg) {
518 case WM_INITDIALOG:
520 HKEY hKeyRoot = NULL;
521 LPSTR ItemPath = GetItemPath(g_pChildWnd->hTreeWnd, NULL, &hKeyRoot);
523 if(!ItemPath || !*ItemPath)
524 ItemPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
525 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
526 SetWindowText(hwndValue, ItemPath);
527 SendMessage(hwndValue, EM_SETLIMITTEXT, 127, 0);
528 return TRUE;
530 case WM_COMMAND:
531 switch(LOWORD(wParam)) {
532 case IDC_VALUE_NAME:
533 if (HIWORD(wParam) == EN_UPDATE) {
534 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLength(hwndValue)>0);
535 return TRUE;
537 break;
538 case IDOK:
539 if (GetWindowTextLength(hwndValue)>0) {
540 GetWindowText(hwndValue, favoriteName, 128);
541 EndDialog(hwndDlg, IDOK);
543 return TRUE;
544 case IDCANCEL:
545 EndDialog(hwndDlg, IDCANCEL);
546 return TRUE;
548 break;
550 return FALSE;
553 static INT_PTR CALLBACK removefavorite_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
555 HWND hwndList = GetDlgItem(hwndDlg, IDC_NAME_LIST);
557 switch(uMsg) {
558 case WM_INITDIALOG: {
559 HKEY hKey;
560 int i = 0;
561 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
562 if (RegOpenKeyEx(HKEY_CURRENT_USER, favoritesKey,
563 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
564 TCHAR namebuf[KEY_MAX_LEN];
565 BYTE valuebuf[4096];
566 DWORD ksize, vsize, type;
567 LONG error;
568 do {
569 ksize = KEY_MAX_LEN;
570 vsize = sizeof(valuebuf);
571 error = RegEnumValue(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
572 if (error != ERROR_SUCCESS)
573 break;
574 if (type == REG_SZ) {
575 SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)namebuf);
577 i++;
578 } while(error == ERROR_SUCCESS);
579 RegCloseKey(hKey);
581 else
582 return FALSE;
583 EnableWindow(GetDlgItem(hwndDlg, IDOK), i != 0);
584 SendMessage(hwndList, LB_SETCURSEL, 0, 0);
585 return TRUE;
587 case WM_COMMAND:
588 switch(LOWORD(wParam)) {
589 case IDC_NAME_LIST:
590 if (HIWORD(wParam) == LBN_SELCHANGE) {
591 EnableWindow(GetDlgItem(hwndDlg, IDOK), lParam != -1);
592 return TRUE;
594 break;
595 case IDOK: {
596 int pos = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
597 int len = SendMessage(hwndList, LB_GETTEXTLEN, pos, 0);
598 if (len>0) {
599 LPTSTR lpName = HeapAlloc(GetProcessHeap(), 0, sizeof(TCHAR)*(len+1));
600 SendMessage(hwndList, LB_GETTEXT, pos, (LPARAM)lpName);
601 if (len>127)
602 lpName[127] = '\0';
603 _tcscpy(favoriteName, lpName);
604 EndDialog(hwndDlg, IDOK);
605 HeapFree(GetProcessHeap(), 0, lpName);
607 return TRUE;
609 case IDCANCEL:
610 EndDialog(hwndDlg, IDCANCEL);
611 return TRUE;
613 break;
615 return FALSE;
618 /*******************************************************************************
620 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
622 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
625 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
627 HKEY hKeyRoot = 0;
628 LPCTSTR keyPath;
629 LPCTSTR valueName;
630 TCHAR newKey[MAX_NEW_KEY_LEN];
631 DWORD valueType;
632 int curIndex;
633 BOOL firstItem = TRUE;
635 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
637 if (LOWORD(wParam) >= ID_FAVORITE_FIRST && LOWORD(wParam) <= ID_FAVORITE_LAST) {
638 HKEY hKey;
639 if (RegOpenKeyEx(HKEY_CURRENT_USER, favoritesKey,
640 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
641 TCHAR namebuf[KEY_MAX_LEN];
642 BYTE valuebuf[4096];
643 DWORD ksize = KEY_MAX_LEN, vsize = sizeof(valuebuf), type = 0;
644 if (RegEnumValue(hKey, LOWORD(wParam) - ID_FAVORITE_FIRST, namebuf, &ksize, NULL,
645 &type, valuebuf, &vsize) == ERROR_SUCCESS) {
646 SendMessage( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET,
647 (LPARAM) FindPathInTree(g_pChildWnd->hTreeWnd, (TCHAR *)valuebuf) );
649 RegCloseKey(hKey);
651 return TRUE;
653 switch (LOWORD(wParam)) {
654 case ID_REGISTRY_IMPORTREGISTRYFILE:
655 ImportRegistryFile(hWnd);
656 break;
657 case ID_EDIT_EXPORT:
658 ExportRegistryFile(hWnd, TRUE);
659 break;
660 case ID_REGISTRY_EXPORTREGISTRYFILE:
661 ExportRegistryFile(hWnd, FALSE);
662 break;
663 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
664 break;
665 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
666 break;
667 case ID_REGISTRY_PRINT:
668 PrintRegistryHive(hWnd, _T(""));
669 break;
670 case ID_EDIT_DELETE:
671 if (GetFocus() == g_pChildWnd->hTreeWnd) {
672 if (keyPath == 0 || *keyPath == 0) {
673 MessageBeep(MB_ICONHAND);
674 } else if (DeleteKey(hWnd, hKeyRoot, keyPath)) {
675 DeleteNode(g_pChildWnd->hTreeWnd, 0);
677 } else if (GetFocus() == g_pChildWnd->hListWnd) {
678 curIndex = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
679 while(curIndex != -1) {
680 valueName = GetItemText(g_pChildWnd->hListWnd, curIndex);
681 curIndex = ListView_GetNextItem(g_pChildWnd->hListWnd, curIndex, LVNI_SELECTED);
682 if(curIndex != -1 && firstItem) {
683 TCHAR title[256];
684 TCHAR text[1024];
685 if(!LoadString(hInst, IDS_DELETE_BOX_TITLE, title, COUNT_OF(title)))
686 lstrcpy(title, "Error");
687 if(!LoadString(hInst, IDS_DELETE_BOX_TEXT_MULTIPLE, text, COUNT_OF(text)))
688 lstrcpy(text, "Unknown error string!");
689 if (MessageBox(hWnd, text, title, MB_YESNO | MB_ICONEXCLAMATION) != IDYES)
690 break;
692 if (!DeleteValue(hWnd, hKeyRoot, keyPath, valueName, curIndex==-1 && firstItem))
693 break;
694 firstItem = FALSE;
696 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
698 break;
699 case ID_EDIT_MODIFY:
700 valueName = GetValueName(g_pChildWnd->hListWnd);
701 if (ModifyValue(hWnd, hKeyRoot, keyPath, valueName))
702 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, valueName);
703 break;
704 case ID_EDIT_FIND:
705 case ID_EDIT_FINDNEXT:
707 HTREEITEM hItem;
708 if (LOWORD(wParam) == ID_EDIT_FIND &&
709 DialogBox(0, MAKEINTRESOURCE(IDD_FIND), hWnd, find_dlgproc) != IDOK)
710 break;
711 if (!*searchString)
712 break;
713 hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
714 if (hItem) {
715 int row = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_FOCUSED);
716 HCURSOR hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
717 hItem = FindNext(g_pChildWnd->hTreeWnd, hItem, searchString, searchMask, &row);
718 SetCursor(hcursorOld);
719 if (hItem) {
720 SendMessage( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM) hItem );
721 InvalidateRect(g_pChildWnd->hTreeWnd, NULL, TRUE);
722 UpdateWindow(g_pChildWnd->hTreeWnd);
723 if (row != -1) {
724 ListView_SetItemState(g_pChildWnd->hListWnd, -1, 0, LVIS_FOCUSED|LVIS_SELECTED);
725 ListView_SetItemState(g_pChildWnd->hListWnd, row, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
726 SetFocus(g_pChildWnd->hListWnd);
727 } else {
728 SetFocus(g_pChildWnd->hTreeWnd);
730 } else {
731 error(hWnd, IDS_NOTFOUND, searchString);
734 break;
736 case ID_EDIT_COPYKEYNAME:
738 LPTSTR fullPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
739 if (fullPath) {
740 CopyKeyName(hWnd, fullPath);
741 HeapFree(GetProcessHeap(), 0, fullPath);
743 break;
745 case ID_EDIT_NEW_KEY:
746 if (CreateKey(hWnd, hKeyRoot, keyPath, newKey)) {
747 if (InsertNode(g_pChildWnd->hTreeWnd, 0, newKey))
748 StartKeyRename(g_pChildWnd->hTreeWnd);
750 break;
751 case ID_EDIT_NEW_STRINGVALUE:
752 valueType = REG_SZ;
753 goto create_value;
754 case ID_EDIT_NEW_MULTI_STRINGVALUE:
755 valueType = REG_MULTI_SZ;
756 goto create_value;
757 case ID_EDIT_NEW_BINARYVALUE:
758 valueType = REG_BINARY;
759 goto create_value;
760 case ID_EDIT_NEW_DWORDVALUE:
761 valueType = REG_DWORD;
762 /* fall through */
763 create_value:
764 if (CreateValue(hWnd, hKeyRoot, keyPath, valueType, newKey)) {
765 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, newKey);
766 StartValueRename(g_pChildWnd->hListWnd);
767 /* FIXME: start rename */
769 break;
770 case ID_EDIT_RENAME:
771 if (keyPath == 0 || *keyPath == 0) {
772 MessageBeep(MB_ICONHAND);
773 } else if (GetFocus() == g_pChildWnd->hTreeWnd) {
774 StartKeyRename(g_pChildWnd->hTreeWnd);
775 } else if (GetFocus() == g_pChildWnd->hListWnd) {
776 StartValueRename(g_pChildWnd->hListWnd);
778 break;
779 case ID_REGISTRY_PRINTERSETUP:
780 /*PRINTDLG pd;*/
781 /*PrintDlg(&pd);*/
782 /*PAGESETUPDLG psd;*/
783 /*PageSetupDlg(&psd);*/
784 break;
785 case ID_REGISTRY_OPENLOCAL:
786 break;
787 case ID_REGISTRY_EXIT:
788 DestroyWindow(hWnd);
789 break;
790 case ID_FAVORITES_ADDTOFAVORITES:
792 HKEY hKey;
793 LPTSTR lpKeyPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
794 if (lpKeyPath) {
795 if (DialogBox(0, MAKEINTRESOURCE(IDD_ADDFAVORITE), hWnd, addtofavorites_dlgproc) == IDOK) {
796 if (RegCreateKeyEx(HKEY_CURRENT_USER, favoritesKey,
797 0, NULL, 0,
798 KEY_READ|KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) {
799 RegSetValueEx(hKey, favoriteName, 0, REG_SZ, (BYTE *)lpKeyPath, (_tcslen(lpKeyPath)+1)*sizeof(TCHAR));
800 RegCloseKey(hKey);
803 HeapFree(GetProcessHeap(), 0, lpKeyPath);
805 break;
807 case ID_FAVORITES_REMOVEFAVORITE:
809 if (DialogBox(0, MAKEINTRESOURCE(IDD_DELFAVORITE), hWnd, removefavorite_dlgproc) == IDOK) {
810 HKEY hKey;
811 if (RegOpenKeyEx(HKEY_CURRENT_USER, favoritesKey,
812 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS) {
813 RegDeleteValue(hKey, favoriteName);
814 RegCloseKey(hKey);
817 break;
819 case ID_VIEW_REFRESH:
820 RefreshTreeView(g_pChildWnd->hTreeWnd);
821 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
822 break;
823 /*case ID_OPTIONS_TOOLBAR:*/
824 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
825 /* break;*/
826 case ID_VIEW_STATUSBAR:
827 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
828 break;
829 case ID_HELP_HELPTOPICS:
830 WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
831 break;
832 case ID_HELP_ABOUT:
833 ShowAboutBox(hWnd);
834 break;
835 case ID_VIEW_SPLIT: {
836 RECT rt;
837 POINT pt, pts;
838 GetClientRect(g_pChildWnd->hWnd, &rt);
839 pt.x = rt.left + g_pChildWnd->nSplitPos;
840 pt.y = (rt.bottom / 2);
841 pts = pt;
842 if(ClientToScreen(g_pChildWnd->hWnd, &pts)) {
843 SetCursorPos(pts.x, pts.y);
844 SetCursor(LoadCursor(0, IDC_SIZEWE));
845 SendMessage(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
847 return TRUE;
849 default:
850 return FALSE;
853 return TRUE;
856 /********************************************************************************
858 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
860 * PURPOSE: Processes messages for the main frame window.
862 * WM_COMMAND - process the application menu
863 * WM_DESTROY - post a quit message and return
867 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
869 switch (message) {
870 case WM_CREATE:
871 CreateWindowEx(0, szChildClass, _T("regedit child window"), WS_CHILD | WS_VISIBLE,
872 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
873 hWnd, NULL, hInst, 0);
874 break;
875 case WM_COMMAND:
876 if (!_CmdWndProc(hWnd, message, wParam, lParam))
877 return DefWindowProc(hWnd, message, wParam, lParam);
878 break;
879 case WM_ACTIVATE:
880 if (LOWORD(hWnd))
881 SetFocus(g_pChildWnd->hWnd);
882 break;
883 case WM_SIZE:
884 resize_frame_client(hWnd);
885 break;
886 case WM_TIMER:
887 break;
888 case WM_ENTERMENULOOP:
889 OnEnterMenuLoop(hWnd);
890 break;
891 case WM_EXITMENULOOP:
892 OnExitMenuLoop(hWnd);
893 break;
894 case WM_INITMENUPOPUP:
895 if (!HIWORD(lParam))
896 OnInitMenuPopup(hWnd, (HMENU)wParam, LOWORD(lParam));
897 break;
898 case WM_MENUSELECT:
899 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
900 break;
901 case WM_DESTROY:
902 WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
903 PostQuitMessage(0);
904 default:
905 return DefWindowProc(hWnd, message, wParam, lParam);
907 return 0;