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 */
31 #include "wine/debug.h"
32 #include "wine/heap.h"
33 #include "wine/unicode.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(regedit
);
37 /********************************************************************************
38 * Global and Local Variables:
41 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};
42 static BOOL bInMenuLoop
= FALSE
; /* Tells us if we are in the menu loop */
43 static WCHAR favoriteName
[128];
44 static WCHAR searchString
[128];
45 static int searchMask
= SEARCH_KEYS
| SEARCH_VALUES
| SEARCH_CONTENT
;
47 static WCHAR FileNameBuffer
[_MAX_PATH
];
48 static WCHAR FileTitleBuffer
[_MAX_PATH
];
49 static WCHAR FilterBuffer
[_MAX_PATH
];
50 static WCHAR expandW
[32], collapseW
[32];
51 static WCHAR modifyW
[32], modify_binaryW
[64];
53 /*******************************************************************************
54 * Local module support methods
57 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
59 if (IsWindowVisible(hStatusBar
)) {
62 SetupStatusBar(hWnd
, TRUE
);
63 GetClientRect(hStatusBar
, &rt
);
64 prect
->bottom
-= rt
.bottom
;
66 MoveWindow(g_pChildWnd
->hWnd
, prect
->left
, prect
->top
, prect
->right
, prect
->bottom
, TRUE
);
69 static void resize_frame_client(HWND hWnd
)
73 GetClientRect(hWnd
, &rect
);
74 resize_frame_rect(hWnd
, &rect
);
77 /********************************************************************************/
79 static void OnEnterMenuLoop(HWND hWnd
)
84 /* Update the status bar pane sizes */
86 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
88 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)&empty
);
91 static void OnExitMenuLoop(HWND hWnd
)
94 /* Update the status bar pane sizes*/
95 SetupStatusBar(hWnd
, TRUE
);
99 static void update_expand_or_collapse_item(HWND hwndTV
, HTREEITEM selection
, HMENU hMenu
)
104 item
.hItem
= selection
;
105 item
.mask
= TVIF_CHILDREN
| TVIF_HANDLE
| TVIF_STATE
;
106 item
.stateMask
= TVIS_EXPANDED
;
107 SendMessageW(hwndTV
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
109 info
.cbSize
= sizeof(MENUITEMINFOW
);
110 info
.fMask
= MIIM_FTYPE
| MIIM_STRING
| MIIM_STATE
;
111 info
.fType
= MFT_STRING
;
112 info
.fState
= MFS_ENABLED
;
113 info
.dwTypeData
= expandW
;
117 info
.fState
= MFS_GRAYED
;
121 if (item
.state
& TVIS_EXPANDED
)
122 info
.dwTypeData
= collapseW
;
125 SetMenuItemInfoW(hMenu
, ID_TREE_EXPAND_COLLAPSE
, FALSE
, &info
);
128 static void update_modify_items(HMENU hMenu
, int index
)
130 unsigned int state
= MF_ENABLED
;
135 EnableMenuItem(hMenu
, ID_EDIT_MODIFY
, state
| MF_BYCOMMAND
);
136 EnableMenuItem(hMenu
, ID_EDIT_MODIFY_BIN
, state
| MF_BYCOMMAND
);
139 static void update_delete_and_rename_items(HMENU hMenu
, WCHAR
*keyName
, int index
)
141 unsigned int state_d
= MF_ENABLED
, state_r
= MF_ENABLED
;
143 if (!g_pChildWnd
->nFocusPanel
)
145 if (!keyName
|| !*keyName
)
146 state_d
= state_r
= MF_GRAYED
;
151 if (index
== -1) state_d
= MF_GRAYED
;
154 EnableMenuItem(hMenu
, ID_EDIT_DELETE
, state_d
| MF_BYCOMMAND
);
155 EnableMenuItem(hMenu
, ID_EDIT_RENAME
, state_r
| MF_BYCOMMAND
);
158 static void update_new_items_and_copy_keyname(HMENU hMenu
, WCHAR
*keyName
)
160 unsigned int state
= MF_ENABLED
, i
;
161 unsigned int items
[] = {ID_EDIT_NEW_KEY
, ID_EDIT_NEW_STRINGVALUE
, ID_EDIT_NEW_BINARYVALUE
,
162 ID_EDIT_NEW_DWORDVALUE
, ID_EDIT_NEW_MULTI_STRINGVALUE
,
163 ID_EDIT_NEW_EXPANDVALUE
, ID_EDIT_COPYKEYNAME
};
168 for (i
= 0; i
< ARRAY_SIZE(items
); i
++)
169 EnableMenuItem(hMenu
, items
[i
], state
| MF_BYCOMMAND
);
172 static void UpdateMenuItems(HMENU hMenu
) {
173 HWND hwndTV
= g_pChildWnd
->hTreeWnd
;
174 HKEY hRootKey
= NULL
;
179 selection
= (HTREEITEM
)SendMessageW(hwndTV
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
180 keyName
= GetItemPath(hwndTV
, selection
, &hRootKey
);
181 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1,
182 MAKELPARAM(LVNI_FOCUSED
| LVNI_SELECTED
, 0));
184 update_expand_or_collapse_item(hwndTV
, selection
, hMenu
);
185 update_modify_items(hMenu
, index
);
186 update_delete_and_rename_items(hMenu
, keyName
, index
);
187 update_new_items_and_copy_keyname(hMenu
, keyName
);
188 EnableMenuItem(hMenu
, ID_FAVORITES_ADDTOFAVORITES
, (hRootKey
? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
189 EnableMenuItem(hMenu
, ID_FAVORITES_REMOVEFAVORITE
,
190 (GetMenuItemCount(hMenu
)>2 ? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
195 static void add_remove_modify_menu_items(HMENU hMenu
)
197 if (!g_pChildWnd
->nFocusPanel
)
199 while (GetMenuItemCount(hMenu
) > 9)
200 DeleteMenu(hMenu
, 0, MF_BYPOSITION
);
202 else if (GetMenuItemCount(hMenu
) < 10)
204 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
205 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY_BIN
, modify_binaryW
);
206 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY
, modifyW
);
210 static int add_favourite_key_items(HMENU hMenu
, HWND hList
)
214 DWORD num_values
, max_value_len
, value_len
, type
, i
= 0;
217 rc
= RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
, 0, KEY_READ
, &hkey
);
218 if (rc
!= ERROR_SUCCESS
) return 0;
220 rc
= RegQueryInfoKeyW(hkey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &num_values
,
221 &max_value_len
, NULL
, NULL
, NULL
);
222 if (rc
!= ERROR_SUCCESS
)
224 ERR("RegQueryInfoKey failed: %d\n", rc
);
228 if (!num_values
) goto exit
;
231 value_name
= heap_xalloc(max_value_len
* sizeof(WCHAR
));
233 if (hMenu
) AppendMenuW(hMenu
, MF_SEPARATOR
, 0, 0);
235 for (i
= 0; i
< num_values
; i
++)
237 value_len
= max_value_len
;
238 rc
= RegEnumValueW(hkey
, i
, value_name
, &value_len
, NULL
, &type
, NULL
, NULL
);
239 if (rc
== ERROR_SUCCESS
&& type
== REG_SZ
)
242 AppendMenuW(hMenu
, MF_ENABLED
| MF_STRING
, ID_FAVORITE_FIRST
+ i
, value_name
);
244 SendMessageW(hList
, LB_ADDSTRING
, 0, (LPARAM
)value_name
);
248 heap_free(value_name
);
254 static void OnInitMenuPopup(HWND hWnd
, HMENU hMenu
)
256 if (hMenu
== GetSubMenu(hMenuFrame
, ID_EDIT_MENU
))
257 add_remove_modify_menu_items(hMenu
);
258 else if (hMenu
== GetSubMenu(hMenuFrame
, ID_FAVORITES_MENU
))
260 while (GetMenuItemCount(hMenu
) > 2)
261 DeleteMenu(hMenu
, 2, MF_BYPOSITION
);
263 add_favourite_key_items(hMenu
, NULL
);
266 UpdateMenuItems(hMenu
);
269 static void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
274 if (nFlags
& MF_POPUP
) {
275 if (hSysMenu
!= GetMenu(hWnd
)) {
276 if (nItemID
== 2) nItemID
= 5;
279 if (LoadStringW(hInst
, nItemID
, str
, 100)) {
280 /* load appropriate string*/
282 /* first newline terminates actual string*/
283 lpsz
= strchrW(lpsz
, '\n');
287 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)str
);
290 void SetupStatusBar(HWND hWnd
, BOOL bResize
)
294 GetClientRect(hWnd
, &rc
);
298 SendMessageW(hStatusBar
, WM_SIZE
, 0, 0);
299 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
303 void UpdateStatusBar(void)
305 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
306 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)fullPath
);
310 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
312 BOOL vis
= IsWindowVisible(hchild
);
313 HMENU hMenuView
= GetSubMenu(hMenuFrame
, ID_VIEW_MENU
);
315 CheckMenuItem(hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
316 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
317 resize_frame_client(hWnd
);
320 static BOOL
CheckCommDlgError(HWND hWnd
)
322 DWORD dwErrorCode
= CommDlgExtendedError();
323 switch (dwErrorCode
) {
324 case CDERR_DIALOGFAILURE
:
326 case CDERR_FINDRESFAILURE
:
328 case CDERR_NOHINSTANCE
:
330 case CDERR_INITIALIZATION
:
334 case CDERR_LOCKRESFAILURE
:
336 case CDERR_NOTEMPLATE
:
338 case CDERR_LOADRESFAILURE
:
340 case CDERR_STRUCTSIZE
:
342 case CDERR_LOADSTRFAILURE
:
344 case FNERR_BUFFERTOOSMALL
:
346 case CDERR_MEMALLOCFAILURE
:
348 case FNERR_INVALIDFILENAME
:
350 case CDERR_MEMLOCKFAILURE
:
352 case FNERR_SUBCLASSFAILURE
:
360 static void ExportRegistryFile_StoreSelection(HWND hdlg
, OPENFILENAMEW
*pOpenFileName
)
362 if (IsDlgButtonChecked(hdlg
, IDC_EXPORT_SELECTED
))
364 INT len
= SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXTLENGTH
, 0, 0);
365 pOpenFileName
->lCustData
= (LPARAM
)heap_xalloc((len
+ 1) * sizeof(WCHAR
));
366 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXT
, len
+1, pOpenFileName
->lCustData
);
370 pOpenFileName
->lCustData
= (LPARAM
)heap_xalloc(sizeof(WCHAR
));
371 *(WCHAR
*)pOpenFileName
->lCustData
= 0;
375 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
377 static OPENFILENAMEW
* pOpenFileName
;
378 OFNOTIFYW
*pOfNotify
;
382 pOpenFileName
= (OPENFILENAMEW
*)lParam
;
385 if (LOWORD(wParam
) == IDC_EXPORT_PATH
&& HIWORD(wParam
) == EN_UPDATE
)
386 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, IDC_EXPORT_SELECTED
);
389 pOfNotify
= (OFNOTIFYW
*)lParam
;
390 switch (pOfNotify
->hdr
.code
)
394 BOOL export_branch
= FALSE
;
395 WCHAR
* path
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
396 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_SETTEXT
, 0, (LPARAM
)path
);
398 export_branch
= TRUE
;
400 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, export_branch
? IDC_EXPORT_SELECTED
: IDC_EXPORT_ALL
);
404 ExportRegistryFile_StoreSelection(hdlg
, pOpenFileName
);
415 static BOOL
InitOpenFileName(HWND hWnd
, OPENFILENAMEW
*pofn
)
417 memset(pofn
, 0, sizeof(OPENFILENAMEW
));
418 pofn
->lStructSize
= sizeof(OPENFILENAMEW
);
419 pofn
->hwndOwner
= hWnd
;
420 pofn
->hInstance
= hInst
;
422 if (FilterBuffer
[0] == 0)
424 static const WCHAR filterW
[] = {'%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','*','%','c',0};
425 WCHAR filter_reg
[MAX_PATH
], filter_reg4
[MAX_PATH
], filter_all
[MAX_PATH
];
427 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG
, filter_reg
, MAX_PATH
);
428 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG4
, filter_reg4
, MAX_PATH
);
429 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_ALL
, filter_all
, MAX_PATH
);
430 snprintfW( FilterBuffer
, MAX_PATH
, filterW
, filter_reg
, 0, 0, filter_reg4
, 0, 0, filter_all
, 0, 0 );
432 pofn
->lpstrFilter
= FilterBuffer
;
433 pofn
->nFilterIndex
= 1;
434 pofn
->lpstrFile
= FileNameBuffer
;
435 pofn
->nMaxFile
= _MAX_PATH
;
436 pofn
->lpstrFileTitle
= FileTitleBuffer
;
437 pofn
->nMaxFileTitle
= _MAX_PATH
;
438 pofn
->Flags
= OFN_HIDEREADONLY
;
439 /* some other fields may be set by the caller */
443 static BOOL
import_registry_filename(LPWSTR filename
)
445 static const WCHAR rb_mode
[] = {'r','b',0};
448 FILE* reg_file
= _wfopen(filename
, rb_mode
);
453 Success
= import_registry_file(reg_file
);
455 if(fclose(reg_file
) != 0)
461 static BOOL
ImportRegistryFile(HWND hWnd
)
465 HKEY root_key
= NULL
;
468 InitOpenFileName(hWnd
, &ofn
);
469 ofn
.Flags
|= OFN_ENABLESIZING
;
470 LoadStringW(hInst
, IDS_FILEDIALOG_IMPORT_TITLE
, title
, ARRAY_SIZE(title
));
471 ofn
.lpstrTitle
= title
;
472 if (GetOpenFileNameW(&ofn
)) {
473 if (!import_registry_filename(ofn
.lpstrFile
)) {
474 messagebox(hWnd
, MB_OK
|MB_ICONERROR
, IDS_APP_TITLE
, IDS_IMPORT_FAILED
, ofn
.lpstrFile
);
477 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
,
478 IDS_IMPORT_SUCCESSFUL
, ofn
.lpstrFile
);
481 CheckCommDlgError(hWnd
);
483 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
485 key_path
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &root_key
);
486 RefreshListView(g_pChildWnd
->hListWnd
, root_key
, key_path
, NULL
);
493 static BOOL
ExportRegistryFile(HWND hWnd
)
498 InitOpenFileName(hWnd
, &ofn
);
499 LoadStringW(hInst
, IDS_FILEDIALOG_EXPORT_TITLE
, title
, ARRAY_SIZE(title
));
500 ofn
.lpstrTitle
= title
;
501 ofn
.Flags
= OFN_ENABLETEMPLATE
| OFN_ENABLEHOOK
| OFN_EXPLORER
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
502 ofn
.lpfnHook
= ExportRegistryFile_OFNHookProc
;
503 ofn
.lpTemplateName
= MAKEINTRESOURCEW(IDD_EXPORT_TEMPLATE
);
504 if (GetSaveFileNameW(&ofn
)) {
506 result
= export_registry_key(ofn
.lpstrFile
, (LPWSTR
)ofn
.lCustData
, ofn
.nFilterIndex
);
508 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
512 CheckCommDlgError(hWnd
);
517 static BOOL
PrintRegistryHive(HWND hWnd
, LPCWSTR path
)
522 ZeroMemory(&pd
, sizeof(PRINTDLGW
));
523 pd
.lStructSize
= sizeof(PRINTDLGW
);
525 pd
.hDevMode
= NULL
; /* Don't forget to free or store hDevMode*/
526 pd
.hDevNames
= NULL
; /* Don't forget to free or store hDevNames*/
527 pd
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
529 pd
.nFromPage
= 0xFFFF;
532 pd
.nMaxPage
= 0xFFFF;
533 if (PrintDlgW(&pd
)) {
534 FIXME("printing is not yet implemented.\n");
535 /* GDI calls to render output. */
536 DeleteDC(pd
.hDC
); /* Delete DC when done.*/
542 hResult
= PrintDlgExW(&pd
);
543 if (hResult
== S_OK
) {
544 switch (pd
.dwResultAction
) {
545 case PD_RESULT_APPLY
:
546 /*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. */
547 FIXME("printing is not yet implemented.\n");
549 case PD_RESULT_CANCEL
:
550 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
552 case PD_RESULT_PRINT
:
553 FIXME("printing is not yet implemented.\n");
554 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
562 /*Insufficient memory. */
565 /* One or more arguments are invalid. */
568 /*Invalid pointer. */
574 /*Unspecified error. */
585 static BOOL
CopyKeyName(HWND hWnd
, LPCWSTR keyName
)
589 result
= OpenClipboard(hWnd
);
591 result
= EmptyClipboard();
593 int len
= (lstrlenW(keyName
)+1)*sizeof(WCHAR
);
594 HANDLE hClipData
= GlobalAlloc(GHND
, len
);
595 LPVOID pLoc
= GlobalLock(hClipData
);
596 lstrcpyW(pLoc
, keyName
);
597 GlobalUnlock(hClipData
);
598 SetClipboardData(CF_UNICODETEXT
, hClipData
);
601 /* error emptying clipboard*/
602 /* DWORD dwError = GetLastError(); */
605 if (!CloseClipboard()) {
606 /* error closing clipboard*/
607 /* DWORD dwError = GetLastError(); */
611 /* error opening clipboard*/
612 /* DWORD dwError = GetLastError(); */
618 static INT_PTR CALLBACK
find_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
620 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
624 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
625 CheckDlgButton(hwndDlg
, IDC_FIND_KEYS
, searchMask
&SEARCH_KEYS
? BST_CHECKED
: BST_UNCHECKED
);
626 CheckDlgButton(hwndDlg
, IDC_FIND_VALUES
, searchMask
&SEARCH_VALUES
? BST_CHECKED
: BST_UNCHECKED
);
627 CheckDlgButton(hwndDlg
, IDC_FIND_CONTENT
, searchMask
&SEARCH_CONTENT
? BST_CHECKED
: BST_UNCHECKED
);
628 CheckDlgButton(hwndDlg
, IDC_FIND_WHOLE
, searchMask
&SEARCH_WHOLE
? BST_CHECKED
: BST_UNCHECKED
);
629 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
630 SetWindowTextW(hwndValue
, searchString
);
633 switch(LOWORD(wParam
)) {
635 if (HIWORD(wParam
) == EN_UPDATE
) {
636 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
)>0);
641 if (GetWindowTextLengthW(hwndValue
)>0) {
643 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_KEYS
)) mask
|= SEARCH_KEYS
;
644 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_VALUES
)) mask
|= SEARCH_VALUES
;
645 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_CONTENT
)) mask
|= SEARCH_CONTENT
;
646 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_WHOLE
)) mask
|= SEARCH_WHOLE
;
648 GetWindowTextW(hwndValue
, searchString
, 128);
649 EndDialog(hwndDlg
, IDOK
);
653 EndDialog(hwndDlg
, IDCANCEL
);
661 static INT_PTR CALLBACK
addtofavorites_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
663 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
672 selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
674 item
.mask
= TVIF_HANDLE
| TVIF_TEXT
;
675 item
.hItem
= selected
;
677 item
.cchTextMax
= ARRAY_SIZE(buf
);
678 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
680 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
681 SetWindowTextW(hwndValue
, buf
);
682 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
686 switch(LOWORD(wParam
)) {
688 if (HIWORD(wParam
) == EN_UPDATE
) {
689 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
) > 0);
694 if (GetWindowTextLengthW(hwndValue
)>0) {
695 GetWindowTextW(hwndValue
, favoriteName
, 128);
696 EndDialog(hwndDlg
, IDOK
);
700 EndDialog(hwndDlg
, IDCANCEL
);
708 static INT_PTR CALLBACK
removefavorite_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
710 HWND hwndList
= GetDlgItem(hwndDlg
, IDC_NAME_LIST
);
714 if (!add_favourite_key_items(NULL
, hwndList
))
716 SendMessageW(hwndList
, LB_SETCURSEL
, 0, 0);
719 switch(LOWORD(wParam
)) {
721 if (HIWORD(wParam
) == LBN_SELCHANGE
) {
722 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), lParam
!= -1);
727 int pos
= SendMessageW(hwndList
, LB_GETCURSEL
, 0, 0);
728 int len
= SendMessageW(hwndList
, LB_GETTEXTLEN
, pos
, 0);
730 WCHAR
*lpName
= heap_xalloc((len
+ 1) * sizeof(WCHAR
));
731 SendMessageW(hwndList
, LB_GETTEXT
, pos
, (LPARAM
)lpName
);
734 lstrcpyW(favoriteName
, lpName
);
735 EndDialog(hwndDlg
, IDOK
);
741 EndDialog(hwndDlg
, IDCANCEL
);
749 /*******************************************************************************
751 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
753 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
756 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
761 if (LOWORD(wParam
) >= ID_FAVORITE_FIRST
&& LOWORD(wParam
) <= ID_FAVORITE_LAST
) {
763 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
764 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
) {
765 WCHAR namebuf
[KEY_MAX_LEN
];
767 DWORD ksize
= KEY_MAX_LEN
, vsize
= sizeof(valuebuf
), type
= 0;
768 if (RegEnumValueW(hKey
, LOWORD(wParam
) - ID_FAVORITE_FIRST
, namebuf
, &ksize
, NULL
,
769 &type
, valuebuf
, &vsize
) == ERROR_SUCCESS
) {
770 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
,
771 (LPARAM
) FindPathInTree(g_pChildWnd
->hTreeWnd
, (WCHAR
*)valuebuf
) );
777 switch (LOWORD(wParam
)) {
778 case ID_REGISTRY_IMPORTREGISTRYFILE
:
779 ImportRegistryFile(hWnd
);
782 case ID_REGISTRY_EXPORTREGISTRYFILE
:
783 ExportRegistryFile(hWnd
);
785 case ID_REGISTRY_PRINT
:
787 const WCHAR empty
= 0;
788 PrintRegistryHive(hWnd
, &empty
);
793 HWND hWndDelete
= GetFocus();
794 if (hWndDelete
== g_pChildWnd
->hTreeWnd
) {
795 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
796 if (keyPath
== 0 || *keyPath
== 0) {
797 MessageBeep(MB_ICONHAND
);
798 } else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
)) {
799 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
802 } else if (hWndDelete
== g_pChildWnd
->hListWnd
) {
803 unsigned int num_selected
, index
, focus_idx
;
806 num_selected
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETSELECTEDCOUNT
, 0, 0L);
810 else if (num_selected
== 1)
811 index
= IDS_DELETE_VALUE_TEXT
;
813 index
= IDS_DELETE_VALUE_TEXT_MULTIPLE
;
815 if (messagebox(hWnd
, MB_YESNO
| MB_ICONEXCLAMATION
, IDS_DELETE_VALUE_TITLE
, index
) != 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
))
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 WCHAR
*valueName
= GetValueName(g_pChildWnd
->hListWnd
);
857 WCHAR
*keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
858 ModifyValue(hWnd
, hKeyRoot
, keyPath
, valueName
);
860 heap_free(valueName
);
864 case ID_EDIT_FINDNEXT
:
867 if (LOWORD(wParam
) == ID_EDIT_FIND
&&
868 DialogBoxW(0, MAKEINTRESOURCEW(IDD_FIND
), hWnd
, find_dlgproc
) != IDOK
)
872 hItem
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
874 int row
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
875 HCURSOR hcursorOld
= SetCursor(LoadCursorW(NULL
, (LPCWSTR
)IDC_WAIT
));
876 hItem
= FindNext(g_pChildWnd
->hTreeWnd
, hItem
, searchString
, searchMask
, &row
);
877 SetCursor(hcursorOld
);
879 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
) hItem
);
880 InvalidateRect(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
881 UpdateWindow(g_pChildWnd
->hTreeWnd
);
886 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
887 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, (UINT
)-1, (LPARAM
)&item
);
889 item
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
890 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
891 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, row
, (LPARAM
)&item
);
892 SetFocus(g_pChildWnd
->hListWnd
);
894 SetFocus(g_pChildWnd
->hTreeWnd
);
897 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
, IDS_NOTFOUND
, searchString
);
902 case ID_EDIT_COPYKEYNAME
:
904 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
906 CopyKeyName(hWnd
, fullPath
);
911 case ID_EDIT_NEW_KEY
:
913 WCHAR newKeyW
[MAX_NEW_KEY_LEN
];
914 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
915 if (CreateKey(hWnd
, hKeyRoot
, keyPath
, newKeyW
)) {
916 if (InsertNode(g_pChildWnd
->hTreeWnd
, 0, newKeyW
))
917 StartKeyRename(g_pChildWnd
->hTreeWnd
);
922 case ID_EDIT_NEW_STRINGVALUE
:
925 case ID_EDIT_NEW_EXPANDVALUE
:
926 valueType
= REG_EXPAND_SZ
;
928 case ID_EDIT_NEW_MULTI_STRINGVALUE
:
929 valueType
= REG_MULTI_SZ
;
931 case ID_EDIT_NEW_BINARYVALUE
:
932 valueType
= REG_BINARY
;
934 case ID_EDIT_NEW_DWORDVALUE
:
935 valueType
= REG_DWORD
;
939 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
940 WCHAR newKey
[MAX_NEW_KEY_LEN
];
941 if (CreateValue(hWnd
, hKeyRoot
, keyPath
, valueType
, newKey
))
942 StartValueRename(g_pChildWnd
->hListWnd
);
948 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
949 if (keyPath
== 0 || *keyPath
== 0) {
950 MessageBeep(MB_ICONHAND
);
951 } else if (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
));
989 heap_free(lpKeyPath
);
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 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1022 WinHelpW(hWnd
, help_regedit
, HELP_FINDER
, 0);
1028 case ID_VIEW_SPLIT
: {
1031 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1032 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1033 pt
.y
= (rt
.bottom
/ 2);
1035 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
)) {
1036 SetCursorPos(pts
.x
, pts
.y
);
1037 SetCursor(LoadCursorW(0, (LPCWSTR
)IDC_SIZEWE
));
1038 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1049 /********************************************************************************
1051 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1053 * PURPOSE: Processes messages for the main frame window.
1055 * WM_COMMAND - process the application menu
1056 * WM_DESTROY - post a quit message and return
1060 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1062 static const WCHAR captionW
[] = {'r','e','g','e','d','i','t',' ','c','h','i','l','d',' ','w','i','n','d','o','w',0};
1066 CreateWindowExW(0, szChildClass
, captionW
, WS_CHILD
| WS_VISIBLE
,
1067 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1068 hWnd
, NULL
, hInst
, 0);
1069 LoadStringW(hInst
, IDS_EXPAND
, expandW
, ARRAY_SIZE(expandW
));
1070 LoadStringW(hInst
, IDS_COLLAPSE
, collapseW
, ARRAY_SIZE(collapseW
));
1071 LoadStringW(hInst
, IDS_EDIT_MODIFY
, modifyW
, ARRAY_SIZE(modifyW
));
1072 LoadStringW(hInst
, IDS_EDIT_MODIFY_BIN
, modify_binaryW
, ARRAY_SIZE(modify_binaryW
));
1075 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1076 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1080 SetFocus(g_pChildWnd
->hWnd
);
1083 resize_frame_client(hWnd
);
1087 case WM_ENTERMENULOOP
:
1088 OnEnterMenuLoop(hWnd
);
1090 case WM_EXITMENULOOP
:
1091 OnExitMenuLoop(hWnd
);
1093 case WM_INITMENUPOPUP
:
1094 if (!HIWORD(lParam
))
1095 OnInitMenuPopup(hWnd
, (HMENU
)wParam
);
1098 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1102 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1103 WinHelpW(hWnd
, help_regedit
, HELP_QUIT
, 0);
1107 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);