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
);
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
= heap_xalloc(max_value_len
* sizeof(WCHAR
));
241 if (hMenu
) AppendMenuW(hMenu
, MF_SEPARATOR
, 0, 0);
243 for (i
= 0; i
< num_values
; i
++)
245 value_len
= max_value_len
;
246 rc
= RegEnumValueW(hkey
, i
, value_name
, &value_len
, NULL
, &type
, NULL
, NULL
);
247 if (rc
== ERROR_SUCCESS
&& type
== REG_SZ
)
250 AppendMenuW(hMenu
, MF_ENABLED
| MF_STRING
, ID_FAVORITE_FIRST
+ i
, value_name
);
252 SendMessageW(hList
, LB_ADDSTRING
, 0, (LPARAM
)value_name
);
256 heap_free(value_name
);
262 static void OnInitMenuPopup(HWND hWnd
, HMENU hMenu
)
264 if (hMenu
== GetSubMenu(hMenuFrame
, ID_EDIT_MENU
))
265 add_remove_modify_menu_items(hMenu
);
266 else if (hMenu
== GetSubMenu(hMenuFrame
, ID_FAVORITES_MENU
))
268 while (GetMenuItemCount(hMenu
) > 2)
269 DeleteMenu(hMenu
, 2, MF_BYPOSITION
);
271 add_favourite_key_items(hMenu
, NULL
);
274 UpdateMenuItems(hMenu
);
277 static void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
282 if (nFlags
& MF_POPUP
) {
283 if (hSysMenu
!= GetMenu(hWnd
)) {
284 if (nItemID
== 2) nItemID
= 5;
287 if (LoadStringW(hInst
, nItemID
, str
, 100)) {
288 /* load appropriate string*/
290 /* first newline terminates actual string*/
291 lpsz
= strchrW(lpsz
, '\n');
295 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)str
);
298 void SetupStatusBar(HWND hWnd
, BOOL bResize
)
302 GetClientRect(hWnd
, &rc
);
306 SendMessageW(hStatusBar
, WM_SIZE
, 0, 0);
307 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
311 void UpdateStatusBar(void)
313 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
314 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)fullPath
);
318 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
320 BOOL vis
= IsWindowVisible(hchild
);
321 HMENU hMenuView
= GetSubMenu(hMenuFrame
, ID_VIEW_MENU
);
323 CheckMenuItem(hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
324 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
325 resize_frame_client(hWnd
);
328 static BOOL
CheckCommDlgError(HWND hWnd
)
330 DWORD dwErrorCode
= CommDlgExtendedError();
331 switch (dwErrorCode
) {
332 case CDERR_DIALOGFAILURE
:
334 case CDERR_FINDRESFAILURE
:
336 case CDERR_NOHINSTANCE
:
338 case CDERR_INITIALIZATION
:
342 case CDERR_LOCKRESFAILURE
:
344 case CDERR_NOTEMPLATE
:
346 case CDERR_LOADRESFAILURE
:
348 case CDERR_STRUCTSIZE
:
350 case CDERR_LOADSTRFAILURE
:
352 case FNERR_BUFFERTOOSMALL
:
354 case CDERR_MEMALLOCFAILURE
:
356 case FNERR_INVALIDFILENAME
:
358 case CDERR_MEMLOCKFAILURE
:
360 case FNERR_SUBCLASSFAILURE
:
368 static void ExportRegistryFile_StoreSelection(HWND hdlg
, OPENFILENAMEW
*pOpenFileName
)
370 if (IsDlgButtonChecked(hdlg
, IDC_EXPORT_SELECTED
))
372 INT len
= SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXTLENGTH
, 0, 0);
373 pOpenFileName
->lCustData
= (LPARAM
)heap_xalloc((len
+ 1) * sizeof(WCHAR
));
374 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_GETTEXT
, len
+1, pOpenFileName
->lCustData
);
377 pOpenFileName
->lCustData
= (LPARAM
)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(WCHAR
));
380 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
382 static OPENFILENAMEW
* pOpenFileName
;
383 OFNOTIFYW
*pOfNotify
;
387 pOpenFileName
= (OPENFILENAMEW
*)lParam
;
390 if (LOWORD(wParam
) == IDC_EXPORT_PATH
&& HIWORD(wParam
) == EN_UPDATE
)
391 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, IDC_EXPORT_SELECTED
);
394 pOfNotify
= (OFNOTIFYW
*)lParam
;
395 switch (pOfNotify
->hdr
.code
)
399 BOOL export_branch
= FALSE
;
400 WCHAR
* path
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
401 SendDlgItemMessageW(hdlg
, IDC_EXPORT_PATH
, WM_SETTEXT
, 0, (LPARAM
)path
);
403 export_branch
= TRUE
;
405 CheckRadioButton(hdlg
, IDC_EXPORT_ALL
, IDC_EXPORT_SELECTED
, export_branch
? IDC_EXPORT_SELECTED
: IDC_EXPORT_ALL
);
409 ExportRegistryFile_StoreSelection(hdlg
, pOpenFileName
);
420 static BOOL
InitOpenFileName(HWND hWnd
, OPENFILENAMEW
*pofn
)
422 memset(pofn
, 0, sizeof(OPENFILENAMEW
));
423 pofn
->lStructSize
= sizeof(OPENFILENAMEW
);
424 pofn
->hwndOwner
= hWnd
;
425 pofn
->hInstance
= hInst
;
427 if (FilterBuffer
[0] == 0)
429 static const WCHAR filterW
[] = {'%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','r','e','g','%','c','%','s','%','c','*','.','*','%','c',0};
430 WCHAR filter_reg
[MAX_PATH
], filter_reg4
[MAX_PATH
], filter_all
[MAX_PATH
];
432 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG
, filter_reg
, MAX_PATH
);
433 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_REG4
, filter_reg4
, MAX_PATH
);
434 LoadStringW(hInst
, IDS_FILEDIALOG_FILTER_ALL
, filter_all
, MAX_PATH
);
435 snprintfW( FilterBuffer
, MAX_PATH
, filterW
, filter_reg
, 0, 0, filter_reg4
, 0, 0, filter_all
, 0, 0 );
437 pofn
->lpstrFilter
= FilterBuffer
;
438 pofn
->nFilterIndex
= 2;
439 pofn
->lpstrFile
= FileNameBuffer
;
440 pofn
->nMaxFile
= _MAX_PATH
;
441 pofn
->lpstrFileTitle
= FileTitleBuffer
;
442 pofn
->nMaxFileTitle
= _MAX_PATH
;
443 pofn
->Flags
= OFN_HIDEREADONLY
;
444 /* some other fields may be set by the caller */
448 static BOOL
import_registry_filename(LPWSTR filename
)
450 static const WCHAR rb_mode
[] = {'r','b',0};
453 FILE* reg_file
= _wfopen(filename
, rb_mode
);
458 Success
= import_registry_file(reg_file
);
460 if(fclose(reg_file
) != 0)
466 static BOOL
ImportRegistryFile(HWND hWnd
)
470 HKEY root_key
= NULL
;
473 InitOpenFileName(hWnd
, &ofn
);
474 ofn
.Flags
|= OFN_ENABLESIZING
;
475 LoadStringW(hInst
, IDS_FILEDIALOG_IMPORT_TITLE
, title
, COUNT_OF(title
));
476 ofn
.lpstrTitle
= title
;
477 if (GetOpenFileNameW(&ofn
)) {
478 if (!import_registry_filename(ofn
.lpstrFile
)) {
479 messagebox(hWnd
, MB_OK
|MB_ICONERROR
, IDS_APP_TITLE
, IDS_IMPORT_FAILED
, ofn
.lpstrFile
);
482 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
,
483 IDS_IMPORT_SUCCESSFUL
, ofn
.lpstrFile
);
486 CheckCommDlgError(hWnd
);
488 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
490 key_path
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &root_key
);
491 RefreshListView(g_pChildWnd
->hListWnd
, root_key
, key_path
, NULL
);
498 static BOOL
ExportRegistryFile(HWND hWnd
)
503 InitOpenFileName(hWnd
, &ofn
);
504 LoadStringW(hInst
, IDS_FILEDIALOG_EXPORT_TITLE
, title
, COUNT_OF(title
));
505 ofn
.lpstrTitle
= title
;
506 ofn
.Flags
= OFN_ENABLETEMPLATE
| OFN_ENABLEHOOK
| OFN_EXPLORER
| OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
;
507 ofn
.lpfnHook
= ExportRegistryFile_OFNHookProc
;
508 ofn
.lpTemplateName
= MAKEINTRESOURCEW(IDD_EXPORT_TEMPLATE
);
509 if (GetSaveFileNameW(&ofn
)) {
511 result
= export_registry_key(ofn
.lpstrFile
, (LPWSTR
)ofn
.lCustData
, ofn
.nFilterIndex
);
513 /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
517 CheckCommDlgError(hWnd
);
522 static BOOL
PrintRegistryHive(HWND hWnd
, LPCWSTR path
)
527 ZeroMemory(&pd
, sizeof(PRINTDLGW
));
528 pd
.lStructSize
= sizeof(PRINTDLGW
);
530 pd
.hDevMode
= NULL
; /* Don't forget to free or store hDevMode*/
531 pd
.hDevNames
= NULL
; /* Don't forget to free or store hDevNames*/
532 pd
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
534 pd
.nFromPage
= 0xFFFF;
537 pd
.nMaxPage
= 0xFFFF;
538 if (PrintDlgW(&pd
)) {
539 FIXME("printing is not yet implemented.\n");
540 /* GDI calls to render output. */
541 DeleteDC(pd
.hDC
); /* Delete DC when done.*/
547 hResult
= PrintDlgExW(&pd
);
548 if (hResult
== S_OK
) {
549 switch (pd
.dwResultAction
) {
550 case PD_RESULT_APPLY
:
551 /*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. */
552 FIXME("printing is not yet implemented.\n");
554 case PD_RESULT_CANCEL
:
555 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
557 case PD_RESULT_PRINT
:
558 FIXME("printing is not yet implemented.\n");
559 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
567 /*Insufficient memory. */
570 /* One or more arguments are invalid. */
573 /*Invalid pointer. */
579 /*Unspecified error. */
590 static BOOL
CopyKeyName(HWND hWnd
, LPCWSTR keyName
)
594 result
= OpenClipboard(hWnd
);
596 result
= EmptyClipboard();
598 int len
= (lstrlenW(keyName
)+1)*sizeof(WCHAR
);
599 HANDLE hClipData
= GlobalAlloc(GHND
, len
);
600 LPVOID pLoc
= GlobalLock(hClipData
);
601 lstrcpyW(pLoc
, keyName
);
602 GlobalUnlock(hClipData
);
603 SetClipboardData(CF_UNICODETEXT
, hClipData
);
606 /* error emptying clipboard*/
607 /* DWORD dwError = GetLastError(); */
610 if (!CloseClipboard()) {
611 /* error closing clipboard*/
612 /* DWORD dwError = GetLastError(); */
616 /* error opening clipboard*/
617 /* DWORD dwError = GetLastError(); */
623 static INT_PTR CALLBACK
find_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
625 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
629 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
630 CheckDlgButton(hwndDlg
, IDC_FIND_KEYS
, searchMask
&SEARCH_KEYS
? BST_CHECKED
: BST_UNCHECKED
);
631 CheckDlgButton(hwndDlg
, IDC_FIND_VALUES
, searchMask
&SEARCH_VALUES
? BST_CHECKED
: BST_UNCHECKED
);
632 CheckDlgButton(hwndDlg
, IDC_FIND_CONTENT
, searchMask
&SEARCH_CONTENT
? BST_CHECKED
: BST_UNCHECKED
);
633 CheckDlgButton(hwndDlg
, IDC_FIND_WHOLE
, searchMask
&SEARCH_WHOLE
? BST_CHECKED
: BST_UNCHECKED
);
634 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
635 SetWindowTextW(hwndValue
, searchString
);
638 switch(LOWORD(wParam
)) {
640 if (HIWORD(wParam
) == EN_UPDATE
) {
641 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
)>0);
646 if (GetWindowTextLengthW(hwndValue
)>0) {
648 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_KEYS
)) mask
|= SEARCH_KEYS
;
649 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_VALUES
)) mask
|= SEARCH_VALUES
;
650 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_CONTENT
)) mask
|= SEARCH_CONTENT
;
651 if (IsDlgButtonChecked(hwndDlg
, IDC_FIND_WHOLE
)) mask
|= SEARCH_WHOLE
;
653 GetWindowTextW(hwndValue
, searchString
, 128);
654 EndDialog(hwndDlg
, IDOK
);
658 EndDialog(hwndDlg
, IDCANCEL
);
666 static INT_PTR CALLBACK
addtofavorites_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
668 HWND hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_NAME
);
677 selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
679 item
.mask
= TVIF_HANDLE
| TVIF_TEXT
;
680 item
.hItem
= selected
;
682 item
.cchTextMax
= COUNT_OF(buf
);
683 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETITEMW
, 0, (LPARAM
)&item
);
685 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), FALSE
);
686 SetWindowTextW(hwndValue
, buf
);
687 SendMessageW(hwndValue
, EM_SETLIMITTEXT
, 127, 0);
691 switch(LOWORD(wParam
)) {
693 if (HIWORD(wParam
) == EN_UPDATE
) {
694 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), GetWindowTextLengthW(hwndValue
) > 0);
699 if (GetWindowTextLengthW(hwndValue
)>0) {
700 GetWindowTextW(hwndValue
, favoriteName
, 128);
701 EndDialog(hwndDlg
, IDOK
);
705 EndDialog(hwndDlg
, IDCANCEL
);
713 static INT_PTR CALLBACK
removefavorite_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
715 HWND hwndList
= GetDlgItem(hwndDlg
, IDC_NAME_LIST
);
719 if (!add_favourite_key_items(NULL
, hwndList
))
721 SendMessageW(hwndList
, LB_SETCURSEL
, 0, 0);
724 switch(LOWORD(wParam
)) {
726 if (HIWORD(wParam
) == LBN_SELCHANGE
) {
727 EnableWindow(GetDlgItem(hwndDlg
, IDOK
), lParam
!= -1);
732 int pos
= SendMessageW(hwndList
, LB_GETCURSEL
, 0, 0);
733 int len
= SendMessageW(hwndList
, LB_GETTEXTLEN
, pos
, 0);
735 WCHAR
*lpName
= heap_xalloc((len
+ 1) * sizeof(WCHAR
));
736 SendMessageW(hwndList
, LB_GETTEXT
, pos
, (LPARAM
)lpName
);
739 lstrcpyW(favoriteName
, lpName
);
740 EndDialog(hwndDlg
, IDOK
);
746 EndDialog(hwndDlg
, IDCANCEL
);
754 /*******************************************************************************
756 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
758 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
761 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
766 if (LOWORD(wParam
) >= ID_FAVORITE_FIRST
&& LOWORD(wParam
) <= ID_FAVORITE_LAST
) {
768 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
769 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
) {
770 WCHAR namebuf
[KEY_MAX_LEN
];
772 DWORD ksize
= KEY_MAX_LEN
, vsize
= sizeof(valuebuf
), type
= 0;
773 if (RegEnumValueW(hKey
, LOWORD(wParam
) - ID_FAVORITE_FIRST
, namebuf
, &ksize
, NULL
,
774 &type
, valuebuf
, &vsize
) == ERROR_SUCCESS
) {
775 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
,
776 (LPARAM
) FindPathInTree(g_pChildWnd
->hTreeWnd
, (WCHAR
*)valuebuf
) );
782 switch (LOWORD(wParam
)) {
783 case ID_REGISTRY_IMPORTREGISTRYFILE
:
784 ImportRegistryFile(hWnd
);
787 case ID_REGISTRY_EXPORTREGISTRYFILE
:
788 ExportRegistryFile(hWnd
);
790 case ID_REGISTRY_PRINT
:
792 const WCHAR empty
= 0;
793 PrintRegistryHive(hWnd
, &empty
);
798 HWND hWndDelete
= GetFocus();
799 if (hWndDelete
== g_pChildWnd
->hTreeWnd
) {
800 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
801 if (keyPath
== 0 || *keyPath
== 0) {
802 MessageBeep(MB_ICONHAND
);
803 } else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
)) {
804 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
807 } else if (hWndDelete
== g_pChildWnd
->hListWnd
) {
808 unsigned int num_selected
, index
, focus_idx
;
811 if (!(num_selected
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETSELECTEDCOUNT
, 0, 0L)))
814 if (num_selected
> 1)
816 if (messagebox(hWnd
, MB_YESNO
| MB_ICONEXCLAMATION
, IDS_DELETE_VALUE_TITLE
,
817 IDS_DELETE_VALUE_TEXT_MULTIPLE
) != IDYES
)
821 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
823 focus_idx
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
824 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
828 WCHAR
*valueName
= GetItemText(g_pChildWnd
->hListWnd
, index
);
829 if (!DeleteValue(hWnd
, hKeyRoot
, keyPath
, valueName
, num_selected
== 1))
831 heap_free(valueName
);
834 heap_free(valueName
);
835 SendMessageW(g_pChildWnd
->hListWnd
, LVM_DELETEITEM
, index
, 0L);
836 /* the default value item is always visible, so add it back in */
839 AddEntryToList(g_pChildWnd
->hListWnd
, NULL
, REG_SZ
, NULL
, 0, 0);
843 item
.state
= item
.stateMask
= LVIS_FOCUSED
;
844 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, 0, (LPARAM
)&item
);
847 index
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_SELECTED
, 0));
850 } else if (IsChild(g_pChildWnd
->hTreeWnd
, hWndDelete
) ||
851 IsChild(g_pChildWnd
->hListWnd
, hWndDelete
)) {
852 SendMessageW(hWndDelete
, WM_KEYDOWN
, VK_DELETE
, 0);
857 case ID_EDIT_MODIFY_BIN
:
859 LPCWSTR valueName
= GetValueName(g_pChildWnd
->hListWnd
);
860 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
861 ModifyValue(hWnd
, hKeyRoot
, keyPath
, valueName
);
866 case ID_EDIT_FINDNEXT
:
869 if (LOWORD(wParam
) == ID_EDIT_FIND
&&
870 DialogBoxW(0, MAKEINTRESOURCEW(IDD_FIND
), hWnd
, find_dlgproc
) != IDOK
)
874 hItem
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
876 int row
= SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETNEXTITEM
, -1, MAKELPARAM(LVNI_FOCUSED
, 0));
877 HCURSOR hcursorOld
= SetCursor(LoadCursorW(NULL
, (LPCWSTR
)IDC_WAIT
));
878 hItem
= FindNext(g_pChildWnd
->hTreeWnd
, hItem
, searchString
, searchMask
, &row
);
879 SetCursor(hcursorOld
);
881 SendMessageW( g_pChildWnd
->hTreeWnd
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
) hItem
);
882 InvalidateRect(g_pChildWnd
->hTreeWnd
, NULL
, TRUE
);
883 UpdateWindow(g_pChildWnd
->hTreeWnd
);
888 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
889 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, (UINT
)-1, (LPARAM
)&item
);
891 item
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
892 item
.stateMask
= LVIS_FOCUSED
| LVIS_SELECTED
;
893 SendMessageW(g_pChildWnd
->hListWnd
, LVM_SETITEMSTATE
, row
, (LPARAM
)&item
);
894 SetFocus(g_pChildWnd
->hListWnd
);
896 SetFocus(g_pChildWnd
->hTreeWnd
);
899 messagebox(hWnd
, MB_OK
|MB_ICONINFORMATION
, IDS_APP_TITLE
, IDS_NOTFOUND
, searchString
);
904 case ID_EDIT_COPYKEYNAME
:
906 LPWSTR fullPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
908 CopyKeyName(hWnd
, fullPath
);
913 case ID_EDIT_NEW_KEY
:
915 WCHAR newKeyW
[MAX_NEW_KEY_LEN
];
916 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
917 if (CreateKey(hWnd
, hKeyRoot
, keyPath
, newKeyW
)) {
918 if (InsertNode(g_pChildWnd
->hTreeWnd
, 0, newKeyW
))
919 StartKeyRename(g_pChildWnd
->hTreeWnd
);
924 case ID_EDIT_NEW_STRINGVALUE
:
927 case ID_EDIT_NEW_EXPANDVALUE
:
928 valueType
= REG_EXPAND_SZ
;
930 case ID_EDIT_NEW_MULTI_STRINGVALUE
:
931 valueType
= REG_MULTI_SZ
;
933 case ID_EDIT_NEW_BINARYVALUE
:
934 valueType
= REG_BINARY
;
936 case ID_EDIT_NEW_DWORDVALUE
:
937 valueType
= REG_DWORD
;
941 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
942 WCHAR newKey
[MAX_NEW_KEY_LEN
];
943 if (CreateValue(hWnd
, hKeyRoot
, keyPath
, valueType
, newKey
))
944 StartValueRename(g_pChildWnd
->hListWnd
);
950 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
951 if (keyPath
== 0 || *keyPath
== 0) {
952 MessageBeep(MB_ICONHAND
);
953 } else if (GetFocus() == g_pChildWnd
->hTreeWnd
) {
954 StartKeyRename(g_pChildWnd
->hTreeWnd
);
955 } else if (GetFocus() == g_pChildWnd
->hListWnd
) {
956 StartValueRename(g_pChildWnd
->hListWnd
);
961 case ID_TREE_EXPAND_COLLAPSE
:
963 HTREEITEM selected
= (HTREEITEM
)SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_GETNEXTITEM
, TVGN_CARET
, 0);
964 SendMessageW(g_pChildWnd
->hTreeWnd
, TVM_EXPAND
, TVE_TOGGLE
, (LPARAM
)selected
);
967 case ID_REGISTRY_PRINTERSETUP
:
970 /*PAGESETUPDLG psd;*/
971 /*PageSetupDlg(&psd);*/
973 case ID_REGISTRY_OPENLOCAL
:
975 case ID_REGISTRY_EXIT
:
978 case ID_FAVORITES_ADDTOFAVORITES
:
981 LPWSTR lpKeyPath
= GetItemFullPath(g_pChildWnd
->hTreeWnd
, NULL
, FALSE
);
983 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_ADDFAVORITE
), hWnd
, addtofavorites_dlgproc
) == IDOK
) {
984 if (RegCreateKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
986 KEY_READ
|KEY_WRITE
, NULL
, &hKey
, NULL
) == ERROR_SUCCESS
) {
987 RegSetValueExW(hKey
, favoriteName
, 0, REG_SZ
, (BYTE
*)lpKeyPath
, (lstrlenW(lpKeyPath
)+1)*sizeof(WCHAR
));
991 heap_free(lpKeyPath
);
995 case ID_FAVORITES_REMOVEFAVORITE
:
997 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_DELFAVORITE
), hWnd
, removefavorite_dlgproc
) == IDOK
) {
999 if (RegOpenKeyExW(HKEY_CURRENT_USER
, favoritesKey
,
1000 0, KEY_READ
|KEY_WRITE
, &hKey
) == ERROR_SUCCESS
) {
1001 RegDeleteValueW(hKey
, favoriteName
);
1007 case ID_VIEW_REFRESH
:
1009 WCHAR
* keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1010 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1011 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
, NULL
);
1015 /*case ID_OPTIONS_TOOLBAR:*/
1016 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1018 case ID_VIEW_STATUSBAR
:
1019 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1021 case ID_HELP_HELPTOPICS
:
1023 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1024 WinHelpW(hWnd
, help_regedit
, HELP_FINDER
, 0);
1030 case ID_VIEW_SPLIT
: {
1033 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1034 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1035 pt
.y
= (rt
.bottom
/ 2);
1037 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
)) {
1038 SetCursorPos(pts
.x
, pts
.y
);
1039 SetCursor(LoadCursorW(0, (LPCWSTR
)IDC_SIZEWE
));
1040 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1051 /********************************************************************************
1053 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1055 * PURPOSE: Processes messages for the main frame window.
1057 * WM_COMMAND - process the application menu
1058 * WM_DESTROY - post a quit message and return
1062 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1064 static const WCHAR captionW
[] = {'r','e','g','e','d','i','t',' ','c','h','i','l','d',' ','w','i','n','d','o','w',0};
1068 CreateWindowExW(0, szChildClass
, captionW
, WS_CHILD
| WS_VISIBLE
,
1069 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1070 hWnd
, NULL
, hInst
, 0);
1071 LoadStringW(hInst
, IDS_EXPAND
, expandW
, COUNT_OF(expandW
));
1072 LoadStringW(hInst
, IDS_COLLAPSE
, collapseW
, COUNT_OF(collapseW
));
1073 LoadStringW(hInst
, IDS_EDIT_MODIFY
, modifyW
, COUNT_OF(modifyW
));
1074 LoadStringW(hInst
, IDS_EDIT_MODIFY_BIN
, modify_binaryW
, COUNT_OF(modify_binaryW
));
1077 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1078 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1082 SetFocus(g_pChildWnd
->hWnd
);
1085 resize_frame_client(hWnd
);
1089 case WM_ENTERMENULOOP
:
1090 OnEnterMenuLoop(hWnd
);
1092 case WM_EXITMENULOOP
:
1093 OnExitMenuLoop(hWnd
);
1095 case WM_INITMENUPOPUP
:
1096 if (!HIWORD(lParam
))
1097 OnInitMenuPopup(hWnd
, (HMENU
)wParam
);
1100 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1104 const WCHAR help_regedit
[] = {'r','e','g','e','d','i','t',0};
1105 WinHelpW(hWnd
, help_regedit
, HELP_QUIT
, 0);
1109 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);