regedit: Remove some ANSI functions.
[wine/multimedia.git] / programs / regedit / framewnd.c
blobb0631b7f985437f5ee69505c27ccd7b80c73d2b9
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 TCHAR FileNameBuffer[_MAX_PATH];
47 static TCHAR FileTitleBuffer[_MAX_PATH];
48 static TCHAR 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 SendMessage(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, (long)&nParts);
91 bInMenuLoop = TRUE;
92 SendMessageW(hStatusBar, SB_SETTEXTW, (WPARAM)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, OPENFILENAME *pOpenFileName)
252 if (IsDlgButtonChecked(hdlg, IDC_EXPORT_SELECTED))
254 INT len = SendDlgItemMessage(hdlg, IDC_EXPORT_PATH, WM_GETTEXTLENGTH, 0, 0);
255 pOpenFileName->lCustData = (LPARAM)HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(TCHAR));
256 SendDlgItemMessage(hdlg, IDC_EXPORT_PATH, WM_GETTEXT, len+1, pOpenFileName->lCustData);
258 else
259 pOpenFileName->lCustData = (LPARAM)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TCHAR));
262 static UINT CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
264 static OPENFILENAME* pOpenFileName;
265 OFNOTIFY *pOfNotify;
267 switch (uiMsg) {
268 case WM_INITDIALOG:
269 pOpenFileName = (OPENFILENAME*)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 = (OFNOTIFY*)lParam;
277 switch (pOfNotify->hdr.code)
279 case CDN_INITDONE:
281 WCHAR* pathW = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
282 CHAR* pathA = GetMultiByteString(pathW);
283 SendDlgItemMessage(hdlg, IDC_EXPORT_PATH, WM_SETTEXT, 0, (LPARAM)pathA);
284 HeapFree(GetProcessHeap(), 0, pathW);
285 HeapFree(GetProcessHeap(), 0, pathA);
286 CheckRadioButton(hdlg, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, pOpenFileName->lCustData ? IDC_EXPORT_SELECTED : IDC_EXPORT_ALL);
287 break;
289 case CDN_FILEOK:
290 ExportRegistryFile_StoreSelection(hdlg, pOpenFileName);
291 break;
293 break;
294 default:
295 break;
297 return 0L;
301 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME *pofn)
303 memset(pofn, 0, sizeof(OPENFILENAME));
304 pofn->lStructSize = sizeof(OPENFILENAME);
305 pofn->hwndOwner = hWnd;
306 pofn->hInstance = hInst;
308 if (FilterBuffer[0] == 0)
309 LoadString(hInst, IDS_FILEDIALOG_FILTER, FilterBuffer, _MAX_PATH);
310 pofn->lpstrFilter = FilterBuffer;
311 pofn->nFilterIndex = 1;
312 pofn->lpstrFile = FileNameBuffer;
313 pofn->nMaxFile = _MAX_PATH;
314 pofn->lpstrFileTitle = FileTitleBuffer;
315 pofn->nMaxFileTitle = _MAX_PATH;
316 pofn->Flags = OFN_HIDEREADONLY;
317 /* some other fields may be set by the caller */
318 return TRUE;
321 static BOOL import_registry_filename(LPTSTR filename)
323 BOOL Success;
324 FILE* reg_file = fopen(filename, "r");
326 if(!reg_file)
327 return FALSE;
329 Success = import_registry_file(reg_file);
331 if(fclose(reg_file) != 0)
332 Success = FALSE;
334 return Success;
337 static BOOL ImportRegistryFile(HWND hWnd)
339 OPENFILENAME ofn;
340 TCHAR title[128];
342 InitOpenFileName(hWnd, &ofn);
343 LoadString(hInst, IDS_FILEDIALOG_IMPORT_TITLE, title, COUNT_OF(title));
344 ofn.lpstrTitle = title;
345 if (GetOpenFileName(&ofn)) {
346 if (!import_registry_filename(ofn.lpstrFile)) {
347 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
348 return FALSE;
350 } else {
351 CheckCommDlgError(hWnd);
353 RefreshTreeView(g_pChildWnd->hTreeWnd);
354 return TRUE;
358 static BOOL ExportRegistryFile(HWND hWnd, BOOL export_branch)
360 OPENFILENAME ofn;
361 TCHAR ExportKeyPath[_MAX_PATH];
362 TCHAR title[128];
364 ExportKeyPath[0] = _T('\0');
365 InitOpenFileName(hWnd, &ofn);
366 LoadString(hInst, IDS_FILEDIALOG_EXPORT_TITLE, title, COUNT_OF(title));
367 ofn.lpstrTitle = title;
368 ofn.lCustData = export_branch;
369 ofn.Flags = OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
370 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
371 ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORT_TEMPLATE);
372 if (GetSaveFileName(&ofn)) {
373 BOOL result;
374 result = export_registry_key(ofn.lpstrFile, (LPTSTR)ofn.lCustData);
375 if (!result) {
376 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
377 return FALSE;
379 } else {
380 CheckCommDlgError(hWnd);
382 return TRUE;
385 static BOOL PrintRegistryHive(HWND hWnd, LPCWSTR path)
387 #if 1
388 PRINTDLGW pd;
390 ZeroMemory(&pd, sizeof(PRINTDLG));
391 pd.lStructSize = sizeof(PRINTDLG);
392 pd.hwndOwner = hWnd;
393 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
394 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
395 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
396 pd.nCopies = 1;
397 pd.nFromPage = 0xFFFF;
398 pd.nToPage = 0xFFFF;
399 pd.nMinPage = 1;
400 pd.nMaxPage = 0xFFFF;
401 if (PrintDlgW(&pd)) {
402 /* GDI calls to render output. */
403 DeleteDC(pd.hDC); /* Delete DC when done.*/
405 #else
406 HRESULT hResult;
407 PRINTDLGEXW pd;
409 hResult = PrintDlgExW(&pd);
410 if (hResult == S_OK) {
411 switch (pd.dwResultAction) {
412 case PD_RESULT_APPLY:
413 /*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. */
414 break;
415 case PD_RESULT_CANCEL:
416 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
417 break;
418 case PD_RESULT_PRINT:
419 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
420 break;
421 default:
422 break;
424 } else {
425 switch (hResult) {
426 case E_OUTOFMEMORY:
427 /*Insufficient memory. */
428 break;
429 case E_INVALIDARG:
430 /* One or more arguments are invalid. */
431 break;
432 case E_POINTER:
433 /*Invalid pointer. */
434 break;
435 case E_HANDLE:
436 /*Invalid handle. */
437 break;
438 case E_FAIL:
439 /*Unspecified error. */
440 break;
441 default:
442 break;
444 return FALSE;
446 #endif
447 return TRUE;
450 static BOOL CopyKeyName(HWND hWnd, LPCWSTR keyName)
452 BOOL result;
454 result = OpenClipboard(hWnd);
455 if (result) {
456 result = EmptyClipboard();
457 if (result) {
458 int len = (lstrlenW(keyName)+1)*sizeof(WCHAR);
459 HANDLE hClipData = GlobalAlloc(GHND, len);
460 LPVOID pLoc = GlobalLock(hClipData);
461 lstrcpyW(pLoc, keyName);
462 GlobalUnlock(hClipData);
463 hClipData = SetClipboardData(CF_UNICODETEXT, hClipData);
465 } else {
466 /* error emptying clipboard*/
467 /* DWORD dwError = GetLastError(); */
470 if (!CloseClipboard()) {
471 /* error closing clipboard*/
472 /* DWORD dwError = GetLastError(); */
475 } else {
476 /* error opening clipboard*/
477 /* DWORD dwError = GetLastError(); */
480 return result;
483 static INT_PTR CALLBACK find_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
485 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
487 switch(uMsg) {
488 case WM_INITDIALOG:
489 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
490 CheckDlgButton(hwndDlg, IDC_FIND_KEYS, searchMask&SEARCH_KEYS ? BST_CHECKED : BST_UNCHECKED);
491 CheckDlgButton(hwndDlg, IDC_FIND_VALUES, searchMask&SEARCH_VALUES ? BST_CHECKED : BST_UNCHECKED);
492 CheckDlgButton(hwndDlg, IDC_FIND_CONTENT, searchMask&SEARCH_CONTENT ? BST_CHECKED : BST_UNCHECKED);
493 CheckDlgButton(hwndDlg, IDC_FIND_WHOLE, searchMask&SEARCH_WHOLE ? BST_CHECKED : BST_UNCHECKED);
494 SendMessageW(hwndValue, EM_SETLIMITTEXT, 127, 0);
495 SetWindowTextW(hwndValue, searchString);
496 return TRUE;
497 case WM_COMMAND:
498 switch(LOWORD(wParam)) {
499 case IDC_VALUE_NAME:
500 if (HIWORD(wParam) == EN_UPDATE) {
501 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLengthW(hwndValue)>0);
502 return TRUE;
504 break;
505 case IDOK:
506 if (GetWindowTextLengthW(hwndValue)>0) {
507 int mask = 0;
508 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_KEYS)) mask |= SEARCH_KEYS;
509 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_VALUES)) mask |= SEARCH_VALUES;
510 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_CONTENT)) mask |= SEARCH_CONTENT;
511 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_WHOLE)) mask |= SEARCH_WHOLE;
512 searchMask = mask;
513 GetWindowTextW(hwndValue, searchString, 128);
514 EndDialog(hwndDlg, IDOK);
516 return TRUE;
517 case IDCANCEL:
518 EndDialog(hwndDlg, IDCANCEL);
519 return TRUE;
521 break;
523 return FALSE;
526 static INT_PTR CALLBACK addtofavorites_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
528 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
530 switch(uMsg) {
531 case WM_INITDIALOG:
533 HKEY hKeyRoot = NULL;
534 LPWSTR ItemPath = GetItemPath(g_pChildWnd->hTreeWnd, NULL, &hKeyRoot);
536 if(!ItemPath || !*ItemPath)
537 ItemPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
538 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
539 SetWindowTextW(hwndValue, ItemPath);
540 SendMessageW(hwndValue, EM_SETLIMITTEXT, 127, 0);
541 HeapFree(GetProcessHeap(), 0, ItemPath);
542 return TRUE;
544 case WM_COMMAND:
545 switch(LOWORD(wParam)) {
546 case IDC_VALUE_NAME:
547 if (HIWORD(wParam) == EN_UPDATE) {
548 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLength(hwndValue)>0);
549 return TRUE;
551 break;
552 case IDOK:
553 if (GetWindowTextLengthW(hwndValue)>0) {
554 GetWindowTextW(hwndValue, favoriteName, 128);
555 EndDialog(hwndDlg, IDOK);
557 return TRUE;
558 case IDCANCEL:
559 EndDialog(hwndDlg, IDCANCEL);
560 return TRUE;
562 break;
564 return FALSE;
567 static INT_PTR CALLBACK removefavorite_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
569 HWND hwndList = GetDlgItem(hwndDlg, IDC_NAME_LIST);
571 switch(uMsg) {
572 case WM_INITDIALOG: {
573 HKEY hKey;
574 int i = 0;
575 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
576 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
577 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
578 WCHAR namebuf[KEY_MAX_LEN];
579 BYTE valuebuf[4096];
580 DWORD ksize, vsize, type;
581 LONG error;
582 do {
583 ksize = KEY_MAX_LEN;
584 vsize = sizeof(valuebuf);
585 error = RegEnumValueW(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
586 if (error != ERROR_SUCCESS)
587 break;
588 if (type == REG_SZ) {
589 SendMessageW(hwndList, LB_ADDSTRING, 0, (LPARAM)namebuf);
591 i++;
592 } while(error == ERROR_SUCCESS);
593 RegCloseKey(hKey);
595 else
596 return FALSE;
597 EnableWindow(GetDlgItem(hwndDlg, IDOK), i != 0);
598 SendMessageW(hwndList, LB_SETCURSEL, 0, 0);
599 return TRUE;
601 case WM_COMMAND:
602 switch(LOWORD(wParam)) {
603 case IDC_NAME_LIST:
604 if (HIWORD(wParam) == LBN_SELCHANGE) {
605 EnableWindow(GetDlgItem(hwndDlg, IDOK), lParam != -1);
606 return TRUE;
608 break;
609 case IDOK: {
610 int pos = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
611 int len = SendMessage(hwndList, LB_GETTEXTLEN, pos, 0);
612 if (len>0) {
613 LPWSTR lpName = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
614 SendMessageW(hwndList, LB_GETTEXT, pos, (LPARAM)lpName);
615 if (len>127)
616 lpName[127] = '\0';
617 lstrcpyW(favoriteName, lpName);
618 EndDialog(hwndDlg, IDOK);
619 HeapFree(GetProcessHeap(), 0, lpName);
621 return TRUE;
623 case IDCANCEL:
624 EndDialog(hwndDlg, IDCANCEL);
625 return TRUE;
627 break;
629 return FALSE;
632 /*******************************************************************************
634 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
636 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
639 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
641 HKEY hKeyRoot = 0;
642 LPCTSTR valueName;
643 DWORD valueType;
644 int curIndex;
645 BOOL firstItem = TRUE;
647 if (LOWORD(wParam) >= ID_FAVORITE_FIRST && LOWORD(wParam) <= ID_FAVORITE_LAST) {
648 HKEY hKey;
649 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
650 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
651 WCHAR namebuf[KEY_MAX_LEN];
652 BYTE valuebuf[4096];
653 DWORD ksize = KEY_MAX_LEN, vsize = sizeof(valuebuf), type = 0;
654 if (RegEnumValueW(hKey, LOWORD(wParam) - ID_FAVORITE_FIRST, namebuf, &ksize, NULL,
655 &type, valuebuf, &vsize) == ERROR_SUCCESS) {
656 SendMessageW( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET,
657 (LPARAM) FindPathInTree(g_pChildWnd->hTreeWnd, (WCHAR *)valuebuf) );
659 RegCloseKey(hKey);
661 return TRUE;
663 switch (LOWORD(wParam)) {
664 case ID_REGISTRY_IMPORTREGISTRYFILE:
665 ImportRegistryFile(hWnd);
666 break;
667 case ID_EDIT_EXPORT:
668 ExportRegistryFile(hWnd, TRUE);
669 break;
670 case ID_REGISTRY_EXPORTREGISTRYFILE:
671 ExportRegistryFile(hWnd, FALSE);
672 break;
673 case ID_REGISTRY_CONNECTNETWORKREGISTRY:
674 break;
675 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
676 break;
677 case ID_REGISTRY_PRINT:
679 const WCHAR empty = 0;
680 PrintRegistryHive(hWnd, &empty);
681 break;
683 case ID_EDIT_DELETE:
684 if (GetFocus() == g_pChildWnd->hTreeWnd) {
685 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
686 if (keyPath == 0 || *keyPath == 0) {
687 MessageBeep(MB_ICONHAND);
688 } else if (DeleteKey(hWnd, hKeyRoot, keyPath)) {
689 DeleteNode(g_pChildWnd->hTreeWnd, 0);
691 HeapFree(GetProcessHeap(), 0, keyPath);
692 } else if (GetFocus() == g_pChildWnd->hListWnd) {
693 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
694 curIndex = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
695 while(curIndex != -1) {
696 WCHAR* valueNameW;
698 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;
706 valueNameW = GetWideString(valueName);
707 if (!DeleteValue(hWnd, hKeyRoot, keyPath, valueNameW, curIndex==-1 && firstItem))
709 HeapFree(GetProcessHeap(), 0, valueNameW);
710 break;
712 firstItem = FALSE;
713 HeapFree(GetProcessHeap(), 0, valueNameW);
715 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
716 HeapFree(GetProcessHeap(), 0, keyPath);
718 break;
719 case ID_EDIT_MODIFY:
721 LPCWSTR valueName = GetValueName(g_pChildWnd->hListWnd);
722 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
723 if (ModifyValue(hWnd, hKeyRoot, keyPath, valueName))
724 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, valueName);
725 HeapFree(GetProcessHeap(), 0, keyPath);
726 break;
728 case ID_EDIT_FIND:
729 case ID_EDIT_FINDNEXT:
731 HTREEITEM hItem;
732 if (LOWORD(wParam) == ID_EDIT_FIND &&
733 DialogBox(0, MAKEINTRESOURCE(IDD_FIND), hWnd, find_dlgproc) != IDOK)
734 break;
735 if (!*searchString)
736 break;
737 hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd);
738 if (hItem) {
739 int row = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_FOCUSED);
740 HCURSOR hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
741 hItem = FindNext(g_pChildWnd->hTreeWnd, hItem, searchString, searchMask, &row);
742 SetCursor(hcursorOld);
743 if (hItem) {
744 SendMessage( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM) hItem );
745 InvalidateRect(g_pChildWnd->hTreeWnd, NULL, TRUE);
746 UpdateWindow(g_pChildWnd->hTreeWnd);
747 if (row != -1) {
748 ListView_SetItemState(g_pChildWnd->hListWnd, -1, 0, LVIS_FOCUSED|LVIS_SELECTED);
749 ListView_SetItemState(g_pChildWnd->hListWnd, row, LVIS_FOCUSED|LVIS_SELECTED, LVIS_FOCUSED|LVIS_SELECTED);
750 SetFocus(g_pChildWnd->hListWnd);
751 } else {
752 SetFocus(g_pChildWnd->hTreeWnd);
754 } else {
755 CHAR* searchStringA = GetMultiByteString(searchString);
756 error(hWnd, IDS_NOTFOUND, searchStringA);
757 HeapFree(GetProcessHeap(), 0, searchStringA);
760 break;
762 case ID_EDIT_COPYKEYNAME:
764 LPWSTR fullPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
765 if (fullPath) {
766 CopyKeyName(hWnd, fullPath);
767 HeapFree(GetProcessHeap(), 0, fullPath);
769 break;
771 case ID_EDIT_NEW_KEY:
773 WCHAR newKeyW[MAX_NEW_KEY_LEN];
774 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
775 if (CreateKey(hWnd, hKeyRoot, keyPath, newKeyW)) {
776 if (InsertNode(g_pChildWnd->hTreeWnd, 0, newKeyW))
777 StartKeyRename(g_pChildWnd->hTreeWnd);
779 HeapFree(GetProcessHeap(), 0, keyPath);
781 break;
782 case ID_EDIT_NEW_STRINGVALUE:
783 valueType = REG_SZ;
784 goto create_value;
785 case ID_EDIT_NEW_MULTI_STRINGVALUE:
786 valueType = REG_MULTI_SZ;
787 goto create_value;
788 case ID_EDIT_NEW_BINARYVALUE:
789 valueType = REG_BINARY;
790 goto create_value;
791 case ID_EDIT_NEW_DWORDVALUE:
792 valueType = REG_DWORD;
793 /* fall through */
794 create_value:
796 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
797 WCHAR newKey[MAX_NEW_KEY_LEN];
798 if (CreateValue(hWnd, hKeyRoot, keyPath, valueType, newKey)) {
799 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, newKey);
800 StartValueRename(g_pChildWnd->hListWnd);
802 HeapFree(GetProcessHeap(), 0, keyPath);
804 break;
805 case ID_EDIT_RENAME:
807 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
808 if (keyPath == 0 || *keyPath == 0) {
809 MessageBeep(MB_ICONHAND);
810 } else if (GetFocus() == g_pChildWnd->hTreeWnd) {
811 StartKeyRename(g_pChildWnd->hTreeWnd);
812 } else if (GetFocus() == g_pChildWnd->hListWnd) {
813 StartValueRename(g_pChildWnd->hListWnd);
815 HeapFree(GetProcessHeap(), 0, keyPath);
817 break;
818 case ID_REGISTRY_PRINTERSETUP:
819 /*PRINTDLG pd;*/
820 /*PrintDlg(&pd);*/
821 /*PAGESETUPDLG psd;*/
822 /*PageSetupDlg(&psd);*/
823 break;
824 case ID_REGISTRY_OPENLOCAL:
825 break;
826 case ID_REGISTRY_EXIT:
827 DestroyWindow(hWnd);
828 break;
829 case ID_FAVORITES_ADDTOFAVORITES:
831 HKEY hKey;
832 LPWSTR lpKeyPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
833 if (lpKeyPath) {
834 if (DialogBox(0, MAKEINTRESOURCE(IDD_ADDFAVORITE), hWnd, addtofavorites_dlgproc) == IDOK) {
835 if (RegCreateKeyExW(HKEY_CURRENT_USER, favoritesKey,
836 0, NULL, 0,
837 KEY_READ|KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) {
838 RegSetValueExW(hKey, favoriteName, 0, REG_SZ, (BYTE *)lpKeyPath, (lstrlenW(lpKeyPath)+1)*sizeof(WCHAR));
839 RegCloseKey(hKey);
842 HeapFree(GetProcessHeap(), 0, lpKeyPath);
844 break;
846 case ID_FAVORITES_REMOVEFAVORITE:
848 if (DialogBox(0, MAKEINTRESOURCE(IDD_DELFAVORITE), hWnd, removefavorite_dlgproc) == IDOK) {
849 HKEY hKey;
850 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
851 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS) {
852 RegDeleteValueW(hKey, favoriteName);
853 RegCloseKey(hKey);
856 break;
858 case ID_VIEW_REFRESH:
860 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
861 RefreshTreeView(g_pChildWnd->hTreeWnd);
862 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
863 HeapFree(GetProcessHeap(), 0, keyPath);
865 break;
866 /*case ID_OPTIONS_TOOLBAR:*/
867 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
868 /* break;*/
869 case ID_VIEW_STATUSBAR:
870 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
871 break;
872 case ID_HELP_HELPTOPICS:
874 const WCHAR help_regedit[] = {'r','e','g','e','d','i','t',0};
875 WinHelpW(hWnd, help_regedit, HELP_FINDER, 0);
876 break;
878 case ID_HELP_ABOUT:
879 ShowAboutBox(hWnd);
880 break;
881 case ID_VIEW_SPLIT: {
882 RECT rt;
883 POINT pt, pts;
884 GetClientRect(g_pChildWnd->hWnd, &rt);
885 pt.x = rt.left + g_pChildWnd->nSplitPos;
886 pt.y = (rt.bottom / 2);
887 pts = pt;
888 if(ClientToScreen(g_pChildWnd->hWnd, &pts)) {
889 SetCursorPos(pts.x, pts.y);
890 SetCursor(LoadCursor(0, IDC_SIZEWE));
891 SendMessage(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
893 return TRUE;
895 default:
896 return FALSE;
899 return TRUE;
902 /********************************************************************************
904 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
906 * PURPOSE: Processes messages for the main frame window.
908 * WM_COMMAND - process the application menu
909 * WM_DESTROY - post a quit message and return
913 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
915 switch (message) {
916 case WM_CREATE:
917 CreateWindowEx(0, szChildClass, _T("regedit child window"), WS_CHILD | WS_VISIBLE,
918 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
919 hWnd, NULL, hInst, 0);
920 break;
921 case WM_COMMAND:
922 if (!_CmdWndProc(hWnd, message, wParam, lParam))
923 return DefWindowProc(hWnd, message, wParam, lParam);
924 break;
925 case WM_ACTIVATE:
926 if (LOWORD(hWnd))
927 SetFocus(g_pChildWnd->hWnd);
928 break;
929 case WM_SIZE:
930 resize_frame_client(hWnd);
931 break;
932 case WM_TIMER:
933 break;
934 case WM_ENTERMENULOOP:
935 OnEnterMenuLoop(hWnd);
936 break;
937 case WM_EXITMENULOOP:
938 OnExitMenuLoop(hWnd);
939 break;
940 case WM_INITMENUPOPUP:
941 if (!HIWORD(lParam))
942 OnInitMenuPopup(hWnd, (HMENU)wParam, LOWORD(lParam));
943 break;
944 case WM_MENUSELECT:
945 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
946 break;
947 case WM_DESTROY:
949 const WCHAR help_regedit[] = {'r','e','g','e','d','i','t',0};
950 WinHelpW(hWnd, help_regedit, HELP_QUIT, 0);
951 PostQuitMessage(0);
953 default:
954 return DefWindowProc(hWnd, message, wParam, lParam);
956 return 0;