localspl: Add Welsh resource.
[wine/hacks.git] / programs / regedit / framewnd.c
blobc5eba382a630bd2c75cfa42532fa03c3f2750745
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"
34 #include "wine/unicode.h"
36 /********************************************************************************
37 * Global and Local Variables:
40 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};
41 static BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */
42 static WCHAR favoriteName[128];
43 static WCHAR searchString[128];
44 static int searchMask = SEARCH_KEYS | SEARCH_VALUES | SEARCH_CONTENT;
46 static WCHAR FileNameBuffer[_MAX_PATH];
47 static WCHAR FileTitleBuffer[_MAX_PATH];
48 static WCHAR FilterBuffer[_MAX_PATH];
50 /*******************************************************************************
51 * Local module support methods
54 static void resize_frame_rect(HWND hWnd, PRECT prect)
56 RECT rt;
58 if (IsWindowVisible(hToolBar)) {
59 SendMessageW(hToolBar, WM_SIZE, 0, 0);
60 GetClientRect(hToolBar, &rt);
61 prect->top = rt.bottom+3;
62 prect->bottom -= rt.bottom+3;
65 if (IsWindowVisible(hStatusBar)) {
66 SetupStatusBar(hWnd, TRUE);
67 GetClientRect(hStatusBar, &rt);
68 prect->bottom -= rt.bottom;
70 MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
73 static void resize_frame_client(HWND hWnd)
75 RECT rect;
77 GetClientRect(hWnd, &rect);
78 resize_frame_rect(hWnd, &rect);
81 /********************************************************************************/
83 static void OnEnterMenuLoop(HWND hWnd)
85 int nParts;
86 WCHAR empty = 0;
88 /* Update the status bar pane sizes */
89 nParts = -1;
90 SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
91 bInMenuLoop = TRUE;
92 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)&empty);
95 static void OnExitMenuLoop(HWND hWnd)
97 bInMenuLoop = FALSE;
98 /* Update the status bar pane sizes*/
99 SetupStatusBar(hWnd, TRUE);
100 UpdateStatusBar();
103 static void UpdateMenuItems(HMENU hMenu) {
104 HWND hwndTV = g_pChildWnd->hTreeWnd;
105 BOOL bAllowEdit = FALSE;
106 HKEY hRootKey = NULL;
107 LPWSTR keyName;
108 keyName = GetItemPath(hwndTV, TreeView_GetSelection(hwndTV), &hRootKey);
109 if (GetFocus() != hwndTV || (keyName && *keyName)) { /* can't modify root keys, but allow for their values */
110 bAllowEdit = TRUE;
112 EnableMenuItem(hMenu, ID_EDIT_FIND, MF_ENABLED | MF_BYCOMMAND);
113 EnableMenuItem(hMenu, ID_EDIT_FINDNEXT, MF_ENABLED | MF_BYCOMMAND);
114 EnableMenuItem(hMenu, ID_EDIT_MODIFY, (bAllowEdit ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
115 EnableMenuItem(hMenu, ID_EDIT_DELETE, (bAllowEdit ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
116 EnableMenuItem(hMenu, ID_EDIT_RENAME, (bAllowEdit ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
117 EnableMenuItem(hMenu, ID_FAVORITES_ADDTOFAVORITES, (hRootKey ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
118 EnableMenuItem(hMenu, ID_FAVORITES_REMOVEFAVORITE,
119 (GetMenuItemCount(hMenu)>2 ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
121 HeapFree(GetProcessHeap(), 0, keyName);
124 static void OnInitMenuPopup(HWND hWnd, HMENU hMenu, short wItem)
126 if (wItem == 3) {
127 HKEY hKey;
128 while(GetMenuItemCount(hMenu)>2)
129 DeleteMenu(hMenu, 2, MF_BYPOSITION);
130 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
131 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
132 WCHAR namebuf[KEY_MAX_LEN];
133 BYTE valuebuf[4096];
134 int i = 0;
135 BOOL sep = FALSE;
136 DWORD ksize, vsize, type;
137 LONG error;
138 do {
139 ksize = KEY_MAX_LEN;
140 vsize = sizeof(valuebuf);
141 error = RegEnumValueW(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
142 if (error != ERROR_SUCCESS)
143 break;
144 if (type == REG_SZ) {
145 if (!sep) {
146 AppendMenuW(hMenu, MF_SEPARATOR, -1, NULL);
147 sep = TRUE;
149 AppendMenuW(hMenu, MF_STRING, ID_FAVORITE_FIRST+i, namebuf);
151 i++;
152 } while(error == ERROR_SUCCESS);
153 RegCloseKey(hKey);
156 UpdateMenuItems(hMenu);
159 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
161 WCHAR str[100];
163 str[0] = 0;
164 if (nFlags & MF_POPUP) {
165 if (hSysMenu != GetMenu(hWnd)) {
166 if (nItemID == 2) nItemID = 5;
169 if (LoadStringW(hInst, nItemID, str, 100)) {
170 /* load appropriate string*/
171 LPWSTR lpsz = str;
172 /* first newline terminates actual string*/
173 lpsz = strchrW(lpsz, '\n');
174 if (lpsz != NULL)
175 *lpsz = '\0';
177 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)str);
180 void SetupStatusBar(HWND hWnd, BOOL bResize)
182 RECT rc;
183 int nParts;
184 GetClientRect(hWnd, &rc);
185 nParts = rc.right;
186 /* nParts = -1;*/
187 if (bResize)
188 SendMessageW(hStatusBar, WM_SIZE, 0, 0);
189 SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
190 UpdateStatusBar();
193 void UpdateStatusBar(void)
195 LPWSTR fullPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, TRUE);
196 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)fullPath);
197 HeapFree(GetProcessHeap(), 0, fullPath);
200 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
202 BOOL vis = IsWindowVisible(hchild);
203 HMENU hMenuView = GetSubMenu(hMenuFrame, ID_VIEW_MENU);
205 CheckMenuItem(hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
206 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
207 resize_frame_client(hWnd);
210 static BOOL CheckCommDlgError(HWND hWnd)
212 DWORD dwErrorCode = CommDlgExtendedError();
213 switch (dwErrorCode) {
214 case CDERR_DIALOGFAILURE:
215 break;
216 case CDERR_FINDRESFAILURE:
217 break;
218 case CDERR_NOHINSTANCE:
219 break;
220 case CDERR_INITIALIZATION:
221 break;
222 case CDERR_NOHOOK:
223 break;
224 case CDERR_LOCKRESFAILURE:
225 break;
226 case CDERR_NOTEMPLATE:
227 break;
228 case CDERR_LOADRESFAILURE:
229 break;
230 case CDERR_STRUCTSIZE:
231 break;
232 case CDERR_LOADSTRFAILURE:
233 break;
234 case FNERR_BUFFERTOOSMALL:
235 break;
236 case CDERR_MEMALLOCFAILURE:
237 break;
238 case FNERR_INVALIDFILENAME:
239 break;
240 case CDERR_MEMLOCKFAILURE:
241 break;
242 case FNERR_SUBCLASSFAILURE:
243 break;
244 default:
245 break;
247 return TRUE;
250 static void ExportRegistryFile_StoreSelection(HWND hdlg, OPENFILENAMEW *pOpenFileName)
252 if (IsDlgButtonChecked(hdlg, IDC_EXPORT_SELECTED))
254 INT len = SendDlgItemMessageW(hdlg, IDC_EXPORT_PATH, WM_GETTEXTLENGTH, 0, 0);
255 pOpenFileName->lCustData = (LPARAM)HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
256 SendDlgItemMessageW(hdlg, IDC_EXPORT_PATH, WM_GETTEXT, len+1, pOpenFileName->lCustData);
258 else
259 pOpenFileName->lCustData = (LPARAM)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR));
262 static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
264 static OPENFILENAMEW* pOpenFileName;
265 OFNOTIFYW *pOfNotify;
267 switch (uiMsg) {
268 case WM_INITDIALOG:
269 pOpenFileName = (OPENFILENAMEW*)lParam;
270 break;
271 case WM_COMMAND:
272 if (LOWORD(wParam) == IDC_EXPORT_PATH && HIWORD(wParam) == EN_UPDATE)
273 CheckRadioButton(hdlg, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, IDC_EXPORT_SELECTED);
274 break;
275 case WM_NOTIFY:
276 pOfNotify = (OFNOTIFYW*)lParam;
277 switch (pOfNotify->hdr.code)
279 case CDN_INITDONE:
281 BOOL export_branch = FALSE;
282 WCHAR* path = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
283 SendDlgItemMessageW(hdlg, IDC_EXPORT_PATH, WM_SETTEXT, 0, (LPARAM)path);
284 if (path && strlenW(path) > 0)
285 export_branch = TRUE;
286 HeapFree(GetProcessHeap(), 0, path);
287 CheckRadioButton(hdlg, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, export_branch ? IDC_EXPORT_SELECTED : IDC_EXPORT_ALL);
288 break;
290 case CDN_FILEOK:
291 ExportRegistryFile_StoreSelection(hdlg, pOpenFileName);
292 break;
294 break;
295 default:
296 break;
298 return 0L;
302 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAMEW *pofn)
304 memset(pofn, 0, sizeof(OPENFILENAMEW));
305 pofn->lStructSize = sizeof(OPENFILENAMEW);
306 pofn->hwndOwner = hWnd;
307 pofn->hInstance = hInst;
309 if (FilterBuffer[0] == 0)
310 LoadStringW(hInst, IDS_FILEDIALOG_FILTER, FilterBuffer, _MAX_PATH);
311 pofn->lpstrFilter = FilterBuffer;
312 pofn->nFilterIndex = 2;
313 pofn->lpstrFile = FileNameBuffer;
314 pofn->nMaxFile = _MAX_PATH;
315 pofn->lpstrFileTitle = FileTitleBuffer;
316 pofn->nMaxFileTitle = _MAX_PATH;
317 pofn->Flags = OFN_HIDEREADONLY;
318 /* some other fields may be set by the caller */
319 return TRUE;
322 static BOOL import_registry_filename(LPTSTR filename)
324 BOOL Success;
325 FILE* reg_file = fopen(filename, "r");
327 if(!reg_file)
328 return FALSE;
330 Success = import_registry_file(reg_file);
332 if(fclose(reg_file) != 0)
333 Success = FALSE;
335 return Success;
338 static BOOL ImportRegistryFile(HWND hWnd)
340 OPENFILENAMEW ofn;
341 WCHAR title[128];
343 InitOpenFileName(hWnd, &ofn);
344 ofn.Flags |= OFN_ENABLESIZING;
345 LoadStringW(hInst, IDS_FILEDIALOG_IMPORT_TITLE, title, COUNT_OF(title));
346 ofn.lpstrTitle = title;
347 if (GetOpenFileNameW(&ofn)) {
348 CHAR* fileA = GetMultiByteString(ofn.lpstrFile);
349 if (!import_registry_filename(fileA)) {
350 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
351 HeapFree(GetProcessHeap(), 0, fileA);
352 return FALSE;
354 HeapFree(GetProcessHeap(), 0, fileA);
355 } else {
356 CheckCommDlgError(hWnd);
358 RefreshTreeView(g_pChildWnd->hTreeWnd);
359 return TRUE;
363 static BOOL ExportRegistryFile(HWND hWnd)
365 OPENFILENAMEW ofn;
366 WCHAR title[128];
368 InitOpenFileName(hWnd, &ofn);
369 LoadStringW(hInst, IDS_FILEDIALOG_EXPORT_TITLE, title, COUNT_OF(title));
370 ofn.lpstrTitle = title;
371 ofn.Flags = OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
372 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
373 ofn.lpTemplateName = MAKEINTRESOURCEW(IDD_EXPORT_TEMPLATE);
374 if (GetSaveFileNameW(&ofn)) {
375 BOOL result;
376 result = export_registry_key(ofn.lpstrFile, (LPWSTR)ofn.lCustData, ofn.nFilterIndex);
377 if (!result) {
378 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
379 return FALSE;
381 } else {
382 CheckCommDlgError(hWnd);
384 return TRUE;
387 static BOOL PrintRegistryHive(HWND hWnd, LPCWSTR path)
389 #if 1
390 PRINTDLGW pd;
392 ZeroMemory(&pd, sizeof(PRINTDLG));
393 pd.lStructSize = sizeof(PRINTDLG);
394 pd.hwndOwner = hWnd;
395 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
396 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
397 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
398 pd.nCopies = 1;
399 pd.nFromPage = 0xFFFF;
400 pd.nToPage = 0xFFFF;
401 pd.nMinPage = 1;
402 pd.nMaxPage = 0xFFFF;
403 if (PrintDlgW(&pd)) {
404 /* GDI calls to render output. */
405 DeleteDC(pd.hDC); /* Delete DC when done.*/
407 #else
408 HRESULT hResult;
409 PRINTDLGEXW pd;
411 hResult = PrintDlgExW(&pd);
412 if (hResult == S_OK) {
413 switch (pd.dwResultAction) {
414 case PD_RESULT_APPLY:
415 /*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. */
416 break;
417 case PD_RESULT_CANCEL:
418 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
419 break;
420 case PD_RESULT_PRINT:
421 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
422 break;
423 default:
424 break;
426 } else {
427 switch (hResult) {
428 case E_OUTOFMEMORY:
429 /*Insufficient memory. */
430 break;
431 case E_INVALIDARG:
432 /* One or more arguments are invalid. */
433 break;
434 case E_POINTER:
435 /*Invalid pointer. */
436 break;
437 case E_HANDLE:
438 /*Invalid handle. */
439 break;
440 case E_FAIL:
441 /*Unspecified error. */
442 break;
443 default:
444 break;
446 return FALSE;
448 #endif
449 return TRUE;
452 static BOOL CopyKeyName(HWND hWnd, LPCWSTR keyName)
454 BOOL result;
456 result = OpenClipboard(hWnd);
457 if (result) {
458 result = EmptyClipboard();
459 if (result) {
460 int len = (lstrlenW(keyName)+1)*sizeof(WCHAR);
461 HANDLE hClipData = GlobalAlloc(GHND, len);
462 LPVOID pLoc = GlobalLock(hClipData);
463 lstrcpyW(pLoc, keyName);
464 GlobalUnlock(hClipData);
465 hClipData = SetClipboardData(CF_UNICODETEXT, hClipData);
467 } else {
468 /* error emptying clipboard*/
469 /* DWORD dwError = GetLastError(); */
472 if (!CloseClipboard()) {
473 /* error closing clipboard*/
474 /* DWORD dwError = GetLastError(); */
477 } else {
478 /* error opening clipboard*/
479 /* DWORD dwError = GetLastError(); */
482 return result;
485 static INT_PTR CALLBACK find_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
487 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
489 switch(uMsg) {
490 case WM_INITDIALOG:
491 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
492 CheckDlgButton(hwndDlg, IDC_FIND_KEYS, searchMask&SEARCH_KEYS ? BST_CHECKED : BST_UNCHECKED);
493 CheckDlgButton(hwndDlg, IDC_FIND_VALUES, searchMask&SEARCH_VALUES ? BST_CHECKED : BST_UNCHECKED);
494 CheckDlgButton(hwndDlg, IDC_FIND_CONTENT, searchMask&SEARCH_CONTENT ? BST_CHECKED : BST_UNCHECKED);
495 CheckDlgButton(hwndDlg, IDC_FIND_WHOLE, searchMask&SEARCH_WHOLE ? BST_CHECKED : BST_UNCHECKED);
496 SendMessageW(hwndValue, EM_SETLIMITTEXT, 127, 0);
497 SetWindowTextW(hwndValue, searchString);
498 return TRUE;
499 case WM_COMMAND:
500 switch(LOWORD(wParam)) {
501 case IDC_VALUE_NAME:
502 if (HIWORD(wParam) == EN_UPDATE) {
503 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLengthW(hwndValue)>0);
504 return TRUE;
506 break;
507 case IDOK:
508 if (GetWindowTextLengthW(hwndValue)>0) {
509 int mask = 0;
510 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_KEYS)) mask |= SEARCH_KEYS;
511 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_VALUES)) mask |= SEARCH_VALUES;
512 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_CONTENT)) mask |= SEARCH_CONTENT;
513 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_WHOLE)) mask |= SEARCH_WHOLE;
514 searchMask = mask;
515 GetWindowTextW(hwndValue, searchString, 128);
516 EndDialog(hwndDlg, IDOK);
518 return TRUE;
519 case IDCANCEL:
520 EndDialog(hwndDlg, IDCANCEL);
521 return TRUE;
523 break;
525 return FALSE;
528 static INT_PTR CALLBACK addtofavorites_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
530 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
532 switch(uMsg) {
533 case WM_INITDIALOG:
535 HKEY hKeyRoot = NULL;
536 LPWSTR ItemPath = GetItemPath(g_pChildWnd->hTreeWnd, NULL, &hKeyRoot);
538 if(!ItemPath || !*ItemPath)
539 ItemPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
540 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
541 SetWindowTextW(hwndValue, ItemPath);
542 SendMessageW(hwndValue, EM_SETLIMITTEXT, 127, 0);
543 HeapFree(GetProcessHeap(), 0, ItemPath);
544 return TRUE;
546 case WM_COMMAND:
547 switch(LOWORD(wParam)) {
548 case IDC_VALUE_NAME:
549 if (HIWORD(wParam) == EN_UPDATE) {
550 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLength(hwndValue)>0);
551 return TRUE;
553 break;
554 case IDOK:
555 if (GetWindowTextLengthW(hwndValue)>0) {
556 GetWindowTextW(hwndValue, favoriteName, 128);
557 EndDialog(hwndDlg, IDOK);
559 return TRUE;
560 case IDCANCEL:
561 EndDialog(hwndDlg, IDCANCEL);
562 return TRUE;
564 break;
566 return FALSE;
569 static INT_PTR CALLBACK removefavorite_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
571 HWND hwndList = GetDlgItem(hwndDlg, IDC_NAME_LIST);
573 switch(uMsg) {
574 case WM_INITDIALOG: {
575 HKEY hKey;
576 int i = 0;
577 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
578 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
579 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
580 WCHAR namebuf[KEY_MAX_LEN];
581 BYTE valuebuf[4096];
582 DWORD ksize, vsize, type;
583 LONG error;
584 do {
585 ksize = KEY_MAX_LEN;
586 vsize = sizeof(valuebuf);
587 error = RegEnumValueW(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
588 if (error != ERROR_SUCCESS)
589 break;
590 if (type == REG_SZ) {
591 SendMessageW(hwndList, LB_ADDSTRING, 0, (LPARAM)namebuf);
593 i++;
594 } while(error == ERROR_SUCCESS);
595 RegCloseKey(hKey);
597 else
598 return FALSE;
599 EnableWindow(GetDlgItem(hwndDlg, IDOK), i != 0);
600 SendMessageW(hwndList, LB_SETCURSEL, 0, 0);
601 return TRUE;
603 case WM_COMMAND:
604 switch(LOWORD(wParam)) {
605 case IDC_NAME_LIST:
606 if (HIWORD(wParam) == LBN_SELCHANGE) {
607 EnableWindow(GetDlgItem(hwndDlg, IDOK), lParam != -1);
608 return TRUE;
610 break;
611 case IDOK: {
612 int pos = SendMessageW(hwndList, LB_GETCURSEL, 0, 0);
613 int len = SendMessageW(hwndList, LB_GETTEXTLEN, pos, 0);
614 if (len>0) {
615 LPWSTR lpName = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
616 SendMessageW(hwndList, LB_GETTEXT, pos, (LPARAM)lpName);
617 if (len>127)
618 lpName[127] = '\0';
619 lstrcpyW(favoriteName, lpName);
620 EndDialog(hwndDlg, IDOK);
621 HeapFree(GetProcessHeap(), 0, lpName);
623 return TRUE;
625 case IDCANCEL:
626 EndDialog(hwndDlg, IDCANCEL);
627 return TRUE;
629 break;
631 return FALSE;
634 /*******************************************************************************
636 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
638 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
641 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
643 HKEY hKeyRoot = 0;
644 DWORD valueType;
645 int curIndex;
646 BOOL firstItem = TRUE;
648 if (LOWORD(wParam) >= ID_FAVORITE_FIRST && LOWORD(wParam) <= ID_FAVORITE_LAST) {
649 HKEY hKey;
650 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
651 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
652 WCHAR namebuf[KEY_MAX_LEN];
653 BYTE valuebuf[4096];
654 DWORD ksize = KEY_MAX_LEN, vsize = sizeof(valuebuf), type = 0;
655 if (RegEnumValueW(hKey, LOWORD(wParam) - ID_FAVORITE_FIRST, namebuf, &ksize, NULL,
656 &type, valuebuf, &vsize) == ERROR_SUCCESS) {
657 SendMessageW( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET,
658 (LPARAM) FindPathInTree(g_pChildWnd->hTreeWnd, (WCHAR *)valuebuf) );
660 RegCloseKey(hKey);
662 return TRUE;
664 switch (LOWORD(wParam)) {
665 case ID_REGISTRY_IMPORTREGISTRYFILE:
666 ImportRegistryFile(hWnd);
667 break;
668 case ID_EDIT_EXPORT:
669 case ID_REGISTRY_EXPORTREGISTRYFILE:
670 ExportRegistryFile(hWnd);
671 break;
672 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
673 break;
674 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
675 break;
676 case ID_REGISTRY_PRINT:
678 const WCHAR empty = 0;
679 PrintRegistryHive(hWnd, &empty);
680 break;
682 case ID_EDIT_DELETE:
684 HWND hWndDelete = GetFocus();
685 if (hWndDelete == g_pChildWnd->hTreeWnd) {
686 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
687 if (keyPath == 0 || *keyPath == 0) {
688 MessageBeep(MB_ICONHAND);
689 } else if (DeleteKey(hWnd, hKeyRoot, keyPath)) {
690 DeleteNode(g_pChildWnd->hTreeWnd, 0);
692 HeapFree(GetProcessHeap(), 0, keyPath);
693 } else if (hWndDelete == g_pChildWnd->hListWnd) {
694 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
695 curIndex = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
696 while(curIndex != -1) {
697 WCHAR* valueName = GetItemText(g_pChildWnd->hListWnd, curIndex);
699 curIndex = ListView_GetNextItem(g_pChildWnd->hListWnd, curIndex, LVNI_SELECTED);
700 if(curIndex != -1 && firstItem) {
701 if (MessageBoxW(hWnd, MAKEINTRESOURCEW(IDS_DELETE_BOX_TEXT_MULTIPLE),
702 MAKEINTRESOURCEW(IDS_DELETE_BOX_TITLE),
703 MB_YESNO | MB_ICONEXCLAMATION) != IDYES)
704 break;
707 if (!DeleteValue(hWnd, hKeyRoot, keyPath, valueName, curIndex==-1 && firstItem))
709 HeapFree(GetProcessHeap(), 0, valueName);
710 break;
712 firstItem = FALSE;
713 HeapFree(GetProcessHeap(), 0, valueName);
715 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
716 HeapFree(GetProcessHeap(), 0, keyPath);
717 } else if (IsChild(g_pChildWnd->hTreeWnd, hWndDelete) ||
718 IsChild(g_pChildWnd->hListWnd, hWndDelete)) {
719 SendMessage(hWndDelete, WM_KEYDOWN, VK_DELETE, 0);
721 break;
723 case ID_EDIT_MODIFY:
725 LPCWSTR valueName = GetValueName(g_pChildWnd->hListWnd);
726 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
727 if (ModifyValue(hWnd, hKeyRoot, keyPath, valueName))
728 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, valueName);
729 HeapFree(GetProcessHeap(), 0, keyPath);
730 break;
732 case ID_EDIT_FIND:
733 case ID_EDIT_FINDNEXT:
735 HTREEITEM hItem;
736 if (LOWORD(wParam) == ID_EDIT_FIND &&
737 DialogBox(0, MAKEINTRESOURCE(IDD_FIND), hWnd, find_dlgproc) != IDOK)
738 break;
739 if (!*searchString)
740 break;
741 hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
742 if (hItem) {
743 int row = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_FOCUSED);
744 HCURSOR hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
745 hItem = FindNext(g_pChildWnd->hTreeWnd, hItem, searchString, searchMask, &row);
746 SetCursor(hcursorOld);
747 if (hItem) {
748 SendMessageW( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM) hItem );
749 InvalidateRect(g_pChildWnd->hTreeWnd, NULL, TRUE);
750 UpdateWindow(g_pChildWnd->hTreeWnd);
751 if (row != -1) {
752 ListView_SetItemState(g_pChildWnd->hListWnd, -1, 0, LVIS_FOCUSED|LVIS_SELECTED);
753 ListView_SetItemState(g_pChildWnd->hListWnd, row, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
754 SetFocus(g_pChildWnd->hListWnd);
755 } else {
756 SetFocus(g_pChildWnd->hTreeWnd);
758 } else {
759 error(hWnd, IDS_NOTFOUND, searchString);
762 break;
764 case ID_EDIT_COPYKEYNAME:
766 LPWSTR fullPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
767 if (fullPath) {
768 CopyKeyName(hWnd, fullPath);
769 HeapFree(GetProcessHeap(), 0, fullPath);
771 break;
773 case ID_EDIT_NEW_KEY:
775 WCHAR newKeyW[MAX_NEW_KEY_LEN];
776 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
777 if (CreateKey(hWnd, hKeyRoot, keyPath, newKeyW)) {
778 if (InsertNode(g_pChildWnd->hTreeWnd, 0, newKeyW))
779 StartKeyRename(g_pChildWnd->hTreeWnd);
781 HeapFree(GetProcessHeap(), 0, keyPath);
783 break;
784 case ID_EDIT_NEW_STRINGVALUE:
785 valueType = REG_SZ;
786 goto create_value;
787 case ID_EDIT_NEW_MULTI_STRINGVALUE:
788 valueType = REG_MULTI_SZ;
789 goto create_value;
790 case ID_EDIT_NEW_BINARYVALUE:
791 valueType = REG_BINARY;
792 goto create_value;
793 case ID_EDIT_NEW_DWORDVALUE:
794 valueType = REG_DWORD;
795 /* fall through */
796 create_value:
798 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
799 WCHAR newKey[MAX_NEW_KEY_LEN];
800 if (CreateValue(hWnd, hKeyRoot, keyPath, valueType, newKey)) {
801 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, newKey);
802 StartValueRename(g_pChildWnd->hListWnd);
804 HeapFree(GetProcessHeap(), 0, keyPath);
806 break;
807 case ID_EDIT_RENAME:
809 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
810 if (keyPath == 0 || *keyPath == 0) {
811 MessageBeep(MB_ICONHAND);
812 } else if (GetFocus() == g_pChildWnd->hTreeWnd) {
813 StartKeyRename(g_pChildWnd->hTreeWnd);
814 } else if (GetFocus() == g_pChildWnd->hListWnd) {
815 StartValueRename(g_pChildWnd->hListWnd);
817 HeapFree(GetProcessHeap(), 0, keyPath);
819 break;
820 case ID_REGISTRY_PRINTERSETUP:
821 /*PRINTDLG pd;*/
822 /*PrintDlg(&pd);*/
823 /*PAGESETUPDLG psd;*/
824 /*PageSetupDlg(&psd);*/
825 break;
826 case ID_REGISTRY_OPENLOCAL:
827 break;
828 case ID_REGISTRY_EXIT:
829 DestroyWindow(hWnd);
830 break;
831 case ID_FAVORITES_ADDTOFAVORITES:
833 HKEY hKey;
834 LPWSTR lpKeyPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
835 if (lpKeyPath) {
836 if (DialogBox(0, MAKEINTRESOURCE(IDD_ADDFAVORITE), hWnd, addtofavorites_dlgproc) == IDOK) {
837 if (RegCreateKeyExW(HKEY_CURRENT_USER, favoritesKey,
838 0, NULL, 0,
839 KEY_READ|KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) {
840 RegSetValueExW(hKey, favoriteName, 0, REG_SZ, (BYTE *)lpKeyPath, (lstrlenW(lpKeyPath)+1)*sizeof(WCHAR));
841 RegCloseKey(hKey);
844 HeapFree(GetProcessHeap(), 0, lpKeyPath);
846 break;
848 case ID_FAVORITES_REMOVEFAVORITE:
850 if (DialogBox(0, MAKEINTRESOURCE(IDD_DELFAVORITE), hWnd, removefavorite_dlgproc) == IDOK) {
851 HKEY hKey;
852 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
853 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS) {
854 RegDeleteValueW(hKey, favoriteName);
855 RegCloseKey(hKey);
858 break;
860 case ID_VIEW_REFRESH:
862 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
863 RefreshTreeView(g_pChildWnd->hTreeWnd);
864 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
865 HeapFree(GetProcessHeap(), 0, keyPath);
867 break;
868 /*case ID_OPTIONS_TOOLBAR:*/
869 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
870 /* break;*/
871 case ID_VIEW_STATUSBAR:
872 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
873 break;
874 case ID_HELP_HELPTOPICS:
876 const WCHAR help_regedit[] = {'r','e','g','e','d','i','t',0};
877 WinHelpW(hWnd, help_regedit, HELP_FINDER, 0);
878 break;
880 case ID_HELP_ABOUT:
881 ShowAboutBox(hWnd);
882 break;
883 case ID_VIEW_SPLIT: {
884 RECT rt;
885 POINT pt, pts;
886 GetClientRect(g_pChildWnd->hWnd, &rt);
887 pt.x = rt.left + g_pChildWnd->nSplitPos;
888 pt.y = (rt.bottom / 2);
889 pts = pt;
890 if(ClientToScreen(g_pChildWnd->hWnd, &pts)) {
891 SetCursorPos(pts.x, pts.y);
892 SetCursor(LoadCursor(0, IDC_SIZEWE));
893 SendMessageW(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
895 return TRUE;
897 default:
898 return FALSE;
901 return TRUE;
904 /********************************************************************************
906 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
908 * PURPOSE: Processes messages for the main frame window.
910 * WM_COMMAND - process the application menu
911 * WM_DESTROY - post a quit message and return
915 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
917 switch (message) {
918 case WM_CREATE:
919 CreateWindowEx(0, szChildClass, _T("regedit child window"), WS_CHILD | WS_VISIBLE,
920 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
921 hWnd, NULL, hInst, 0);
922 break;
923 case WM_COMMAND:
924 if (!_CmdWndProc(hWnd, message, wParam, lParam))
925 return DefWindowProc(hWnd, message, wParam, lParam);
926 break;
927 case WM_ACTIVATE:
928 if (LOWORD(hWnd))
929 SetFocus(g_pChildWnd->hWnd);
930 break;
931 case WM_SIZE:
932 resize_frame_client(hWnd);
933 break;
934 case WM_TIMER:
935 break;
936 case WM_ENTERMENULOOP:
937 OnEnterMenuLoop(hWnd);
938 break;
939 case WM_EXITMENULOOP:
940 OnExitMenuLoop(hWnd);
941 break;
942 case WM_INITMENUPOPUP:
943 if (!HIWORD(lParam))
944 OnInitMenuPopup(hWnd, (HMENU)wParam, LOWORD(lParam));
945 break;
946 case WM_MENUSELECT:
947 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
948 break;
949 case WM_DESTROY:
951 const WCHAR help_regedit[] = {'r','e','g','e','d','i','t',0};
952 WinHelpW(hWnd, help_regedit, HELP_QUIT, 0);
953 PostQuitMessage(0);
955 default:
956 return DefWindowProc(hWnd, message, wParam, lParam);
958 return 0;