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 */
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(regedit
);
38 /********************************************************************************
39 * Global and Local Variables:
42 static const 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};
43 static BOOL bInMenuLoop
= FALSE
; /* Tells us if we are in the menu loop */
44 static WCHAR favoriteName
[128];
45 static WCHAR searchString
[128];
46 static int searchMask
= SEARCH_KEYS
| SEARCH_VALUES
| SEARCH_CONTENT
;
48 static WCHAR FileNameBuffer
[_MAX_PATH
];
49 static WCHAR FileTitleBuffer
[_MAX_PATH
];
50 static WCHAR FilterBuffer
[_MAX_PATH
];
51 static WCHAR expandW
[32], collapseW
[32];
52 static WCHAR modifyW
[32], modify_binaryW
[64];
54 /*******************************************************************************
55 * Local module support methods
58 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
60 if (IsWindowVisible(hStatusBar
)) {
63 SetupStatusBar(hWnd
, TRUE
);
64 GetClientRect(hStatusBar
, &rt
);
65 prect
->bottom
-= rt
.bottom
;
67 MoveWindow(g_pChildWnd
->hWnd
, prect
->left
, prect
->top
, prect
->right
, prect
->bottom
, TRUE
);
70 static void resize_frame_client(HWND hWnd
)
74 GetClientRect(hWnd
, &rect
);
75 resize_frame_rect(hWnd
, &rect
);
78 /********************************************************************************/
80 static void OnEnterMenuLoop(HWND hWnd
)
85 /* Update the status bar pane sizes */
87 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
89 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)&empty
);
92 static void OnExitMenuLoop(HWND hWnd
)
95 /* Update the status bar pane sizes*/
96 SetupStatusBar(hWnd
, TRUE
);
100 static void update_expand_or_collapse_item(HWND hwndTV
, HTREEITEM selection
, HMENU hMenu
)
105 item
.hItem
= selection
;
106 item
.mask
= TVIF_CHILDREN
| TVIF_HANDLE
| TVIF_STATE
;
107 item
.stateMask
= TVIS_EXPANDED
;
108 SendMessageW(hwndTV
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
110 info
.cbSize
= sizeof(MENUITEMINFOW
);
111 info
.fMask
= MIIM_FTYPE
| MIIM_STRING
| MIIM_STATE
;
112 info
.fType
= MFT_STRING
;
113 info
.fState
= MFS_ENABLED
;
114 info
.dwTypeData
= expandW
;
118 info
.fState
= MFS_GRAYED
;
122 if (item
.state
& TVIS_EXPANDED
)
123 info
.dwTypeData
= collapseW
;
126 SetMenuItemInfoW(hMenu
, ID_TREE_EXPAND_COLLAPSE
, FALSE
, &info
);
129 static void update_modify_items(HMENU hMenu
, int index
)
131 unsigned int state
= MF_ENABLED
;
136 EnableMenuItem(hMenu
, ID_EDIT_MODIFY
, state
| MF_BYCOMMAND
);
137 EnableMenuItem(hMenu
, ID_EDIT_MODIFY_BIN
, state
| MF_BYCOMMAND
);
140 static void update_delete_and_rename_items(HMENU hMenu
, WCHAR
*keyName
, int index
)
142 unsigned int state_d
= MF_ENABLED
, state_r
= MF_ENABLED
;
144 if (!g_pChildWnd
->nFocusPanel
)
146 if (!keyName
|| !*keyName
)
147 state_d
= state_r
= MF_GRAYED
;
152 if (index
== -1) state_d
= MF_GRAYED
;
155 EnableMenuItem(hMenu
, ID_EDIT_DELETE
, state_d
| MF_BYCOMMAND
);
156 EnableMenuItem(hMenu
, ID_EDIT_RENAME
, state_r
| MF_BYCOMMAND
);
159 static void update_new_items_and_copy_keyname(HMENU hMenu
, WCHAR
*keyName
)
161 unsigned int state
= MF_ENABLED
, i
;
162 unsigned int items
[] = {ID_EDIT_NEW_KEY
, ID_EDIT_NEW_STRINGVALUE
, ID_EDIT_NEW_BINARYVALUE
,
163 ID_EDIT_NEW_DWORDVALUE
, ID_EDIT_NEW_MULTI_STRINGVALUE
,
164 ID_EDIT_NEW_EXPANDVALUE
, ID_EDIT_COPYKEYNAME
};
169 for (i
= 0; i
< COUNT_OF(items
); i
++)
170 EnableMenuItem(hMenu
, items
[i
], state
| MF_BYCOMMAND
);
173 static void UpdateMenuItems(HMENU hMenu
) {
174 HWND hwndTV
= g_pChildWnd
->hTreeWnd
;
175 HKEY hRootKey
= NULL
;
180 selection
= (HTREEITEM
)SendMessageW(hwndTV
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
181 keyName
= GetItemPath(hwndTV
, selection
, &hRootKey
);
182 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1,
183 MAKELPARAM(LVNI_FOCUSED
| LVNI_SELECTED
, 0));
185 update_expand_or_collapse_item(hwndTV
, selection
, hMenu
);
186 update_modify_items(hMenu
, index
);
187 update_delete_and_rename_items(hMenu
, keyName
, index
);
188 update_new_items_and_copy_keyname(hMenu
, keyName
);
189 EnableMenuItem(hMenu
, ID_FAVORITES_ADDTOFAVORITES
, (hRootKey
? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
190 EnableMenuItem(hMenu
, ID_FAVORITES_REMOVEFAVORITE
,
191 (GetMenuItemCount(hMenu
)>2 ? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
196 static void add_remove_modify_menu_items(HMENU hMenu
)
198 if (!g_pChildWnd
->nFocusPanel
)
200 while (GetMenuItemCount(hMenu
) > 9)
201 DeleteMenu(hMenu
, 0, MF_BYPOSITION
);
203 else if (GetMenuItemCount(hMenu
) < 10)
205 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
206 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY_BIN
, modify_binaryW
);
207 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY
, modifyW
);
211 static int add_favourite_key_items(HMENU hMenu
, HWND hList
)
215 DWORD num_values
, max_value_len
, value_len
, type
, i
= 0;
218 rc
= RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
, 0, KEY_READ
, &hkey
);
219 if (rc
!= ERROR_SUCCESS
) return 0;
221 rc
= RegQueryInfoKeyW(hkey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &num_values
,
222 &max_value_len
, NULL
, NULL
, NULL
);
223 if (rc
!= ERROR_SUCCESS
)
225 ERR("RegQueryInfoKey failed: %d\n", rc
);
229 if (!num_values
) goto exit
;
232 value_name
= heap_xalloc(max_value_len
* sizeof(WCHAR
));
234 if (hMenu
) AppendMenuW(hMenu
, MF_SEPARATOR
, 0, 0);
236 for (i
= 0; i
< num_values
; i
++)
238 value_len
= max_value_len
;
239 rc
= RegEnumValueW(hkey
, i
, value_name
, &value_len
, NULL
, &type
, NULL
, NULL
);
240 if (rc
== ERROR_SUCCESS
&& type
== REG_SZ
)
243 AppendMenuW(hMenu
, MF_ENABLED
| MF_STRING
, ID_FAVORITE_FIRST
+ i
, value_name
);
245 SendMessageW(hList
, LB_ADDSTRING
, 0, (LPARAM
)value_name
);
249 heap_free(value_name
);
255 static void OnInitMenuPopup(HWND hWnd
, HMENU hMenu
)
257 if (hMenu
== GetSubMenu(hMenuFrame
, ID_EDIT_MENU
))
258 add_remove_modify_menu_items(hMenu
);
259 else if (hMenu
== GetSubMenu(hMenuFrame
, ID_FAVORITES_MENU
))
261 while (GetMenuItemCount(hMenu
) > 2)
262 DeleteMenu(hMenu
, 2, MF_BYPOSITION
);
264 add_favourite_key_items(hMenu
, NULL
);
267 UpdateMenuItems(hMenu
);
270 static void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
275 if (nFlags
& MF_POPUP
) {
276 if (hSysMenu
!= GetMenu(hWnd
)) {
277 if (nItemID
== 2) nItemID
= 5;
280 if (LoadStringW(hInst
, nItemID
, str
, 100)) {
281 /* load appropriate string*/
283 /* first newline terminates actual string*/
284 lpsz
= strchrW(lpsz
, '\n');
288 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)str
);
291 void SetupStatusBar(HWND hWnd
, BOOL bResize
)
295 GetClientRect(hWnd
, &rc
);
299 SendMessageW(hStatusBar
, WM_SIZE
, 0, 0);
300 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
304 void UpdateStatusBar(void)
306 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
307 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)fullPath
);
311 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
313 BOOL vis
= IsWindowVisible(hchild
);
314 HMENU hMenuView
= GetSubMenu(hMenuFrame
, ID_VIEW_MENU
);
316 CheckMenuItem(hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
317 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
318 resize_frame_client(hWnd
);
321 static BOOL
CheckCommDlgError(HWND hWnd
)
323 DWORD dwErrorCode
= CommDlgExtendedError();
324 switch (dwErrorCode
) {
325 case CDERR_DIALOGFAILURE
:
327 case CDERR_FINDRESFAILURE
:
329 case CDERR_NOHINSTANCE
:
331 case CDERR_INITIALIZATION
:
335 case CDERR_LOCKRESFAILURE
:
337 case CDERR_NOTEMPLATE
:
339 case CDERR_LOADRESFAILURE
:
341 case CDERR_STRUCTSIZE
:
343 case CDERR_LOADSTRFAILURE
:
345 case FNERR_BUFFERTOOSMALL
:
347 case CDERR_MEMALLOCFAILURE
:
349 case FNERR_INVALIDFILENAME
:
351 case CDERR_MEMLOCKFAILURE
:
353 case FNERR_SUBCLASSFAILURE
:
361 static void ExportRegistryFile_StoreSelection(HWND hdlg
, OPENFILENAMEW
*pOpenFileName
)
363 if (IsDlgButtonChecked(hdlg
, IDC_EXPORT_SELECTED
))
365 INT len
= SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXTLENGTH
, 0, 0);
366 pOpenFileName
->lCustData
= (LPARAM
)heap_xalloc((len
+ 1) * sizeof(WCHAR
));
367 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXT
, len
+1, pOpenFileName
->lCustData
);
371 pOpenFileName
->lCustData
= (LPARAM
)heap_xalloc(sizeof(WCHAR
));
372 *(WCHAR
*)pOpenFileName
->lCustData
= 0;
376 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
378 static OPENFILENAMEW
* pOpenFileName
;
379 OFNOTIFYW
*pOfNotify
;
383 pOpenFileName
= (OPENFILENAMEW
*)lParam
;
386 if (LOWORD(wParam
) == IDC_EXPORT_PATH
&& HIWORD(wParam
) == EN_UPDATE
)
387 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, IDC_EXPORT_SELECTED
);
390 pOfNotify
= (OFNOTIFYW
*)lParam
;
391 switch (pOfNotify
->hdr
.code
)
395 BOOL export_branch
= FALSE
;
396 WCHAR
* path
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
397 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_SETTEXT
, 0, (LPARAM
)path
);
399 export_branch
= TRUE
;
401 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, export_branch
? IDC_EXPORT_SELECTED
: IDC_EXPORT_ALL
);
405 ExportRegistryFile_StoreSelection(hdlg
, pOpenFileName
);
416 static BOOL
InitOpenFileName(HWND hWnd
, OPENFILENAMEW
*pofn
)
418 memset(pofn
, 0, sizeof(OPENFILENAMEW
));
419 pofn
->lStructSize
= sizeof(OPENFILENAMEW
);
420 pofn
->hwndOwner
= hWnd
;
421 pofn
->hInstance
= hInst
;
423 if (FilterBuffer
[0] == 0)
425 static const WCHAR filterW
[] = {'%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','*','%','c',0};
426 WCHAR filter_reg
[MAX_PATH
], filter_reg4
[MAX_PATH
], filter_all
[MAX_PATH
];
428 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG
, filter_reg
, MAX_PATH
);
429 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG4
, filter_reg4
, MAX_PATH
);
430 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_ALL
, filter_all
, MAX_PATH
);
431 snprintfW( FilterBuffer
, MAX_PATH
, filterW
, filter_reg
, 0, 0, filter_reg4
, 0, 0, filter_all
, 0, 0 );
433 pofn
->lpstrFilter
= FilterBuffer
;
434 pofn
->nFilterIndex
= 1;
435 pofn
->lpstrFile
= FileNameBuffer
;
436 pofn
->nMaxFile
= _MAX_PATH
;
437 pofn
->lpstrFileTitle
= FileTitleBuffer
;
438 pofn
->nMaxFileTitle
= _MAX_PATH
;
439 pofn
->Flags
= OFN_HIDEREADONLY
;
440 /* some other fields may be set by the caller */
444 static BOOL
import_registry_filename(LPWSTR filename
)
446 static const WCHAR rb_mode
[] = {'r','b',0};
449 FILE* reg_file
= _wfopen(filename
, rb_mode
);
454 Success
= import_registry_file(reg_file
);
456 if(fclose(reg_file
) != 0)
462 static BOOL
ImportRegistryFile(HWND hWnd
)
466 HKEY root_key
= NULL
;
469 InitOpenFileName(hWnd
, &ofn
);
470 ofn
.Flags
|= OFN_ENABLESIZING
;
471 LoadStringW(hInst
, IDS_FILEDIALOG_IMPORT_TITLE
, title
, COUNT_OF(title
));
472 ofn
.lpstrTitle
= title
;
473 if (GetOpenFileNameW(&ofn
)) {
474 if (!import_registry_filename(ofn
.lpstrFile
)) {
475 messagebox(hWnd
, MB_OK
|MB_ICONERROR
, IDS_APP_TITLE
, IDS_IMPORT_FAILED
, ofn
.lpstrFile
);
478 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
,
479 IDS_IMPORT_SUCCESSFUL
, ofn
.lpstrFile
);
482 CheckCommDlgError(hWnd
);
484 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
486 key_path
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &root_key
);
487 RefreshListView(g_pChildWnd
->hListWnd
, root_key
, key_path
, NULL
);
494 static BOOL
ExportRegistryFile(HWND hWnd
)
499 InitOpenFileName(hWnd
, &ofn
);
500 LoadStringW(hInst
, IDS_FILEDIALOG_EXPORT_TITLE
, title
, COUNT_OF(title
));
501 ofn
.lpstrTitle
= title
;
502 ofn
.Flags
= OFN_ENABLETEMPLATE
| OFN_ENABLEHOOK
| OFN_EXPLORER
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
503 ofn
.lpfnHook
= ExportRegistryFile_OFNHookProc
;
504 ofn
.lpTemplateName
= MAKEINTRESOURCEW(IDD_EXPORT_TEMPLATE
);
505 if (GetSaveFileNameW(&ofn
)) {
507 result
= export_registry_key(ofn
.lpstrFile
, (LPWSTR
)ofn
.lCustData
, ofn
.nFilterIndex
);
509 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
513 CheckCommDlgError(hWnd
);
518 static BOOL
PrintRegistryHive(HWND hWnd
, LPCWSTR path
)
523 ZeroMemory(&pd
, sizeof(PRINTDLGW
));
524 pd
.lStructSize
= sizeof(PRINTDLGW
);
526 pd
.hDevMode
= NULL
; /* Don't forget to free or store hDevMode*/
527 pd
.hDevNames
= NULL
; /* Don't forget to free or store hDevNames*/
528 pd
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
530 pd
.nFromPage
= 0xFFFF;
533 pd
.nMaxPage
= 0xFFFF;
534 if (PrintDlgW(&pd
)) {
535 FIXME("printing is not yet implemented.\n");
536 /* GDI calls to render output. */
537 DeleteDC(pd
.hDC
); /* Delete DC when done.*/
543 hResult
= PrintDlgExW(&pd
);
544 if (hResult
== S_OK
) {
545 switch (pd
.dwResultAction
) {
546 case PD_RESULT_APPLY
:
547 /*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. */
548 FIXME("printing is not yet implemented.\n");
550 case PD_RESULT_CANCEL
:
551 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
553 case PD_RESULT_PRINT
:
554 FIXME("printing is not yet implemented.\n");
555 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
563 /*Insufficient memory. */
566 /* One or more arguments are invalid. */
569 /*Invalid pointer. */
575 /*Unspecified error. */
586 static BOOL
CopyKeyName(HWND hWnd
, LPCWSTR keyName
)
590 result
= OpenClipboard(hWnd
);
592 result
= EmptyClipboard();
594 int len
= (lstrlenW(keyName
)+1)*sizeof(WCHAR
);
595 HANDLE hClipData
= GlobalAlloc(GHND
, len
);
596 LPVOID pLoc
= GlobalLock(hClipData
);
597 lstrcpyW(pLoc
, keyName
);
598 GlobalUnlock(hClipData
);
599 SetClipboardData(CF_UNICODETEXT
, hClipData
);
602 /* error emptying clipboard*/
603 /* DWORD dwError = GetLastError(); */
606 if (!CloseClipboard()) {
607 /* error closing clipboard*/
608 /* DWORD dwError = GetLastError(); */
612 /* error opening clipboard*/
613 /* DWORD dwError = GetLastError(); */
619 static INT_PTR CALLBACK
find_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
621 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
625 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
626 CheckDlgButton(hwndDlg
, IDC_FIND_KEYS
, searchMask
&SEARCH_KEYS
? BST_CHECKED
: BST_UNCHECKED
);
627 CheckDlgButton(hwndDlg
, IDC_FIND_VALUES
, searchMask
&SEARCH_VALUES
? BST_CHECKED
: BST_UNCHECKED
);
628 CheckDlgButton(hwndDlg
, IDC_FIND_CONTENT
, searchMask
&SEARCH_CONTENT
? BST_CHECKED
: BST_UNCHECKED
);
629 CheckDlgButton(hwndDlg
, IDC_FIND_WHOLE
, searchMask
&SEARCH_WHOLE
? BST_CHECKED
: BST_UNCHECKED
);
630 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
631 SetWindowTextW(hwndValue
, searchString
);
634 switch(LOWORD(wParam
)) {
636 if (HIWORD(wParam
) == EN_UPDATE
) {
637 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
)>0);
642 if (GetWindowTextLengthW(hwndValue
)>0) {
644 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_KEYS
)) mask
|= SEARCH_KEYS
;
645 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_VALUES
)) mask
|= SEARCH_VALUES
;
646 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_CONTENT
)) mask
|= SEARCH_CONTENT
;
647 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_WHOLE
)) mask
|= SEARCH_WHOLE
;
649 GetWindowTextW(hwndValue
, searchString
, 128);
650 EndDialog(hwndDlg
, IDOK
);
654 EndDialog(hwndDlg
, IDCANCEL
);
662 static INT_PTR CALLBACK
addtofavorites_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
664 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
673 selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
675 item
.mask
= TVIF_HANDLE
| TVIF_TEXT
;
676 item
.hItem
= selected
;
678 item
.cchTextMax
= COUNT_OF(buf
);
679 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
681 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
682 SetWindowTextW(hwndValue
, buf
);
683 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
687 switch(LOWORD(wParam
)) {
689 if (HIWORD(wParam
) == EN_UPDATE
) {
690 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
) > 0);
695 if (GetWindowTextLengthW(hwndValue
)>0) {
696 GetWindowTextW(hwndValue
, favoriteName
, 128);
697 EndDialog(hwndDlg
, IDOK
);
701 EndDialog(hwndDlg
, IDCANCEL
);
709 static INT_PTR CALLBACK
removefavorite_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
711 HWND hwndList
= GetDlgItem(hwndDlg
, IDC_NAME_LIST
);
715 if (!add_favourite_key_items(NULL
, hwndList
))
717 SendMessageW(hwndList
, LB_SETCURSEL
, 0, 0);
720 switch(LOWORD(wParam
)) {
722 if (HIWORD(wParam
) == LBN_SELCHANGE
) {
723 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), lParam
!= -1);
728 int pos
= SendMessageW(hwndList
, LB_GETCURSEL
, 0, 0);
729 int len
= SendMessageW(hwndList
, LB_GETTEXTLEN
, pos
, 0);
731 WCHAR
*lpName
= heap_xalloc((len
+ 1) * sizeof(WCHAR
));
732 SendMessageW(hwndList
, LB_GETTEXT
, pos
, (LPARAM
)lpName
);
735 lstrcpyW(favoriteName
, lpName
);
736 EndDialog(hwndDlg
, IDOK
);
742 EndDialog(hwndDlg
, IDCANCEL
);
750 /*******************************************************************************
752 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
754 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
757 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
762 if (LOWORD(wParam
) >= ID_FAVORITE_FIRST
&& LOWORD(wParam
) <= ID_FAVORITE_LAST
) {
764 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
765 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
) {
766 WCHAR namebuf
[KEY_MAX_LEN
];
768 DWORD ksize
= KEY_MAX_LEN
, vsize
= sizeof(valuebuf
), type
= 0;
769 if (RegEnumValueW(hKey
, LOWORD(wParam
) - ID_FAVORITE_FIRST
, namebuf
, &ksize
, NULL
,
770 &type
, valuebuf
, &vsize
) == ERROR_SUCCESS
) {
771 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
,
772 (LPARAM
) FindPathInTree(g_pChildWnd
->hTreeWnd
, (WCHAR
*)valuebuf
) );
778 switch (LOWORD(wParam
)) {
779 case ID_REGISTRY_IMPORTREGISTRYFILE
:
780 ImportRegistryFile(hWnd
);
783 case ID_REGISTRY_EXPORTREGISTRYFILE
:
784 ExportRegistryFile(hWnd
);
786 case ID_REGISTRY_PRINT
:
788 const WCHAR empty
= 0;
789 PrintRegistryHive(hWnd
, &empty
);
794 HWND hWndDelete
= GetFocus();
795 if (hWndDelete
== g_pChildWnd
->hTreeWnd
) {
796 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
797 if (keyPath
== 0 || *keyPath
== 0) {
798 MessageBeep(MB_ICONHAND
);
799 } else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
)) {
800 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
803 } else if (hWndDelete
== g_pChildWnd
->hListWnd
) {
804 unsigned int num_selected
, index
, focus_idx
;
807 if (!(num_selected
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETSELECTEDCOUNT
, 0, 0L)))
810 if (num_selected
> 1)
812 if (messagebox(hWnd
, MB_YESNO
| MB_ICONEXCLAMATION
, IDS_DELETE_VALUE_TITLE
,
813 IDS_DELETE_VALUE_TEXT_MULTIPLE
) != IDYES
)
817 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
819 focus_idx
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
820 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
824 WCHAR
*valueName
= GetItemText(g_pChildWnd
->hListWnd
, index
);
825 if (!DeleteValue(hWnd
, hKeyRoot
, keyPath
, valueName
, num_selected
== 1))
827 heap_free(valueName
);
830 heap_free(valueName
);
831 SendMessageW(g_pChildWnd
->hListWnd
, LVM_DELETEITEM
, index
, 0L);
832 /* the default value item is always visible, so add it back in */
835 AddEntryToList(g_pChildWnd
->hListWnd
, NULL
, REG_SZ
, NULL
, 0, 0);
839 item
.state
= item
.stateMask
= LVIS_FOCUSED
;
840 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, 0, (LPARAM
)&item
);
843 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
846 } else if (IsChild(g_pChildWnd
->hTreeWnd
, hWndDelete
) ||
847 IsChild(g_pChildWnd
->hListWnd
, hWndDelete
)) {
848 SendMessageW(hWndDelete
, WM_KEYDOWN
, VK_DELETE
, 0);
853 case ID_EDIT_MODIFY_BIN
:
855 LPCWSTR valueName
= GetValueName(g_pChildWnd
->hListWnd
);
856 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
857 ModifyValue(hWnd
, hKeyRoot
, keyPath
, valueName
);
862 case ID_EDIT_FINDNEXT
:
865 if (LOWORD(wParam
) == ID_EDIT_FIND
&&
866 DialogBoxW(0, MAKEINTRESOURCEW(IDD_FIND
), hWnd
, find_dlgproc
) != IDOK
)
870 hItem
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
872 int row
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
873 HCURSOR hcursorOld
= SetCursor(LoadCursorW(NULL
, (LPCWSTR
)IDC_WAIT
));
874 hItem
= FindNext(g_pChildWnd
->hTreeWnd
, hItem
, searchString
, searchMask
, &row
);
875 SetCursor(hcursorOld
);
877 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
) hItem
);
878 InvalidateRect(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
879 UpdateWindow(g_pChildWnd
->hTreeWnd
);
884 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
885 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, (UINT
)-1, (LPARAM
)&item
);
887 item
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
888 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
889 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, row
, (LPARAM
)&item
);
890 SetFocus(g_pChildWnd
->hListWnd
);
892 SetFocus(g_pChildWnd
->hTreeWnd
);
895 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
, IDS_NOTFOUND
, searchString
);
900 case ID_EDIT_COPYKEYNAME
:
902 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
904 CopyKeyName(hWnd
, fullPath
);
909 case ID_EDIT_NEW_KEY
:
911 WCHAR newKeyW
[MAX_NEW_KEY_LEN
];
912 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
913 if (CreateKey(hWnd
, hKeyRoot
, keyPath
, newKeyW
)) {
914 if (InsertNode(g_pChildWnd
->hTreeWnd
, 0, newKeyW
))
915 StartKeyRename(g_pChildWnd
->hTreeWnd
);
920 case ID_EDIT_NEW_STRINGVALUE
:
923 case ID_EDIT_NEW_EXPANDVALUE
:
924 valueType
= REG_EXPAND_SZ
;
926 case ID_EDIT_NEW_MULTI_STRINGVALUE
:
927 valueType
= REG_MULTI_SZ
;
929 case ID_EDIT_NEW_BINARYVALUE
:
930 valueType
= REG_BINARY
;
932 case ID_EDIT_NEW_DWORDVALUE
:
933 valueType
= REG_DWORD
;
937 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
938 WCHAR newKey
[MAX_NEW_KEY_LEN
];
939 if (CreateValue(hWnd
, hKeyRoot
, keyPath
, valueType
, newKey
))
940 StartValueRename(g_pChildWnd
->hListWnd
);
946 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
947 if (keyPath
== 0 || *keyPath
== 0) {
948 MessageBeep(MB_ICONHAND
);
949 } else if (GetFocus() == g_pChildWnd
->hTreeWnd
) {
950 StartKeyRename(g_pChildWnd
->hTreeWnd
);
951 } else if (GetFocus() == g_pChildWnd
->hListWnd
) {
952 StartValueRename(g_pChildWnd
->hListWnd
);
957 case ID_TREE_EXPAND_COLLAPSE
:
959 HTREEITEM selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
960 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_EXPAND
, TVE_TOGGLE
, (LPARAM
)selected
);
963 case ID_REGISTRY_PRINTERSETUP
:
966 /*PAGESETUPDLG psd;*/
967 /*PageSetupDlg(&psd);*/
969 case ID_REGISTRY_OPENLOCAL
:
971 case ID_REGISTRY_EXIT
:
974 case ID_FAVORITES_ADDTOFAVORITES
:
977 LPWSTR lpKeyPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
979 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_ADDFAVORITE
), hWnd
, addtofavorites_dlgproc
) == IDOK
) {
980 if (RegCreateKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
982 KEY_READ
|KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
) {
983 RegSetValueExW(hKey
, favoriteName
, 0, REG_SZ
, (BYTE
*)lpKeyPath
, (lstrlenW(lpKeyPath
)+1)*sizeof(WCHAR
));
987 heap_free(lpKeyPath
);
991 case ID_FAVORITES_REMOVEFAVORITE
:
993 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_DELFAVORITE
), hWnd
, removefavorite_dlgproc
) == IDOK
) {
995 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
996 0, KEY_READ
|KEY_WRITE
, &hKey
) == ERROR_SUCCESS
) {
997 RegDeleteValueW(hKey
, favoriteName
);
1003 case ID_VIEW_REFRESH
:
1005 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1006 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1007 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
, NULL
);
1011 /*case ID_OPTIONS_TOOLBAR:*/
1012 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1014 case ID_VIEW_STATUSBAR
:
1015 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1017 case ID_HELP_HELPTOPICS
:
1019 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1020 WinHelpW(hWnd
, help_regedit
, HELP_FINDER
, 0);
1026 case ID_VIEW_SPLIT
: {
1029 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1030 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1031 pt
.y
= (rt
.bottom
/ 2);
1033 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
)) {
1034 SetCursorPos(pts
.x
, pts
.y
);
1035 SetCursor(LoadCursorW(0, (LPCWSTR
)IDC_SIZEWE
));
1036 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1047 /********************************************************************************
1049 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1051 * PURPOSE: Processes messages for the main frame window.
1053 * WM_COMMAND - process the application menu
1054 * WM_DESTROY - post a quit message and return
1058 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1060 static const WCHAR captionW
[] = {'r','e','g','e','d','i','t',' ','c','h','i','l','d',' ','w','i','n','d','o','w',0};
1064 CreateWindowExW(0, szChildClass
, captionW
, WS_CHILD
| WS_VISIBLE
,
1065 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1066 hWnd
, NULL
, hInst
, 0);
1067 LoadStringW(hInst
, IDS_EXPAND
, expandW
, COUNT_OF(expandW
));
1068 LoadStringW(hInst
, IDS_COLLAPSE
, collapseW
, COUNT_OF(collapseW
));
1069 LoadStringW(hInst
, IDS_EDIT_MODIFY
, modifyW
, COUNT_OF(modifyW
));
1070 LoadStringW(hInst
, IDS_EDIT_MODIFY_BIN
, modify_binaryW
, COUNT_OF(modify_binaryW
));
1073 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1074 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1078 SetFocus(g_pChildWnd
->hWnd
);
1081 resize_frame_client(hWnd
);
1085 case WM_ENTERMENULOOP
:
1086 OnEnterMenuLoop(hWnd
);
1088 case WM_EXITMENULOOP
:
1089 OnExitMenuLoop(hWnd
);
1091 case WM_INITMENUPOPUP
:
1092 if (!HIWORD(lParam
))
1093 OnInitMenuPopup(hWnd
, (HMENU
)wParam
);
1096 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1100 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1101 WinHelpW(hWnd
, help_regedit
, HELP_QUIT
, 0);
1105 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);