4 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(regedit
);
38 /********************************************************************************
39 * Global and Local Variables:
42 static const WCHAR favoritesKey
[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','A','p','p','l','e','t','s','\\','R','e','g','E','d','i','t','\\','F','a','v','o','r','i','t','e','s',0};
43 static BOOL bInMenuLoop
= FALSE
; /* Tells us if we are in the menu loop */
44 static WCHAR favoriteName
[128];
45 static WCHAR searchString
[128];
46 static int searchMask
= SEARCH_KEYS
| SEARCH_VALUES
| SEARCH_CONTENT
;
48 static WCHAR FileNameBuffer
[_MAX_PATH
];
49 static WCHAR FileTitleBuffer
[_MAX_PATH
];
50 static WCHAR FilterBuffer
[_MAX_PATH
];
51 static WCHAR expandW
[32], collapseW
[32];
52 static WCHAR modifyW
[32], modify_binaryW
[64];
54 /*******************************************************************************
55 * Local module support methods
58 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
62 if (IsWindowVisible(hToolBar)) {
63 SendMessageW(hToolBar, WM_SIZE, 0, 0);
64 GetClientRect(hToolBar, &rt);
65 prect->top = rt.bottom+3;
66 prect->bottom -= rt.bottom+3;
69 if (IsWindowVisible(hStatusBar
)) {
70 SetupStatusBar(hWnd
, TRUE
);
71 GetClientRect(hStatusBar
, &rt
);
72 prect
->bottom
-= rt
.bottom
;
74 MoveWindow(g_pChildWnd
->hWnd
, prect
->left
, prect
->top
, prect
->right
, prect
->bottom
, TRUE
);
77 static void resize_frame_client(HWND hWnd
)
81 GetClientRect(hWnd
, &rect
);
82 resize_frame_rect(hWnd
, &rect
);
85 /********************************************************************************/
87 static void OnEnterMenuLoop(HWND hWnd
)
92 /* Update the status bar pane sizes */
94 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
96 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)&empty
);
99 static void OnExitMenuLoop(HWND hWnd
)
102 /* Update the status bar pane sizes*/
103 SetupStatusBar(hWnd
, TRUE
);
107 static void update_expand_or_collapse_item(HWND hwndTV
, HTREEITEM selection
, HMENU hMenu
)
112 item
.hItem
= selection
;
113 item
.mask
= TVIF_CHILDREN
| TVIF_HANDLE
| TVIF_STATE
;
114 item
.stateMask
= TVIS_EXPANDED
;
115 SendMessageW(hwndTV
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
117 info
.cbSize
= sizeof(MENUITEMINFOW
);
118 info
.fMask
= MIIM_FTYPE
| MIIM_STRING
| MIIM_STATE
;
119 info
.fType
= MFT_STRING
;
120 info
.fState
= MFS_ENABLED
;
121 info
.dwTypeData
= expandW
;
125 info
.fState
= MFS_GRAYED
;
129 if (item
.state
& TVIS_EXPANDED
)
130 info
.dwTypeData
= collapseW
;
133 SetMenuItemInfoW(hMenu
, ID_TREE_EXPAND_COLLAPSE
, FALSE
, &info
);
136 static void update_modify_items(HMENU hMenu
, int index
)
138 unsigned int state
= MF_ENABLED
;
143 EnableMenuItem(hMenu
, ID_EDIT_MODIFY
, state
| MF_BYCOMMAND
);
144 EnableMenuItem(hMenu
, ID_EDIT_MODIFY_BIN
, state
| MF_BYCOMMAND
);
147 static void update_delete_and_rename_items(HMENU hMenu
, WCHAR
*keyName
, int index
)
149 unsigned int state_d
= MF_ENABLED
, state_r
= MF_ENABLED
;
151 if (!g_pChildWnd
->nFocusPanel
)
153 if (!keyName
|| !*keyName
)
154 state_d
= state_r
= MF_GRAYED
;
159 if (index
== -1) state_d
= MF_GRAYED
;
162 EnableMenuItem(hMenu
, ID_EDIT_DELETE
, state_d
| MF_BYCOMMAND
);
163 EnableMenuItem(hMenu
, ID_EDIT_RENAME
, state_r
| MF_BYCOMMAND
);
166 static void update_new_items_and_copy_keyname(HMENU hMenu
, WCHAR
*keyName
)
168 unsigned int state
= MF_ENABLED
, i
;
169 unsigned int items
[] = {ID_EDIT_NEW_KEY
, ID_EDIT_NEW_STRINGVALUE
, ID_EDIT_NEW_BINARYVALUE
,
170 ID_EDIT_NEW_DWORDVALUE
, ID_EDIT_NEW_MULTI_STRINGVALUE
,
171 ID_EDIT_NEW_EXPANDVALUE
, ID_EDIT_COPYKEYNAME
};
176 for (i
= 0; i
< COUNT_OF(items
); i
++)
177 EnableMenuItem(hMenu
, items
[i
], state
| MF_BYCOMMAND
);
180 static void UpdateMenuItems(HMENU hMenu
) {
181 HWND hwndTV
= g_pChildWnd
->hTreeWnd
;
182 HKEY hRootKey
= NULL
;
187 selection
= (HTREEITEM
)SendMessageW(hwndTV
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
188 keyName
= GetItemPath(hwndTV
, selection
, &hRootKey
);
189 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1,
190 MAKELPARAM(LVNI_FOCUSED
| LVNI_SELECTED
, 0));
192 update_expand_or_collapse_item(hwndTV
, selection
, hMenu
);
193 update_modify_items(hMenu
, index
);
194 update_delete_and_rename_items(hMenu
, keyName
, index
);
195 update_new_items_and_copy_keyname(hMenu
, keyName
);
196 EnableMenuItem(hMenu
, ID_FAVORITES_ADDTOFAVORITES
, (hRootKey
? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
197 EnableMenuItem(hMenu
, ID_FAVORITES_REMOVEFAVORITE
,
198 (GetMenuItemCount(hMenu
)>2 ? MF_ENABLED
: MF_GRAYED
) | MF_BYCOMMAND
);
200 HeapFree(GetProcessHeap(), 0, keyName
);
203 static void add_remove_modify_menu_items(HMENU hMenu
)
205 if (!g_pChildWnd
->nFocusPanel
)
207 while (GetMenuItemCount(hMenu
) > 9)
208 DeleteMenu(hMenu
, 0, MF_BYPOSITION
);
210 else if (GetMenuItemCount(hMenu
) < 10)
212 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_SEPARATOR
, 0, 0);
213 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY_BIN
, modify_binaryW
);
214 InsertMenuW(hMenu
, 0, MF_BYPOSITION
| MF_STRING
, ID_EDIT_MODIFY
, modifyW
);
218 static int add_favourite_key_items(HMENU hMenu
, HWND hList
)
222 DWORD num_values
, max_value_len
, value_len
, type
, i
= 0;
225 rc
= RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
, 0, KEY_READ
, &hkey
);
226 if (rc
!= ERROR_SUCCESS
) return 0;
228 rc
= RegQueryInfoKeyW(hkey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &num_values
,
229 &max_value_len
, NULL
, NULL
, NULL
);
230 if (rc
!= ERROR_SUCCESS
)
232 ERR("RegQueryInfoKey failed: %d\n", rc
);
236 if (!num_values
) goto exit
;
239 value_name
= HeapAlloc(GetProcessHeap(), 0, max_value_len
* sizeof(WCHAR
));
240 CHECK_ENOUGH_MEMORY(value_name
);
242 if (hMenu
) AppendMenuW(hMenu
, MF_SEPARATOR
, 0, 0);
244 for (i
= 0; i
< num_values
; i
++)
246 value_len
= max_value_len
;
247 rc
= RegEnumValueW(hkey
, i
, value_name
, &value_len
, NULL
, &type
, NULL
, NULL
);
248 if (rc
== ERROR_SUCCESS
&& type
== REG_SZ
)
251 AppendMenuW(hMenu
, MF_ENABLED
| MF_STRING
, ID_FAVORITE_FIRST
+ i
, value_name
);
253 SendMessageW(hList
, LB_ADDSTRING
, 0, (LPARAM
)value_name
);
257 HeapFree(GetProcessHeap(), 0, value_name
);
263 static void OnInitMenuPopup(HWND hWnd
, HMENU hMenu
)
265 if (hMenu
== GetSubMenu(hMenuFrame
, ID_EDIT_MENU
))
266 add_remove_modify_menu_items(hMenu
);
267 else if (hMenu
== GetSubMenu(hMenuFrame
, ID_FAVORITES_MENU
))
269 while (GetMenuItemCount(hMenu
) > 2)
270 DeleteMenu(hMenu
, 2, MF_BYPOSITION
);
272 add_favourite_key_items(hMenu
, NULL
);
275 UpdateMenuItems(hMenu
);
278 static void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
283 if (nFlags
& MF_POPUP
) {
284 if (hSysMenu
!= GetMenu(hWnd
)) {
285 if (nItemID
== 2) nItemID
= 5;
288 if (LoadStringW(hInst
, nItemID
, str
, 100)) {
289 /* load appropriate string*/
291 /* first newline terminates actual string*/
292 lpsz
= strchrW(lpsz
, '\n');
296 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)str
);
299 void SetupStatusBar(HWND hWnd
, BOOL bResize
)
303 GetClientRect(hWnd
, &rc
);
307 SendMessageW(hStatusBar
, WM_SIZE
, 0, 0);
308 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
312 void UpdateStatusBar(void)
314 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
315 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)fullPath
);
316 HeapFree(GetProcessHeap(), 0, fullPath
);
319 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
321 BOOL vis
= IsWindowVisible(hchild
);
322 HMENU hMenuView
= GetSubMenu(hMenuFrame
, ID_VIEW_MENU
);
324 CheckMenuItem(hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
325 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
326 resize_frame_client(hWnd
);
329 static BOOL
CheckCommDlgError(HWND hWnd
)
331 DWORD dwErrorCode
= CommDlgExtendedError();
332 switch (dwErrorCode
) {
333 case CDERR_DIALOGFAILURE
:
335 case CDERR_FINDRESFAILURE
:
337 case CDERR_NOHINSTANCE
:
339 case CDERR_INITIALIZATION
:
343 case CDERR_LOCKRESFAILURE
:
345 case CDERR_NOTEMPLATE
:
347 case CDERR_LOADRESFAILURE
:
349 case CDERR_STRUCTSIZE
:
351 case CDERR_LOADSTRFAILURE
:
353 case FNERR_BUFFERTOOSMALL
:
355 case CDERR_MEMALLOCFAILURE
:
357 case FNERR_INVALIDFILENAME
:
359 case CDERR_MEMLOCKFAILURE
:
361 case FNERR_SUBCLASSFAILURE
:
369 static void ExportRegistryFile_StoreSelection(HWND hdlg
, OPENFILENAMEW
*pOpenFileName
)
371 if (IsDlgButtonChecked(hdlg
, IDC_EXPORT_SELECTED
))
373 INT len
= SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXTLENGTH
, 0, 0);
374 pOpenFileName
->lCustData
= (LPARAM
)HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
375 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXT
, len
+1, pOpenFileName
->lCustData
);
378 pOpenFileName
->lCustData
= (LPARAM
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(WCHAR
));
381 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
383 static OPENFILENAMEW
* pOpenFileName
;
384 OFNOTIFYW
*pOfNotify
;
388 pOpenFileName
= (OPENFILENAMEW
*)lParam
;
391 if (LOWORD(wParam
) == IDC_EXPORT_PATH
&& HIWORD(wParam
) == EN_UPDATE
)
392 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, IDC_EXPORT_SELECTED
);
395 pOfNotify
= (OFNOTIFYW
*)lParam
;
396 switch (pOfNotify
->hdr
.code
)
400 BOOL export_branch
= FALSE
;
401 WCHAR
* path
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
402 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_SETTEXT
, 0, (LPARAM
)path
);
404 export_branch
= TRUE
;
405 HeapFree(GetProcessHeap(), 0, path
);
406 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, export_branch
? IDC_EXPORT_SELECTED
: IDC_EXPORT_ALL
);
410 ExportRegistryFile_StoreSelection(hdlg
, pOpenFileName
);
421 static BOOL
InitOpenFileName(HWND hWnd
, OPENFILENAMEW
*pofn
)
423 memset(pofn
, 0, sizeof(OPENFILENAMEW
));
424 pofn
->lStructSize
= sizeof(OPENFILENAMEW
);
425 pofn
->hwndOwner
= hWnd
;
426 pofn
->hInstance
= hInst
;
428 if (FilterBuffer
[0] == 0)
430 static const WCHAR filterW
[] = {'%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','*','%','c',0};
431 WCHAR filter_reg
[MAX_PATH
], filter_reg4
[MAX_PATH
], filter_all
[MAX_PATH
];
433 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG
, filter_reg
, MAX_PATH
);
434 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG4
, filter_reg4
, MAX_PATH
);
435 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_ALL
, filter_all
, MAX_PATH
);
436 snprintfW( FilterBuffer
, MAX_PATH
, filterW
, filter_reg
, 0, 0, filter_reg4
, 0, 0, filter_all
, 0, 0 );
438 pofn
->lpstrFilter
= FilterBuffer
;
439 pofn
->nFilterIndex
= 2;
440 pofn
->lpstrFile
= FileNameBuffer
;
441 pofn
->nMaxFile
= _MAX_PATH
;
442 pofn
->lpstrFileTitle
= FileTitleBuffer
;
443 pofn
->nMaxFileTitle
= _MAX_PATH
;
444 pofn
->Flags
= OFN_HIDEREADONLY
;
445 /* some other fields may be set by the caller */
449 static BOOL
import_registry_filename(LPWSTR filename
)
451 static const WCHAR rb_mode
[] = {'r','b',0};
454 FILE* reg_file
= _wfopen(filename
, rb_mode
);
459 Success
= import_registry_file(reg_file
);
461 if(fclose(reg_file
) != 0)
467 static BOOL
ImportRegistryFile(HWND hWnd
)
471 HKEY root_key
= NULL
;
474 InitOpenFileName(hWnd
, &ofn
);
475 ofn
.Flags
|= OFN_ENABLESIZING
;
476 LoadStringW(hInst
, IDS_FILEDIALOG_IMPORT_TITLE
, title
, COUNT_OF(title
));
477 ofn
.lpstrTitle
= title
;
478 if (GetOpenFileNameW(&ofn
)) {
479 if (!import_registry_filename(ofn
.lpstrFile
)) {
480 messagebox(hWnd
, MB_OK
|MB_ICONERROR
, IDS_APP_TITLE
, IDS_IMPORT_FAILED
, ofn
.lpstrFile
);
483 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
,
484 IDS_IMPORT_SUCCESSFUL
, ofn
.lpstrFile
);
487 CheckCommDlgError(hWnd
);
489 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
491 key_path
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &root_key
);
492 RefreshListView(g_pChildWnd
->hListWnd
, root_key
, key_path
, NULL
);
493 HeapFree(GetProcessHeap(), 0, key_path
);
499 static BOOL
ExportRegistryFile(HWND hWnd
)
504 InitOpenFileName(hWnd
, &ofn
);
505 LoadStringW(hInst
, IDS_FILEDIALOG_EXPORT_TITLE
, title
, COUNT_OF(title
));
506 ofn
.lpstrTitle
= title
;
507 ofn
.Flags
= OFN_ENABLETEMPLATE
| OFN_ENABLEHOOK
| OFN_EXPLORER
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
508 ofn
.lpfnHook
= ExportRegistryFile_OFNHookProc
;
509 ofn
.lpTemplateName
= MAKEINTRESOURCEW(IDD_EXPORT_TEMPLATE
);
510 if (GetSaveFileNameW(&ofn
)) {
512 result
= export_registry_key(ofn
.lpstrFile
, (LPWSTR
)ofn
.lCustData
, ofn
.nFilterIndex
);
514 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
518 CheckCommDlgError(hWnd
);
523 static BOOL
PrintRegistryHive(HWND hWnd
, LPCWSTR path
)
528 ZeroMemory(&pd
, sizeof(PRINTDLGW
));
529 pd
.lStructSize
= sizeof(PRINTDLGW
);
531 pd
.hDevMode
= NULL
; /* Don't forget to free or store hDevMode*/
532 pd
.hDevNames
= NULL
; /* Don't forget to free or store hDevNames*/
533 pd
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
535 pd
.nFromPage
= 0xFFFF;
538 pd
.nMaxPage
= 0xFFFF;
539 if (PrintDlgW(&pd
)) {
540 FIXME("printing is not yet implemented.\n");
541 /* GDI calls to render output. */
542 DeleteDC(pd
.hDC
); /* Delete DC when done.*/
548 hResult
= PrintDlgExW(&pd
);
549 if (hResult
== S_OK
) {
550 switch (pd
.dwResultAction
) {
551 case PD_RESULT_APPLY
:
552 /*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. */
553 FIXME("printing is not yet implemented.\n");
555 case PD_RESULT_CANCEL
:
556 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
558 case PD_RESULT_PRINT
:
559 FIXME("printing is not yet implemented.\n");
560 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
568 /*Insufficient memory. */
571 /* One or more arguments are invalid. */
574 /*Invalid pointer. */
580 /*Unspecified error. */
591 static BOOL
CopyKeyName(HWND hWnd
, LPCWSTR keyName
)
595 result
= OpenClipboard(hWnd
);
597 result
= EmptyClipboard();
599 int len
= (lstrlenW(keyName
)+1)*sizeof(WCHAR
);
600 HANDLE hClipData
= GlobalAlloc(GHND
, len
);
601 LPVOID pLoc
= GlobalLock(hClipData
);
602 lstrcpyW(pLoc
, keyName
);
603 GlobalUnlock(hClipData
);
604 SetClipboardData(CF_UNICODETEXT
, hClipData
);
607 /* error emptying clipboard*/
608 /* DWORD dwError = GetLastError(); */
611 if (!CloseClipboard()) {
612 /* error closing clipboard*/
613 /* DWORD dwError = GetLastError(); */
617 /* error opening clipboard*/
618 /* DWORD dwError = GetLastError(); */
624 static INT_PTR CALLBACK
find_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
626 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
630 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
631 CheckDlgButton(hwndDlg
, IDC_FIND_KEYS
, searchMask
&SEARCH_KEYS
? BST_CHECKED
: BST_UNCHECKED
);
632 CheckDlgButton(hwndDlg
, IDC_FIND_VALUES
, searchMask
&SEARCH_VALUES
? BST_CHECKED
: BST_UNCHECKED
);
633 CheckDlgButton(hwndDlg
, IDC_FIND_CONTENT
, searchMask
&SEARCH_CONTENT
? BST_CHECKED
: BST_UNCHECKED
);
634 CheckDlgButton(hwndDlg
, IDC_FIND_WHOLE
, searchMask
&SEARCH_WHOLE
? BST_CHECKED
: BST_UNCHECKED
);
635 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
636 SetWindowTextW(hwndValue
, searchString
);
639 switch(LOWORD(wParam
)) {
641 if (HIWORD(wParam
) == EN_UPDATE
) {
642 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
)>0);
647 if (GetWindowTextLengthW(hwndValue
)>0) {
649 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_KEYS
)) mask
|= SEARCH_KEYS
;
650 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_VALUES
)) mask
|= SEARCH_VALUES
;
651 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_CONTENT
)) mask
|= SEARCH_CONTENT
;
652 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_WHOLE
)) mask
|= SEARCH_WHOLE
;
654 GetWindowTextW(hwndValue
, searchString
, 128);
655 EndDialog(hwndDlg
, IDOK
);
659 EndDialog(hwndDlg
, IDCANCEL
);
667 static INT_PTR CALLBACK
addtofavorites_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
669 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
678 selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
680 item
.mask
= TVIF_HANDLE
| TVIF_TEXT
;
681 item
.hItem
= selected
;
683 item
.cchTextMax
= COUNT_OF(buf
);
684 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
686 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
687 SetWindowTextW(hwndValue
, buf
);
688 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
692 switch(LOWORD(wParam
)) {
694 if (HIWORD(wParam
) == EN_UPDATE
) {
695 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
) > 0);
700 if (GetWindowTextLengthW(hwndValue
)>0) {
701 GetWindowTextW(hwndValue
, favoriteName
, 128);
702 EndDialog(hwndDlg
, IDOK
);
706 EndDialog(hwndDlg
, IDCANCEL
);
714 static INT_PTR CALLBACK
removefavorite_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
716 HWND hwndList
= GetDlgItem(hwndDlg
, IDC_NAME_LIST
);
720 if (!add_favourite_key_items(NULL
, hwndList
))
722 SendMessageW(hwndList
, LB_SETCURSEL
, 0, 0);
725 switch(LOWORD(wParam
)) {
727 if (HIWORD(wParam
) == LBN_SELCHANGE
) {
728 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), lParam
!= -1);
733 int pos
= SendMessageW(hwndList
, LB_GETCURSEL
, 0, 0);
734 int len
= SendMessageW(hwndList
, LB_GETTEXTLEN
, pos
, 0);
736 LPWSTR lpName
= HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR
)*(len
+1));
737 SendMessageW(hwndList
, LB_GETTEXT
, pos
, (LPARAM
)lpName
);
740 lstrcpyW(favoriteName
, lpName
);
741 EndDialog(hwndDlg
, IDOK
);
742 HeapFree(GetProcessHeap(), 0, lpName
);
747 EndDialog(hwndDlg
, IDCANCEL
);
755 /*******************************************************************************
757 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
759 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
762 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
767 if (LOWORD(wParam
) >= ID_FAVORITE_FIRST
&& LOWORD(wParam
) <= ID_FAVORITE_LAST
) {
769 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
770 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
) {
771 WCHAR namebuf
[KEY_MAX_LEN
];
773 DWORD ksize
= KEY_MAX_LEN
, vsize
= sizeof(valuebuf
), type
= 0;
774 if (RegEnumValueW(hKey
, LOWORD(wParam
) - ID_FAVORITE_FIRST
, namebuf
, &ksize
, NULL
,
775 &type
, valuebuf
, &vsize
) == ERROR_SUCCESS
) {
776 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
,
777 (LPARAM
) FindPathInTree(g_pChildWnd
->hTreeWnd
, (WCHAR
*)valuebuf
) );
783 switch (LOWORD(wParam
)) {
784 case ID_REGISTRY_IMPORTREGISTRYFILE
:
785 ImportRegistryFile(hWnd
);
788 case ID_REGISTRY_EXPORTREGISTRYFILE
:
789 ExportRegistryFile(hWnd
);
791 case ID_REGISTRY_PRINT
:
793 const WCHAR empty
= 0;
794 PrintRegistryHive(hWnd
, &empty
);
799 HWND hWndDelete
= GetFocus();
800 if (hWndDelete
== g_pChildWnd
->hTreeWnd
) {
801 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
802 if (keyPath
== 0 || *keyPath
== 0) {
803 MessageBeep(MB_ICONHAND
);
804 } else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
)) {
805 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
807 HeapFree(GetProcessHeap(), 0, keyPath
);
808 } else if (hWndDelete
== g_pChildWnd
->hListWnd
) {
809 unsigned int num_selected
, index
, focus_idx
;
812 if (!(num_selected
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETSELECTEDCOUNT
, 0, 0L)))
815 if (num_selected
> 1)
817 if (messagebox(hWnd
, MB_YESNO
| MB_ICONEXCLAMATION
, IDS_DELETE_VALUE_TITLE
,
818 IDS_DELETE_VALUE_TEXT_MULTIPLE
) != IDYES
)
822 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
824 focus_idx
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
825 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
829 WCHAR
*valueName
= GetItemText(g_pChildWnd
->hListWnd
, index
);
830 if (!DeleteValue(hWnd
, hKeyRoot
, keyPath
, valueName
, num_selected
== 1))
832 HeapFree(GetProcessHeap(), 0, valueName
);
835 HeapFree(GetProcessHeap(), 0, valueName
);
836 SendMessageW(g_pChildWnd
->hListWnd
, LVM_DELETEITEM
, index
, 0L);
837 /* the default value item is always visible, so add it back in */
840 AddEntryToList(g_pChildWnd
->hListWnd
, NULL
, REG_SZ
, NULL
, 0, 0);
844 item
.state
= item
.stateMask
= LVIS_FOCUSED
;
845 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, 0, (LPARAM
)&item
);
848 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
850 HeapFree(GetProcessHeap(), 0, keyPath
);
851 } else if (IsChild(g_pChildWnd
->hTreeWnd
, hWndDelete
) ||
852 IsChild(g_pChildWnd
->hListWnd
, hWndDelete
)) {
853 SendMessageW(hWndDelete
, WM_KEYDOWN
, VK_DELETE
, 0);
858 case ID_EDIT_MODIFY_BIN
:
860 LPCWSTR valueName
= GetValueName(g_pChildWnd
->hListWnd
);
861 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
862 ModifyValue(hWnd
, hKeyRoot
, keyPath
, valueName
);
863 HeapFree(GetProcessHeap(), 0, keyPath
);
867 case ID_EDIT_FINDNEXT
:
870 if (LOWORD(wParam
) == ID_EDIT_FIND
&&
871 DialogBoxW(0, MAKEINTRESOURCEW(IDD_FIND
), hWnd
, find_dlgproc
) != IDOK
)
875 hItem
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
877 int row
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
878 HCURSOR hcursorOld
= SetCursor(LoadCursorW(NULL
, (LPCWSTR
)IDC_WAIT
));
879 hItem
= FindNext(g_pChildWnd
->hTreeWnd
, hItem
, searchString
, searchMask
, &row
);
880 SetCursor(hcursorOld
);
882 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
) hItem
);
883 InvalidateRect(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
884 UpdateWindow(g_pChildWnd
->hTreeWnd
);
889 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
890 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, (UINT
)-1, (LPARAM
)&item
);
892 item
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
893 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
894 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, row
, (LPARAM
)&item
);
895 SetFocus(g_pChildWnd
->hListWnd
);
897 SetFocus(g_pChildWnd
->hTreeWnd
);
900 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
, IDS_NOTFOUND
, searchString
);
905 case ID_EDIT_COPYKEYNAME
:
907 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
909 CopyKeyName(hWnd
, fullPath
);
910 HeapFree(GetProcessHeap(), 0, fullPath
);
914 case ID_EDIT_NEW_KEY
:
916 WCHAR newKeyW
[MAX_NEW_KEY_LEN
];
917 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
918 if (CreateKey(hWnd
, hKeyRoot
, keyPath
, newKeyW
)) {
919 if (InsertNode(g_pChildWnd
->hTreeWnd
, 0, newKeyW
))
920 StartKeyRename(g_pChildWnd
->hTreeWnd
);
922 HeapFree(GetProcessHeap(), 0, keyPath
);
925 case ID_EDIT_NEW_STRINGVALUE
:
928 case ID_EDIT_NEW_EXPANDVALUE
:
929 valueType
= REG_EXPAND_SZ
;
931 case ID_EDIT_NEW_MULTI_STRINGVALUE
:
932 valueType
= REG_MULTI_SZ
;
934 case ID_EDIT_NEW_BINARYVALUE
:
935 valueType
= REG_BINARY
;
937 case ID_EDIT_NEW_DWORDVALUE
:
938 valueType
= REG_DWORD
;
942 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
943 WCHAR newKey
[MAX_NEW_KEY_LEN
];
944 if (CreateValue(hWnd
, hKeyRoot
, keyPath
, valueType
, newKey
))
945 StartValueRename(g_pChildWnd
->hListWnd
);
946 HeapFree(GetProcessHeap(), 0, keyPath
);
951 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
952 if (keyPath
== 0 || *keyPath
== 0) {
953 MessageBeep(MB_ICONHAND
);
954 } else if (GetFocus() == g_pChildWnd
->hTreeWnd
) {
955 StartKeyRename(g_pChildWnd
->hTreeWnd
);
956 } else if (GetFocus() == g_pChildWnd
->hListWnd
) {
957 StartValueRename(g_pChildWnd
->hListWnd
);
959 HeapFree(GetProcessHeap(), 0, keyPath
);
962 case ID_TREE_EXPAND_COLLAPSE
:
964 HTREEITEM selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
965 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_EXPAND
, TVE_TOGGLE
, (LPARAM
)selected
);
968 case ID_REGISTRY_PRINTERSETUP
:
971 /*PAGESETUPDLG psd;*/
972 /*PageSetupDlg(&psd);*/
974 case ID_REGISTRY_OPENLOCAL
:
976 case ID_REGISTRY_EXIT
:
979 case ID_FAVORITES_ADDTOFAVORITES
:
982 LPWSTR lpKeyPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
984 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_ADDFAVORITE
), hWnd
, addtofavorites_dlgproc
) == IDOK
) {
985 if (RegCreateKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
987 KEY_READ
|KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
) {
988 RegSetValueExW(hKey
, favoriteName
, 0, REG_SZ
, (BYTE
*)lpKeyPath
, (lstrlenW(lpKeyPath
)+1)*sizeof(WCHAR
));
992 HeapFree(GetProcessHeap(), 0, lpKeyPath
);
996 case ID_FAVORITES_REMOVEFAVORITE
:
998 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_DELFAVORITE
), hWnd
, removefavorite_dlgproc
) == IDOK
) {
1000 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
1001 0, KEY_READ
|KEY_WRITE
, &hKey
) == ERROR_SUCCESS
) {
1002 RegDeleteValueW(hKey
, favoriteName
);
1008 case ID_VIEW_REFRESH
:
1010 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1011 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1012 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
, NULL
);
1013 HeapFree(GetProcessHeap(), 0, keyPath
);
1016 /*case ID_OPTIONS_TOOLBAR:*/
1017 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1019 case ID_VIEW_STATUSBAR
:
1020 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1022 case ID_HELP_HELPTOPICS
:
1024 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1025 WinHelpW(hWnd
, help_regedit
, HELP_FINDER
, 0);
1031 case ID_VIEW_SPLIT
: {
1034 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1035 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1036 pt
.y
= (rt
.bottom
/ 2);
1038 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
)) {
1039 SetCursorPos(pts
.x
, pts
.y
);
1040 SetCursor(LoadCursorW(0, (LPCWSTR
)IDC_SIZEWE
));
1041 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1052 /********************************************************************************
1054 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1056 * PURPOSE: Processes messages for the main frame window.
1058 * WM_COMMAND - process the application menu
1059 * WM_DESTROY - post a quit message and return
1063 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1065 static const WCHAR captionW
[] = {'r','e','g','e','d','i','t',' ','c','h','i','l','d',' ','w','i','n','d','o','w',0};
1069 CreateWindowExW(0, szChildClass
, captionW
, WS_CHILD
| WS_VISIBLE
,
1070 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1071 hWnd
, NULL
, hInst
, 0);
1072 LoadStringW(hInst
, IDS_EXPAND
, expandW
, COUNT_OF(expandW
));
1073 LoadStringW(hInst
, IDS_COLLAPSE
, collapseW
, COUNT_OF(collapseW
));
1074 LoadStringW(hInst
, IDS_EDIT_MODIFY
, modifyW
, COUNT_OF(modifyW
));
1075 LoadStringW(hInst
, IDS_EDIT_MODIFY_BIN
, modify_binaryW
, COUNT_OF(modify_binaryW
));
1078 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1079 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1083 SetFocus(g_pChildWnd
->hWnd
);
1086 resize_frame_client(hWnd
);
1090 case WM_ENTERMENULOOP
:
1091 OnEnterMenuLoop(hWnd
);
1093 case WM_EXITMENULOOP
:
1094 OnExitMenuLoop(hWnd
);
1096 case WM_INITMENUPOPUP
:
1097 if (!HIWORD(lParam
))
1098 OnInitMenuPopup(hWnd
, (HMENU
)wParam
);
1101 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1105 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1106 WinHelpW(hWnd
, help_regedit
, HELP_QUIT
, 0);
1110 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);