wineps: Set the printer's devmode using SetPrinter.
[wine/multimedia.git] / programs / regedit / framewnd.c
blobb3ca5949e61b26f5bfce1180e9c991d96fb7a60a
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 <commctrl.h>
25 #include <commdlg.h>
26 #include <cderr.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <shellapi.h>
31 #include "main.h"
32 #include "regproc.h"
33 #include "wine/unicode.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 WCHAR searchString[128];
43 static int searchMask = SEARCH_KEYS | SEARCH_VALUES | SEARCH_CONTENT;
45 static WCHAR FileNameBuffer[_MAX_PATH];
46 static WCHAR FileTitleBuffer[_MAX_PATH];
47 static WCHAR 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 SendMessageW(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;
85 WCHAR empty = 0;
87 /* Update the status bar pane sizes */
88 nParts = -1;
89 SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
90 bInMenuLoop = TRUE;
91 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)&empty);
94 static void OnExitMenuLoop(HWND hWnd)
96 bInMenuLoop = FALSE;
97 /* Update the status bar pane sizes*/
98 SetupStatusBar(hWnd, TRUE);
99 UpdateStatusBar();
102 static void UpdateMenuItems(HMENU hMenu) {
103 HWND hwndTV = g_pChildWnd->hTreeWnd;
104 BOOL bAllowEdit = FALSE;
105 HKEY hRootKey = NULL;
106 LPWSTR keyName;
107 HTREEITEM selection;
109 selection = (HTREEITEM)SendMessageW(hwndTV, TVM_GETNEXTITEM, TVGN_CARET, 0);
110 keyName = GetItemPath(hwndTV, selection, &hRootKey);
111 if (GetFocus() != hwndTV || (keyName && *keyName)) { /* can't modify root keys, but allow for their values */
112 bAllowEdit = TRUE;
114 EnableMenuItem(hMenu, ID_EDIT_FIND, MF_ENABLED | MF_BYCOMMAND);
115 EnableMenuItem(hMenu, ID_EDIT_FINDNEXT, MF_ENABLED | MF_BYCOMMAND);
116 EnableMenuItem(hMenu, ID_EDIT_MODIFY, (bAllowEdit ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
117 EnableMenuItem(hMenu, ID_EDIT_DELETE, (bAllowEdit ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
118 EnableMenuItem(hMenu, ID_EDIT_RENAME, (bAllowEdit ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
119 EnableMenuItem(hMenu, ID_FAVORITES_ADDTOFAVORITES, (hRootKey ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
120 EnableMenuItem(hMenu, ID_FAVORITES_REMOVEFAVORITE,
121 (GetMenuItemCount(hMenu)>2 ? MF_ENABLED : MF_GRAYED) | MF_BYCOMMAND);
123 HeapFree(GetProcessHeap(), 0, keyName);
126 static void OnInitMenuPopup(HWND hWnd, HMENU hMenu, short wItem)
128 if (wItem == 3) {
129 HKEY hKey;
130 while(GetMenuItemCount(hMenu)>2)
131 DeleteMenu(hMenu, 2, MF_BYPOSITION);
132 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
133 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
134 WCHAR namebuf[KEY_MAX_LEN];
135 BYTE valuebuf[4096];
136 int i = 0;
137 BOOL sep = FALSE;
138 DWORD ksize, vsize, type;
139 LONG error;
140 do {
141 ksize = KEY_MAX_LEN;
142 vsize = sizeof(valuebuf);
143 error = RegEnumValueW(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
144 if (error != ERROR_SUCCESS)
145 break;
146 if (type == REG_SZ) {
147 if (!sep) {
148 AppendMenuW(hMenu, MF_SEPARATOR, -1, NULL);
149 sep = TRUE;
151 AppendMenuW(hMenu, MF_STRING, ID_FAVORITE_FIRST+i, namebuf);
153 i++;
154 } while(error == ERROR_SUCCESS);
155 RegCloseKey(hKey);
158 UpdateMenuItems(hMenu);
161 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
163 WCHAR str[100];
165 str[0] = 0;
166 if (nFlags & MF_POPUP) {
167 if (hSysMenu != GetMenu(hWnd)) {
168 if (nItemID == 2) nItemID = 5;
171 if (LoadStringW(hInst, nItemID, str, 100)) {
172 /* load appropriate string*/
173 LPWSTR lpsz = str;
174 /* first newline terminates actual string*/
175 lpsz = strchrW(lpsz, '\n');
176 if (lpsz != NULL)
177 *lpsz = '\0';
179 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)str);
182 void SetupStatusBar(HWND hWnd, BOOL bResize)
184 RECT rc;
185 int nParts;
186 GetClientRect(hWnd, &rc);
187 nParts = rc.right;
188 /* nParts = -1;*/
189 if (bResize)
190 SendMessageW(hStatusBar, WM_SIZE, 0, 0);
191 SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
192 UpdateStatusBar();
195 void UpdateStatusBar(void)
197 LPWSTR fullPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, TRUE);
198 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)fullPath);
199 HeapFree(GetProcessHeap(), 0, fullPath);
202 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
204 BOOL vis = IsWindowVisible(hchild);
205 HMENU hMenuView = GetSubMenu(hMenuFrame, ID_VIEW_MENU);
207 CheckMenuItem(hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED);
208 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW);
209 resize_frame_client(hWnd);
212 static BOOL CheckCommDlgError(HWND hWnd)
214 DWORD dwErrorCode = CommDlgExtendedError();
215 switch (dwErrorCode) {
216 case CDERR_DIALOGFAILURE:
217 break;
218 case CDERR_FINDRESFAILURE:
219 break;
220 case CDERR_NOHINSTANCE:
221 break;
222 case CDERR_INITIALIZATION:
223 break;
224 case CDERR_NOHOOK:
225 break;
226 case CDERR_LOCKRESFAILURE:
227 break;
228 case CDERR_NOTEMPLATE:
229 break;
230 case CDERR_LOADRESFAILURE:
231 break;
232 case CDERR_STRUCTSIZE:
233 break;
234 case CDERR_LOADSTRFAILURE:
235 break;
236 case FNERR_BUFFERTOOSMALL:
237 break;
238 case CDERR_MEMALLOCFAILURE:
239 break;
240 case FNERR_INVALIDFILENAME:
241 break;
242 case CDERR_MEMLOCKFAILURE:
243 break;
244 case FNERR_SUBCLASSFAILURE:
245 break;
246 default:
247 break;
249 return TRUE;
252 static void ExportRegistryFile_StoreSelection(HWND hdlg, OPENFILENAMEW *pOpenFileName)
254 if (IsDlgButtonChecked(hdlg, IDC_EXPORT_SELECTED))
256 INT len = SendDlgItemMessageW(hdlg, IDC_EXPORT_PATH, WM_GETTEXTLENGTH, 0, 0);
257 pOpenFileName->lCustData = (LPARAM)HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR));
258 SendDlgItemMessageW(hdlg, IDC_EXPORT_PATH, WM_GETTEXT, len+1, pOpenFileName->lCustData);
260 else
261 pOpenFileName->lCustData = (LPARAM)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR));
264 static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
266 static OPENFILENAMEW* pOpenFileName;
267 OFNOTIFYW *pOfNotify;
269 switch (uiMsg) {
270 case WM_INITDIALOG:
271 pOpenFileName = (OPENFILENAMEW*)lParam;
272 break;
273 case WM_COMMAND:
274 if (LOWORD(wParam) == IDC_EXPORT_PATH && HIWORD(wParam) == EN_UPDATE)
275 CheckRadioButton(hdlg, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, IDC_EXPORT_SELECTED);
276 break;
277 case WM_NOTIFY:
278 pOfNotify = (OFNOTIFYW*)lParam;
279 switch (pOfNotify->hdr.code)
281 case CDN_INITDONE:
283 BOOL export_branch = FALSE;
284 WCHAR* path = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
285 SendDlgItemMessageW(hdlg, IDC_EXPORT_PATH, WM_SETTEXT, 0, (LPARAM)path);
286 if (path && strlenW(path) > 0)
287 export_branch = TRUE;
288 HeapFree(GetProcessHeap(), 0, path);
289 CheckRadioButton(hdlg, IDC_EXPORT_ALL, IDC_EXPORT_SELECTED, export_branch ? IDC_EXPORT_SELECTED : IDC_EXPORT_ALL);
290 break;
292 case CDN_FILEOK:
293 ExportRegistryFile_StoreSelection(hdlg, pOpenFileName);
294 break;
296 break;
297 default:
298 break;
300 return 0L;
304 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAMEW *pofn)
306 memset(pofn, 0, sizeof(OPENFILENAMEW));
307 pofn->lStructSize = sizeof(OPENFILENAMEW);
308 pofn->hwndOwner = hWnd;
309 pofn->hInstance = hInst;
311 if (FilterBuffer[0] == 0)
313 static const WCHAR filterW[] = {'%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','*','%','c',0};
314 WCHAR filter_reg[MAX_PATH], filter_reg4[MAX_PATH], filter_all[MAX_PATH];
316 LoadStringW(hInst, IDS_FILEDIALOG_FILTER_REG, filter_reg, MAX_PATH);
317 LoadStringW(hInst, IDS_FILEDIALOG_FILTER_REG4, filter_reg4, MAX_PATH);
318 LoadStringW(hInst, IDS_FILEDIALOG_FILTER_ALL, filter_all, MAX_PATH);
319 snprintfW( FilterBuffer, MAX_PATH, filterW, filter_reg, 0, 0, filter_reg4, 0, 0, filter_all, 0, 0 );
321 pofn->lpstrFilter = FilterBuffer;
322 pofn->nFilterIndex = 2;
323 pofn->lpstrFile = FileNameBuffer;
324 pofn->nMaxFile = _MAX_PATH;
325 pofn->lpstrFileTitle = FileTitleBuffer;
326 pofn->nMaxFileTitle = _MAX_PATH;
327 pofn->Flags = OFN_HIDEREADONLY;
328 /* some other fields may be set by the caller */
329 return TRUE;
332 static BOOL import_registry_filename(LPWSTR filename)
334 static const WCHAR mode_r[] = {'r',0};
336 BOOL Success;
337 FILE* reg_file = _wfopen(filename, mode_r);
339 if(!reg_file)
340 return FALSE;
342 Success = import_registry_file(reg_file);
344 if(fclose(reg_file) != 0)
345 Success = FALSE;
347 return Success;
350 static BOOL ImportRegistryFile(HWND hWnd)
352 OPENFILENAMEW ofn;
353 WCHAR title[128];
355 InitOpenFileName(hWnd, &ofn);
356 ofn.Flags |= OFN_ENABLESIZING;
357 LoadStringW(hInst, IDS_FILEDIALOG_IMPORT_TITLE, title, COUNT_OF(title));
358 ofn.lpstrTitle = title;
359 if (GetOpenFileNameW(&ofn)) {
360 if (!import_registry_filename(ofn.lpstrFile))
361 return FALSE;
362 } else {
363 CheckCommDlgError(hWnd);
365 RefreshTreeView(g_pChildWnd->hTreeWnd);
366 return TRUE;
370 static BOOL ExportRegistryFile(HWND hWnd)
372 OPENFILENAMEW ofn;
373 WCHAR title[128];
375 InitOpenFileName(hWnd, &ofn);
376 LoadStringW(hInst, IDS_FILEDIALOG_EXPORT_TITLE, title, COUNT_OF(title));
377 ofn.lpstrTitle = title;
378 ofn.Flags = OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
379 ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
380 ofn.lpTemplateName = MAKEINTRESOURCEW(IDD_EXPORT_TEMPLATE);
381 if (GetSaveFileNameW(&ofn)) {
382 BOOL result;
383 result = export_registry_key(ofn.lpstrFile, (LPWSTR)ofn.lCustData, ofn.nFilterIndex);
384 if (!result) {
385 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
386 return FALSE;
388 } else {
389 CheckCommDlgError(hWnd);
391 return TRUE;
394 static BOOL PrintRegistryHive(HWND hWnd, LPCWSTR path)
396 #if 1
397 PRINTDLGW pd;
399 ZeroMemory(&pd, sizeof(PRINTDLGW));
400 pd.lStructSize = sizeof(PRINTDLGW);
401 pd.hwndOwner = hWnd;
402 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/
403 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/
404 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
405 pd.nCopies = 1;
406 pd.nFromPage = 0xFFFF;
407 pd.nToPage = 0xFFFF;
408 pd.nMinPage = 1;
409 pd.nMaxPage = 0xFFFF;
410 if (PrintDlgW(&pd)) {
411 /* GDI calls to render output. */
412 DeleteDC(pd.hDC); /* Delete DC when done.*/
414 #else
415 HRESULT hResult;
416 PRINTDLGEXW pd;
418 hResult = PrintDlgExW(&pd);
419 if (hResult == S_OK) {
420 switch (pd.dwResultAction) {
421 case PD_RESULT_APPLY:
422 /*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. */
423 break;
424 case PD_RESULT_CANCEL:
425 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
426 break;
427 case PD_RESULT_PRINT:
428 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
429 break;
430 default:
431 break;
433 } else {
434 switch (hResult) {
435 case E_OUTOFMEMORY:
436 /*Insufficient memory. */
437 break;
438 case E_INVALIDARG:
439 /* One or more arguments are invalid. */
440 break;
441 case E_POINTER:
442 /*Invalid pointer. */
443 break;
444 case E_HANDLE:
445 /*Invalid handle. */
446 break;
447 case E_FAIL:
448 /*Unspecified error. */
449 break;
450 default:
451 break;
453 return FALSE;
455 #endif
456 return TRUE;
459 static BOOL CopyKeyName(HWND hWnd, LPCWSTR keyName)
461 BOOL result;
463 result = OpenClipboard(hWnd);
464 if (result) {
465 result = EmptyClipboard();
466 if (result) {
467 int len = (lstrlenW(keyName)+1)*sizeof(WCHAR);
468 HANDLE hClipData = GlobalAlloc(GHND, len);
469 LPVOID pLoc = GlobalLock(hClipData);
470 lstrcpyW(pLoc, keyName);
471 GlobalUnlock(hClipData);
472 hClipData = SetClipboardData(CF_UNICODETEXT, hClipData);
474 } else {
475 /* error emptying clipboard*/
476 /* DWORD dwError = GetLastError(); */
479 if (!CloseClipboard()) {
480 /* error closing clipboard*/
481 /* DWORD dwError = GetLastError(); */
484 } else {
485 /* error opening clipboard*/
486 /* DWORD dwError = GetLastError(); */
489 return result;
492 static INT_PTR CALLBACK find_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
494 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
496 switch(uMsg) {
497 case WM_INITDIALOG:
498 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
499 CheckDlgButton(hwndDlg, IDC_FIND_KEYS, searchMask&SEARCH_KEYS ? BST_CHECKED : BST_UNCHECKED);
500 CheckDlgButton(hwndDlg, IDC_FIND_VALUES, searchMask&SEARCH_VALUES ? BST_CHECKED : BST_UNCHECKED);
501 CheckDlgButton(hwndDlg, IDC_FIND_CONTENT, searchMask&SEARCH_CONTENT ? BST_CHECKED : BST_UNCHECKED);
502 CheckDlgButton(hwndDlg, IDC_FIND_WHOLE, searchMask&SEARCH_WHOLE ? BST_CHECKED : BST_UNCHECKED);
503 SendMessageW(hwndValue, EM_SETLIMITTEXT, 127, 0);
504 SetWindowTextW(hwndValue, searchString);
505 return TRUE;
506 case WM_COMMAND:
507 switch(LOWORD(wParam)) {
508 case IDC_VALUE_NAME:
509 if (HIWORD(wParam) == EN_UPDATE) {
510 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLengthW(hwndValue)>0);
511 return TRUE;
513 break;
514 case IDOK:
515 if (GetWindowTextLengthW(hwndValue)>0) {
516 int mask = 0;
517 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_KEYS)) mask |= SEARCH_KEYS;
518 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_VALUES)) mask |= SEARCH_VALUES;
519 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_CONTENT)) mask |= SEARCH_CONTENT;
520 if (IsDlgButtonChecked(hwndDlg, IDC_FIND_WHOLE)) mask |= SEARCH_WHOLE;
521 searchMask = mask;
522 GetWindowTextW(hwndValue, searchString, 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 addtofavorites_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
537 HWND hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_NAME);
539 switch(uMsg) {
540 case WM_INITDIALOG:
542 HKEY hKeyRoot = NULL;
543 LPWSTR ItemPath = GetItemPath(g_pChildWnd->hTreeWnd, NULL, &hKeyRoot);
545 if(!ItemPath || !*ItemPath)
546 ItemPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
547 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
548 SetWindowTextW(hwndValue, ItemPath);
549 SendMessageW(hwndValue, EM_SETLIMITTEXT, 127, 0);
550 HeapFree(GetProcessHeap(), 0, ItemPath);
551 return TRUE;
553 case WM_COMMAND:
554 switch(LOWORD(wParam)) {
555 case IDC_VALUE_NAME:
556 if (HIWORD(wParam) == EN_UPDATE) {
557 EnableWindow(GetDlgItem(hwndDlg, IDOK), GetWindowTextLengthW(hwndValue) > 0);
558 return TRUE;
560 break;
561 case IDOK:
562 if (GetWindowTextLengthW(hwndValue)>0) {
563 GetWindowTextW(hwndValue, favoriteName, 128);
564 EndDialog(hwndDlg, IDOK);
566 return TRUE;
567 case IDCANCEL:
568 EndDialog(hwndDlg, IDCANCEL);
569 return TRUE;
571 break;
573 return FALSE;
576 static INT_PTR CALLBACK removefavorite_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
578 HWND hwndList = GetDlgItem(hwndDlg, IDC_NAME_LIST);
580 switch(uMsg) {
581 case WM_INITDIALOG: {
582 HKEY hKey;
583 int i = 0;
584 EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
585 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
586 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
587 WCHAR namebuf[KEY_MAX_LEN];
588 BYTE valuebuf[4096];
589 DWORD ksize, vsize, type;
590 LONG error;
591 do {
592 ksize = KEY_MAX_LEN;
593 vsize = sizeof(valuebuf);
594 error = RegEnumValueW(hKey, i, namebuf, &ksize, NULL, &type, valuebuf, &vsize);
595 if (error != ERROR_SUCCESS)
596 break;
597 if (type == REG_SZ) {
598 SendMessageW(hwndList, LB_ADDSTRING, 0, (LPARAM)namebuf);
600 i++;
601 } while(error == ERROR_SUCCESS);
602 RegCloseKey(hKey);
604 else
605 return FALSE;
606 EnableWindow(GetDlgItem(hwndDlg, IDOK), i != 0);
607 SendMessageW(hwndList, LB_SETCURSEL, 0, 0);
608 return TRUE;
610 case WM_COMMAND:
611 switch(LOWORD(wParam)) {
612 case IDC_NAME_LIST:
613 if (HIWORD(wParam) == LBN_SELCHANGE) {
614 EnableWindow(GetDlgItem(hwndDlg, IDOK), lParam != -1);
615 return TRUE;
617 break;
618 case IDOK: {
619 int pos = SendMessageW(hwndList, LB_GETCURSEL, 0, 0);
620 int len = SendMessageW(hwndList, LB_GETTEXTLEN, pos, 0);
621 if (len>0) {
622 LPWSTR lpName = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(len+1));
623 SendMessageW(hwndList, LB_GETTEXT, pos, (LPARAM)lpName);
624 if (len>127)
625 lpName[127] = '\0';
626 lstrcpyW(favoriteName, lpName);
627 EndDialog(hwndDlg, IDOK);
628 HeapFree(GetProcessHeap(), 0, lpName);
630 return TRUE;
632 case IDCANCEL:
633 EndDialog(hwndDlg, IDCANCEL);
634 return TRUE;
636 break;
638 return FALSE;
641 /*******************************************************************************
643 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
645 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
648 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
650 HKEY hKeyRoot = 0;
651 DWORD valueType;
652 int curIndex;
653 BOOL firstItem = TRUE;
655 if (LOWORD(wParam) >= ID_FAVORITE_FIRST && LOWORD(wParam) <= ID_FAVORITE_LAST) {
656 HKEY hKey;
657 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
658 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
659 WCHAR namebuf[KEY_MAX_LEN];
660 BYTE valuebuf[4096];
661 DWORD ksize = KEY_MAX_LEN, vsize = sizeof(valuebuf), type = 0;
662 if (RegEnumValueW(hKey, LOWORD(wParam) - ID_FAVORITE_FIRST, namebuf, &ksize, NULL,
663 &type, valuebuf, &vsize) == ERROR_SUCCESS) {
664 SendMessageW( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET,
665 (LPARAM) FindPathInTree(g_pChildWnd->hTreeWnd, (WCHAR *)valuebuf) );
667 RegCloseKey(hKey);
669 return TRUE;
671 switch (LOWORD(wParam)) {
672 case ID_REGISTRY_IMPORTREGISTRYFILE:
673 ImportRegistryFile(hWnd);
674 break;
675 case ID_EDIT_EXPORT:
676 case ID_REGISTRY_EXPORTREGISTRYFILE:
677 ExportRegistryFile(hWnd);
678 break;
679 case ID_REGISTRY_PRINT:
681 const WCHAR empty = 0;
682 PrintRegistryHive(hWnd, &empty);
683 break;
685 case ID_EDIT_DELETE:
687 HWND hWndDelete = GetFocus();
688 if (hWndDelete == g_pChildWnd->hTreeWnd) {
689 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
690 if (keyPath == 0 || *keyPath == 0) {
691 MessageBeep(MB_ICONHAND);
692 } else if (DeleteKey(hWnd, hKeyRoot, keyPath)) {
693 DeleteNode(g_pChildWnd->hTreeWnd, 0);
695 HeapFree(GetProcessHeap(), 0, keyPath);
696 } else if (hWndDelete == g_pChildWnd->hListWnd) {
697 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
698 curIndex = SendMessageW(g_pChildWnd->hListWnd, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_SELECTED, 0));
699 while(curIndex != -1) {
700 WCHAR* valueName = GetItemText(g_pChildWnd->hListWnd, curIndex);
702 curIndex = SendMessageW(g_pChildWnd->hListWnd, LVM_GETNEXTITEM, curIndex, MAKELPARAM(LVNI_SELECTED, 0));
703 if(curIndex != -1 && firstItem) {
704 if (MessageBoxW(hWnd, MAKEINTRESOURCEW(IDS_DELETE_BOX_TEXT_MULTIPLE),
705 MAKEINTRESOURCEW(IDS_DELETE_BOX_TITLE),
706 MB_YESNO | MB_ICONEXCLAMATION) != IDYES)
707 break;
710 if (!DeleteValue(hWnd, hKeyRoot, keyPath, valueName, curIndex==-1 && firstItem))
712 HeapFree(GetProcessHeap(), 0, valueName);
713 break;
715 firstItem = FALSE;
716 HeapFree(GetProcessHeap(), 0, valueName);
718 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
719 HeapFree(GetProcessHeap(), 0, keyPath);
720 } else if (IsChild(g_pChildWnd->hTreeWnd, hWndDelete) ||
721 IsChild(g_pChildWnd->hListWnd, hWndDelete)) {
722 SendMessageW(hWndDelete, WM_KEYDOWN, VK_DELETE, 0);
724 break;
726 case ID_EDIT_MODIFY:
728 LPCWSTR valueName = GetValueName(g_pChildWnd->hListWnd);
729 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
730 if (ModifyValue(hWnd, hKeyRoot, keyPath, valueName))
731 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, valueName);
732 HeapFree(GetProcessHeap(), 0, keyPath);
733 break;
735 case ID_EDIT_FIND:
736 case ID_EDIT_FINDNEXT:
738 HTREEITEM hItem;
739 if (LOWORD(wParam) == ID_EDIT_FIND &&
740 DialogBoxW(0, MAKEINTRESOURCEW(IDD_FIND), hWnd, find_dlgproc) != IDOK)
741 break;
742 if (!*searchString)
743 break;
744 hItem = (HTREEITEM)SendMessageW(g_pChildWnd->hTreeWnd, TVM_GETNEXTITEM, TVGN_CARET, 0);
745 if (hItem) {
746 int row = SendMessageW(g_pChildWnd->hListWnd, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_FOCUSED, 0));
747 HCURSOR hcursorOld = SetCursor(LoadCursorW(NULL, (LPCWSTR)IDC_WAIT));
748 hItem = FindNext(g_pChildWnd->hTreeWnd, hItem, searchString, searchMask, &row);
749 SetCursor(hcursorOld);
750 if (hItem) {
751 SendMessageW( g_pChildWnd->hTreeWnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM) hItem );
752 InvalidateRect(g_pChildWnd->hTreeWnd, NULL, TRUE);
753 UpdateWindow(g_pChildWnd->hTreeWnd);
754 if (row != -1) {
755 LVITEMW item;
757 item.state = 0;
758 item.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
759 SendMessageW(g_pChildWnd->hListWnd, LVM_SETITEMSTATE, (UINT)-1, (LPARAM)&item);
761 item.state = LVIS_FOCUSED | LVIS_SELECTED;
762 item.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
763 SendMessageW(g_pChildWnd->hListWnd, LVM_SETITEMSTATE, row, (LPARAM)&item);
764 SetFocus(g_pChildWnd->hListWnd);
765 } else {
766 SetFocus(g_pChildWnd->hTreeWnd);
768 } else {
769 error(hWnd, IDS_NOTFOUND, searchString);
772 break;
774 case ID_EDIT_COPYKEYNAME:
776 LPWSTR fullPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
777 if (fullPath) {
778 CopyKeyName(hWnd, fullPath);
779 HeapFree(GetProcessHeap(), 0, fullPath);
781 break;
783 case ID_EDIT_NEW_KEY:
785 WCHAR newKeyW[MAX_NEW_KEY_LEN];
786 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
787 if (CreateKey(hWnd, hKeyRoot, keyPath, newKeyW)) {
788 if (InsertNode(g_pChildWnd->hTreeWnd, 0, newKeyW))
789 StartKeyRename(g_pChildWnd->hTreeWnd);
791 HeapFree(GetProcessHeap(), 0, keyPath);
793 break;
794 case ID_EDIT_NEW_STRINGVALUE:
795 valueType = REG_SZ;
796 goto create_value;
797 case ID_EDIT_NEW_EXPANDVALUE:
798 valueType = REG_EXPAND_SZ;
799 goto create_value;
800 case ID_EDIT_NEW_MULTI_STRINGVALUE:
801 valueType = REG_MULTI_SZ;
802 goto create_value;
803 case ID_EDIT_NEW_BINARYVALUE:
804 valueType = REG_BINARY;
805 goto create_value;
806 case ID_EDIT_NEW_DWORDVALUE:
807 valueType = REG_DWORD;
808 /* fall through */
809 create_value:
811 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
812 WCHAR newKey[MAX_NEW_KEY_LEN];
813 if (CreateValue(hWnd, hKeyRoot, keyPath, valueType, newKey)) {
814 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, newKey);
815 StartValueRename(g_pChildWnd->hListWnd);
817 HeapFree(GetProcessHeap(), 0, keyPath);
819 break;
820 case ID_EDIT_RENAME:
822 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
823 if (keyPath == 0 || *keyPath == 0) {
824 MessageBeep(MB_ICONHAND);
825 } else if (GetFocus() == g_pChildWnd->hTreeWnd) {
826 StartKeyRename(g_pChildWnd->hTreeWnd);
827 } else if (GetFocus() == g_pChildWnd->hListWnd) {
828 StartValueRename(g_pChildWnd->hListWnd);
830 HeapFree(GetProcessHeap(), 0, keyPath);
832 break;
833 case ID_REGISTRY_PRINTERSETUP:
834 /*PRINTDLG pd;*/
835 /*PrintDlg(&pd);*/
836 /*PAGESETUPDLG psd;*/
837 /*PageSetupDlg(&psd);*/
838 break;
839 case ID_REGISTRY_OPENLOCAL:
840 break;
841 case ID_REGISTRY_EXIT:
842 DestroyWindow(hWnd);
843 break;
844 case ID_FAVORITES_ADDTOFAVORITES:
846 HKEY hKey;
847 LPWSTR lpKeyPath = GetItemFullPath(g_pChildWnd->hTreeWnd, NULL, FALSE);
848 if (lpKeyPath) {
849 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_ADDFAVORITE), hWnd, addtofavorites_dlgproc) == IDOK) {
850 if (RegCreateKeyExW(HKEY_CURRENT_USER, favoritesKey,
851 0, NULL, 0,
852 KEY_READ|KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) {
853 RegSetValueExW(hKey, favoriteName, 0, REG_SZ, (BYTE *)lpKeyPath, (lstrlenW(lpKeyPath)+1)*sizeof(WCHAR));
854 RegCloseKey(hKey);
857 HeapFree(GetProcessHeap(), 0, lpKeyPath);
859 break;
861 case ID_FAVORITES_REMOVEFAVORITE:
863 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_DELFAVORITE), hWnd, removefavorite_dlgproc) == IDOK) {
864 HKEY hKey;
865 if (RegOpenKeyExW(HKEY_CURRENT_USER, favoritesKey,
866 0, KEY_READ|KEY_WRITE, &hKey) == ERROR_SUCCESS) {
867 RegDeleteValueW(hKey, favoriteName);
868 RegCloseKey(hKey);
871 break;
873 case ID_VIEW_REFRESH:
875 WCHAR* keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
876 RefreshTreeView(g_pChildWnd->hTreeWnd);
877 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL);
878 HeapFree(GetProcessHeap(), 0, keyPath);
880 break;
881 /*case ID_OPTIONS_TOOLBAR:*/
882 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
883 /* break;*/
884 case ID_VIEW_STATUSBAR:
885 toggle_child(hWnd, LOWORD(wParam), hStatusBar);
886 break;
887 case ID_HELP_HELPTOPICS:
889 const WCHAR help_regedit[] = {'r','e','g','e','d','i','t',0};
890 WinHelpW(hWnd, help_regedit, HELP_FINDER, 0);
891 break;
893 case ID_HELP_ABOUT:
894 ShowAboutBox(hWnd);
895 break;
896 case ID_VIEW_SPLIT: {
897 RECT rt;
898 POINT pt, pts;
899 GetClientRect(g_pChildWnd->hWnd, &rt);
900 pt.x = rt.left + g_pChildWnd->nSplitPos;
901 pt.y = (rt.bottom / 2);
902 pts = pt;
903 if(ClientToScreen(g_pChildWnd->hWnd, &pts)) {
904 SetCursorPos(pts.x, pts.y);
905 SetCursor(LoadCursorW(0, (LPCWSTR)IDC_SIZEWE));
906 SendMessageW(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
908 return TRUE;
910 default:
911 return FALSE;
914 return TRUE;
917 /********************************************************************************
919 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
921 * PURPOSE: Processes messages for the main frame window.
923 * WM_COMMAND - process the application menu
924 * WM_DESTROY - post a quit message and return
928 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
930 static const WCHAR captionW[] = {'r','e','g','e','d','i','t',' ','c','h','i','l','d',' ','w','i','n','d','o','w',0};
932 switch (message) {
933 case WM_CREATE:
934 CreateWindowExW(0, szChildClass, captionW, WS_CHILD | WS_VISIBLE,
935 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
936 hWnd, NULL, hInst, 0);
937 break;
938 case WM_COMMAND:
939 if (!_CmdWndProc(hWnd, message, wParam, lParam))
940 return DefWindowProcW(hWnd, message, wParam, lParam);
941 break;
942 case WM_ACTIVATE:
943 if (LOWORD(hWnd))
944 SetFocus(g_pChildWnd->hWnd);
945 break;
946 case WM_SIZE:
947 resize_frame_client(hWnd);
948 break;
949 case WM_TIMER:
950 break;
951 case WM_ENTERMENULOOP:
952 OnEnterMenuLoop(hWnd);
953 break;
954 case WM_EXITMENULOOP:
955 OnExitMenuLoop(hWnd);
956 break;
957 case WM_INITMENUPOPUP:
958 if (!HIWORD(lParam))
959 OnInitMenuPopup(hWnd, (HMENU)wParam, LOWORD(lParam));
960 break;
961 case WM_MENUSELECT:
962 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam);
963 break;
964 case WM_DESTROY:
966 const WCHAR help_regedit[] = {'r','e','g','e','d','i','t',0};
967 WinHelpW(hWnd, help_regedit, HELP_QUIT, 0);
968 PostQuitMessage(0);
970 default:
971 return DefWindowProcW(hWnd, message, wParam, lParam);
973 return 0;