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"
34 WINE_DEFAULT_DEBUG_CHANNEL(regedit
);
36 /********************************************************************************
37 * Global and Local Variables:
40 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};
41 static BOOL bInMenuLoop
= FALSE
; /* Tells us if we are in the menu loop */
42 static WCHAR favoriteName
[128];
43 static WCHAR searchString
[128];
44 static int searchMask
= SEARCH_KEYS
| SEARCH_VALUES
| SEARCH_CONTENT
;
46 static WCHAR FileNameBuffer
[_MAX_PATH
];
47 static WCHAR FileTitleBuffer
[_MAX_PATH
];
48 static WCHAR FilterBuffer
[_MAX_PATH
];
49 static WCHAR expandW
[32], collapseW
[32];
50 static WCHAR modifyW
[32], modify_binaryW
[64];
52 /*******************************************************************************
53 * Local module support methods
56 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
58 if (IsWindowVisible(hStatusBar
)) {
61 SetupStatusBar(hWnd
, TRUE
);
62 GetClientRect(hStatusBar
, &rt
);
63 prect
->bottom
-= rt
.bottom
;
65 MoveWindow(g_pChildWnd
->hWnd
, prect
->left
, prect
->top
, prect
->right
, prect
->bottom
, TRUE
);
68 static void resize_frame_client(HWND hWnd
)
72 GetClientRect(hWnd
, &rect
);
73 resize_frame_rect(hWnd
, &rect
);
76 /********************************************************************************/
78 static void OnEnterMenuLoop(HWND hWnd
)
83 /* Update the status bar pane sizes */
85 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
87 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)&empty
);
90 static void OnExitMenuLoop(HWND hWnd
)
93 /* Update the status bar pane sizes*/
94 SetupStatusBar(hWnd
, TRUE
);
98 static void update_expand_or_collapse_item(HWND hwndTV
, HTREEITEM selection
, HMENU hMenu
)
103 item
.hItem
= selection
;
104 item
.mask
= TVIF_CHILDREN
| TVIF_HANDLE
| TVIF_STATE
;
105 item
.stateMask
= TVIS_EXPANDED
;
106 SendMessageW(hwndTV
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
108 info
.cbSize
= sizeof(MENUITEMINFOW
);
109 info
.fMask
= MIIM_FTYPE
| MIIM_STRING
| MIIM_STATE
;
110 info
.fType
= MFT_STRING
;
111 info
.fState
= MFS_ENABLED
;
112 info
.dwTypeData
= expandW
;
116 info
.fState
= MFS_GRAYED
;
120 if (item
.state
& TVIS_EXPANDED
)
121 info
.dwTypeData
= collapseW
;
124 SetMenuItemInfoW(hMenu
, ID_TREE_EXPAND_COLLAPSE
, FALSE
, &info
);
127 static void update_modify_items(HMENU hMenu
, int index
)
129 unsigned int state
= MF_ENABLED
;
134 EnableMenuItem(hMenu
, ID_EDIT_MODIFY
, state
| MF_BYCOMMAND
);
135 EnableMenuItem(hMenu
, ID_EDIT_MODIFY_BIN
, state
| MF_BYCOMMAND
);
138 static void update_delete_and_rename_items(HMENU hMenu
, WCHAR
*keyName
, int index
)
140 unsigned int state_d
= MF_ENABLED
, state_r
= MF_ENABLED
;
142 if (!g_pChildWnd
->nFocusPanel
)
144 if (!keyName
|| !*keyName
)
145 state_d
= state_r
= MF_GRAYED
;
150 if (index
== -1) state_d
= MF_GRAYED
;
153 EnableMenuItem(hMenu
, ID_EDIT_DELETE
, state_d
| MF_BYCOMMAND
);
154 EnableMenuItem(hMenu
, ID_EDIT_RENAME
, state_r
| MF_BYCOMMAND
);
157 static void update_new_items_and_copy_keyname(HMENU hMenu
, WCHAR
*keyName
)
159 unsigned int state
= MF_ENABLED
, i
;
160 unsigned int items
[] = {ID_EDIT_NEW_KEY
, ID_EDIT_NEW_STRINGVALUE
, ID_EDIT_NEW_BINARYVALUE
,
161 ID_EDIT_NEW_DWORDVALUE
, ID_EDIT_NEW_MULTI_STRINGVALUE
,
162 ID_EDIT_NEW_EXPANDVALUE
, ID_EDIT_COPYKEYNAME
};
167 for (i
= 0; i
< ARRAY_SIZE(items
); i
++)
168 EnableMenuItem(hMenu
, items
[i
], state
| MF_BYCOMMAND
);
171 static void UpdateMenuItems(HMENU hMenu
) {
172 HWND hwndTV
= g_pChildWnd
->hTreeWnd
;
173 HKEY hRootKey
= NULL
;
178 selection
= (HTREEITEM
)SendMessageW(hwndTV
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
179 keyName
= GetItemPath(hwndTV
, selection
, &hRootKey
);
180 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1,
181 MAKELPARAM(LVNI_FOCUSED
| LVNI_SELECTED
, 0));
183 update_expand_or_collapse_item(hwndTV
, selection
, hMenu
);
184 update_modify_items(hMenu
, index
);
185 update_delete_and_rename_items(hMenu
, keyName
, index
);
186 update_new_items_and_copy_keyname(hMenu
, keyName
);
187 EnableMenuItem(hMenu
, ID_FAVORITES_ADDTOFAVORITES
, (hRootKey
? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
188 EnableMenuItem(hMenu
, ID_FAVORITES_REMOVEFAVORITE
,
189 (GetMenuItemCount(hMenu
)>2 ? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
194 static void add_remove_modify_menu_items(HMENU hMenu
)
196 if (!g_pChildWnd
->nFocusPanel
)
198 while (GetMenuItemCount(hMenu
) > 9)
199 DeleteMenu(hMenu
, 0, MF_BYPOSITION
);
201 else if (GetMenuItemCount(hMenu
) < 10)
203 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
204 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY_BIN
, modify_binaryW
);
205 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY
, modifyW
);
209 static int add_favourite_key_items(HMENU hMenu
, HWND hList
)
213 DWORD num_values
, max_value_len
, value_len
, type
, i
= 0;
216 rc
= RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
, 0, KEY_READ
, &hkey
);
217 if (rc
!= ERROR_SUCCESS
) return 0;
219 rc
= RegQueryInfoKeyW(hkey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &num_values
,
220 &max_value_len
, NULL
, NULL
, NULL
);
221 if (rc
!= ERROR_SUCCESS
)
223 ERR("RegQueryInfoKey failed: %d\n", rc
);
227 if (!num_values
) goto exit
;
230 value_name
= heap_xalloc(max_value_len
* sizeof(WCHAR
));
232 if (hMenu
) AppendMenuW(hMenu
, MF_SEPARATOR
, 0, 0);
234 for (i
= 0; i
< num_values
; i
++)
236 value_len
= max_value_len
;
237 rc
= RegEnumValueW(hkey
, i
, value_name
, &value_len
, NULL
, &type
, NULL
, NULL
);
238 if (rc
== ERROR_SUCCESS
&& type
== REG_SZ
)
241 AppendMenuW(hMenu
, MF_ENABLED
| MF_STRING
, ID_FAVORITE_FIRST
+ i
, value_name
);
243 SendMessageW(hList
, LB_ADDSTRING
, 0, (LPARAM
)value_name
);
247 heap_free(value_name
);
253 static void OnInitMenuPopup(HWND hWnd
, HMENU hMenu
)
255 if (hMenu
== GetSubMenu(hMenuFrame
, ID_EDIT_MENU
))
256 add_remove_modify_menu_items(hMenu
);
257 else if (hMenu
== GetSubMenu(hMenuFrame
, ID_FAVORITES_MENU
))
259 while (GetMenuItemCount(hMenu
) > 2)
260 DeleteMenu(hMenu
, 2, MF_BYPOSITION
);
262 add_favourite_key_items(hMenu
, NULL
);
265 UpdateMenuItems(hMenu
);
268 static void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
273 if (nFlags
& MF_POPUP
) {
274 if (hSysMenu
!= GetMenu(hWnd
)) {
275 if (nItemID
== 2) nItemID
= 5;
278 if (LoadStringW(hInst
, nItemID
, str
, 100)) {
279 /* load appropriate string*/
281 /* first newline terminates actual string*/
282 lpsz
= wcschr(lpsz
, '\n');
286 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)str
);
289 void SetupStatusBar(HWND hWnd
, BOOL bResize
)
293 GetClientRect(hWnd
, &rc
);
297 SendMessageW(hStatusBar
, WM_SIZE
, 0, 0);
298 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
302 void UpdateStatusBar(void)
304 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
305 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)fullPath
);
309 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
311 BOOL vis
= IsWindowVisible(hchild
);
312 HMENU hMenuView
= GetSubMenu(hMenuFrame
, ID_VIEW_MENU
);
314 CheckMenuItem(hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
315 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
316 resize_frame_client(hWnd
);
319 static BOOL
CheckCommDlgError(HWND hWnd
)
321 DWORD dwErrorCode
= CommDlgExtendedError();
322 switch (dwErrorCode
) {
323 case CDERR_DIALOGFAILURE
:
325 case CDERR_FINDRESFAILURE
:
327 case CDERR_NOHINSTANCE
:
329 case CDERR_INITIALIZATION
:
333 case CDERR_LOCKRESFAILURE
:
335 case CDERR_NOTEMPLATE
:
337 case CDERR_LOADRESFAILURE
:
339 case CDERR_STRUCTSIZE
:
341 case CDERR_LOADSTRFAILURE
:
343 case FNERR_BUFFERTOOSMALL
:
345 case CDERR_MEMALLOCFAILURE
:
347 case FNERR_INVALIDFILENAME
:
349 case CDERR_MEMLOCKFAILURE
:
351 case FNERR_SUBCLASSFAILURE
:
359 static void ExportRegistryFile_StoreSelection(HWND hdlg
, OPENFILENAMEW
*pOpenFileName
)
361 if (IsDlgButtonChecked(hdlg
, IDC_EXPORT_SELECTED
))
363 INT len
= SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXTLENGTH
, 0, 0);
364 pOpenFileName
->lCustData
= (LPARAM
)heap_xalloc((len
+ 1) * sizeof(WCHAR
));
365 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXT
, len
+1, pOpenFileName
->lCustData
);
369 pOpenFileName
->lCustData
= (LPARAM
)heap_xalloc(sizeof(WCHAR
));
370 *(WCHAR
*)pOpenFileName
->lCustData
= 0;
374 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
376 static OPENFILENAMEW
* pOpenFileName
;
377 OFNOTIFYW
*pOfNotify
;
381 pOpenFileName
= (OPENFILENAMEW
*)lParam
;
384 if (LOWORD(wParam
) == IDC_EXPORT_PATH
&& HIWORD(wParam
) == EN_UPDATE
)
385 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, IDC_EXPORT_SELECTED
);
388 pOfNotify
= (OFNOTIFYW
*)lParam
;
389 switch (pOfNotify
->hdr
.code
)
393 BOOL export_branch
= FALSE
;
394 WCHAR
* path
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
395 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_SETTEXT
, 0, (LPARAM
)path
);
397 export_branch
= TRUE
;
399 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, export_branch
? IDC_EXPORT_SELECTED
: IDC_EXPORT_ALL
);
403 ExportRegistryFile_StoreSelection(hdlg
, pOpenFileName
);
414 static BOOL
InitOpenFileName(HWND hWnd
, OPENFILENAMEW
*pofn
)
416 memset(pofn
, 0, sizeof(OPENFILENAMEW
));
417 pofn
->lStructSize
= sizeof(OPENFILENAMEW
);
418 pofn
->hwndOwner
= hWnd
;
419 pofn
->hInstance
= hInst
;
421 if (FilterBuffer
[0] == 0)
423 static const WCHAR filterW
[] = {'%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','*','%','c',0};
424 WCHAR filter_reg
[MAX_PATH
], filter_reg4
[MAX_PATH
], filter_all
[MAX_PATH
];
426 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG
, filter_reg
, MAX_PATH
);
427 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG4
, filter_reg4
, MAX_PATH
);
428 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_ALL
, filter_all
, MAX_PATH
);
429 swprintf( FilterBuffer
, ARRAY_SIZE(FilterBuffer
), filterW
,
430 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
);