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/heap.h"
35 #include "wine/unicode.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(regedit
);
39 /********************************************************************************
40 * Global and Local Variables:
43 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};
44 static BOOL bInMenuLoop
= FALSE
; /* Tells us if we are in the menu loop */
45 static WCHAR favoriteName
[128];
46 static WCHAR searchString
[128];
47 static int searchMask
= SEARCH_KEYS
| SEARCH_VALUES
| SEARCH_CONTENT
;
49 static WCHAR FileNameBuffer
[_MAX_PATH
];
50 static WCHAR FileTitleBuffer
[_MAX_PATH
];
51 static WCHAR FilterBuffer
[_MAX_PATH
];
52 static WCHAR expandW
[32], collapseW
[32];
53 static WCHAR modifyW
[32], modify_binaryW
[64];
55 /*******************************************************************************
56 * Local module support methods
59 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
61 if (IsWindowVisible(hStatusBar
)) {
64 SetupStatusBar(hWnd
, TRUE
);
65 GetClientRect(hStatusBar
, &rt
);
66 prect
->bottom
-= rt
.bottom
;
68 MoveWindow(g_pChildWnd
->hWnd
, prect
->left
, prect
->top
, prect
->right
, prect
->bottom
, TRUE
);
71 static void resize_frame_client(HWND hWnd
)
75 GetClientRect(hWnd
, &rect
);
76 resize_frame_rect(hWnd
, &rect
);
79 /********************************************************************************/
81 static void OnEnterMenuLoop(HWND hWnd
)
86 /* Update the status bar pane sizes */
88 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
90 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)&empty
);
93 static void OnExitMenuLoop(HWND hWnd
)
96 /* Update the status bar pane sizes*/
97 SetupStatusBar(hWnd
, TRUE
);
101 static void update_expand_or_collapse_item(HWND hwndTV
, HTREEITEM selection
, HMENU hMenu
)
106 item
.hItem
= selection
;
107 item
.mask
= TVIF_CHILDREN
| TVIF_HANDLE
| TVIF_STATE
;
108 item
.stateMask
= TVIS_EXPANDED
;
109 SendMessageW(hwndTV
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
111 info
.cbSize
= sizeof(MENUITEMINFOW
);
112 info
.fMask
= MIIM_FTYPE
| MIIM_STRING
| MIIM_STATE
;
113 info
.fType
= MFT_STRING
;
114 info
.fState
= MFS_ENABLED
;
115 info
.dwTypeData
= expandW
;
119 info
.fState
= MFS_GRAYED
;
123 if (item
.state
& TVIS_EXPANDED
)
124 info
.dwTypeData
= collapseW
;
127 SetMenuItemInfoW(hMenu
, ID_TREE_EXPAND_COLLAPSE
, FALSE
, &info
);
130 static void update_modify_items(HMENU hMenu
, int index
)
132 unsigned int state
= MF_ENABLED
;
137 EnableMenuItem(hMenu
, ID_EDIT_MODIFY
, state
| MF_BYCOMMAND
);
138 EnableMenuItem(hMenu
, ID_EDIT_MODIFY_BIN
, state
| MF_BYCOMMAND
);
141 static void update_delete_and_rename_items(HMENU hMenu
, WCHAR
*keyName
, int index
)
143 unsigned int state_d
= MF_ENABLED
, state_r
= MF_ENABLED
;
145 if (!g_pChildWnd
->nFocusPanel
)
147 if (!keyName
|| !*keyName
)
148 state_d
= state_r
= MF_GRAYED
;
153 if (index
== -1) state_d
= MF_GRAYED
;
156 EnableMenuItem(hMenu
, ID_EDIT_DELETE
, state_d
| MF_BYCOMMAND
);
157 EnableMenuItem(hMenu
, ID_EDIT_RENAME
, state_r
| MF_BYCOMMAND
);
160 static void update_new_items_and_copy_keyname(HMENU hMenu
, WCHAR
*keyName
)
162 unsigned int state
= MF_ENABLED
, i
;
163 unsigned int items
[] = {ID_EDIT_NEW_KEY
, ID_EDIT_NEW_STRINGVALUE
, ID_EDIT_NEW_BINARYVALUE
,
164 ID_EDIT_NEW_DWORDVALUE
, ID_EDIT_NEW_MULTI_STRINGVALUE
,
165 ID_EDIT_NEW_EXPANDVALUE
, ID_EDIT_COPYKEYNAME
};
170 for (i
= 0; i
< COUNT_OF(items
); i
++)
171 EnableMenuItem(hMenu
, items
[i
], state
| MF_BYCOMMAND
);
174 static void UpdateMenuItems(HMENU hMenu
) {
175 HWND hwndTV
= g_pChildWnd
->hTreeWnd
;
176 HKEY hRootKey
= NULL
;
181 selection
= (HTREEITEM
)SendMessageW(hwndTV
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
182 keyName
= GetItemPath(hwndTV
, selection
, &hRootKey
);
183 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1,
184 MAKELPARAM(LVNI_FOCUSED
| LVNI_SELECTED
, 0));
186 update_expand_or_collapse_item(hwndTV
, selection
, hMenu
);
187 update_modify_items(hMenu
, index
);
188 update_delete_and_rename_items(hMenu
, keyName
, index
);
189 update_new_items_and_copy_keyname(hMenu
, keyName
);
190 EnableMenuItem(hMenu
, ID_FAVORITES_ADDTOFAVORITES
, (hRootKey
? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
191 EnableMenuItem(hMenu
, ID_FAVORITES_REMOVEFAVORITE
,
192 (GetMenuItemCount(hMenu
)>2 ? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
197 static void add_remove_modify_menu_items(HMENU hMenu
)
199 if (!g_pChildWnd
->nFocusPanel
)
201 while (GetMenuItemCount(hMenu
) > 9)
202 DeleteMenu(hMenu
, 0, MF_BYPOSITION
);
204 else if (GetMenuItemCount(hMenu
) < 10)
206 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
207 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY_BIN
, modify_binaryW
);
208 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY
, modifyW
);
212 static int add_favourite_key_items(HMENU hMenu
, HWND hList
)
216 DWORD num_values
, max_value_len
, value_len
, type
, i
= 0;
219 rc
= RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
, 0, KEY_READ
, &hkey
);
220 if (rc
!= ERROR_SUCCESS
) return 0;
222 rc
= RegQueryInfoKeyW(hkey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &num_values
,
223 &max_value_len
, NULL
, NULL
, NULL
);
224 if (rc
!= ERROR_SUCCESS
)
226 ERR("RegQueryInfoKey failed: %d\n", rc
);
230 if (!num_values
) goto exit
;
233 value_name
= heap_xalloc(max_value_len
* sizeof(WCHAR
));
235 if (hMenu
) AppendMenuW(hMenu
, MF_SEPARATOR
, 0, 0);
237 for (i
= 0; i
< num_values
; i
++)
239 value_len
= max_value_len
;
240 rc
= RegEnumValueW(hkey
, i
, value_name
, &value_len
, NULL
, &type
, NULL
, NULL
);
241 if (rc
== ERROR_SUCCESS
&& type
== REG_SZ
)
244 AppendMenuW(hMenu
, MF_ENABLED
| MF_STRING
, ID_FAVORITE_FIRST
+ i
, value_name
);
246 SendMessageW(hList
, LB_ADDSTRING
, 0, (LPARAM
)value_name
);
250 heap_free(value_name
);
256 static void OnInitMenuPopup(HWND hWnd
, HMENU hMenu
)
258 if (hMenu
== GetSubMenu(hMenuFrame
, ID_EDIT_MENU
))
259 add_remove_modify_menu_items(hMenu
);
260 else if (hMenu
== GetSubMenu(hMenuFrame
, ID_FAVORITES_MENU
))
262 while (GetMenuItemCount(hMenu
) > 2)
263 DeleteMenu(hMenu
, 2, MF_BYPOSITION
);
265 add_favourite_key_items(hMenu
, NULL
);
268 UpdateMenuItems(hMenu
);
271 static void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
276 if (nFlags
& MF_POPUP
) {
277 if (hSysMenu
!= GetMenu(hWnd
)) {
278 if (nItemID
== 2) nItemID
= 5;
281 if (LoadStringW(hInst
, nItemID
, str
, 100)) {
282 /* load appropriate string*/
284 /* first newline terminates actual string*/
285 lpsz
= strchrW(lpsz
, '\n');
289 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)str
);
292 void SetupStatusBar(HWND hWnd
, BOOL bResize
)
296 GetClientRect(hWnd
, &rc
);
300 SendMessageW(hStatusBar
, WM_SIZE
, 0, 0);
301 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
305 void UpdateStatusBar(void)
307 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
308 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)fullPath
);
312 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
314 BOOL vis
= IsWindowVisible(hchild
);
315 HMENU hMenuView
= GetSubMenu(hMenuFrame
, ID_VIEW_MENU
);
317 CheckMenuItem(hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
318 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
319 resize_frame_client(hWnd
);
322 static BOOL
CheckCommDlgError(HWND hWnd
)
324 DWORD dwErrorCode
= CommDlgExtendedError();
325 switch (dwErrorCode
) {
326 case CDERR_DIALOGFAILURE
:
328 case CDERR_FINDRESFAILURE
:
330 case CDERR_NOHINSTANCE
:
332 case CDERR_INITIALIZATION
:
336 case CDERR_LOCKRESFAILURE
:
338 case CDERR_NOTEMPLATE
:
340 case CDERR_LOADRESFAILURE
:
342 case CDERR_STRUCTSIZE
:
344 case CDERR_LOADSTRFAILURE
:
346 case FNERR_BUFFERTOOSMALL
:
348 case CDERR_MEMALLOCFAILURE
:
350 case FNERR_INVALIDFILENAME
:
352 case CDERR_MEMLOCKFAILURE
:
354 case FNERR_SUBCLASSFAILURE
:
362 static void ExportRegistryFile_StoreSelection(HWND hdlg
, OPENFILENAMEW
*pOpenFileName
)
364 if (IsDlgButtonChecked(hdlg
, IDC_EXPORT_SELECTED
))
366 INT len
= SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXTLENGTH
, 0, 0);
367 pOpenFileName
->lCustData
= (LPARAM
)heap_xalloc((len
+ 1) * sizeof(WCHAR
));
368 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXT
, len
+1, pOpenFileName
->lCustData
);
372 pOpenFileName
->lCustData
= (LPARAM
)heap_xalloc(sizeof(WCHAR
));
373 *(WCHAR
*)pOpenFileName
->lCustData
= 0;
377 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
379 static OPENFILENAMEW
* pOpenFileName
;
380 OFNOTIFYW
*pOfNotify
;
384 pOpenFileName
= (OPENFILENAMEW
*)lParam
;
387 if (LOWORD(wParam
) == IDC_EXPORT_PATH
&& HIWORD(wParam
) == EN_UPDATE
)
388 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, IDC_EXPORT_SELECTED
);
391 pOfNotify
= (OFNOTIFYW
*)lParam
;
392 switch (pOfNotify
->hdr
.code
)
396 BOOL export_branch
= FALSE
;
397 WCHAR
* path
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
398 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_SETTEXT
, 0, (LPARAM
)path
);
400 export_branch
= TRUE
;
402 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, export_branch
? IDC_EXPORT_SELECTED
: IDC_EXPORT_ALL
);
406 ExportRegistryFile_StoreSelection(hdlg
, pOpenFileName
);
417 static BOOL
InitOpenFileName(HWND hWnd
, OPENFILENAMEW
*pofn
)
419 memset(pofn
, 0, sizeof(OPENFILENAMEW
));
420 pofn
->lStructSize
= sizeof(OPENFILENAMEW
);
421 pofn
->hwndOwner
= hWnd
;
422 pofn
->hInstance
= hInst
;
424 if (FilterBuffer
[0] == 0)
426 static const WCHAR filterW
[] = {'%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','*','%','c',0};
427 WCHAR filter_reg
[MAX_PATH
], filter_reg4
[MAX_PATH
], filter_all
[MAX_PATH
];
429 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG
, filter_reg
, MAX_PATH
);
430 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG4
, filter_reg4
, MAX_PATH
);
431 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_ALL
, filter_all
, MAX_PATH
);
432 snprintfW( FilterBuffer
, MAX_PATH
, filterW
, filter_reg
, 0, 0, filter_reg4
, 0, 0, filter_all
, 0, 0 );
434 pofn
->lpstrFilter
= FilterBuffer
;
435 pofn
->nFilterIndex
= 1;
436 pofn
->lpstrFile
= FileNameBuffer
;
437 pofn
->nMaxFile
= _MAX_PATH
;
438 pofn
->lpstrFileTitle
= FileTitleBuffer
;
439 pofn
->nMaxFileTitle
= _MAX_PATH
;
440 pofn
->Flags
= OFN_HIDEREADONLY
;
441 /* some other fields may be set by the caller */
445 static BOOL
import_registry_filename(LPWSTR filename
)
447 static const WCHAR rb_mode
[] = {'r','b',0};
450 FILE* reg_file
= _wfopen(filename
, rb_mode
);
455 Success
= import_registry_file(reg_file
);
457 if(fclose(reg_file
) != 0)
463 static BOOL
ImportRegistryFile(HWND hWnd
)
467 HKEY root_key
= NULL
;
470 InitOpenFileName(hWnd
, &ofn
);
471 ofn
.Flags
|= OFN_ENABLESIZING
;
472 LoadStringW(hInst
, IDS_FILEDIALOG_IMPORT_TITLE
, title
, COUNT_OF(title
));
473 ofn
.lpstrTitle
= title
;
474 if (GetOpenFileNameW(&ofn
)) {
475 if (!import_registry_filename(ofn
.lpstrFile
)) {
476 messagebox(hWnd
, MB_OK
|MB_ICONERROR
, IDS_APP_TITLE
, IDS_IMPORT_FAILED
, ofn
.lpstrFile
);
479 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
,
480 IDS_IMPORT_SUCCESSFUL
, ofn
.lpstrFile
);
483 CheckCommDlgError(hWnd
);
485 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
487 key_path
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &root_key
);
488 RefreshListView(g_pChildWnd
->hListWnd
, root_key
, key_path
, NULL
);
495 static BOOL
ExportRegistryFile(HWND hWnd
)
500 InitOpenFileName(hWnd
, &ofn
);
501 LoadStringW(hInst
, IDS_FILEDIALOG_EXPORT_TITLE
, title
, COUNT_OF(title
));
502 ofn
.lpstrTitle
= title
;
503 ofn
.Flags
= OFN_ENABLETEMPLATE
| OFN_ENABLEHOOK
| OFN_EXPLORER
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
504 ofn
.lpfnHook
= ExportRegistryFile_OFNHookProc
;
505 ofn
.lpTemplateName
= MAKEINTRESOURCEW(IDD_EXPORT_TEMPLATE
);
506 if (GetSaveFileNameW(&ofn
)) {
508 result
= export_registry_key(ofn
.lpstrFile
, (LPWSTR
)ofn
.lCustData
, ofn
.nFilterIndex
);
510 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
514 CheckCommDlgError(hWnd
);
519 static BOOL
PrintRegistryHive(HWND hWnd
, LPCWSTR path
)
524 ZeroMemory(&pd
, sizeof(PRINTDLGW
));
525 pd
.lStructSize
= sizeof(PRINTDLGW
);
527 pd
.hDevMode
= NULL
; /* Don't forget to free or store hDevMode*/
528 pd
.hDevNames
= NULL
; /* Don't forget to free or store hDevNames*/
529 pd
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
531 pd
.nFromPage
= 0xFFFF;
534 pd
.nMaxPage
= 0xFFFF;
535 if (PrintDlgW(&pd
)) {
536 FIXME("printing is not yet implemented.\n");
537 /* GDI calls to render output. */
538 DeleteDC(pd
.hDC
); /* Delete DC when done.*/
544 hResult
= PrintDlgExW(&pd
);
545 if (hResult
== S_OK
) {
546 switch (pd
.dwResultAction
) {
547 case PD_RESULT_APPLY
:
548 /*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. */
549 FIXME("printing is not yet implemented.\n");
551 case PD_RESULT_CANCEL
:
552 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
554 case PD_RESULT_PRINT
:
555 FIXME("printing is not yet implemented.\n");
556 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
564 /*Insufficient memory. */
567 /* One or more arguments are invalid. */
570 /*Invalid pointer. */
576 /*Unspecified error. */
587 static BOOL
CopyKeyName(HWND hWnd
, LPCWSTR keyName
)
591 result
= OpenClipboard(hWnd
);
593 result
= EmptyClipboard();
595 int len
= (lstrlenW(keyName
)+1)*sizeof(WCHAR
);
596 HANDLE hClipData
= GlobalAlloc(GHND
, len
);
597 LPVOID pLoc
= GlobalLock(hClipData
);
598 lstrcpyW(pLoc
, keyName
);
599 GlobalUnlock(hClipData
);
600 SetClipboardData(CF_UNICODETEXT
, hClipData
);
603 /* error emptying clipboard*/
604 /* DWORD dwError = GetLastError(); */
607 if (!CloseClipboard()) {
608 /* error closing clipboard*/
609 /* DWORD dwError = GetLastError(); */
613 /* error opening clipboard*/
614 /* DWORD dwError = GetLastError(); */
620 static INT_PTR CALLBACK
find_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
622 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
626 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
627 CheckDlgButton(hwndDlg
, IDC_FIND_KEYS
, searchMask
&SEARCH_KEYS
? BST_CHECKED
: BST_UNCHECKED
);
628 CheckDlgButton(hwndDlg
, IDC_FIND_VALUES
, searchMask
&SEARCH_VALUES
? BST_CHECKED
: BST_UNCHECKED
);
629 CheckDlgButton(hwndDlg
, IDC_FIND_CONTENT
, searchMask
&SEARCH_CONTENT
? BST_CHECKED
: BST_UNCHECKED
);
630 CheckDlgButton(hwndDlg
, IDC_FIND_WHOLE
, searchMask
&SEARCH_WHOLE
? BST_CHECKED
: BST_UNCHECKED
);
631 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
632 SetWindowTextW(hwndValue
, searchString
);
635 switch(LOWORD(wParam
)) {
637 if (HIWORD(wParam
) == EN_UPDATE
) {
638 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
)>0);
643 if (GetWindowTextLengthW(hwndValue
)>0) {
645 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_KEYS
)) mask
|= SEARCH_KEYS
;
646 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_VALUES
)) mask
|= SEARCH_VALUES
;
647 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_CONTENT
)) mask
|= SEARCH_CONTENT
;
648 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_WHOLE
)) mask
|= SEARCH_WHOLE
;
650 GetWindowTextW(hwndValue
, searchString
, 128);
651 EndDialog(hwndDlg
, IDOK
);
655 EndDialog(hwndDlg
, IDCANCEL
);
663 static INT_PTR CALLBACK
addtofavorites_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
665 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
674 selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
676 item
.mask
= TVIF_HANDLE
| TVIF_TEXT
;
677 item
.hItem
= selected
;
679 item
.cchTextMax
= COUNT_OF(buf
);
680 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
682 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
683 SetWindowTextW(hwndValue
, buf
);
684 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
688 switch(LOWORD(wParam
)) {
690 if (HIWORD(wParam
) == EN_UPDATE
) {
691 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
) > 0);
696 if (GetWindowTextLengthW(hwndValue
)>0) {
697 GetWindowTextW(hwndValue
, favoriteName
, 128);
698 EndDialog(hwndDlg
, IDOK
);
702 EndDialog(hwndDlg
, IDCANCEL
);
710 static INT_PTR CALLBACK
removefavorite_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
712 HWND hwndList
= GetDlgItem(hwndDlg
, IDC_NAME_LIST
);
716 if (!add_favourite_key_items(NULL
, hwndList
))
718 SendMessageW(hwndList
, LB_SETCURSEL
, 0, 0);
721 switch(LOWORD(wParam
)) {
723 if (HIWORD(wParam
) == LBN_SELCHANGE
) {
724 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), lParam
!= -1);
729 int pos
= SendMessageW(hwndList
, LB_GETCURSEL
, 0, 0);
730 int len
= SendMessageW(hwndList
, LB_GETTEXTLEN
, pos
, 0);
732 WCHAR
*lpName
= heap_xalloc((len
+ 1) * sizeof(WCHAR
));
733 SendMessageW(hwndList
, LB_GETTEXT
, pos
, (LPARAM
)lpName
);
736 lstrcpyW(favoriteName
, lpName
);
737 EndDialog(hwndDlg
, IDOK
);
743 EndDialog(hwndDlg
, IDCANCEL
);
751 /*******************************************************************************
753 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
755 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
758 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
763 if (LOWORD(wParam
) >= ID_FAVORITE_FIRST
&& LOWORD(wParam
) <= ID_FAVORITE_LAST
) {
765 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
766 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
) {
767 WCHAR namebuf
[KEY_MAX_LEN
];
769 DWORD ksize
= KEY_MAX_LEN
, vsize
= sizeof(valuebuf
), type
= 0;
770 if (RegEnumValueW(hKey
, LOWORD(wParam
) - ID_FAVORITE_FIRST
, namebuf
, &ksize
, NULL
,
771 &type
, valuebuf
, &vsize
) == ERROR_SUCCESS
) {
772 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
,
773 (LPARAM
) FindPathInTree(g_pChildWnd
->hTreeWnd
, (WCHAR
*)valuebuf
) );
779 switch (LOWORD(wParam
)) {
780 case ID_REGISTRY_IMPORTREGISTRYFILE
:
781 ImportRegistryFile(hWnd
);
784 case ID_REGISTRY_EXPORTREGISTRYFILE
:
785 ExportRegistryFile(hWnd
);
787 case ID_REGISTRY_PRINT
:
789 const WCHAR empty
= 0;
790 PrintRegistryHive(hWnd
, &empty
);
795 HWND hWndDelete
= GetFocus();
796 if (hWndDelete
== g_pChildWnd
->hTreeWnd
) {
797 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
798 if (keyPath
== 0 || *keyPath
== 0) {
799 MessageBeep(MB_ICONHAND
);
800 } else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
)) {
801 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
804 } else if (hWndDelete
== g_pChildWnd
->hListWnd
) {
805 unsigned int num_selected
, index
, focus_idx
;
808 if (!(num_selected
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETSELECTEDCOUNT
, 0, 0L)))
811 if (num_selected
> 1)
813 if (messagebox(hWnd
, MB_YESNO
| MB_ICONEXCLAMATION
, IDS_DELETE_VALUE_TITLE
,
814 IDS_DELETE_VALUE_TEXT_MULTIPLE
) != IDYES
)
818 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
820 focus_idx
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
821 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
825 WCHAR
*valueName
= GetItemText(g_pChildWnd
->hListWnd
, index
);
826 if (!DeleteValue(hWnd
, hKeyRoot
, keyPath
, valueName
, num_selected
== 1))
828 heap_free(valueName
);
831 heap_free(valueName
);
832 SendMessageW(g_pChildWnd
->hListWnd
, LVM_DELETEITEM
, index
, 0L);
833 /* the default value item is always visible, so add it back in */
836 AddEntryToList(g_pChildWnd
->hListWnd
, NULL
, REG_SZ
, NULL
, 0, 0);
840 item
.state
= item
.stateMask
= LVIS_FOCUSED
;
841 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, 0, (LPARAM
)&item
);
844 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
847 } else if (IsChild(g_pChildWnd
->hTreeWnd
, hWndDelete
) ||
848 IsChild(g_pChildWnd
->hListWnd
, hWndDelete
)) {
849 SendMessageW(hWndDelete
, WM_KEYDOWN
, VK_DELETE
, 0);
854 case ID_EDIT_MODIFY_BIN
:
856 LPCWSTR valueName
= GetValueName(g_pChildWnd
->hListWnd
);
857 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
858 ModifyValue(hWnd
, hKeyRoot
, keyPath
, valueName
);
863 case ID_EDIT_FINDNEXT
:
866 if (LOWORD(wParam
) == ID_EDIT_FIND
&&
867 DialogBoxW(0, MAKEINTRESOURCEW(IDD_FIND
), hWnd
, find_dlgproc
) != IDOK
)
871 hItem
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
873 int row
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
874 HCURSOR hcursorOld
= SetCursor(LoadCursorW(NULL
, (LPCWSTR
)IDC_WAIT
));
875 hItem
= FindNext(g_pChildWnd
->hTreeWnd
, hItem
, searchString
, searchMask
, &row
);
876 SetCursor(hcursorOld
);
878 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
) hItem
);
879 InvalidateRect(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
880 UpdateWindow(g_pChildWnd
->hTreeWnd
);
885 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
886 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, (UINT
)-1, (LPARAM
)&item
);
888 item
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
889 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
890 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, row
, (LPARAM
)&item
);
891 SetFocus(g_pChildWnd
->hListWnd
);
893 SetFocus(g_pChildWnd
->hTreeWnd
);
896 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
, IDS_NOTFOUND
, searchString
);
901 case ID_EDIT_COPYKEYNAME
:
903 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
905 CopyKeyName(hWnd
, fullPath
);
910 case ID_EDIT_NEW_KEY
:
912 WCHAR newKeyW
[MAX_NEW_KEY_LEN
];
913 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
914 if (CreateKey(hWnd
, hKeyRoot
, keyPath
, newKeyW
)) {
915 if (InsertNode(g_pChildWnd
->hTreeWnd
, 0, newKeyW
))
916 StartKeyRename(g_pChildWnd
->hTreeWnd
);
921 case ID_EDIT_NEW_STRINGVALUE
:
924 case ID_EDIT_NEW_EXPANDVALUE
:
925 valueType
= REG_EXPAND_SZ
;
927 case ID_EDIT_NEW_MULTI_STRINGVALUE
:
928 valueType
= REG_MULTI_SZ
;
930 case ID_EDIT_NEW_BINARYVALUE
:
931 valueType
= REG_BINARY
;
933 case ID_EDIT_NEW_DWORDVALUE
:
934 valueType
= REG_DWORD
;
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
);
948 if (keyPath
== 0 || *keyPath
== 0) {
949 MessageBeep(MB_ICONHAND
);
950 } else if (GetFocus() == g_pChildWnd
->hTreeWnd
) {
951 StartKeyRename(g_pChildWnd
->hTreeWnd
);
952 } else if (GetFocus() == g_pChildWnd
->hListWnd
) {
953 StartValueRename(g_pChildWnd
->hListWnd
);
958 case ID_TREE_EXPAND_COLLAPSE
:
960 HTREEITEM selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
961 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_EXPAND
, TVE_TOGGLE
, (LPARAM
)selected
);
964 case ID_REGISTRY_PRINTERSETUP
:
967 /*PAGESETUPDLG psd;*/
968 /*PageSetupDlg(&psd);*/
970 case ID_REGISTRY_OPENLOCAL
:
972 case ID_REGISTRY_EXIT
:
975 case ID_FAVORITES_ADDTOFAVORITES
:
978 LPWSTR lpKeyPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
980 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_ADDFAVORITE
), hWnd
, addtofavorites_dlgproc
) == IDOK
) {
981 if (RegCreateKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
983 KEY_READ
|KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
) {
984 RegSetValueExW(hKey
, favoriteName
, 0, REG_SZ
, (BYTE
*)lpKeyPath
, (lstrlenW(lpKeyPath
)+1)*sizeof(WCHAR
));
988 heap_free(lpKeyPath
);
992 case ID_FAVORITES_REMOVEFAVORITE
:
994 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_DELFAVORITE
), hWnd
, removefavorite_dlgproc
) == IDOK
) {
996 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
997 0, KEY_READ
|KEY_WRITE
, &hKey
) == ERROR_SUCCESS
) {
998 RegDeleteValueW(hKey
, favoriteName
);
1004 case ID_VIEW_REFRESH
:
1006 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1007 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1008 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
, NULL
);
1012 /*case ID_OPTIONS_TOOLBAR:*/
1013 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1015 case ID_VIEW_STATUSBAR
:
1016 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1018 case ID_HELP_HELPTOPICS
:
1020 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1021 WinHelpW(hWnd
, help_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
)
1061 static const WCHAR captionW
[] = {'r','e','g','e','d','i','t',' ','c','h','i','l','d',' ','w','i','n','d','o','w',0};
1065 CreateWindowExW(0, szChildClass
, captionW
, WS_CHILD
| WS_VISIBLE
,
1066 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1067 hWnd
, NULL
, hInst
, 0);
1068 LoadStringW(hInst
, IDS_EXPAND
, expandW
, COUNT_OF(expandW
));
1069 LoadStringW(hInst
, IDS_COLLAPSE
, collapseW
, COUNT_OF(collapseW
));
1070 LoadStringW(hInst
, IDS_EDIT_MODIFY
, modifyW
, COUNT_OF(modifyW
));
1071 LoadStringW(hInst
, IDS_EDIT_MODIFY_BIN
, modify_binaryW
, COUNT_OF(modify_binaryW
));
1074 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1075 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1079 SetFocus(g_pChildWnd
->hWnd
);
1082 resize_frame_client(hWnd
);
1086 case WM_ENTERMENULOOP
:
1087 OnEnterMenuLoop(hWnd
);
1089 case WM_EXITMENULOOP
:
1090 OnExitMenuLoop(hWnd
);
1092 case WM_INITMENUPOPUP
:
1093 if (!HIWORD(lParam
))
1094 OnInitMenuPopup(hWnd
, (HMENU
)wParam
);
1097 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1101 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1102 WinHelpW(hWnd
, help_regedit
, HELP_QUIT
, 0);
1106 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);