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 nButtonWidth
= 44;
46 const int nButtonHeight
= 22;
47 int cyEdge
= GetSystemMetrics(SM_CYEDGE
);
48 const UINT uFlags
= SWP_NOZORDER
| SWP_NOACTIVATE
;
49 SetRect(&rt
, 0, 0, cx
, cy
);
51 if (hStatusBar
!= NULL
)
53 GetWindowRect(hStatusBar
, &rs
);
54 cy
= rs
.bottom
- rs
.top
;
56 GetWindowRect(g_pChildWnd
->hAddressBtnWnd
, &rb
);
57 cx
= g_pChildWnd
->nSplitPos
+ SPLIT_WIDTH
/ 2;
59 hdwp
= DeferWindowPos(hdwp
, g_pChildWnd
->hAddressBarWnd
, NULL
,
61 rt
.right
- rt
.left
- nButtonWidth
, nButtonHeight
,
64 hdwp
= DeferWindowPos(hdwp
, g_pChildWnd
->hAddressBtnWnd
, NULL
,
65 rt
.right
- nButtonWidth
, rt
.top
,
66 nButtonWidth
, nButtonHeight
,
69 hdwp
= DeferWindowPos(hdwp
, g_pChildWnd
->hTreeWnd
, NULL
,
71 rt
.top
+ nButtonHeight
+ cyEdge
,
72 g_pChildWnd
->nSplitPos
- SPLIT_WIDTH
/2 - rt
.left
,
73 rt
.bottom
- rt
.top
- cy
- 2 * cyEdge
,
76 hdwp
= DeferWindowPos(hdwp
, g_pChildWnd
->hListWnd
, NULL
,
78 rt
.top
+ nButtonHeight
+ cyEdge
,
80 rt
.bottom
- rt
.top
- cy
- 2 * cyEdge
,
83 EndDeferWindowPos(hdwp
);
86 /*******************************************************************************
87 * Local module support methods
90 static void draw_splitbar(HWND hWnd
, int x
)
94 HDC hdc
= GetDC(hWnd
);
98 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
99 SizingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
103 SizingBrush
= CreatePatternBrush(SizingPattern
);
105 GetClientRect(hWnd
, &rt
);
106 rt
.left
= x
- SPLIT_WIDTH
/2;
107 rt
.right
= x
+ SPLIT_WIDTH
/2+1;
108 OldObj
= SelectObject(hdc
, SizingBrush
);
109 PatBlt(hdc
, rt
.left
, rt
.top
, rt
.right
- rt
.left
, rt
.bottom
- rt
.top
, PATINVERT
);
110 SelectObject(hdc
, OldObj
);
111 ReleaseDC(hWnd
, hdc
);
114 /*******************************************************************************
115 * finish_splitbar [internal]
117 * make the splitbar invisible and resize the windows
118 * (helper for ChildWndProc)
120 static void finish_splitbar(HWND hWnd
, int x
)
124 draw_splitbar(hWnd
, last_split
);
126 GetClientRect(hWnd
, &rt
);
127 g_pChildWnd
->nSplitPos
= x
;
128 ResizeWnd(rt
.right
, rt
.bottom
);
132 /*******************************************************************************
134 * FUNCTION: ChildWnd_CmdWndProc(HWND, unsigned, WORD, LONG)
136 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
140 static BOOL
ChildWnd_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
142 HTREEITEM hSelection
;
145 WORD wID
= LOWORD(wParam
);
147 UNREFERENCED_PARAMETER(message
);
151 /* Parse the menu selections: */
152 case ID_REGISTRY_EXIT
:
155 case ID_VIEW_REFRESH
:
158 case ID_TREE_EXPANDBRANCH
:
159 TreeView_Expand(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
), TVE_EXPAND
);
161 case ID_TREE_COLLAPSEBRANCH
:
162 TreeView_Expand(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
), TVE_COLLAPSE
);
165 SetFocus(g_pChildWnd
->hTreeWnd
);
166 TreeView_EditLabel(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
));
169 hSelection
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
170 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, hSelection
, &hRootKey
);
172 if (keyPath
== 0 || *keyPath
== 0)
174 MessageBeep(MB_ICONHAND
);
176 else if (DeleteKey(hWnd
, hRootKey
, keyPath
))
177 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
180 ExportRegistryFile(g_pChildWnd
->hTreeWnd
);
185 case ID_EDIT_COPYKEYNAME
:
186 hSelection
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
187 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, hSelection
, &hRootKey
);
188 CopyKeyName(hWnd
, hRootKey
, keyPath
);
190 case ID_EDIT_NEW_KEY
:
191 CreateNewKey(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
));
193 case ID_EDIT_NEW_STRINGVALUE
:
194 case ID_EDIT_NEW_BINARYVALUE
:
195 case ID_EDIT_NEW_DWORDVALUE
:
196 SendMessageW(hFrameWnd
, WM_COMMAND
, wParam
, lParam
);
198 case ID_SWITCH_PANELS
:
199 g_pChildWnd
->nFocusPanel
= !g_pChildWnd
->nFocusPanel
;
200 SetFocus(g_pChildWnd
->nFocusPanel
? g_pChildWnd
->hListWnd
: g_pChildWnd
->hTreeWnd
);
203 if ((wID
>= ID_TREE_SUGGESTION_MIN
) && (wID
<= ID_TREE_SUGGESTION_MAX
))
206 while(wID
> ID_TREE_SUGGESTION_MIN
)
212 SelectNode(g_pChildWnd
->hTreeWnd
, s
);
220 /*******************************************************************************
225 #define MIN(a,b) ((a < b) ? (a) : (b))
227 static void SuggestKeys(HKEY hRootKey
, LPCWSTR pszKeyPath
, LPWSTR pszSuggestions
,
228 size_t iSuggestionsLength
)
231 WCHAR szLastFound
[256];
233 HKEY hOtherKey
, hSubKey
;
236 memset(pszSuggestions
, 0, iSuggestionsLength
* sizeof(*pszSuggestions
));
237 iSuggestionsLength
--;
239 /* Are we a root key in HKEY_CLASSES_ROOT? */
240 if ((hRootKey
== HKEY_CLASSES_ROOT
) && pszKeyPath
[0] && !wcschr(pszKeyPath
, L
'\\'))
246 /* Check default key */
247 if (QueryStringValue(hRootKey
, pszKeyPath
, NULL
,
248 szBuffer
, COUNT_OF(szBuffer
)) == ERROR_SUCCESS
)
250 /* Sanity check this key; it cannot be empty, nor can it be a
252 if ((szBuffer
[0] != L
'\0') && _wcsicmp(szBuffer
, pszKeyPath
))
254 if (RegOpenKeyW(hRootKey
, szBuffer
, &hOtherKey
) == ERROR_SUCCESS
)
256 lstrcpynW(pszSuggestions
, L
"HKCR\\", (int) iSuggestionsLength
);
257 i
= wcslen(pszSuggestions
);
259 iSuggestionsLength
-= i
;
261 lstrcpynW(pszSuggestions
, szBuffer
, (int) iSuggestionsLength
);
262 i
= MIN(wcslen(pszSuggestions
) + 1, iSuggestionsLength
);
264 iSuggestionsLength
-= i
;
265 RegCloseKey(hOtherKey
);
268 wcscpy(szLastFound
, szBuffer
);
269 pszKeyPath
= szLastFound
;
274 while(bFound
&& (iSuggestionsLength
> 0));
276 /* Check CLSID key */
277 if (RegOpenKeyW(hRootKey
, pszKeyPath
, &hSubKey
) == ERROR_SUCCESS
)
279 if (QueryStringValue(hSubKey
, L
"CLSID", NULL
, szBuffer
,
280 COUNT_OF(szBuffer
)) == ERROR_SUCCESS
)
282 lstrcpynW(pszSuggestions
, L
"HKCR\\CLSID\\", (int)iSuggestionsLength
);
283 i
= wcslen(pszSuggestions
);
285 iSuggestionsLength
-= i
;
287 lstrcpynW(pszSuggestions
, szBuffer
, (int)iSuggestionsLength
);
288 i
= MIN(wcslen(pszSuggestions
) + 1, iSuggestionsLength
);
290 iSuggestionsLength
-= i
;
292 RegCloseKey(hSubKey
);
298 LRESULT CALLBACK
AddressBarProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
301 static WCHAR s_szNode
[256];
302 oldwndproc
= (WNDPROC
)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
307 if (wParam
== VK_RETURN
)
309 GetWindowTextW(hwnd
, s_szNode
, COUNT_OF(s_szNode
));
310 SelectNode(g_pChildWnd
->hTreeWnd
, s_szNode
);
316 return CallWindowProcW(oldwndproc
, hwnd
, uMsg
, wParam
, lParam
);
320 UpdateAddress(HTREEITEM hItem
, HKEY hRootKey
, LPCWSTR pszPath
)
322 LPCWSTR keyPath
, rootName
;
325 /* Wipe the listview, the status bar and the address bar if the root key was selected */
326 if (TreeView_GetParent(g_pChildWnd
->hTreeWnd
, hItem
) == NULL
)
328 ListView_DeleteAllItems(g_pChildWnd
->hListWnd
);
329 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)NULL
);
330 SendMessageW(g_pChildWnd
->hAddressBarWnd
, WM_SETTEXT
, 0, (LPARAM
)NULL
);
335 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, hItem
, &hRootKey
);
341 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, keyPath
);
342 rootName
= get_root_key_name(hRootKey
);
343 fullPath
= HeapAlloc(GetProcessHeap(), 0, (wcslen(rootName
) + 1 + wcslen(keyPath
) + 1) * sizeof(WCHAR
));
346 /* set (correct) the address bar text */
347 if (keyPath
[0] != L
'\0')
348 swprintf(fullPath
, L
"%s\\%s", rootName
, keyPath
);
350 fullPath
= wcscpy(fullPath
, rootName
);
351 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)fullPath
);
352 SendMessageW(g_pChildWnd
->hAddressBarWnd
, WM_SETTEXT
, 0, (LPARAM
)fullPath
);
353 HeapFree(GetProcessHeap(), 0, fullPath
);
354 /* disable hive manipulation items temporarily (enable only if necessary) */
355 EnableMenuItem(GetSubMenu(hMenuFrame
,0), ID_REGISTRY_LOADHIVE
, MF_BYCOMMAND
| MF_GRAYED
);
356 EnableMenuItem(GetSubMenu(hMenuFrame
,0), ID_REGISTRY_UNLOADHIVE
, MF_BYCOMMAND
| MF_GRAYED
);
357 /* compare the strings to see if we should enable/disable the "Load Hive" menus accordingly */
358 if (!(_wcsicmp(rootName
, L
"HKEY_LOCAL_MACHINE") &&
359 _wcsicmp(rootName
, L
"HKEY_USERS")))
362 * enable the unload menu item if at the root, otherwise
363 * enable the load menu item if there is no slash in
364 * keyPath (ie. immediate child selected)
366 if(keyPath
[0] == L
'\0')
367 EnableMenuItem(GetSubMenu(hMenuFrame
,0), ID_REGISTRY_LOADHIVE
, MF_BYCOMMAND
| MF_ENABLED
);
368 else if(!wcschr(keyPath
, L
'\\'))
369 EnableMenuItem(GetSubMenu(hMenuFrame
,0), ID_REGISTRY_UNLOADHIVE
, MF_BYCOMMAND
| MF_ENABLED
);
375 /*******************************************************************************
377 * FUNCTION: ChildWndProc(HWND, unsigned, WORD, LONG)
379 * PURPOSE: Processes messages for the child windows.
381 * WM_COMMAND - process the application menu
382 * WM_DESTROY - post a quit message and return
385 LRESULT CALLBACK
ChildWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
396 WCHAR buffer
[MAX_PATH
];
399 /* Load "My Computer" string */
400 LoadStringW(hInst
, IDS_MY_COMPUTER
, buffer
, COUNT_OF(buffer
));
402 g_pChildWnd
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(ChildWnd
));
403 if (!g_pChildWnd
) return 0;
405 wcsncpy(g_pChildWnd
->szPath
, buffer
, MAX_PATH
);
406 g_pChildWnd
->nSplitPos
= 190;
407 g_pChildWnd
->hWnd
= hWnd
;
409 style
= WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
;
410 g_pChildWnd
->hAddressBarWnd
= CreateWindowExW(WS_EX_CLIENTEDGE
, L
"Edit", NULL
, style
,
411 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
412 hWnd
, (HMENU
)0, hInst
, 0);
414 style
= WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| BS_ICON
| BS_CENTER
|
415 BS_VCENTER
| BS_FLAT
| BS_DEFPUSHBUTTON
;
416 g_pChildWnd
->hAddressBtnWnd
= CreateWindowExW(0, L
"Button", L
"\x00BB", style
,
417 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
418 hWnd
, (HMENU
)0, hInst
, 0);
419 g_pChildWnd
->hArrowIcon
= (HICON
)LoadImageW(hInst
, MAKEINTRESOURCEW(IDI_ARROW
),
420 IMAGE_ICON
, 12, 12, 0);
421 SendMessageW(g_pChildWnd
->hAddressBtnWnd
, BM_SETIMAGE
, IMAGE_ICON
, (LPARAM
)g_pChildWnd
->hArrowIcon
);
423 GetClientRect(hWnd
, &rc
);
424 g_pChildWnd
->hTreeWnd
= CreateTreeView(hWnd
, g_pChildWnd
->szPath
, (HMENU
) TREE_WINDOW
);
425 g_pChildWnd
->hListWnd
= CreateListView(hWnd
, (HMENU
) LIST_WINDOW
, rc
.right
- g_pChildWnd
->nSplitPos
);
426 SetFocus(g_pChildWnd
->hTreeWnd
);
428 /* set the address bar and button font */
429 if ((g_pChildWnd
->hAddressBarWnd
) && (g_pChildWnd
->hAddressBtnWnd
))
431 hFont
= (HFONT
)GetStockObject(DEFAULT_GUI_FONT
);
432 SendMessageW(g_pChildWnd
->hAddressBarWnd
,
436 SendMessageW(g_pChildWnd
->hAddressBtnWnd
,
441 /* Subclass the AddressBar */
442 oldproc
= (WNDPROC
)GetWindowLongPtr(g_pChildWnd
->hAddressBarWnd
, GWLP_WNDPROC
);
443 SetWindowLongPtr(g_pChildWnd
->hAddressBarWnd
, GWLP_USERDATA
, (DWORD_PTR
)oldproc
);
444 SetWindowLongPtr(g_pChildWnd
->hAddressBarWnd
, GWLP_WNDPROC
, (DWORD_PTR
)AddressBarProc
);
448 if(HIWORD(wParam
) == BN_CLICKED
)
450 PostMessageW(g_pChildWnd
->hAddressBarWnd
, WM_KEYUP
, VK_RETURN
, 0);
453 if (!ChildWnd_CmdWndProc(hWnd
, message
, wParam
, lParam
))
459 if (LOWORD(lParam
) == HTCLIENT
)
463 ScreenToClient(hWnd
, &pt
);
464 if (pt
.x
>=g_pChildWnd
->nSplitPos
-SPLIT_WIDTH
/2 && pt
.x
<g_pChildWnd
->nSplitPos
+SPLIT_WIDTH
/2+1)
466 SetCursor(LoadCursorW(0, IDC_SIZEWE
));
472 DestroyListView(g_pChildWnd
->hListWnd
);
473 DestroyTreeView(g_pChildWnd
->hTreeWnd
);
475 DestroyIcon(g_pChildWnd
->hArrowIcon
);
476 HeapFree(GetProcessHeap(), 0, g_pChildWnd
);
483 int x
= (short)LOWORD(lParam
);
484 GetClientRect(hWnd
, &rt
);
485 if (x
>=g_pChildWnd
->nSplitPos
-SPLIT_WIDTH
/2 && x
<g_pChildWnd
->nSplitPos
+SPLIT_WIDTH
/2+1)
487 last_split
= g_pChildWnd
->nSplitPos
;
488 draw_splitbar(hWnd
, last_split
);
496 if (GetCapture() == hWnd
)
498 finish_splitbar(hWnd
, LOWORD(lParam
));
502 case WM_CAPTURECHANGED
:
503 if (GetCapture()==hWnd
&& last_split
>=0)
504 draw_splitbar(hWnd
, last_split
);
508 if (wParam
== VK_ESCAPE
)
509 if (GetCapture() == hWnd
)
512 draw_splitbar(hWnd
, last_split
);
513 GetClientRect(hWnd
, &rt
);
514 ResizeWnd(rt
.right
, rt
.bottom
);
517 SetCursor(LoadCursorW(0, IDC_ARROW
));
522 if (GetCapture() == hWnd
)
527 int x
= LOWORD(lParam
);
530 const DWORD Pattern
[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
531 SizingPattern
= CreateBitmap(8, 8, 1, 1, Pattern
);
535 SizingBrush
= CreatePatternBrush(SizingPattern
);
538 GetClientRect(hWnd
, &rt
);
539 x
= (SHORT
) min(max(x
, SPLIT_MIN
), rt
.right
- SPLIT_MIN
);
542 rt
.left
= last_split
-SPLIT_WIDTH
/2;
543 rt
.right
= last_split
+SPLIT_WIDTH
/2+1;
545 OldObj
= SelectObject(hdc
, SizingBrush
);
546 PatBlt(hdc
, rt
.left
, rt
.top
, rt
.right
- rt
.left
, rt
.bottom
- rt
.top
, PATINVERT
);
548 rt
.left
= x
-SPLIT_WIDTH
/2;
549 rt
.right
= x
+SPLIT_WIDTH
/2+1;
550 PatBlt(hdc
, rt
.left
, rt
.top
, rt
.right
- rt
.left
, rt
.bottom
- rt
.top
, PATINVERT
);
551 SelectObject(hdc
, OldObj
);
552 ReleaseDC(hWnd
, hdc
);
558 if (g_pChildWnd
!= NULL
)
560 SetFocus(g_pChildWnd
->nFocusPanel
? g_pChildWnd
->hListWnd
: g_pChildWnd
->hTreeWnd
);
568 if ((int)wParam
== TREE_WINDOW
&& g_pChildWnd
!= NULL
)
570 switch (((LPNMHDR
)lParam
)->code
)
572 case TVN_ITEMEXPANDING
:
573 return !OnTreeExpanding(g_pChildWnd
->hTreeWnd
, (NMTREEVIEW
*)lParam
);
576 NMTREEVIEW
* pnmtv
= (NMTREEVIEW
*)lParam
;
577 /* Get the parent of the current item */
578 HTREEITEM hParentItem
= TreeView_GetParent(g_pChildWnd
->hTreeWnd
, pnmtv
->itemNew
.hItem
);
580 UpdateAddress(pnmtv
->itemNew
.hItem
, NULL
, NULL
);
583 * Disable Delete/Rename menu options for 'My Computer' (first item so doesn't have any parent)
584 * and HKEY_* keys (their parent is 'My Computer' and the previous remark applies).
586 if (!hParentItem
|| !TreeView_GetParent(g_pChildWnd
->hTreeWnd
, hParentItem
))
588 EnableMenuItem(hMenuFrame
, ID_EDIT_DELETE
, MF_BYCOMMAND
| MF_GRAYED
);
589 EnableMenuItem(hMenuFrame
, ID_EDIT_RENAME
, MF_BYCOMMAND
| MF_GRAYED
);
590 EnableMenuItem(hPopupMenus
, ID_TREE_DELETE
, MF_BYCOMMAND
| MF_GRAYED
);
591 EnableMenuItem(hPopupMenus
, ID_TREE_RENAME
, MF_BYCOMMAND
| MF_GRAYED
);
595 EnableMenuItem(hMenuFrame
, ID_EDIT_DELETE
, MF_BYCOMMAND
| MF_ENABLED
);
596 EnableMenuItem(hMenuFrame
, ID_EDIT_RENAME
, MF_BYCOMMAND
| MF_ENABLED
);
597 EnableMenuItem(hPopupMenus
, ID_TREE_DELETE
, MF_BYCOMMAND
| MF_ENABLED
);
598 EnableMenuItem(hPopupMenus
, ID_TREE_RENAME
, MF_BYCOMMAND
| MF_ENABLED
);
604 g_pChildWnd
->nFocusPanel
= 0;
606 case TVN_BEGINLABELEDIT
:
608 LPNMTVDISPINFO ptvdi
;
609 /* cancel label edit for rootkeys */
610 ptvdi
= (LPNMTVDISPINFO
) lParam
;
611 if (!TreeView_GetParent(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
) ||
612 !TreeView_GetParent(g_pChildWnd
->hTreeWnd
, TreeView_GetParent(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
)))
616 case TVN_ENDLABELEDIT
:
621 LPNMTVDISPINFO ptvdi
;
623 WCHAR szBuffer
[MAX_PATH
];
625 ptvdi
= (LPNMTVDISPINFO
) lParam
;
626 if (ptvdi
->item
.pszText
)
628 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, TreeView_GetParent(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
), &hRootKey
);
629 _snwprintf(szBuffer
, COUNT_OF(szBuffer
), L
"%s\\%s", keyPath
, ptvdi
->item
.pszText
);
630 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
, &hRootKey
);
631 if (RegOpenKeyExW(hRootKey
, szBuffer
, 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
635 TreeView_EditLabel(g_pChildWnd
->hTreeWnd
, ptvdi
->item
.hItem
);
639 if (RenameKey(hRootKey
, keyPath
, ptvdi
->item
.pszText
) != ERROR_SUCCESS
)
642 UpdateAddress(ptvdi
->item
.hItem
, hRootKey
, szBuffer
);
653 if ((int)wParam
== LIST_WINDOW
&& g_pChildWnd
!= NULL
)
655 switch (((LPNMHDR
)lParam
)->code
)
658 g_pChildWnd
->nFocusPanel
= 1;
661 if(!ListWndNotifyProc(g_pChildWnd
->hListWnd
, wParam
, lParam
, &Result
))
675 if((HWND
)wParam
== g_pChildWnd
->hListWnd
)
679 pt
.x
= (short) LOWORD(lParam
);
680 pt
.y
= (short) HIWORD(lParam
);
681 cnt
= ListView_GetSelectedCount(g_pChildWnd
->hListWnd
);
682 i
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, -1, LVNI_FOCUSED
| LVNI_SELECTED
);
683 if (pt
.x
== -1 && pt
.y
== -1)
688 rc
.left
= LVIR_BOUNDS
;
689 SendMessageW(g_pChildWnd
->hListWnd
, LVM_GETITEMRECT
, i
, (LPARAM
) &rc
);
695 ClientToScreen(g_pChildWnd
->hListWnd
, &pt
);
699 TrackPopupMenu(GetSubMenu(hPopupMenus
, PM_NEW
), TPM_RIGHTBUTTON
, pt
.x
, pt
.y
, 0, hFrameWnd
, NULL
);
703 HMENU mnu
= GetSubMenu(hPopupMenus
, PM_MODIFYVALUE
);
704 SetMenuDefaultItem(mnu
, ID_EDIT_MODIFY
, MF_BYCOMMAND
);
705 IsDefault
= IsDefaultValue(g_pChildWnd
->hListWnd
, i
);
707 EnableMenuItem(mnu
, ID_EDIT_RENAME
, MF_BYCOMMAND
| (IsDefault
? MF_DISABLED
| MF_GRAYED
: MF_ENABLED
));
709 EnableMenuItem(mnu
, ID_EDIT_RENAME
, MF_BYCOMMAND
| MF_DISABLED
| MF_GRAYED
);
710 EnableMenuItem(mnu
, ID_EDIT_MODIFY
, MF_BYCOMMAND
| (cnt
== 1 ? MF_ENABLED
: MF_DISABLED
| MF_GRAYED
));
711 EnableMenuItem(mnu
, ID_EDIT_MODIFY_BIN
, MF_BYCOMMAND
| (cnt
== 1 ? MF_ENABLED
: MF_DISABLED
| MF_GRAYED
));
713 TrackPopupMenu(mnu
, TPM_RIGHTBUTTON
, pt
.x
, pt
.y
, 0, hFrameWnd
, NULL
);
716 else if ((HWND
)wParam
== g_pChildWnd
->hTreeWnd
)
730 pt
.x
= (short) LOWORD(lParam
);
731 pt
.y
= (short) HIWORD(lParam
);
733 if (pt
.x
== -1 && pt
.y
== -1)
736 hti
.hItem
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
737 if (hti
.hItem
!= NULL
)
739 TreeView_GetItemRect(g_pChildWnd
->hTreeWnd
, hti
.hItem
, &rc
, TRUE
);
742 ClientToScreen(g_pChildWnd
->hTreeWnd
, &pt
);
743 hti
.flags
= TVHT_ONITEM
;
752 ScreenToClient(g_pChildWnd
->hTreeWnd
, &hti
.pt
);
753 TreeView_HitTest(g_pChildWnd
->hTreeWnd
, &hti
);
756 if (hti
.flags
& TVHT_ONITEM
)
758 hContextMenu
= GetSubMenu(hPopupMenus
, PM_TREECONTEXT
);
759 TreeView_SelectItem(g_pChildWnd
->hTreeWnd
, hti
.hItem
);
761 memset(&item
, 0, sizeof(item
));
762 item
.mask
= TVIF_STATE
| TVIF_CHILDREN
;
763 item
.hItem
= hti
.hItem
;
764 TreeView_GetItem(g_pChildWnd
->hTreeWnd
, &item
);
766 /* Set the Expand/Collapse menu item appropriately */
767 LoadStringW(hInst
, (item
.state
& TVIS_EXPANDED
) ? IDS_COLLAPSE
: IDS_EXPAND
, buffer
, COUNT_OF(buffer
));
768 memset(&mii
, 0, sizeof(mii
));
769 mii
.cbSize
= sizeof(mii
);
770 mii
.fMask
= MIIM_STRING
| MIIM_STATE
| MIIM_ID
;
771 mii
.fState
= (item
.cChildren
> 0) ? MFS_DEFAULT
: MFS_GRAYED
;
772 mii
.wID
= (item
.state
& TVIS_EXPANDED
) ? ID_TREE_COLLAPSEBRANCH
: ID_TREE_EXPANDBRANCH
;
773 mii
.dwTypeData
= (LPWSTR
) buffer
;
774 SetMenuItemInfo(hContextMenu
, 0, TRUE
, &mii
);
776 /* Remove any existing suggestions */
777 memset(&mii
, 0, sizeof(mii
));
778 mii
.cbSize
= sizeof(mii
);
780 GetMenuItemInfo(hContextMenu
, GetMenuItemCount(hContextMenu
) - 1, TRUE
, &mii
);
781 if ((mii
.wID
>= ID_TREE_SUGGESTION_MIN
) && (mii
.wID
<= ID_TREE_SUGGESTION_MAX
))
785 iLastPos
= GetMenuItemCount(hContextMenu
) - 1;
786 GetMenuItemInfo(hContextMenu
, iLastPos
, TRUE
, &mii
);
787 RemoveMenu(hContextMenu
, iLastPos
, MF_BYPOSITION
);
789 while((mii
.wID
>= ID_TREE_SUGGESTION_MIN
) && (mii
.wID
<= ID_TREE_SUGGESTION_MAX
));
792 /* Come up with suggestions */
793 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, NULL
, &hRootKey
);
794 SuggestKeys(hRootKey
, keyPath
, Suggestions
, COUNT_OF(Suggestions
));
797 AppendMenu(hContextMenu
, MF_SEPARATOR
, 0, NULL
);
799 LoadStringW(hInst
, IDS_GOTO_SUGGESTED_KEY
, resource
, COUNT_OF(resource
));
802 wID
= ID_TREE_SUGGESTION_MIN
;
803 while(*s
&& (wID
<= ID_TREE_SUGGESTION_MAX
))
805 _snwprintf(buffer
, COUNT_OF(buffer
), resource
, s
);
807 memset(&mii
, 0, sizeof(mii
));
808 mii
.cbSize
= sizeof(mii
);
809 mii
.fMask
= MIIM_STRING
| MIIM_ID
;
811 mii
.dwTypeData
= buffer
;
812 InsertMenuItem(hContextMenu
, GetMenuItemCount(hContextMenu
), TRUE
, &mii
);
817 TrackPopupMenu(hContextMenu
, TPM_RIGHTBUTTON
, pt
.x
, pt
.y
, 0, g_pChildWnd
->hWnd
, NULL
);
824 if (wParam
!= SIZE_MINIMIZED
&& g_pChildWnd
!= NULL
)
826 ResizeWnd(LOWORD(lParam
), HIWORD(lParam
));
831 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);