push e5b2529cdc55a2e67d855677d8651b2d2fa8d45f
[wine/hacks.git] / programs / regedit / framewnd.c
blob958b2c7f636cf0e9d781da2e57c169434eb67114
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 WCHAR favoritesKey[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','A','p','p','l','e','t','s','\\','R','e','g','E','d','i','t','\\','F','a','v','o','r','i','t','e','s',0};
40 static BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
41 static WCHAR 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 (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
127 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
128 WCHAR 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 = RegEnumValueW(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
138 if (error != ERROR_SUCCESS)
139 break;
140 if (type == REG_SZ) {
141 if (!sep) {
142 AppendMenuW(hMenu, MF_SEPARATOR, -1, NULL);
143 sep = TRUE;
145 AppendMenuW(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 BOOL Success;
317 FILE* reg_file = fopen(filename, "r");
319 if(!reg_file)
320 return FALSE;
322 Success = import_registry_file(reg_file);
324 if(fclose(reg_file) != 0)
325 Success = FALSE;
327 return Success;
330 static BOOL ImportRegistryFile(HWND hWnd)
332 OPENFILENAME ofn;
333 TCHAR title[128];
335 InitOpenFileName(hWnd, &ofn);
336 LoadString(hInst, IDS_FILEDIALOG_IMPORT_TITLE, title, COUNT_OF(title));
337 ofn.lpstrTitle = title;
338 if (GetOpenFileName(&ofn)) {
339 if (!import_registry_filename(ofn.lpstrFile)) {
340 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
341 return FALSE;
343 } else {
344 CheckCommDlgError(hWnd);
346 RefreshTreeView(g_pChildWnd->hTreeWnd);
347 return TRUE;
351 static BOOL ExportRegistryFile(HWND hWnd, BOOL export_branch)
353 OPENFILENAME ofn;
354 TCHAR ExportKeyPath[_MAX_PATH];
355 TCHAR title[128];
357 ExportKeyPath[0] = _T('\0');
358 InitOpenFileName(hWnd, &ofn);
359 LoadString(hInst, IDS_FILEDIALOG_EXPORT_TITLE, title, COUNT_OF(title));
360 ofn.lpstrTitle = title;
361 ofn.lCustData = export_branch;
362 ofn.Flags = OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
363 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
364 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORT_TEMPLATE);
365 if (GetSaveFileName(&ofn)) {
366 BOOL result;
367 result = export_registry_key(ofn.lpstrFile, (LPTSTR)ofn.lCustData);
368 if (!result) {
369 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
370 return FALSE;
372 } else {
373 CheckCommDlgError(hWnd);
375 return TRUE;
378 static BOOL PrintRegistryHive(HWND hWnd, LPCWSTR path)
380 #if 1
381 PRINTDLGW pd;
383 ZeroMemory(&pd, sizeof(PRINTDLG));
384 pd.lStructSize = sizeof(PRINTDLG);
385 pd.hwndOwner = hWnd;
386 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
387 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
388 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
389 pd.nCopies = 1;
390 pd.nFromPage = 0xFFFF;
391 pd.nToPage = 0xFFFF;
392 pd.nMinPage = 1;
393 pd.nMaxPage = 0xFFFF;
394 if (PrintDlgW(&pd)) {
395 /* GDI calls to render output. */
396 DeleteDC(pd.hDC); /* Delete DC when done.*/
398 #else
399 HRESULT hResult;
400 PRINTDLGEXW pd;
402 hResult = PrintDlgExW(&pd);
403 if (hResult == S_OK) {
404 switch (pd.dwResultAction) {
405 case PD_RESULT_APPLY:
406 /*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. */
407 break;
408 case PD_RESULT_CANCEL:
409 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
410 break;
411 case PD_RESULT_PRINT:
412 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
413 break;
414 default:
415 break;
417 } else {
418 switch (hResult) {
419 case E_OUTOFMEMORY:
420 /*Insufficient memory. */
421 break;
422 case E_INVALIDARG:
423 /* One or more arguments are invalid. */
424 break;
425 case E_POINTER:
426 /*Invalid pointer. */
427 break;
428 case E_HANDLE:
429 /*Invalid handle. */
430 break;
431 case E_FAIL:
432 /*Unspecified error. */
433 break;
434 default:
435 break;
437 return FALSE;
439 #endif
440 return TRUE;
443 static BOOL CopyKeyName(HWND hWnd, LPCWSTR keyName)
445 BOOL result;
447 result = OpenClipboard(hWnd);
448 if (result) {
449 result = EmptyClipboard();
450 if (result) {
451 int len = (lstrlenW(keyName)+1)*sizeof(WCHAR);
452 HANDLE hClipData = GlobalAlloc(GHND, len);
453 LPVOID pLoc = GlobalLock(hClipData);
454 lstrcpyW(pLoc, keyName);
455 GlobalUnlock(hClipData);
456 hClipData = SetClipboardData(CF_UNICODETEXT, hClipData);
458 } else {
459 /* error emptying clipboard*/
460 /* DWORD dwError = GetLastError(); */
463 if (!CloseClipboard()) {
464 /* error closing clipboard*/
465 /* DWORD dwError = GetLastError(); */
468 } else {
469 /* error opening clipboard*/
470 /* DWORD dwError = GetLastError(); */
473 return result;
476 static INT_PTR CALLBACK find_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
478 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
480 switch(uMsg) {
481 case WM_INITDIALOG:
482 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
483 CheckDlgButton(hwndDlg, IDC_FIND_KEYS, searchMask&SEARCH_KEYS ? BST_CHECKED : BST_UNCHECKED);
484 CheckDlgButton(hwndDlg, IDC_FIND_VALUES, searchMask&SEARCH_VALUES ? BST_CHECKED : BST_UNCHECKED);
485 CheckDlgButton(hwndDlg, IDC_FIND_CONTENT, searchMask&SEARCH_CONTENT ? BST_CHECKED : BST_UNCHECKED);
486 CheckDlgButton(hwndDlg, IDC_FIND_WHOLE, searchMask&SEARCH_WHOLE ? BST_CHECKED : BST_UNCHECKED);
487 SendMessage(hwndValue, EM_SETLIMITTEXT, 127, 0);
488 SetWindowText(hwndValue, searchString);
489 return TRUE;
490 case WM_COMMAND:
491 switch(LOWORD(wParam)) {
492 case IDC_VALUE_NAME:
493 if (HIWORD(wParam) == EN_UPDATE) {
494 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLength(hwndValue)>0);
495 return TRUE;
497 break;
498 case IDOK:
499 if (GetWindowTextLength(hwndValue)>0) {
500 int mask = 0;
501 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_KEYS)) mask |= SEARCH_KEYS;
502 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_VALUES)) mask |= SEARCH_VALUES;
503 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_CONTENT)) mask |= SEARCH_CONTENT;
504 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_WHOLE)) mask |= SEARCH_WHOLE;
505 searchMask = mask;
506 GetWindowText(hwndValue, searchString, 128);
507 EndDialog(hwndDlg, IDOK);
509 return TRUE;
510 case IDCANCEL:
511 EndDialog(hwndDlg, IDCANCEL);
512 return TRUE;
514 break;
516 return FALSE;
519 static INT_PTR CALLBACK addtofavorites_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
521 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
523 switch(uMsg) {
524 case WM_INITDIALOG:
526 HKEY hKeyRoot = NULL;
527 LPWSTR ItemPath = GetItemPathW(g_pChildWnd->hTreeWnd, NULL, &hKeyRoot);
529 if(!ItemPath || !*ItemPath)
530 ItemPath = GetItemFullPathW(g_pChildWnd->hTreeWnd, NULL, FALSE);
531 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
532 SetWindowTextW(hwndValue, ItemPath);
533 SendMessageW(hwndValue, EM_SETLIMITTEXT, 127, 0);
534 HeapFree(GetProcessHeap(), 0, ItemPath);
535 return TRUE;
537 case WM_COMMAND:
538 switch(LOWORD(wParam)) {
539 case IDC_VALUE_NAME:
540 if (HIWORD(wParam) == EN_UPDATE) {
541 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLength(hwndValue)>0);
542 return TRUE;
544 break;
545 case IDOK:
546 if (GetWindowTextLengthW(hwndValue)>0) {
547 GetWindowTextW(hwndValue, favoriteName, 128);
548 EndDialog(hwndDlg, IDOK);
550 return TRUE;
551 case IDCANCEL:
552 EndDialog(hwndDlg, IDCANCEL);
553 return TRUE;
555 break;
557 return FALSE;
560 static INT_PTR CALLBACK removefavorite_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
562 HWND hwndList = GetDlgItem(hwndDlg, IDC_NAME_LIST);
564 switch(uMsg) {
565 case WM_INITDIALOG: {
566 HKEY hKey;
567 int i = 0;
568 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
569 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
570 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
571 WCHAR namebuf[KEY_MAX_LEN];
572 BYTE valuebuf[4096];
573 DWORD ksize, vsize, type;
574 LONG error;
575 do {
576 ksize = KEY_MAX_LEN;
577 vsize = sizeof(valuebuf);
578 error = RegEnumValueW(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
579 if (error != ERROR_SUCCESS)
580 break;
581 if (type == REG_SZ) {
582 SendMessageW(hwndList, LB_ADDSTRING, 0, (LPARAM)namebuf);
584 i++;
585 } while(error == ERROR_SUCCESS);
586 RegCloseKey(hKey);
588 else
589 return FALSE;
590 EnableWindow(GetDlgItem(hwndDlg, IDOK), i != 0);
591 SendMessageW(hwndList, LB_SETCURSEL, 0, 0);
592 return TRUE;
594 case WM_COMMAND:
595 switch(LOWORD(wParam)) {
596 case IDC_NAME_LIST:
597 if (HIWORD(wParam) == LBN_SELCHANGE) {
598 EnableWindow(GetDlgItem(hwndDlg, IDOK), lParam != -1);
599 return TRUE;
601 break;
602 case IDOK: {
603 int pos = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
604 int len = SendMessage(hwndList, LB_GETTEXTLEN, pos, 0);
605 if (len>0) {
606 LPWSTR lpName = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
607 SendMessageW(hwndList, LB_GETTEXT, pos, (LPARAM)lpName);
608 if (len>127)
609 lpName[127] = '\0';
610 lstrcpyW(favoriteName, lpName);
611 EndDialog(hwndDlg, IDOK);
612 HeapFree(GetProcessHeap(), 0, lpName);
614 return TRUE;
616 case IDCANCEL:
617 EndDialog(hwndDlg, IDCANCEL);
618 return TRUE;
620 break;
622 return FALSE;
625 /*******************************************************************************
627 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
629 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
632 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
634 HKEY hKeyRoot = 0;
635 LPCTSTR keyPath;
636 LPCTSTR valueName;
637 TCHAR newKey[MAX_NEW_KEY_LEN];
638 DWORD valueType;
639 int curIndex;
640 BOOL firstItem = TRUE;
642 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
644 if (LOWORD(wParam) >= ID_FAVORITE_FIRST && LOWORD(wParam) <= ID_FAVORITE_LAST) {
645 HKEY hKey;
646 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
647 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
648 WCHAR namebuf[KEY_MAX_LEN];
649 BYTE valuebuf[4096];
650 DWORD ksize = KEY_MAX_LEN, vsize = sizeof(valuebuf), type = 0;
651 if (RegEnumValueW(hKey, LOWORD(wParam) - ID_FAVORITE_FIRST, namebuf, &ksize, NULL,
652 &type, valuebuf, &vsize) == ERROR_SUCCESS) {
653 SendMessageW( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET,
654 (LPARAM) FindPathInTree(g_pChildWnd->hTreeWnd, (WCHAR *)valuebuf) );
656 RegCloseKey(hKey);
658 return TRUE;
660 switch (LOWORD(wParam)) {
661 case ID_REGISTRY_IMPORTREGISTRYFILE:
662 ImportRegistryFile(hWnd);
663 break;
664 case ID_EDIT_EXPORT:
665 ExportRegistryFile(hWnd, TRUE);
666 break;
667 case ID_REGISTRY_EXPORTREGISTRYFILE:
668 ExportRegistryFile(hWnd, FALSE);
669 break;
670 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
671 break;
672 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
673 break;
674 case ID_REGISTRY_PRINT:
676 const WCHAR empty = 0;
677 PrintRegistryHive(hWnd, &empty);
678 break;
680 case ID_EDIT_DELETE:
681 if (GetFocus() == g_pChildWnd->hTreeWnd) {
682 WCHAR* keyPathW = GetWideString(keyPath);
683 if (keyPath == 0 || *keyPath == 0) {
684 MessageBeep(MB_ICONHAND);
685 } else if (DeleteKey(hWnd, hKeyRoot, keyPathW)) {
686 DeleteNode(g_pChildWnd->hTreeWnd, 0);
688 HeapFree(GetProcessHeap(), 0, keyPathW);
689 } else if (GetFocus() == g_pChildWnd->hListWnd) {
690 curIndex = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
691 while(curIndex != -1) {
692 WCHAR* valueNameW;
693 WCHAR* keyPathW;
695 valueName = GetItemText(g_pChildWnd->hListWnd, curIndex);
696 curIndex = ListView_GetNextItem(g_pChildWnd->hListWnd, curIndex, LVNI_SELECTED);
697 if(curIndex != -1 && firstItem) {
698 if (MessageBoxW(hWnd, MAKEINTRESOURCEW(IDS_DELETE_BOX_TEXT_MULTIPLE),
699 MAKEINTRESOURCEW(IDS_DELETE_BOX_TITLE),
700 MB_YESNO | MB_ICONEXCLAMATION) != IDYES)
701 break;
703 valueNameW = GetWideString(valueName);
704 keyPathW = GetWideString(keyPath);
705 if (!DeleteValue(hWnd, hKeyRoot, keyPathW, valueNameW, curIndex==-1 && firstItem))
707 HeapFree(GetProcessHeap(), 0, valueNameW);
708 HeapFree(GetProcessHeap(), 0, keyPathW);
709 break;
711 firstItem = FALSE;
712 HeapFree(GetProcessHeap(), 0, valueNameW);
713 HeapFree(GetProcessHeap(), 0, keyPathW);
715 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
717 break;
718 case ID_EDIT_MODIFY:
719 valueName = GetValueName(g_pChildWnd->hListWnd);
720 if (ModifyValue(hWnd, hKeyRoot, keyPath, valueName))
721 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, valueName);
722 break;
723 case ID_EDIT_FIND:
724 case ID_EDIT_FINDNEXT:
726 HTREEITEM hItem;
727 if (LOWORD(wParam) == ID_EDIT_FIND &&
728 DialogBox(0, MAKEINTRESOURCE(IDD_FIND), hWnd, find_dlgproc) != IDOK)
729 break;
730 if (!*searchString)
731 break;
732 hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
733 if (hItem) {
734 int row = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_FOCUSED);
735 HCURSOR hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
736 hItem = FindNext(g_pChildWnd->hTreeWnd, hItem, searchString, searchMask, &row);
737 SetCursor(hcursorOld);
738 if (hItem) {
739 SendMessage( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM) hItem );
740 InvalidateRect(g_pChildWnd->hTreeWnd, NULL, TRUE);
741 UpdateWindow(g_pChildWnd->hTreeWnd);
742 if (row != -1) {
743 ListView_SetItemState(g_pChildWnd->hListWnd, -1, 0, LVIS_FOCUSED|LVIS_SELECTED);
744 ListView_SetItemState(g_pChildWnd->hListWnd, row, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
745 SetFocus(g_pChildWnd->hListWnd);
746 } else {
747 SetFocus(g_pChildWnd->hTreeWnd);
749 } else {
750 error(hWnd, IDS_NOTFOUND, searchString);
753 break;
755 case ID_EDIT_COPYKEYNAME:
757 LPWSTR fullPath = GetItemFullPathW(g_pChildWnd->hTreeWnd, NULL, FALSE);
758 if (fullPath) {
759 CopyKeyName(hWnd, fullPath);
760 HeapFree(GetProcessHeap(), 0, fullPath);
762 break;
764 case ID_EDIT_NEW_KEY:
766 WCHAR newKeyW[MAX_NEW_KEY_LEN];
767 WCHAR* keyPathW = GetWideString(keyPath);
768 if (CreateKey(hWnd, hKeyRoot, keyPathW, newKeyW)) {
769 if (InsertNode(g_pChildWnd->hTreeWnd, 0, newKeyW))
770 StartKeyRename(g_pChildWnd->hTreeWnd);
772 HeapFree(GetProcessHeap(), 0, keyPathW);
774 break;
775 case ID_EDIT_NEW_STRINGVALUE:
776 valueType = REG_SZ;
777 goto create_value;
778 case ID_EDIT_NEW_MULTI_STRINGVALUE:
779 valueType = REG_MULTI_SZ;
780 goto create_value;
781 case ID_EDIT_NEW_BINARYVALUE:
782 valueType = REG_BINARY;
783 goto create_value;
784 case ID_EDIT_NEW_DWORDVALUE:
785 valueType = REG_DWORD;
786 /* fall through */
787 create_value:
788 if (CreateValue(hWnd, hKeyRoot, keyPath, valueType, newKey)) {
789 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, newKey);
790 StartValueRename(g_pChildWnd->hListWnd);
791 /* FIXME: start rename */
793 break;
794 case ID_EDIT_RENAME:
795 if (keyPath == 0 || *keyPath == 0) {
796 MessageBeep(MB_ICONHAND);
797 } else if (GetFocus() == g_pChildWnd->hTreeWnd) {
798 StartKeyRename(g_pChildWnd->hTreeWnd);
799 } else if (GetFocus() == g_pChildWnd->hListWnd) {
800 StartValueRename(g_pChildWnd->hListWnd);
802 break;
803 case ID_REGISTRY_PRINTERSETUP:
804 /*PRINTDLG pd;*/
805 /*PrintDlg(&pd);*/
806 /*PAGESETUPDLG psd;*/
807 /*PageSetupDlg(&psd);*/
808 break;
809 case ID_REGISTRY_OPENLOCAL:
810 break;
811 case ID_REGISTRY_EXIT:
812 DestroyWindow(hWnd);
813 break;
814 case ID_FAVORITES_ADDTOFAVORITES:
816 HKEY hKey;
817 LPWSTR lpKeyPath = GetItemFullPathW(g_pChildWnd->hTreeWnd, NULL, FALSE);
818 if (lpKeyPath) {
819 if (DialogBox(0, MAKEINTRESOURCE(IDD_ADDFAVORITE), hWnd, addtofavorites_dlgproc) == IDOK) {
820 if (RegCreateKeyExW(HKEY_CURRENT_USER, favoritesKey,
821 0, NULL, 0,
822 KEY_READ|KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) {
823 RegSetValueExW(hKey, favoriteName, 0, REG_SZ, (BYTE *)lpKeyPath, (lstrlenW(lpKeyPath)+1)*sizeof(WCHAR));
824 RegCloseKey(hKey);
827 HeapFree(GetProcessHeap(), 0, lpKeyPath);
829 break;
831 case ID_FAVORITES_REMOVEFAVORITE:
833 if (DialogBox(0, MAKEINTRESOURCE(IDD_DELFAVORITE), hWnd, removefavorite_dlgproc) == IDOK) {
834 HKEY hKey;
835 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
836 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS) {
837 RegDeleteValueW(hKey, favoriteName);
838 RegCloseKey(hKey);
841 break;
843 case ID_VIEW_REFRESH:
844 RefreshTreeView(g_pChildWnd->hTreeWnd);
845 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
846 break;
847 /*case ID_OPTIONS_TOOLBAR:*/
848 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
849 /* break;*/
850 case ID_VIEW_STATUSBAR:
851 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
852 break;
853 case ID_HELP_HELPTOPICS:
855 const WCHAR help_regedit[] = {'r','e','g','e','d','i','t',0};
856 WinHelpW(hWnd, help_regedit, HELP_FINDER, 0);
857 break;
859 case ID_HELP_ABOUT:
860 ShowAboutBox(hWnd);
861 break;
862 case ID_VIEW_SPLIT: {
863 RECT rt;
864 POINT pt, pts;
865 GetClientRect(g_pChildWnd->hWnd, &rt);
866 pt.x = rt.left + g_pChildWnd->nSplitPos;
867 pt.y = (rt.bottom / 2);
868 pts = pt;
869 if(ClientToScreen(g_pChildWnd->hWnd, &pts)) {
870 SetCursorPos(pts.x, pts.y);
871 SetCursor(LoadCursor(0, IDC_SIZEWE));
872 SendMessage(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
874 return TRUE;
876 default:
877 return FALSE;
880 return TRUE;
883 /********************************************************************************
885 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
887 * PURPOSE: Processes messages for the main frame window.
889 * WM_COMMAND - process the application menu
890 * WM_DESTROY - post a quit message and return
894 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
896 switch (message) {
897 case WM_CREATE:
898 CreateWindowEx(0, szChildClass, _T("regedit child window"), WS_CHILD | WS_VISIBLE,
899 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
900 hWnd, NULL, hInst, 0);
901 break;
902 case WM_COMMAND:
903 if (!_CmdWndProc(hWnd, message, wParam, lParam))
904 return DefWindowProc(hWnd, message, wParam, lParam);
905 break;
906 case WM_ACTIVATE:
907 if (LOWORD(hWnd))
908 SetFocus(g_pChildWnd->hWnd);
909 break;
910 case WM_SIZE:
911 resize_frame_client(hWnd);
912 break;
913 case WM_TIMER:
914 break;
915 case WM_ENTERMENULOOP:
916 OnEnterMenuLoop(hWnd);
917 break;
918 case WM_EXITMENULOOP:
919 OnExitMenuLoop(hWnd);
920 break;
921 case WM_INITMENUPOPUP:
922 if (!HIWORD(lParam))
923 OnInitMenuPopup(hWnd, (HMENU)wParam, LOWORD(lParam));
924 break;
925 case WM_MENUSELECT:
926 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
927 break;
928 case WM_DESTROY:
930 const WCHAR help_regedit[] = {'r','e','g','e','d','i','t',0};
931 WinHelpW(hWnd, help_regedit, HELP_QUIT, 0);
932 PostQuitMessage(0);
934 default:
935 return DefWindowProc(hWnd, message, wParam, lParam);
937 return 0;