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 */
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(regedit
);
34 /********************************************************************************
35 * Global and Local Variables:
38 static const WCHAR favoritesKey
[] = L
"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Favorites";
39 static BOOL bInMenuLoop
= FALSE
; /* Tells us if we are in the menu loop */
40 static WCHAR favoriteName
[128];
41 static WCHAR searchString
[128];
42 static int searchMask
= SEARCH_KEYS
| SEARCH_VALUES
| SEARCH_CONTENT
;
44 static WCHAR FileNameBuffer
[_MAX_PATH
];
45 static WCHAR FileTitleBuffer
[_MAX_PATH
];
46 static WCHAR FilterBuffer
[_MAX_PATH
];
47 static WCHAR expandW
[32], collapseW
[32];
48 static WCHAR modifyW
[32], modify_binaryW
[64];
50 /*******************************************************************************
51 * Local module support methods
54 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
56 if (IsWindowVisible(hStatusBar
)) {
59 SetupStatusBar(hWnd
, TRUE
);
60 GetClientRect(hStatusBar
, &rt
);
61 prect
->bottom
-= rt
.bottom
;
63 MoveWindow(g_pChildWnd
->hWnd
, prect
->left
, prect
->top
, prect
->right
, prect
->bottom
, TRUE
);
66 static void resize_frame_client(HWND hWnd
)
70 GetClientRect(hWnd
, &rect
);
71 resize_frame_rect(hWnd
, &rect
);
74 /********************************************************************************/
76 static void OnEnterMenuLoop(HWND hWnd
)
81 /* Update the status bar pane sizes */
83 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
85 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)&empty
);
88 static void OnExitMenuLoop(HWND hWnd
)
91 /* Update the status bar pane sizes*/
92 SetupStatusBar(hWnd
, TRUE
);
96 static void update_expand_or_collapse_item(HWND hwndTV
, HTREEITEM selection
, HMENU hMenu
)
101 item
.hItem
= selection
;
102 item
.mask
= TVIF_CHILDREN
| TVIF_HANDLE
| TVIF_STATE
;
103 item
.stateMask
= TVIS_EXPANDED
;
104 SendMessageW(hwndTV
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
106 info
.cbSize
= sizeof(MENUITEMINFOW
);
107 info
.fMask
= MIIM_FTYPE
| MIIM_STRING
| MIIM_STATE
;
108 info
.fType
= MFT_STRING
;
109 info
.fState
= MFS_ENABLED
;
110 info
.dwTypeData
= expandW
;
114 info
.fState
= MFS_GRAYED
;
118 if (item
.state
& TVIS_EXPANDED
)
119 info
.dwTypeData
= collapseW
;
122 SetMenuItemInfoW(hMenu
, ID_TREE_EXPAND_COLLAPSE
, FALSE
, &info
);
125 static void update_modify_items(HMENU hMenu
, int index
)
127 unsigned int state
= MF_ENABLED
;
132 EnableMenuItem(hMenu
, ID_EDIT_MODIFY
, state
| MF_BYCOMMAND
);
133 EnableMenuItem(hMenu
, ID_EDIT_MODIFY_BIN
, state
| MF_BYCOMMAND
);
136 static void update_delete_and_rename_items(HMENU hMenu
, WCHAR
*keyName
, int index
)
138 unsigned int state_d
= MF_ENABLED
, state_r
= MF_ENABLED
;
140 if (!g_pChildWnd
->nFocusPanel
)
142 if (!keyName
|| !*keyName
)
143 state_d
= state_r
= MF_GRAYED
;
148 if (index
== -1) state_d
= MF_GRAYED
;
151 EnableMenuItem(hMenu
, ID_EDIT_DELETE
, state_d
| MF_BYCOMMAND
);
152 EnableMenuItem(hMenu
, ID_EDIT_RENAME
, state_r
| MF_BYCOMMAND
);
155 static void update_new_items_and_copy_keyname(HMENU hMenu
, WCHAR
*keyName
)
157 unsigned int state
= MF_ENABLED
, i
;
158 unsigned int items
[] = {ID_EDIT_NEW_KEY
, ID_EDIT_NEW_STRINGVALUE
, ID_EDIT_NEW_BINARYVALUE
,
159 ID_EDIT_NEW_DWORDVALUE
, ID_EDIT_NEW_QWORDVALUE
, ID_EDIT_NEW_MULTI_STRINGVALUE
,
160 ID_EDIT_NEW_EXPANDVALUE
, ID_EDIT_COPYKEYNAME
};
165 for (i
= 0; i
< ARRAY_SIZE(items
); i
++)
166 EnableMenuItem(hMenu
, items
[i
], state
| MF_BYCOMMAND
);
169 static void UpdateMenuItems(HMENU hMenu
) {
170 HWND hwndTV
= g_pChildWnd
->hTreeWnd
;
171 HKEY hRootKey
= NULL
;
176 selection
= (HTREEITEM
)SendMessageW(hwndTV
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
177 keyName
= GetItemPath(hwndTV
, selection
, &hRootKey
);
178 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1,
179 MAKELPARAM(LVNI_SELECTED
, 0));
181 update_expand_or_collapse_item(hwndTV
, selection
, hMenu
);
182 update_modify_items(hMenu
, index
);
183 update_delete_and_rename_items(hMenu
, keyName
, index
);
184 update_new_items_and_copy_keyname(hMenu
, keyName
);
185 EnableMenuItem(hMenu
, ID_FAVORITES_ADDTOFAVORITES
, (hRootKey
? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
186 EnableMenuItem(hMenu
, ID_FAVORITES_REMOVEFAVORITE
,
187 (GetMenuItemCount(hMenu
)>2 ? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
192 static void add_remove_modify_menu_items(HMENU hMenu
)
194 if (!g_pChildWnd
->nFocusPanel
)
196 while (GetMenuItemCount(hMenu
) > 9)
197 DeleteMenu(hMenu
, 0, MF_BYPOSITION
);
199 else if (GetMenuItemCount(hMenu
) < 10)
201 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
202 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY_BIN
, modify_binaryW
);
203 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY
, modifyW
);
207 static int add_favourite_key_items(HMENU hMenu
, HWND hList
)
211 DWORD num_values
, max_value_len
, value_len
, type
, i
= 0;
214 rc
= RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
, 0, KEY_READ
, &hkey
);
215 if (rc
!= ERROR_SUCCESS
) return 0;
217 rc
= RegQueryInfoKeyW(hkey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &num_values
,
218 &max_value_len
, NULL
, NULL
, NULL
);
219 if (rc
!= ERROR_SUCCESS
)
221 ERR("RegQueryInfoKey failed: %ld\n", rc
);
225 if (!num_values
) goto exit
;
228 value_name
= malloc(max_value_len
* sizeof(WCHAR
));
230 if (hMenu
) AppendMenuW(hMenu
, MF_SEPARATOR
, 0, 0);
232 for (i
= 0; i
< num_values
; i
++)
234 value_len
= max_value_len
;
235 rc
= RegEnumValueW(hkey
, i
, value_name
, &value_len
, NULL
, &type
, NULL
, NULL
);
236 if (rc
== ERROR_SUCCESS
&& type
== REG_SZ
)
239 AppendMenuW(hMenu
, MF_ENABLED
| MF_STRING
, ID_FAVORITE_FIRST
+ i
, value_name
);
241 SendMessageW(hList
, LB_ADDSTRING
, 0, (LPARAM
)value_name
);
251 static void OnInitMenuPopup(HWND hWnd
, HMENU hMenu
)
253 if (hMenu
== GetSubMenu(hMenuFrame
, ID_EDIT_MENU
))
254 add_remove_modify_menu_items(hMenu
);
255 else if (hMenu
== GetSubMenu(hMenuFrame
, ID_FAVORITES_MENU
))
257 while (GetMenuItemCount(hMenu
) > 2)
258 DeleteMenu(hMenu
, 2, MF_BYPOSITION
);
260 add_favourite_key_items(hMenu
, NULL
);
263 UpdateMenuItems(hMenu
);
266 static void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
271 if (nFlags
& MF_POPUP
) {
272 if (hSysMenu
!= GetMenu(hWnd
)) {
273 if (nItemID
== 2) nItemID
= 5;
276 if (LoadStringW(hInst
, nItemID
, str
, 100)) {
277 /* load appropriate string*/
279 /* first newline terminates actual string*/
280 lpsz
= wcschr(lpsz
, '\n');
284 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)str
);
287 void SetupStatusBar(HWND hWnd
, BOOL bResize
)
291 GetClientRect(hWnd
, &rc
);
295 SendMessageW(hStatusBar
, WM_SIZE
, 0, 0);
296 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
300 void UpdateStatusBar(void)
302 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
303 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)fullPath
);
307 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
309 BOOL vis
= IsWindowVisible(hchild
);
310 HMENU hMenuView
= GetSubMenu(hMenuFrame
, ID_VIEW_MENU
);
312 CheckMenuItem(hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
313 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
314 resize_frame_client(hWnd
);
317 static BOOL
CheckCommDlgError(HWND hWnd
)
319 DWORD dwErrorCode
= CommDlgExtendedError();
320 switch (dwErrorCode
) {
321 case CDERR_DIALOGFAILURE
:
323 case CDERR_FINDRESFAILURE
:
325 case CDERR_NOHINSTANCE
:
327 case CDERR_INITIALIZATION
:
331 case CDERR_LOCKRESFAILURE
:
333 case CDERR_NOTEMPLATE
:
335 case CDERR_LOADRESFAILURE
:
337 case CDERR_STRUCTSIZE
:
339 case CDERR_LOADSTRFAILURE
:
341 case FNERR_BUFFERTOOSMALL
:
343 case CDERR_MEMALLOCFAILURE
:
345 case FNERR_INVALIDFILENAME
:
347 case CDERR_MEMLOCKFAILURE
:
349 case FNERR_SUBCLASSFAILURE
:
357 static void ExportRegistryFile_StoreSelection(HWND hdlg
, OPENFILENAMEW
*pOpenFileName
)
359 if (IsDlgButtonChecked(hdlg
, IDC_EXPORT_SELECTED
))
361 INT len
= SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXTLENGTH
, 0, 0);
362 pOpenFileName
->lCustData
= (LPARAM
)malloc((len
+ 1) * sizeof(WCHAR
));
363 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXT
, len
+1, pOpenFileName
->lCustData
);
367 pOpenFileName
->lCustData
= (LPARAM
)malloc(sizeof(WCHAR
));
368 *(WCHAR
*)pOpenFileName
->lCustData
= 0;
372 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
374 static OPENFILENAMEW
* pOpenFileName
;
375 OFNOTIFYW
*pOfNotify
;
379 pOpenFileName
= (OPENFILENAMEW
*)lParam
;
382 if (LOWORD(wParam
) == IDC_EXPORT_PATH
&& HIWORD(wParam
) == EN_UPDATE
)
383 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, IDC_EXPORT_SELECTED
);
386 pOfNotify
= (OFNOTIFYW
*)lParam
;
387 switch (pOfNotify
->hdr
.code
)
391 BOOL export_branch
= FALSE
;
392 WCHAR
* path
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
393 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_SETTEXT
, 0, (LPARAM
)path
);
395 export_branch
= TRUE
;
397 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, export_branch
? IDC_EXPORT_SELECTED
: IDC_EXPORT_ALL
);
401 ExportRegistryFile_StoreSelection(hdlg
, pOpenFileName
);
412 static BOOL
InitOpenFileName(HWND hWnd
, OPENFILENAMEW
*pofn
)
414 memset(pofn
, 0, sizeof(OPENFILENAMEW
));
415 pofn
->lStructSize
= sizeof(OPENFILENAMEW
);
416 pofn
->hwndOwner
= hWnd
;
417 pofn
->hInstance
= hInst
;
419 if (FilterBuffer
[0] == 0)
421 WCHAR filter_reg
[MAX_PATH
], filter_reg4
[MAX_PATH
], filter_all
[MAX_PATH
];
423 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG
, filter_reg
, MAX_PATH
);
424 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG4
, filter_reg4
, MAX_PATH
);
425 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_ALL
, filter_all
, MAX_PATH
);
426 swprintf( FilterBuffer
, ARRAY_SIZE(FilterBuffer
), L
"%s%c*.reg%c%s%c*.reg%c%s%c*.*%c",
427 filter_reg
, 0, 0, filter_reg4
, 0, 0, filter_all
, 0, 0 );
429 pofn
->lpstrFilter
= FilterBuffer
;
430 pofn
->nFilterIndex
= 1;
431 pofn
->lpstrFile
= FileNameBuffer
;
432 pofn
->nMaxFile
= _MAX_PATH
;
433 pofn
->lpstrFileTitle
= FileTitleBuffer
;
434 pofn
->nMaxFileTitle
= _MAX_PATH
;
435 pofn
->Flags
= OFN_HIDEREADONLY
;
436 /* some other fields may be set by the caller */
440 static BOOL
import_registry_filename(LPWSTR filename
)
443 FILE* reg_file
= _wfopen(filename
, L
"rb");
448 Success
= import_registry_file(reg_file
);
450 if(fclose(reg_file
) != 0)
456 static BOOL
ImportRegistryFile(HWND hWnd
)
460 HKEY root_key
= NULL
;
463 InitOpenFileName(hWnd
, &ofn
);
464 ofn
.Flags
|= OFN_ENABLESIZING
;
465 LoadStringW(hInst
, IDS_FILEDIALOG_IMPORT_TITLE
, title
, ARRAY_SIZE(title
));
466 ofn
.lpstrTitle
= title
;
467 if (GetOpenFileNameW(&ofn
)) {
468 if (!import_registry_filename(ofn
.lpstrFile
)) {
469 messagebox(hWnd
, MB_OK
|MB_ICONERROR
, IDS_APP_TITLE
, IDS_IMPORT_FAILED
, ofn
.lpstrFile
);
472 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
,
473 IDS_IMPORT_SUCCESSFUL
, ofn
.lpstrFile
);
476 CheckCommDlgError(hWnd
);
478 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
480 key_path
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &root_key
);
481 RefreshListView(g_pChildWnd
->hListWnd
, root_key
, key_path
, NULL
);
488 static BOOL
ExportRegistryFile(HWND hWnd
)
493 InitOpenFileName(hWnd
, &ofn
);
494 LoadStringW(hInst
, IDS_FILEDIALOG_EXPORT_TITLE
, title
, ARRAY_SIZE(title
));
495 ofn
.lpstrTitle
= title
;
496 ofn
.lpstrDefExt
= L
"reg";
497 ofn
.Flags
= OFN_ENABLETEMPLATE
| OFN_ENABLEHOOK
| OFN_EXPLORER
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
498 ofn
.lpfnHook
= ExportRegistryFile_OFNHookProc
;
499 ofn
.lpTemplateName
= MAKEINTRESOURCEW(IDD_EXPORT_TEMPLATE
);
500 if (GetSaveFileNameW(&ofn
)) {
502 result
= export_registry_key(ofn
.lpstrFile
, (LPWSTR
)ofn
.lCustData
, ofn
.nFilterIndex
);
504 FIXME("Registry export failed.\n");
508 CheckCommDlgError(hWnd
);
513 static BOOL
PrintRegistryHive(HWND hWnd
, LPCWSTR path
)
518 ZeroMemory(&pd
, sizeof(PRINTDLGW
));
519 pd
.lStructSize
= sizeof(PRINTDLGW
);
521 pd
.hDevMode
= NULL
; /* Don't forget to free or store hDevMode*/
522 pd
.hDevNames
= NULL
; /* Don't forget to free or store hDevNames*/
523 pd
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
525 pd
.nFromPage
= 0xFFFF;
528 pd
.nMaxPage
= 0xFFFF;
529 if (PrintDlgW(&pd
)) {
530 FIXME("printing is not yet implemented.\n");
531 /* GDI calls to render output. */
532 DeleteDC(pd
.hDC
); /* Delete DC when done.*/
538 hResult
= PrintDlgExW(&pd
);
539 if (hResult
== S_OK
) {
540 switch (pd
.dwResultAction
) {
541 case PD_RESULT_APPLY
:
542 /*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. */
543 FIXME("printing is not yet implemented.\n");
545 case PD_RESULT_CANCEL
:
546 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
548 case PD_RESULT_PRINT
:
549 FIXME("printing is not yet implemented.\n");
550 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
558 /*Insufficient memory. */
561 /* One or more arguments are invalid. */
564 /*Invalid pointer. */
570 /*Unspecified error. */
581 static BOOL
CopyKeyName(HWND hWnd
, LPCWSTR keyName
)
585 result
= OpenClipboard(hWnd
);
587 result
= EmptyClipboard();
589 int len
= (lstrlenW(keyName
)+1)*sizeof(WCHAR
);
590 HANDLE hClipData
= GlobalAlloc(GHND
, len
);
591 LPVOID pLoc
= GlobalLock(hClipData
);
592 lstrcpyW(pLoc
, keyName
);
593 GlobalUnlock(hClipData
);
594 SetClipboardData(CF_UNICODETEXT
, hClipData
);
597 /* error emptying clipboard*/
598 /* DWORD dwError = GetLastError(); */
601 if (!CloseClipboard()) {
602 /* error closing clipboard*/
603 /* DWORD dwError = GetLastError(); */
607 /* error opening clipboard*/
608 /* DWORD dwError = GetLastError(); */
614 static INT_PTR CALLBACK
find_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
616 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
620 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
621 CheckDlgButton(hwndDlg
, IDC_FIND_KEYS
, searchMask
&SEARCH_KEYS
? BST_CHECKED
: BST_UNCHECKED
);
622 CheckDlgButton(hwndDlg
, IDC_FIND_VALUES
, searchMask
&SEARCH_VALUES
? BST_CHECKED
: BST_UNCHECKED
);
623 CheckDlgButton(hwndDlg
, IDC_FIND_CONTENT
, searchMask
&SEARCH_CONTENT
? BST_CHECKED
: BST_UNCHECKED
);
624 CheckDlgButton(hwndDlg
, IDC_FIND_WHOLE
, searchMask
&SEARCH_WHOLE
? BST_CHECKED
: BST_UNCHECKED
);
625 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
626 SetWindowTextW(hwndValue
, searchString
);
629 switch(LOWORD(wParam
)) {
631 if (HIWORD(wParam
) == EN_UPDATE
) {
632 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
)>0);
637 if (GetWindowTextLengthW(hwndValue
)>0) {
639 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_KEYS
)) mask
|= SEARCH_KEYS
;
640 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_VALUES
)) mask
|= SEARCH_VALUES
;
641 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_CONTENT
)) mask
|= SEARCH_CONTENT
;
642 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_WHOLE
)) mask
|= SEARCH_WHOLE
;
644 GetWindowTextW(hwndValue
, searchString
, 128);
645 EndDialog(hwndDlg
, IDOK
);
649 EndDialog(hwndDlg
, IDCANCEL
);
657 static INT_PTR CALLBACK
addtofavorites_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
659 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
668 selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
670 item
.mask
= TVIF_HANDLE
| TVIF_TEXT
;
671 item
.hItem
= selected
;
673 item
.cchTextMax
= ARRAY_SIZE(buf
);
674 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
676 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
677 SetWindowTextW(hwndValue
, buf
);
678 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
682 switch(LOWORD(wParam
)) {
684 if (HIWORD(wParam
) == EN_UPDATE
) {
685 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
) > 0);
690 if (GetWindowTextLengthW(hwndValue
)>0) {
691 GetWindowTextW(hwndValue
, favoriteName
, 128);
692 EndDialog(hwndDlg
, IDOK
);
696 EndDialog(hwndDlg
, IDCANCEL
);
704 static INT_PTR CALLBACK
removefavorite_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
706 HWND hwndList
= GetDlgItem(hwndDlg
, IDC_NAME_LIST
);
710 if (!add_favourite_key_items(NULL
, hwndList
))
712 SendMessageW(hwndList
, LB_SETCURSEL
, 0, 0);
715 switch(LOWORD(wParam
)) {
717 if (HIWORD(wParam
) == LBN_SELCHANGE
) {
718 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), lParam
!= -1);
723 int pos
= SendMessageW(hwndList
, LB_GETCURSEL
, 0, 0);
724 int len
= SendMessageW(hwndList
, LB_GETTEXTLEN
, pos
, 0);
726 WCHAR
*lpName
= malloc((len
+ 1) * sizeof(WCHAR
));
727 SendMessageW(hwndList
, LB_GETTEXT
, pos
, (LPARAM
)lpName
);
730 lstrcpyW(favoriteName
, lpName
);
731 EndDialog(hwndDlg
, IDOK
);
737 EndDialog(hwndDlg
, IDCANCEL
);
745 /*******************************************************************************
747 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
749 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
752 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
757 if (LOWORD(wParam
) >= ID_FAVORITE_FIRST
&& LOWORD(wParam
) <= ID_FAVORITE_LAST
) {
759 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
760 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
) {
761 WCHAR namebuf
[KEY_MAX_LEN
];
763 DWORD ksize
= KEY_MAX_LEN
, vsize
= sizeof(valuebuf
), type
= 0;
764 if (RegEnumValueW(hKey
, LOWORD(wParam
) - ID_FAVORITE_FIRST
, namebuf
, &ksize
, NULL
,
765 &type
, valuebuf
, &vsize
) == ERROR_SUCCESS
) {
766 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
,
767 (LPARAM
) FindPathInTree(g_pChildWnd
->hTreeWnd
, (WCHAR
*)valuebuf
) );
773 switch (LOWORD(wParam
)) {
774 case ID_REGISTRY_IMPORTREGISTRYFILE
:
775 ImportRegistryFile(hWnd
);
778 case ID_REGISTRY_EXPORTREGISTRYFILE
:
779 ExportRegistryFile(hWnd
);
781 case ID_REGISTRY_PRINT
:
783 const WCHAR empty
= 0;
784 PrintRegistryHive(hWnd
, &empty
);
789 HWND hWndDelete
= GetFocus();
790 if (hWndDelete
== g_pChildWnd
->hTreeWnd
) {
791 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
792 if (keyPath
== 0 || *keyPath
== 0) {
793 MessageBeep(MB_ICONHAND
);
794 } else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
)) {
795 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
798 } else if (hWndDelete
== g_pChildWnd
->hListWnd
) {
799 unsigned int num_selected
, index
, focus_idx
;
802 num_selected
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETSELECTEDCOUNT
, 0, 0L);
806 else if (num_selected
== 1)
807 index
= IDS_DELETE_VALUE_TEXT
;
809 index
= IDS_DELETE_VALUE_TEXT_MULTIPLE
;
811 if (messagebox(hWnd
, MB_YESNO
| MB_ICONEXCLAMATION
, IDS_DELETE_VALUE_TITLE
, index
) != IDYES
)
814 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
816 focus_idx
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
817 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
821 WCHAR
*valueName
= GetItemText(g_pChildWnd
->hListWnd
, index
);
822 if (!DeleteValue(hWnd
, hKeyRoot
, keyPath
, valueName
))
828 SendMessageW(g_pChildWnd
->hListWnd
, LVM_DELETEITEM
, index
, 0L);
829 /* the default value item is always visible, so add it back in */
832 AddEntryToList(g_pChildWnd
->hListWnd
, NULL
, REG_SZ
, NULL
, 0, 0);
836 item
.state
= item
.stateMask
= LVIS_FOCUSED
;
837 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, 0, (LPARAM
)&item
);
840 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
843 } else if (IsChild(g_pChildWnd
->hTreeWnd
, hWndDelete
) ||
844 IsChild(g_pChildWnd
->hListWnd
, hWndDelete
)) {
845 SendMessageW(hWndDelete
, WM_KEYDOWN
, VK_DELETE
, 0);
850 case ID_EDIT_MODIFY_BIN
:
852 WCHAR
*valueName
= GetValueName(g_pChildWnd
->hListWnd
);
853 WCHAR
*keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
854 ModifyValue(hWnd
, hKeyRoot
, keyPath
, valueName
);
860 case ID_EDIT_FINDNEXT
:
863 if (LOWORD(wParam
) == ID_EDIT_FIND
&&
864 DialogBoxW(0, MAKEINTRESOURCEW(IDD_FIND
), hWnd
, find_dlgproc
) != IDOK
)
868 hItem
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
870 int row
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
871 HCURSOR hcursorOld
= SetCursor(LoadCursorW(NULL
, (LPCWSTR
)IDC_WAIT
));
872 hItem
= FindNext(g_pChildWnd
->hTreeWnd
, hItem
, searchString
, searchMask
, &row
);
873 SetCursor(hcursorOld
);
875 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
) hItem
);
876 InvalidateRect(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
877 UpdateWindow(g_pChildWnd
->hTreeWnd
);
882 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
883 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, (UINT
)-1, (LPARAM
)&item
);
885 item
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
886 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
887 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, row
, (LPARAM
)&item
);
888 SetFocus(g_pChildWnd
->hListWnd
);
890 SetFocus(g_pChildWnd
->hTreeWnd
);
893 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
, IDS_NOTFOUND
, searchString
);
898 case ID_EDIT_COPYKEYNAME
:
900 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
902 CopyKeyName(hWnd
, fullPath
);
907 case ID_EDIT_NEW_KEY
:
909 WCHAR newKeyW
[MAX_NEW_KEY_LEN
];
910 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
911 if (CreateKey(hWnd
, hKeyRoot
, keyPath
, newKeyW
)) {
912 if (InsertNode(g_pChildWnd
->hTreeWnd
, 0, newKeyW
))
913 StartKeyRename(g_pChildWnd
->hTreeWnd
);
918 case ID_EDIT_NEW_STRINGVALUE
:
921 case ID_EDIT_NEW_EXPANDVALUE
:
922 valueType
= REG_EXPAND_SZ
;
924 case ID_EDIT_NEW_MULTI_STRINGVALUE
:
925 valueType
= REG_MULTI_SZ
;
927 case ID_EDIT_NEW_BINARYVALUE
:
928 valueType
= REG_BINARY
;
930 case ID_EDIT_NEW_DWORDVALUE
:
931 valueType
= REG_DWORD
;
933 case ID_EDIT_NEW_QWORDVALUE
:
934 valueType
= REG_QWORD
;
938 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
939 WCHAR newKey
[MAX_NEW_KEY_LEN
];
940 if (CreateValue(hWnd
, hKeyRoot
, keyPath
, valueType
, newKey
))
941 StartValueRename(g_pChildWnd
->hListWnd
);
947 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
949 MessageBeep(MB_ICONHAND
);
951 } else if (*keyPath
&& GetFocus() == g_pChildWnd
->hTreeWnd
) {
952 StartKeyRename(g_pChildWnd
->hTreeWnd
);
953 } else if (GetFocus() == g_pChildWnd
->hListWnd
) {
954 StartValueRename(g_pChildWnd
->hListWnd
);
959 case ID_TREE_EXPAND_COLLAPSE
:
961 HTREEITEM selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
962 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_EXPAND
, TVE_TOGGLE
, (LPARAM
)selected
);
965 case ID_REGISTRY_PRINTERSETUP
:
968 /*PAGESETUPDLG psd;*/
969 /*PageSetupDlg(&psd);*/
971 case ID_REGISTRY_OPENLOCAL
:
973 case ID_REGISTRY_EXIT
:
976 case ID_FAVORITES_ADDTOFAVORITES
:
979 LPWSTR lpKeyPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
981 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_ADDFAVORITE
), hWnd
, addtofavorites_dlgproc
) == IDOK
) {
982 if (RegCreateKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
984 KEY_READ
|KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
) {
985 RegSetValueExW(hKey
, favoriteName
, 0, REG_SZ
, (BYTE
*)lpKeyPath
, (lstrlenW(lpKeyPath
)+1)*sizeof(WCHAR
));
993 case ID_FAVORITES_REMOVEFAVORITE
:
995 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_DELFAVORITE
), hWnd
, removefavorite_dlgproc
) == IDOK
) {
997 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
998 0, KEY_READ
|KEY_WRITE
, &hKey
) == ERROR_SUCCESS
) {
999 RegDeleteValueW(hKey
, favoriteName
);
1005 case ID_VIEW_REFRESH
:
1007 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1008 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1009 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
, NULL
);
1013 /*case ID_OPTIONS_TOOLBAR:*/
1014 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1016 case ID_VIEW_STATUSBAR
:
1017 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1019 case ID_HELP_HELPTOPICS
:
1021 WinHelpW(hWnd
, L
"regedit", HELP_FINDER
, 0);
1027 case ID_VIEW_SPLIT
: {
1030 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1031 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1032 pt
.y
= (rt
.bottom
/ 2);
1034 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
)) {
1035 SetCursorPos(pts
.x
, pts
.y
);
1036 SetCursor(LoadCursorW(0, (LPCWSTR
)IDC_SIZEWE
));
1037 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1048 /********************************************************************************
1050 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1052 * PURPOSE: Processes messages for the main frame window.
1054 * WM_COMMAND - process the application menu
1055 * WM_DESTROY - post a quit message and return
1059 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1063 CreateWindowExW(0, szChildClass
, L
"regedit child window", WS_CHILD
| WS_VISIBLE
,
1064 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1065 hWnd
, NULL
, hInst
, 0);
1066 LoadStringW(hInst
, IDS_EXPAND
, expandW
, ARRAY_SIZE(expandW
));
1067 LoadStringW(hInst
, IDS_COLLAPSE
, collapseW
, ARRAY_SIZE(collapseW
));
1068 LoadStringW(hInst
, IDS_EDIT_MODIFY
, modifyW
, ARRAY_SIZE(modifyW
));
1069 LoadStringW(hInst
, IDS_EDIT_MODIFY_BIN
, modify_binaryW
, ARRAY_SIZE(modify_binaryW
));
1072 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1073 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1077 SetFocus(g_pChildWnd
->hWnd
);
1080 resize_frame_client(hWnd
);
1084 case WM_ENTERMENULOOP
:
1085 OnEnterMenuLoop(hWnd
);
1087 case WM_EXITMENULOOP
:
1088 OnExitMenuLoop(hWnd
);
1090 case WM_INITMENUPOPUP
:
1091 if (!HIWORD(lParam
))
1092 OnInitMenuPopup(hWnd
, (HMENU
)wParam
);
1095 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1099 WinHelpW(hWnd
, L
"regedit", HELP_QUIT
, 0);
1103 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);