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 Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ChildWnd
* g_pChildWnd
;
24 static int last_split
;
25 HBITMAP SizingPattern
= 0;
26 HBRUSH SizingBrush
= 0;
27 static WCHAR Suggestions
[256];
29 extern LPCWSTR
get_root_key_name(HKEY hRootKey
)
31 if (hRootKey
== HKEY_CLASSES_ROOT
) return L
"HKEY_CLASSES_ROOT";
32 if (hRootKey
== HKEY_CURRENT_USER
) return L
"HKEY_CURRENT_USER";
33 if (hRootKey
== HKEY_LOCAL_MACHINE
) return L
"HKEY_LOCAL_MACHINE";
34 if (hRootKey
== HKEY_USERS
) return L
"HKEY_USERS";
35 if (hRootKey
== HKEY_CURRENT_CONFIG
) return L
"HKEY_CURRENT_CONFIG";
36 if (hRootKey
== HKEY_DYN_DATA
) return L
"HKEY_DYN_DATA";
38 return L
"UNKNOWN HKEY, PLEASE REPORT";
41 extern void ResizeWnd(int cx
, int cy
)
43 HDWP hdwp
= BeginDeferWindowPos(4);
45 const int tHeight
= 22;
46 const UINT uFlags
= SWP_NOZORDER
| SWP_NOACTIVATE
;
47 SetRect(&rt
, 0, 0, cx
, cy
);
49 if (hStatusBar
!= NULL
)
51 GetWindowRect(hStatusBar
, &rs
);
52 cy
= rs
.bottom
- rs
.top
;
54 GetWindowRect(g_pChildWnd
->hAddressBtnWnd
, &rb
);
55 cx
= g_pChildWnd
->nSplitPos
+ SPLIT_WIDTH
/ 2;
57 hdwp
= DeferWindowPos(hdwp
, g_pChildWnd
->hAddressBarWnd
, NULL
,
59 rt
.right
- rt
.left
- 2*tHeight
, tHeight
,
62 hdwp
= DeferWindowPos(hdwp
, g_pChildWnd
->hAddressBtnWnd
, NULL
,
63 rt
.right
- 2*tHeight
, rt
.top
,
67 hdwp
= DeferWindowPos(hdwp
, g_pChildWnd
->hTreeWnd
, NULL
,
68 rt
.left
, rt
.top
+ tHeight
+ 2,
69 g_pChildWnd
->nSplitPos
- SPLIT_WIDTH
/2 - rt
.left
, rt
.bottom
- rt
.top
- cy
,
72 hdwp
= DeferWindowPos(hdwp
, g_pChildWnd
->hListWnd
, NULL
,
73 rt
.left
+ cx
, rt
.top
+ tHeight
+ 2,
74 rt
.right
- cx
, rt
.bottom
- rt
.top
- cy
,
77 EndDeferWindowPos(hdwp
);
80 /*******************************************************************************
81 * Local module support methods
84 static void draw_splitbar(HWND hWnd
, int x
)
88 HDC hdc
= GetDC(hWnd
);
92 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
93 SizingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
97 SizingBrush
= CreatePatternBrush(SizingPattern
);
99 GetClientRect(hWnd
, &rt
);
100 rt
.left
= x
- SPLIT_WIDTH
/2;
101 rt
.right
= x
+ SPLIT_WIDTH
/2+1;
102 OldObj
= SelectObject(hdc
, SizingBrush
);
103 PatBlt(hdc
, rt
.left
, rt
.top
, rt
.right
- rt
.left
, rt
.bottom
- rt
.top
, PATINVERT
);
104 SelectObject(hdc
, OldObj
);
105 ReleaseDC(hWnd
, hdc
);
108 static void OnPaint(HWND hWnd
)
113 GetClientRect(hWnd
, &rt
);
114 BeginPaint(hWnd
, &ps
);
115 FillRect(ps
.hdc
, &rt
, GetSysColorBrush(COLOR_BTNFACE
));
119 /*******************************************************************************
120 * finish_splitbar [internal]
122 * make the splitbar invisible and resize the windows
123 * (helper for ChildWndProc)
125 static void finish_splitbar(HWND hWnd
, int x
)
129 draw_splitbar(hWnd
, last_split
);
131 GetClientRect(hWnd
, &rt
);
132 g_pChildWnd
->nSplitPos
= x
;
133 ResizeWnd(rt
.right
, rt
.bottom
);
137 /*******************************************************************************
139 * FUNCTION: ChildWnd_CmdWndProc(HWND, unsigned, WORD, LONG)
141 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
145 static BOOL
ChildWnd_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
147 HTREEITEM hSelection
;
150 WORD wID
= LOWORD(wParam
);
152 UNREFERENCED_PARAMETER(message
);
156 /* Parse the menu selections: */
157 case ID_REGISTRY_EXIT
:
160 case ID_VIEW_REFRESH
:
163 case ID_TREE_EXPANDBRANCH
:
164 TreeView_Expand(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
), TVE_EXPAND
);
166 case ID_TREE_COLLAPSEBRANCH
:
167 TreeView_Expand(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
), TVE_COLLAPSE
);
170 SetFocus(g_pChildWnd
->hTreeWnd
);
171 TreeView_EditLabel(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
));
174 hSelection
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
175 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, hSelection
, &hRootKey
);
177 if (keyPath
== 0 || *keyPath
== 0)
179 MessageBeep(MB_ICONHAND
);
181 else if (DeleteKey(hWnd
, hRootKey
, keyPath
))
182 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
185 ExportRegistryFile(g_pChildWnd
->hTreeWnd
);
190 case ID_EDIT_COPYKEYNAME
:
191 hSelection
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
192 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, hSelection
, &hRootKey
);
193 CopyKeyName(hWnd
, hRootKey
, keyPath
);
195 case ID_EDIT_NEW_KEY
:
196 CreateNewKey(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
));
198 case ID_EDIT_NEW_STRINGVALUE
:
199 case ID_EDIT_NEW_BINARYVALUE
:
200 case ID_EDIT_NEW_DWORDVALUE
:
201 SendMessageW(hFrameWnd
, WM_COMMAND
, wParam
, lParam
);
203 case ID_SWITCH_PANELS
:
204 g_pChildWnd
->nFocusPanel
= !g_pChildWnd
->nFocusPanel
;
205 SetFocus(g_pChildWnd
->nFocusPanel
? g_pChildWnd
->hListWnd
: g_pChildWnd
->hTreeWnd
);
208 if ((wID
>= ID_TREE_SUGGESTION_MIN
) && (wID
<= ID_TREE_SUGGESTION_MAX
))
211 while(wID
> ID_TREE_SUGGESTION_MIN
)
217 SelectNode(g_pChildWnd
->hTreeWnd
, s
);
225 /*******************************************************************************
230 #define MIN(a,b) ((a < b) ? (a) : (b))
232 static void SuggestKeys(HKEY hRootKey
, LPCWSTR pszKeyPath
, LPWSTR pszSuggestions
,
233 size_t iSuggestionsLength
)
236 WCHAR szLastFound
[256];
238 HKEY hOtherKey
, hSubKey
;
241 memset(pszSuggestions
, 0, iSuggestionsLength
* sizeof(*pszSuggestions
));
242 iSuggestionsLength
--;
244 /* Are we a root key in HKEY_CLASSES_ROOT? */
245 if ((hRootKey
== HKEY_CLASSES_ROOT
) && pszKeyPath
[0] && !wcschr(pszKeyPath
, L
'\\'))
251 /* Check default key */
252 if (QueryStringValue(hRootKey
, pszKeyPath
, NULL
,
253 szBuffer
, COUNT_OF(szBuffer
)) == ERROR_SUCCESS
)
255 /* Sanity check this key; it cannot be empty, nor can it be a
257 if ((szBuffer
[0] != L
'\0') && _wcsicmp(szBuffer
, pszKeyPath
))
259 if (RegOpenKeyW(hRootKey
, szBuffer
, &hOtherKey
) == ERROR_SUCCESS
)
261 lstrcpynW(pszSuggestions
, L
"HKCR\\", (int) iSuggestionsLength
);
262 i
= wcslen(pszSuggestions
);
264 iSuggestionsLength
-= i
;
266 lstrcpynW(pszSuggestions
, szBuffer
, (int) iSuggestionsLength
);
267 i
= MIN(wcslen(pszSuggestions
) + 1, iSuggestionsLength
);
269 iSuggestionsLength
-= i
;
270 RegCloseKey(hOtherKey
);
273 wcscpy(szLastFound
, szBuffer
);
274 pszKeyPath
= szLastFound
;
279 while(bFound
&& (iSuggestionsLength
> 0));
281 /* Check CLSID key */
282 if (RegOpenKeyW(hRootKey
, pszKeyPath
, &hSubKey
) == ERROR_SUCCESS
)
284 if (QueryStringValue(hSubKey
, L
"CLSID", NULL
, szBuffer
,
285 COUNT_OF(szBuffer
)) == ERROR_SUCCESS
)
287 lstrcpynW(pszSuggestions
, L
"HKCR\\CLSID\\", (int)iSuggestionsLength
);
288 i
= wcslen(pszSuggestions
);
290 iSuggestionsLength
-= i
;
292 lstrcpynW(pszSuggestions
, szBuffer
, (int)iSuggestionsLength
);
293 i
= MIN(wcslen(pszSuggestions
) + 1, iSuggestionsLength
);
295 iSuggestionsLength
-= i
;
297 RegCloseKey(hSubKey
);
303 LRESULT CALLBACK
AddressBarProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
306 static WCHAR s_szNode
[256];
307 oldwndproc
= (WNDPROC
)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
312 if (wParam
== VK_RETURN
)
314 GetWindowTextW(hwnd
, s_szNode
, COUNT_OF(s_szNode
));
315 SelectNode(g_pChildWnd
->hTreeWnd
, s_szNode
);
321 return CallWindowProcW(oldwndproc
, hwnd
, uMsg
, wParam
, lParam
);
325 UpdateAddress(HTREEITEM hItem
, HKEY hRootKey
, LPCWSTR pszPath
)
327 LPCWSTR keyPath
, rootName
;
330 /* Wipe the listview, the status bar and the address bar if the root key was selected */
331 if (TreeView_GetParent(g_pChildWnd
->hTreeWnd
, hItem
) == NULL
)
333 ListView_DeleteAllItems(g_pChildWnd
->hListWnd
);
334 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)NULL
);
335 SendMessageW(g_pChildWnd
->hAddressBarWnd
, WM_SETTEXT
, 0, (LPARAM
)NULL
);
340 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, hItem
, &hRootKey
);
346 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, keyPath
);
347 rootName
= get_root_key_name(hRootKey
);
348 fullPath
= HeapAlloc(GetProcessHeap(), 0, (wcslen(rootName
) + 1 + wcslen(keyPath
) + 1) * sizeof(WCHAR
));
351 /* set (correct) the address bar text */
352 if (keyPath
[0] != L
'\0')
353 swprintf(fullPath
, L
"%s\\%s", rootName
, keyPath
);
355 fullPath
= wcscpy(fullPath
, rootName
);
356 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)fullPath
);
357 SendMessageW(g_pChildWnd
->hAddressBarWnd
, WM_SETTEXT
, 0, (LPARAM
)fullPath
);
358 HeapFree(GetProcessHeap(), 0, fullPath
);
359 /* disable hive manipulation items temporarily (enable only if necessary) */
360 EnableMenuItem(GetSubMenu(hMenuFrame
,0), ID_REGISTRY_LOADHIVE
, MF_BYCOMMAND
| MF_GRAYED
);
361 EnableMenuItem(GetSubMenu(hMenuFrame
,0), ID_REGISTRY_UNLOADHIVE
, MF_BYCOMMAND
| MF_GRAYED
);
362 /* compare the strings to see if we should enable/disable the "Load Hive" menus accordingly */
363 if (!(_wcsicmp(rootName
, L
"HKEY_LOCAL_MACHINE") &&
364 _wcsicmp(rootName
, L
"HKEY_USERS")))
367 * enable the unload menu item if at the root, otherwise
368 * enable the load menu item if there is no slash in
369 * keyPath (ie. immediate child selected)
371 if(keyPath
[0] == L
'\0')
372 EnableMenuItem(GetSubMenu(hMenuFrame
,0), ID_REGISTRY_LOADHIVE
, MF_BYCOMMAND
| MF_ENABLED
);
373 else if(!wcschr(keyPath
, L
'\\'))
374 EnableMenuItem(GetSubMenu(hMenuFrame
,0), ID_REGISTRY_UNLOADHIVE
, MF_BYCOMMAND
| MF_ENABLED
);
380 /*******************************************************************************
382 * FUNCTION: ChildWndProc(HWND, unsigned, WORD, LONG)
384 * PURPOSE: Processes messages for the child windows.
386 * WM_COMMAND - process the application menu
387 * WM_PAINT - Paint the main window
388 * WM_DESTROY - post a quit message and return
391 LRESULT CALLBACK
ChildWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
401 WCHAR buffer
[MAX_PATH
];
403 /* Load "My Computer" string */
404 LoadStringW(hInst
, IDS_MY_COMPUTER
, buffer
, COUNT_OF(buffer
));
406 g_pChildWnd
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(ChildWnd
));
407 if (!g_pChildWnd
) return 0;
409 wcsncpy(g_pChildWnd
->szPath
, buffer
, MAX_PATH
);
410 g_pChildWnd
->nSplitPos
= 250;
411 g_pChildWnd
->hWnd
= hWnd
;
412 g_pChildWnd
->hAddressBarWnd
= CreateWindowExW(WS_EX_CLIENTEDGE
, L
"Edit", NULL
, WS_CHILD
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_TABSTOP
,
413 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
414 hWnd
, (HMENU
)0, hInst
, 0);
415 g_pChildWnd
->hAddressBtnWnd
= CreateWindowExW(0, L
"Button", L
"\x00BB", WS_CHILD
| WS_VISIBLE
| WS_CHILDWINDOW
| WS_TABSTOP
| BS_TEXT
| BS_CENTER
| BS_VCENTER
| BS_FLAT
| BS_DEFPUSHBUTTON
,
416 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
417 hWnd
, (HMENU
)0, hInst
, 0);
418 g_pChildWnd
->hTreeWnd
= CreateTreeView(hWnd
, g_pChildWnd
->szPath
, (HMENU
) TREE_WINDOW
);
419 g_pChildWnd
->hListWnd
= CreateListView(hWnd
, (HMENU
) LIST_WINDOW
/*, g_pChildWnd->szPath*/);
420 SetFocus(g_pChildWnd
->hTreeWnd
);
422 /* set the address bar and button font */
423 if ((g_pChildWnd
->hAddressBarWnd
) && (g_pChildWnd
->hAddressBtnWnd
))
425 hFont
= (HFONT
)GetStockObject(DEFAULT_GUI_FONT
);
426 SendMessageW(g_pChildWnd
->hAddressBarWnd
,
430 SendMessageW(g_pChildWnd
->hAddressBtnWnd
,
435 /* Subclass the AddressBar */
436 oldproc
= (WNDPROC
)GetWindowLongPtr(g_pChildWnd
->hAddressBarWnd
, GWLP_WNDPROC
);
437 SetWindowLongPtr(g_pChildWnd
->hAddressBarWnd
, GWLP_USERDATA
, (DWORD_PTR
)oldproc
);
438 SetWindowLongPtr(g_pChildWnd
->hAddressBarWnd
, GWLP_WNDPROC
, (DWORD_PTR
)AddressBarProc
);
442 if(HIWORD(wParam
) == BN_CLICKED
)
444 PostMessageW(g_pChildWnd
->hAddressBarWnd
, WM_KEYUP
, VK_RETURN
, 0);
447 if (!ChildWnd_CmdWndProc(hWnd
, message
, wParam
, lParam
))
456 if (LOWORD(lParam
) == HTCLIENT
)
460 ScreenToClient(hWnd
, &pt
);
461 if (pt
.x
>=g_pChildWnd
->nSplitPos
-SPLIT_WIDTH
/2 && pt
.x
<g_pChildWnd
->nSplitPos
+SPLIT_WIDTH
/2+1)
463 SetCursor(LoadCursorW(0, IDC_SIZEWE
));
469 DestroyListView(g_pChildWnd
->hListWnd
);
470 DestroyTreeView(g_pChildWnd
->hTreeWnd
);
472 HeapFree(GetProcessHeap(), 0, g_pChildWnd
);
479 int x
= (short)LOWORD(lParam
);
480 GetClientRect(hWnd
, &rt
);
481 if (x
>=g_pChildWnd
->nSplitPos
-SPLIT_WIDTH
/2 && x
<g_pChildWnd
->nSplitPos
+SPLIT_WIDTH
/2+1)
483 last_split
= g_pChildWnd
->nSplitPos
;
484 draw_splitbar(hWnd
, last_split
);
492 if (GetCapture() == hWnd
)
494 finish_splitbar(hWnd
, LOWORD(lParam
));
498 case WM_CAPTURECHANGED
:
499 if (GetCapture()==hWnd
&& last_split
>=0)
500 draw_splitbar(hWnd
, last_split
);
504 if (wParam
== VK_ESCAPE
)
505 if (GetCapture() == hWnd
)
508 draw_splitbar(hWnd
, last_split
);
509 GetClientRect(hWnd
, &rt
);
510 ResizeWnd(rt
.right
, rt
.bottom
);
513 SetCursor(LoadCursorW(0, IDC_ARROW
));
518 if (GetCapture() == hWnd
)
523 int x
= LOWORD(lParam
);
526 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
527 SizingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
531 SizingBrush
= CreatePatternBrush(SizingPattern
);
534 GetClientRect(hWnd
, &rt
);
535 x
= (SHORT
) min(max(x
, SPLIT_MIN
), rt
.right
- SPLIT_MIN
);
538 rt
.left
= last_split
-SPLIT_WIDTH
/2;
539 rt
.right
= last_split
+SPLIT_WIDTH
/2+1;
541 OldObj
= SelectObject(hdc
, SizingBrush
);
542 PatBlt(hdc
, rt
.left
, rt
.top
, rt
.right
- rt
.left
, rt
.bottom
- rt
.top
, PATINVERT
);
544 rt
.left
= x
-SPLIT_WIDTH
/2;
545 rt
.right
= x
+SPLIT_WIDTH
/2+1;
546 PatBlt(hdc
, rt
.left
, rt
.top
, rt
.right
- rt
.left
, rt
.bottom
- rt
.top
, PATINVERT
);
547 SelectObject(hdc
, OldObj
);
548 ReleaseDC(hWnd
, hdc
);
554 if (g_pChildWnd
!= NULL
)
556 SetFocus(g_pChildWnd
->nFocusPanel
? g_pChildWnd
->hListWnd
: g_pChildWnd
->hTreeWnd
);
564 if ((int)wParam
== TREE_WINDOW
&& g_pChildWnd
!= NULL
)
566 switch (((LPNMHDR
)lParam
)->code
)
568 case TVN_ITEMEXPANDING
:
569 return !OnTreeExpanding(g_pChildWnd
->hTreeWnd
, (NMTREEVIEW
*)lParam
);
572 NMTREEVIEW
* pnmtv
= (NMTREEVIEW
*)lParam
;
573 /* Get the parent of the current item */
574 HTREEITEM hParentItem
= TreeView_GetParent(g_pChildWnd
->hTreeWnd
, pnmtv
->itemNew
.hItem
);
576 UpdateAddress(pnmtv
->itemNew
.hItem
, NULL
, NULL
);
579 * Disable Delete/Rename menu options for 'My Computer' (first item so doesn't have any parent)
580 * and HKEY_* keys (their parent is 'My Computer' and the previous remark applies).
582 if (!hParentItem
|| !TreeView_GetParent(g_pChildWnd
->hTreeWnd
, hParentItem
))
584 EnableMenuItem(hMenuFrame
, ID_EDIT_DELETE
, MF_BYCOMMAND
| MF_GRAYED
);
585 EnableMenuItem(hMenuFrame
, ID_EDIT_RENAME
, MF_BYCOMMAND
| MF_GRAYED
);
586 EnableMenuItem(hPopupMenus
, ID_TREE_DELETE
, MF_BYCOMMAND
| MF_GRAYED
);
587 EnableMenuItem(hPopupMenus
, ID_TREE_RENAME
, MF_BYCOMMAND
| MF_GRAYED
);
591 EnableMenuItem(hMenuFrame
, ID_EDIT_DELETE
, MF_BYCOMMAND
| MF_ENABLED
);
592 EnableMenuItem(hMenuFrame
, ID_EDIT_RENAME
, MF_BYCOMMAND
| MF_ENABLED
);
593 EnableMenuItem(hPopupMenus
, ID_TREE_DELETE
, MF_BYCOMMAND
| MF_ENABLED
);
594 EnableMenuItem(hPopupMenus
, ID_TREE_RENAME
, MF_BYCOMMAND
| MF_ENABLED
);
600 g_pChildWnd
->nFocusPanel
= 0;
602 case TVN_BEGINLABELEDIT
:
604 LPNMTVDISPINFO ptvdi
;
605 /* cancel label edit for rootkeys */
606 ptvdi
= (LPNMTVDISPINFO
) lParam
;
607 if (!TreeView_GetParent(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
) ||
608 !TreeView_GetParent(g_pChildWnd
->hTreeWnd
, TreeView_GetParent(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
)))
612 case TVN_ENDLABELEDIT
:
617 LPNMTVDISPINFO ptvdi
;
619 WCHAR szBuffer
[MAX_PATH
];
621 ptvdi
= (LPNMTVDISPINFO
) lParam
;
622 if (ptvdi
->item
.pszText
)
624 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, TreeView_GetParent(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
), &hRootKey
);
625 _snwprintf(szBuffer
, COUNT_OF(szBuffer
), L
"%s\\%s", keyPath
, ptvdi
->item
.pszText
);
626 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
, &hRootKey
);
627 if (RegOpenKeyExW(hRootKey
, szBuffer
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
631 TreeView_EditLabel(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
);
635 if (RenameKey(hRootKey
, keyPath
, ptvdi
->item
.pszText
) != ERROR_SUCCESS
)
638 UpdateAddress(ptvdi
->item
.hItem
, hRootKey
, szBuffer
);
649 if ((int)wParam
== LIST_WINDOW
&& g_pChildWnd
!= NULL
)
651 switch (((LPNMHDR
)lParam
)->code
)
654 g_pChildWnd
->nFocusPanel
= 1;
657 if(!ListWndNotifyProc(g_pChildWnd
->hListWnd
, wParam
, lParam
, &Result
))
671 if((HWND
)wParam
== g_pChildWnd
->hListWnd
)
675 pt
.x
= (short) LOWORD(lParam
);
676 pt
.y
= (short) HIWORD(lParam
);
677 cnt
= ListView_GetSelectedCount(g_pChildWnd
->hListWnd
);
678 i
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, -1, LVNI_FOCUSED
| LVNI_SELECTED
);
679 if (pt
.x
== -1 && pt
.y
== -1)
684 rc
.left
= LVIR_BOUNDS
;
685 SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETITEMRECT
, i
, (LPARAM
) &rc
);
691 ClientToScreen(g_pChildWnd
->hListWnd
, &pt
);
695 TrackPopupMenu(GetSubMenu(hPopupMenus
, PM_NEW
), TPM_RIGHTBUTTON
, pt
.x
, pt
.y
, 0, hFrameWnd
, NULL
);
699 HMENU mnu
= GetSubMenu(hPopupMenus
, PM_MODIFYVALUE
);
700 SetMenuDefaultItem(mnu
, ID_EDIT_MODIFY
, MF_BYCOMMAND
);
701 IsDefault
= IsDefaultValue(g_pChildWnd
->hListWnd
, i
);
703 EnableMenuItem(mnu
, ID_EDIT_RENAME
, MF_BYCOMMAND
| (IsDefault
? MF_DISABLED
| MF_GRAYED
: MF_ENABLED
));
705 EnableMenuItem(mnu
, ID_EDIT_RENAME
, MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
706 EnableMenuItem(mnu
, ID_EDIT_MODIFY
, MF_BYCOMMAND
| (cnt
== 1 ? MF_ENABLED
: MF_DISABLED
| MF_GRAYED
));
707 EnableMenuItem(mnu
, ID_EDIT_MODIFY_BIN
, MF_BYCOMMAND
| (cnt
== 1 ? MF_ENABLED
: MF_DISABLED
| MF_GRAYED
));
709 TrackPopupMenu(mnu
, TPM_RIGHTBUTTON
, pt
.x
, pt
.y
, 0, hFrameWnd
, NULL
);
712 else if ((HWND
)wParam
== g_pChildWnd
->hTreeWnd
)
726 pt
.x
= (short) LOWORD(lParam
);
727 pt
.y
= (short) HIWORD(lParam
);
729 if (pt
.x
== -1 && pt
.y
== -1)
732 hti
.hItem
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
733 if (hti
.hItem
!= NULL
)
735 TreeView_GetItemRect(g_pChildWnd
->hTreeWnd
, hti
.hItem
, &rc
, TRUE
);
738 ClientToScreen(g_pChildWnd
->hTreeWnd
, &pt
);
739 hti
.flags
= TVHT_ONITEM
;
748 ScreenToClient(g_pChildWnd
->hTreeWnd
, &hti
.pt
);
749 TreeView_HitTest(g_pChildWnd
->hTreeWnd
, &hti
);
752 if (hti
.flags
& TVHT_ONITEM
)
754 hContextMenu
= GetSubMenu(hPopupMenus
, PM_TREECONTEXT
);
755 TreeView_SelectItem(g_pChildWnd
->hTreeWnd
, hti
.hItem
);
757 memset(&item
, 0, sizeof(item
));
758 item
.mask
= TVIF_STATE
| TVIF_CHILDREN
;
759 item
.hItem
= hti
.hItem
;
760 TreeView_GetItem(g_pChildWnd
->hTreeWnd
, &item
);
762 /* Set the Expand/Collapse menu item appropriately */
763 LoadStringW(hInst
, (item
.state
& TVIS_EXPANDED
) ? IDS_COLLAPSE
: IDS_EXPAND
, buffer
, COUNT_OF(buffer
));
764 memset(&mii
, 0, sizeof(mii
));
765 mii
.cbSize
= sizeof(mii
);
766 mii
.fMask
= MIIM_STRING
| MIIM_STATE
| MIIM_ID
;
767 mii
.fState
= (item
.cChildren
> 0) ? MFS_DEFAULT
: MFS_GRAYED
;
768 mii
.wID
= (item
.state
& TVIS_EXPANDED
) ? ID_TREE_COLLAPSEBRANCH
: ID_TREE_EXPANDBRANCH
;
769 mii
.dwTypeData
= (LPWSTR
) buffer
;
770 SetMenuItemInfo(hContextMenu
, 0, TRUE
, &mii
);
772 /* Remove any existing suggestions */
773 memset(&mii
, 0, sizeof(mii
));
774 mii
.cbSize
= sizeof(mii
);
776 GetMenuItemInfo(hContextMenu
, GetMenuItemCount(hContextMenu
) - 1, TRUE
, &mii
);
777 if ((mii
.wID
>= ID_TREE_SUGGESTION_MIN
) && (mii
.wID
<= ID_TREE_SUGGESTION_MAX
))
781 iLastPos
= GetMenuItemCount(hContextMenu
) - 1;
782 GetMenuItemInfo(hContextMenu
, iLastPos
, TRUE
, &mii
);
783 RemoveMenu(hContextMenu
, iLastPos
, MF_BYPOSITION
);
785 while((mii
.wID
>= ID_TREE_SUGGESTION_MIN
) && (mii
.wID
<= ID_TREE_SUGGESTION_MAX
));
788 /* Come up with suggestions */
789 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, NULL
, &hRootKey
);
790 SuggestKeys(hRootKey
, keyPath
, Suggestions
, COUNT_OF(Suggestions
));
793 AppendMenu(hContextMenu
, MF_SEPARATOR
, 0, NULL
);
795 LoadStringW(hInst
, IDS_GOTO_SUGGESTED_KEY
, resource
, COUNT_OF(resource
));
798 wID
= ID_TREE_SUGGESTION_MIN
;
799 while(*s
&& (wID
<= ID_TREE_SUGGESTION_MAX
))
801 _snwprintf(buffer
, COUNT_OF(buffer
), resource
, s
);
803 memset(&mii
, 0, sizeof(mii
));
804 mii
.cbSize
= sizeof(mii
);
805 mii
.fMask
= MIIM_STRING
| MIIM_ID
;
807 mii
.dwTypeData
= buffer
;
808 InsertMenuItem(hContextMenu
, GetMenuItemCount(hContextMenu
), TRUE
, &mii
);
813 TrackPopupMenu(hContextMenu
, TPM_RIGHTBUTTON
, pt
.x
, pt
.y
, 0, g_pChildWnd
->hWnd
, NULL
);
820 if (wParam
!= SIZE_MINIMIZED
&& g_pChildWnd
!= NULL
)
822 ResizeWnd(LOWORD(lParam
), HIWORD(lParam
));
827 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);