regedit: Add Export option to context menu.
[wine.git] / programs / regedit / framewnd.c
blobb1f8a5608f7986745ff4f685cd2172f388df64db
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 bIsKeySelected = FALSE;
104 HKEY hRootKey = NULL;
105 LPCTSTR keyName;
106 keyName = GetItemPath(hwndTV, TreeView_GetSelection(hwndTV), &hRootKey);
107 if (keyName && *keyName) { /* can't modify root keys */
108 bIsKeySelected = 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, (bIsKeySelected ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
113 EnableMenuItem(hMenu, ID_EDIT_DELETE, (bIsKeySelected ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
114 EnableMenuItem(hMenu, ID_EDIT_RENAME, (bIsKeySelected ? 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 ImportRegistryFile(HWND hWnd)
316 OPENFILENAME ofn;
317 TCHAR title[128];
319 InitOpenFileName(hWnd, &ofn);
320 LoadString(hInst, IDS_FILEDIALOG_IMPORT_TITLE, title, COUNT_OF(title));
321 ofn.lpstrTitle = title;
322 if (GetOpenFileName(&ofn)) {
323 if (!import_registry_file(ofn.lpstrFile)) {
324 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
325 return FALSE;
327 } else {
328 CheckCommDlgError(hWnd);
330 RefreshTreeView(g_pChildWnd->hTreeWnd);
331 return TRUE;
335 static BOOL ExportRegistryFile(HWND hWnd, BOOL export_branch)
337 OPENFILENAME ofn;
338 TCHAR ExportKeyPath[_MAX_PATH];
339 TCHAR title[128];
341 ExportKeyPath[0] = _T('\0');
342 InitOpenFileName(hWnd, &ofn);
343 LoadString(hInst, IDS_FILEDIALOG_EXPORT_TITLE, title, COUNT_OF(title));
344 ofn.lpstrTitle = title;
345 ofn.lCustData = export_branch;
346 ofn.Flags = OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
347 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
348 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORT_TEMPLATE);
349 if (GetSaveFileName(&ofn)) {
350 BOOL result;
351 result = export_registry_key(ofn.lpstrFile, (LPTSTR)ofn.lCustData);
352 if (!result) {
353 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
354 return FALSE;
356 } else {
357 CheckCommDlgError(hWnd);
359 return TRUE;
362 static BOOL PrintRegistryHive(HWND hWnd, LPCTSTR path)
364 #if 1
365 PRINTDLG pd;
367 ZeroMemory(&pd, sizeof(PRINTDLG));
368 pd.lStructSize = sizeof(PRINTDLG);
369 pd.hwndOwner = hWnd;
370 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
371 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
372 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
373 pd.nCopies = 1;
374 pd.nFromPage = 0xFFFF;
375 pd.nToPage = 0xFFFF;
376 pd.nMinPage = 1;
377 pd.nMaxPage = 0xFFFF;
378 if (PrintDlg(&pd)) {
379 /* GDI calls to render output. */
380 DeleteDC(pd.hDC); /* Delete DC when done.*/
382 #else
383 HRESULT hResult;
384 PRINTDLGEX pd;
386 hResult = PrintDlgEx(&pd);
387 if (hResult == S_OK) {
388 switch (pd.dwResultAction) {
389 case PD_RESULT_APPLY:
390 /*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. */
391 break;
392 case PD_RESULT_CANCEL:
393 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
394 break;
395 case PD_RESULT_PRINT:
396 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
397 break;
398 default:
399 break;
401 } else {
402 switch (hResult) {
403 case E_OUTOFMEMORY:
404 /*Insufficient memory. */
405 break;
406 case E_INVALIDARG:
407 /* One or more arguments are invalid. */
408 break;
409 case E_POINTER:
410 /*Invalid pointer. */
411 break;
412 case E_HANDLE:
413 /*Invalid handle. */
414 break;
415 case E_FAIL:
416 /*Unspecified error. */
417 break;
418 default:
419 break;
421 return FALSE;
423 #endif
424 return TRUE;
427 static BOOL CopyKeyName(HWND hWnd, LPCTSTR keyName)
429 BOOL result;
431 result = OpenClipboard(hWnd);
432 if (result) {
433 result = EmptyClipboard();
434 if (result) {
435 int len = (_tcslen(keyName)+1)*sizeof(TCHAR);
436 HANDLE hClipData = GlobalAlloc(GHND, len);
437 LPVOID pLoc = GlobalLock(hClipData);
438 _tcscpy(pLoc, keyName);
439 GlobalUnlock(hClipData);
440 hClipData = SetClipboardData(CF_TEXT, hClipData);
442 } else {
443 /* error emptying clipboard*/
444 /* DWORD dwError = GetLastError(); */
447 if (!CloseClipboard()) {
448 /* error closing clipboard*/
449 /* DWORD dwError = GetLastError(); */
452 } else {
453 /* error opening clipboard*/
454 /* DWORD dwError = GetLastError(); */
457 return result;
460 static INT_PTR CALLBACK find_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
462 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
464 switch(uMsg) {
465 case WM_INITDIALOG:
466 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
467 CheckDlgButton(hwndDlg, IDC_FIND_KEYS, searchMask&SEARCH_KEYS ? BST_CHECKED : BST_UNCHECKED);
468 CheckDlgButton(hwndDlg, IDC_FIND_VALUES, searchMask&SEARCH_VALUES ? BST_CHECKED : BST_UNCHECKED);
469 CheckDlgButton(hwndDlg, IDC_FIND_CONTENT, searchMask&SEARCH_CONTENT ? BST_CHECKED : BST_UNCHECKED);
470 CheckDlgButton(hwndDlg, IDC_FIND_WHOLE, searchMask&SEARCH_WHOLE ? BST_CHECKED : BST_UNCHECKED);
471 SendMessage(hwndValue, EM_SETLIMITTEXT, 127, 0);
472 SetWindowText(hwndValue, searchString);
473 return TRUE;
474 case WM_COMMAND:
475 switch(LOWORD(wParam)) {
476 case IDC_VALUE_NAME:
477 if (HIWORD(wParam) == EN_UPDATE) {
478 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLength(hwndValue)>0);
479 return TRUE;
481 break;
482 case IDOK:
483 if (GetWindowTextLength(hwndValue)>0) {
484 int mask = 0;
485 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_KEYS)) mask |= SEARCH_KEYS;
486 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_VALUES)) mask |= SEARCH_VALUES;
487 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_CONTENT)) mask |= SEARCH_CONTENT;
488 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_WHOLE)) mask |= SEARCH_WHOLE;
489 searchMask = mask;
490 GetWindowText(hwndValue, searchString, 128);
491 EndDialog(hwndDlg, IDOK);
493 return TRUE;
494 case IDCANCEL:
495 EndDialog(hwndDlg, IDCANCEL);
496 return TRUE;
498 break;
500 return FALSE;
503 static INT_PTR CALLBACK addtofavorites_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
505 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
507 switch(uMsg) {
508 case WM_INITDIALOG:
509 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
510 SendMessage(hwndValue, EM_SETLIMITTEXT, 127, 0);
511 return TRUE;
512 case WM_COMMAND:
513 switch(LOWORD(wParam)) {
514 case IDC_VALUE_NAME:
515 if (HIWORD(wParam) == EN_UPDATE) {
516 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLength(hwndValue)>0);
517 return TRUE;
519 break;
520 case IDOK:
521 if (GetWindowTextLength(hwndValue)>0) {
522 GetWindowText(hwndValue, favoriteName, 128);
523 EndDialog(hwndDlg, IDOK);
525 return TRUE;
526 case IDCANCEL:
527 EndDialog(hwndDlg, IDCANCEL);
528 return TRUE;
530 break;
532 return FALSE;
535 static INT_PTR CALLBACK removefavorite_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
537 HWND hwndList = GetDlgItem(hwndDlg, IDC_NAME_LIST);
539 switch(uMsg) {
540 case WM_INITDIALOG: {
541 HKEY hKey;
542 int i = 0;
543 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
544 if (RegOpenKeyEx(HKEY_CURRENT_USER, favoritesKey,
545 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
546 TCHAR namebuf[KEY_MAX_LEN];
547 BYTE valuebuf[4096];
548 DWORD ksize, vsize, type;
549 LONG error;
550 do {
551 ksize = KEY_MAX_LEN;
552 vsize = sizeof(valuebuf);
553 error = RegEnumValue(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
554 if (error != ERROR_SUCCESS)
555 break;
556 if (type == REG_SZ) {
557 SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)namebuf);
559 i++;
560 } while(error == ERROR_SUCCESS);
561 RegCloseKey(hKey);
563 else
564 return FALSE;
565 EnableWindow(GetDlgItem(hwndDlg, IDOK), i != 0);
566 SendMessage(hwndList, LB_SETCURSEL, 0, 0);
567 return TRUE;
569 case WM_COMMAND:
570 switch(LOWORD(wParam)) {
571 case IDC_NAME_LIST:
572 if (HIWORD(wParam) == LBN_SELCHANGE) {
573 EnableWindow(GetDlgItem(hwndDlg, IDOK), lParam != -1);
574 return TRUE;
576 break;
577 case IDOK: {
578 int pos = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
579 int len = SendMessage(hwndList, LB_GETTEXTLEN, pos, 0);
580 if (len>0) {
581 LPTSTR lpName = HeapAlloc(GetProcessHeap(), 0, sizeof(TCHAR)*(len+1));
582 SendMessage(hwndList, LB_GETTEXT, pos, (LPARAM)lpName);
583 if (len>127)
584 lpName[127] = '\0';
585 _tcscpy(favoriteName, lpName);
586 EndDialog(hwndDlg, IDOK);
587 HeapFree(GetProcessHeap(), 0, lpName);
589 return TRUE;
591 case IDCANCEL:
592 EndDialog(hwndDlg, IDCANCEL);
593 return TRUE;
595 break;
597 return FALSE;
600 /*******************************************************************************
602 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
604 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
607 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
609 HKEY hKeyRoot = 0;
610 LPCTSTR keyPath;
611 LPCTSTR valueName;
612 TCHAR newKey[MAX_NEW_KEY_LEN];
613 DWORD valueType;
615 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
616 valueName = GetValueName(g_pChildWnd->hListWnd);
618 if (LOWORD(wParam) >= ID_FAVORITE_FIRST && LOWORD(wParam) <= ID_FAVORITE_LAST) {
619 HKEY hKey;
620 if (RegOpenKeyEx(HKEY_CURRENT_USER, favoritesKey,
621 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
622 TCHAR namebuf[KEY_MAX_LEN];
623 BYTE valuebuf[4096];
624 DWORD ksize = KEY_MAX_LEN, vsize = sizeof(valuebuf), type = 0;
625 if (RegEnumValue(hKey, LOWORD(wParam) - ID_FAVORITE_FIRST, namebuf, &ksize, NULL,
626 &type, valuebuf, &vsize) == ERROR_SUCCESS) {
627 SendMessage( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET,
628 (LPARAM) FindPathInTree(g_pChildWnd->hTreeWnd, (TCHAR *)valuebuf) );
630 RegCloseKey(hKey);
632 return TRUE;
634 switch (LOWORD(wParam)) {
635 case ID_REGISTRY_IMPORTREGISTRYFILE:
636 ImportRegistryFile(hWnd);
637 break;
638 case ID_EDIT_EXPORT:
639 ExportRegistryFile(hWnd, TRUE);
640 break;
641 case ID_REGISTRY_EXPORTREGISTRYFILE:
642 ExportRegistryFile(hWnd, FALSE);
643 break;
644 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
645 break;
646 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
647 break;
648 case ID_REGISTRY_PRINT:
649 PrintRegistryHive(hWnd, _T(""));
650 break;
651 case ID_EDIT_DELETE:
652 if (GetFocus() == g_pChildWnd->hTreeWnd) {
653 if (keyPath == 0 || *keyPath == 0) {
654 MessageBeep(MB_ICONHAND);
655 } else if (DeleteKey(hWnd, hKeyRoot, keyPath)) {
656 DeleteNode(g_pChildWnd->hTreeWnd, 0);
658 } else if (GetFocus() == g_pChildWnd->hListWnd) {
659 if (DeleteValue(hWnd, hKeyRoot, keyPath, valueName))
660 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
662 break;
663 case ID_EDIT_MODIFY:
664 if (ModifyValue(hWnd, hKeyRoot, keyPath, valueName))
665 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, valueName);
666 break;
667 case ID_EDIT_FIND:
668 case ID_EDIT_FINDNEXT:
670 HTREEITEM hItem;
671 if (LOWORD(wParam) == ID_EDIT_FIND &&
672 DialogBox(0, MAKEINTRESOURCE(IDD_FIND), hWnd, find_dlgproc) != IDOK)
673 break;
674 if (!*searchString)
675 break;
676 hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
677 if (hItem) {
678 int row = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_FOCUSED);
679 HCURSOR hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
680 hItem = FindNext(g_pChildWnd->hTreeWnd, hItem, searchString, searchMask, &row);
681 SetCursor(hcursorOld);
682 if (hItem) {
683 SendMessage( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM) hItem );
684 InvalidateRect(g_pChildWnd->hTreeWnd, NULL, TRUE);
685 UpdateWindow(g_pChildWnd->hTreeWnd);
686 if (row != -1) {
687 ListView_SetItemState(g_pChildWnd->hListWnd, -1, 0, LVIS_FOCUSED|LVIS_SELECTED);
688 ListView_SetItemState(g_pChildWnd->hListWnd, row, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
689 SetFocus(g_pChildWnd->hListWnd);
690 } else {
691 SetFocus(g_pChildWnd->hTreeWnd);
693 } else {
694 error(hWnd, IDS_NOTFOUND, searchString);
697 break;
699 case ID_EDIT_COPYKEYNAME:
701 LPTSTR fullPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
702 if (fullPath) {
703 CopyKeyName(hWnd, fullPath);
704 HeapFree(GetProcessHeap(), 0, fullPath);
706 break;
708 case ID_EDIT_NEW_KEY:
709 if (CreateKey(hWnd, hKeyRoot, keyPath, newKey)) {
710 if (InsertNode(g_pChildWnd->hTreeWnd, 0, newKey))
711 StartKeyRename(g_pChildWnd->hTreeWnd);
713 break;
714 case ID_EDIT_NEW_STRINGVALUE:
715 valueType = REG_SZ;
716 goto create_value;
717 case ID_EDIT_NEW_MULTI_STRINGVALUE:
718 valueType = REG_MULTI_SZ;
719 goto create_value;
720 case ID_EDIT_NEW_BINARYVALUE:
721 valueType = REG_BINARY;
722 goto create_value;
723 case ID_EDIT_NEW_DWORDVALUE:
724 valueType = REG_DWORD;
725 /* fall through */
726 create_value:
727 if (CreateValue(hWnd, hKeyRoot, keyPath, valueType, newKey)) {
728 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, newKey);
729 StartValueRename(g_pChildWnd->hListWnd);
730 /* FIXME: start rename */
732 break;
733 case ID_EDIT_RENAME:
734 if (keyPath == 0 || *keyPath == 0) {
735 MessageBeep(MB_ICONHAND);
736 } else if (GetFocus() == g_pChildWnd->hTreeWnd) {
737 StartKeyRename(g_pChildWnd->hTreeWnd);
738 } else if (GetFocus() == g_pChildWnd->hListWnd) {
739 StartValueRename(g_pChildWnd->hListWnd);
741 break;
742 case ID_REGISTRY_PRINTERSETUP:
743 /*PRINTDLG pd;*/
744 /*PrintDlg(&pd);*/
745 /*PAGESETUPDLG psd;*/
746 /*PageSetupDlg(&psd);*/
747 break;
748 case ID_REGISTRY_OPENLOCAL:
749 break;
750 case ID_REGISTRY_EXIT:
751 DestroyWindow(hWnd);
752 break;
753 case ID_FAVORITES_ADDTOFAVORITES:
755 HKEY hKey;
756 LPTSTR lpKeyPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
757 if (lpKeyPath) {
758 if (DialogBox(0, MAKEINTRESOURCE(IDD_ADDFAVORITE), hWnd, addtofavorites_dlgproc) == IDOK) {
759 if (RegCreateKeyEx(HKEY_CURRENT_USER, favoritesKey,
760 0, NULL, 0,
761 KEY_READ|KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) {
762 RegSetValueEx(hKey, favoriteName, 0, REG_SZ, (BYTE *)lpKeyPath, (_tcslen(lpKeyPath)+1)*sizeof(TCHAR));
763 RegCloseKey(hKey);
766 HeapFree(GetProcessHeap(), 0, lpKeyPath);
768 break;
770 case ID_FAVORITES_REMOVEFAVORITE:
772 if (DialogBox(0, MAKEINTRESOURCE(IDD_DELFAVORITE), hWnd, removefavorite_dlgproc) == IDOK) {
773 HKEY hKey;
774 if (RegOpenKeyEx(HKEY_CURRENT_USER, favoritesKey,
775 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS) {
776 RegDeleteValue(hKey, favoriteName);
777 RegCloseKey(hKey);
780 break;
782 case ID_VIEW_REFRESH:
783 RefreshTreeView(g_pChildWnd->hTreeWnd);
784 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
785 break;
786 /*case ID_OPTIONS_TOOLBAR:*/
787 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
788 /* break;*/
789 case ID_VIEW_STATUSBAR:
790 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
791 break;
792 case ID_HELP_HELPTOPICS:
793 WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
794 break;
795 case ID_HELP_ABOUT:
796 ShowAboutBox(hWnd);
797 break;
798 case ID_VIEW_SPLIT: {
799 RECT rt;
800 POINT pt, pts;
801 GetClientRect(g_pChildWnd->hWnd, &rt);
802 pt.x = rt.left + g_pChildWnd->nSplitPos;
803 pt.y = (rt.bottom / 2);
804 pts = pt;
805 if(ClientToScreen(g_pChildWnd->hWnd, &pts)) {
806 SetCursorPos(pts.x, pts.y);
807 SetCursor(LoadCursor(0, IDC_SIZEWE));
808 SendMessage(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
810 return TRUE;
812 default:
813 return FALSE;
816 return TRUE;
819 /********************************************************************************
821 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
823 * PURPOSE: Processes messages for the main frame window.
825 * WM_COMMAND - process the application menu
826 * WM_DESTROY - post a quit message and return
830 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
832 switch (message) {
833 case WM_CREATE:
834 CreateWindowEx(0, szChildClass, _T("regedit child window"), WS_CHILD | WS_VISIBLE,
835 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
836 hWnd, NULL, hInst, 0);
837 break;
838 case WM_COMMAND:
839 if (!_CmdWndProc(hWnd, message, wParam, lParam))
840 return DefWindowProc(hWnd, message, wParam, lParam);
841 break;
842 case WM_ACTIVATE:
843 if (LOWORD(hWnd))
844 SetFocus(g_pChildWnd->hWnd);
845 break;
846 case WM_SIZE:
847 resize_frame_client(hWnd);
848 break;
849 case WM_TIMER:
850 break;
851 case WM_ENTERMENULOOP:
852 OnEnterMenuLoop(hWnd);
853 break;
854 case WM_EXITMENULOOP:
855 OnExitMenuLoop(hWnd);
856 break;
857 case WM_INITMENUPOPUP:
858 if (!HIWORD(lParam))
859 OnInitMenuPopup(hWnd, (HMENU)wParam, LOWORD(lParam));
860 break;
861 case WM_MENUSELECT:
862 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
863 break;
864 case WM_DESTROY:
865 WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
866 PostQuitMessage(0);
867 default:
868 return DefWindowProc(hWnd, message, wParam, lParam);
870 return 0;