Regedit: Added a "Goto key" right-click option.
This feature allows the user to right click on certain keys that "link"
to other keys, Regedit can provide additional "Go to ...." menu items.
For example, if you click on a ProgID under HKCR, a "Go to
'HKCR\CLSID\{....}' menu item will appear.
Modified: trunk/reactos/subsys/system/regedit/En.rc
Modified: trunk/reactos/subsys/system/regedit/childwnd.c
Modified: trunk/reactos/subsys/system/regedit/main.h
Modified: trunk/reactos/subsys/system/regedit/resource.h
Modified: trunk/reactos/subsys/system/regedit/treeview.c
_____
Modified: trunk/reactos/subsys/system/regedit/En.rc
--- trunk/reactos/subsys/system/regedit/En.rc 2005-10-03 12:12:19 UTC
(rev 18242)
+++ trunk/reactos/subsys/system/regedit/En.rc 2005-10-03 12:39:50 UTC
(rev 18243)
@@ -340,6 +340,7 @@
BEGIN
IDS_EXPAND "&Expand"
IDS_COLLAPSE "&Collapse"
+ IDS_GOTO_SUGGESTED_KEY "&Go to '%s'"
END
/*****************************************************************/
_____
Modified: trunk/reactos/subsys/system/regedit/childwnd.c
--- trunk/reactos/subsys/system/regedit/childwnd.c 2005-10-03
12:12:19 UTC (rev 18242)
+++ trunk/reactos/subsys/system/regedit/childwnd.c 2005-10-03
12:39:50 UTC (rev 18243)
@@ -30,6 +30,7 @@
ChildWnd* g_pChildWnd;
HBITMAP SizingPattern = 0;
HBRUSH SizingBrush = 0;
+static TCHAR Suggestions[256];
/***********************************************************************
********
* Local module support methods
@@ -106,11 +107,12 @@
ChildWnd* pChildWnd = g_pChildWnd;
HTREEITEM hSelection;
HKEY hRootKey;
- LPCTSTR keyPath;
+ LPCTSTR keyPath, s;
TCHAR szConfirmTitle[256];
TCHAR szConfirmText[256];
+ WORD wID = LOWORD(wParam);
- switch (LOWORD(wParam)) {
+ switch (wID) {
/* Parse the menu selections: */
case ID_REGISTRY_EXIT:
DestroyWindow(hWnd);
@@ -154,6 +156,18 @@
SetFocus(pChildWnd->nFocusPanel? pChildWnd->hListWnd:
pChildWnd->hTreeWnd);
break;
default:
+ if ((wID >= ID_TREE_SUGGESTION_MIN) && (wID <=
ID_TREE_SUGGESTION_MAX))
+ {
+ s = Suggestions;
+ while(wID > ID_TREE_SUGGESTION_MIN)
+ {
+ if (*s)
+ s += _tcslen(s) + 1;
+ wID--;
+ }
+ SelectNode(pChildWnd->hTreeWnd, s);
+ break;
+ }
return FALSE;
}
return TRUE;
@@ -161,6 +175,115 @@
/***********************************************************************
********
*
+ * Key suggestion
+ */
+
+static LONG RegQueryStringValue(HKEY hKey, LPCTSTR lpSubKey, LPCTSTR
lpValueName,
+ LPTSTR lpDest, DWORD dwDestLength)
+{
+ LONG lResult;
+ HKEY hSubKey = NULL;
+ DWORD cbData, dwType;
+
+ if (lpSubKey)
+ {
+ lResult = RegOpenKey(hKey, lpSubKey, &hSubKey);
+ if (lResult != ERROR_SUCCESS)
+ goto done;
+ hKey = hSubKey;
+ }
+
+ cbData = (dwDestLength - 1) * sizeof(*lpDest);
+ lResult = RegQueryValueEx(hKey, lpValueName, NULL, &dwType,
+ (LPBYTE) lpDest, &cbData);
+ if (lResult != ERROR_SUCCESS)
+ goto done;
+ if (dwType != REG_SZ)
+ {
+ lResult = -1;
+ goto done;
+ }
+
+ lpDest[cbData / sizeof(*lpDest)] = '\0';
+
+done:
+ if (lResult != ERROR_SUCCESS)
+ lpDest[0] = '\0';
+ if (hSubKey)
+ RegCloseKey(hSubKey);
+ return lResult;
+}
+
+static void SuggestKeys(HKEY hRootKey, LPCTSTR pszKeyPath, LPTSTR
pszSuggestions,
+ size_t iSuggestionsLength)
+{
+ TCHAR szBuffer[256];
+ TCHAR szLastFound[256];
+ size_t i;
+ HKEY hOtherKey, hSubKey;
+ BOOL bFound;
+
+ memset(pszSuggestions, 0, iSuggestionsLength *
sizeof(*pszSuggestions));
+ iSuggestionsLength--;
+
+ /* Are we a root key in HKEY_CLASSES_ROOT? */
+ if ((hRootKey == HKEY_CLASSES_ROOT) && pszKeyPath[0] &&
!_tcschr(pszKeyPath, '\\'))
+ {
+ do
+ {
+ bFound = FALSE;
+
+ /* Check default key */
+ if (RegQueryStringValue(hRootKey, pszKeyPath,
NULL,
+ szBuffer, sizeof(szBuffer) /
sizeof(szBuffer[0])) == ERROR_SUCCESS)
+ {
+ if (szBuffer[0] != '\0')
+ {
+ if (RegOpenKey(hRootKey,
szBuffer, &hOtherKey) == ERROR_SUCCESS)
+ {
+ lstrcpyn(pszSuggestions,
TEXT("HKCR\\"), iSuggestionsLength);
+ i =
_tcslen(pszSuggestions);
+ pszSuggestions += i;
+ iSuggestionsLength -= i;
+
+ lstrcpyn(pszSuggestions,
szBuffer, iSuggestionsLength);
+ i =
_tcslen(pszSuggestions) + 1;
+ pszSuggestions += i;
+ iSuggestionsLength -= i;
+ RegCloseKey(hOtherKey);
+
+ bFound = TRUE;
+ _tcscpy(szLastFound,
szBuffer);
+ pszKeyPath =
szLastFound;
+ }
+ }
+ }
+ }
+ while(bFound);
+
+ /* Check CLSID key */
+ if (RegOpenKey(hRootKey, pszKeyPath, &hSubKey) ==
ERROR_SUCCESS)
+ {
+ if (RegQueryStringValue(hSubKey, TEXT("CLSID"),
NULL,
+ szBuffer, sizeof(szBuffer) /
sizeof(szBuffer[0])) == ERROR_SUCCESS)
+ {
+ lstrcpyn(pszSuggestions,
TEXT("HKCR\\CLSID\\"), iSuggestionsLength);
+ i = _tcslen(pszSuggestions);
+ pszSuggestions += i;
+ iSuggestionsLength -= i;
+
+ lstrcpyn(pszSuggestions, szBuffer,
iSuggestionsLength);
+ i = _tcslen(pszSuggestions) + 1;
+ pszSuggestions += i;
+ iSuggestionsLength -= i;
+ }
+ RegCloseKey(hSubKey);
+ }
+ }
+}
+
+/**********************************************************************
*********
+ *
* FUNCTION: ChildWndProc(HWND, unsigned, WORD, LONG)
*
* PURPOSE: Processes messages for the child windows.
@@ -407,8 +530,13 @@
HMENU hContextMenu;
TVITEM item;
MENUITEMINFO mii;
+ TCHAR resource[256];
TCHAR buffer[256];
LPTSTR s;
+ LPCTSTR keyPath;
+ HKEY hRootKey;
+ int iLastPos;
+ WORD wID;
pt = MAKEPOINTS(lParam);
hti.pt.x = pt.x;
@@ -426,17 +554,58 @@
item.hItem = hti.hItem;
TreeView_GetItem(pChildWnd->hTreeWnd, &item);
+ /* Set the Expand/Collapse menu item appropriately */
LoadString(hInst, (item.state & TVIS_EXPANDED) ? IDS_COLLAPSE
: IDS_EXPAND, buffer, sizeof(buffer) / sizeof(buffer[0]));
-
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING | MIIM_STATE | MIIM_ID;
mii.fState = (item.cChildren > 0) ? MFS_DEFAULT : MFS_GRAYED;
mii.wID = (item.state & TVIS_EXPANDED) ?
ID_TREE_COLLAPSEBRANCH : ID_TREE_EXPANDBRANCH;
- s = buffer;
- memcpy(&mii.dwTypeData, &s, sizeof(mii.dwTypeData)); /* arg
MinGW */
+ mii.dwTypeData = (LPTSTR) buffer;
SetMenuItemInfo(hContextMenu, 0, TRUE, &mii);
+ /* Remove any existing suggestions */
+ memset(&mii, 0, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_ID;
+ GetMenuItemInfo(hContextMenu, GetMenuItemCount(hContextMenu)
- 1, TRUE, &mii);
+ if ((mii.wID >= ID_TREE_SUGGESTION_MIN) && (mii.wID <=
ID_TREE_SUGGESTION_MAX))
+ {
+ do
+ {
+ iLastPos = GetMenuItemCount(hContextMenu) - 1;
+ GetMenuItemInfo(hContextMenu, iLastPos, TRUE, &mii);
+ RemoveMenu(hContextMenu, iLastPos, MF_BYPOSITION);
+ }
+ while((mii.wID >= ID_TREE_SUGGESTION_MIN) &&
(mii.wID <= ID_TREE_SUGGESTION_MAX));
+ }
+
+ /* Come up with suggestions */
+ keyPath = GetItemPath(pChildWnd->hTreeWnd, NULL, &hRootKey);
+ SuggestKeys(hRootKey, keyPath, Suggestions,
sizeof(Suggestions) / sizeof(Suggestions[0]));
+ if (Suggestions[0])
+ {
+ AppendMenu(hContextMenu, MF_SEPARATOR, 0, NULL);
+
+ LoadString(hInst, IDS_GOTO_SUGGESTED_KEY, resource,
sizeof(resource) / sizeof(resource[0]));
+
+ s = Suggestions;
+ wID = ID_TREE_SUGGESTION_MIN;
+ while(*s && (wID <= ID_TREE_SUGGESTION_MAX))
+ {
+ _sntprintf(buffer, sizeof(buffer) / sizeof(buffer[0]),
resource, s);
+
+ memset(&mii, 0, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_STRING | MIIM_ID;
+ mii.wID = wID++;
+ mii.dwTypeData = buffer;
+ InsertMenuItem(hContextMenu,
GetMenuItemCount(hContextMenu), TRUE, &mii);
+
+ s += _tcslen(s) + 1;
+ }
+ }
+
TrackPopupMenu(hContextMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0,
pChildWnd->hWnd, NULL);
}
}
_____
Modified: trunk/reactos/subsys/system/regedit/main.h
--- trunk/reactos/subsys/system/regedit/main.h 2005-10-03 12:12:19 UTC
(rev 18242)
+++ trunk/reactos/subsys/system/regedit/main.h 2005-10-03 12:39:50 UTC
(rev 18243)
@@ -105,6 +105,7 @@
extern HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPTSTR name);
extern HWND StartKeyRename(HWND hwndTV);
extern BOOL CreateNewKey(HWND hwndTV, HTREEITEM hItem);
+extern BOOL SelectNode(HWND hwndTV, LPCTSTR keyPath);
/* edit.c */
extern BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCTSTR valueName, BOOL
EditBin);
_____
Modified: trunk/reactos/subsys/system/regedit/resource.h
--- trunk/reactos/subsys/system/regedit/resource.h 2005-10-03
12:12:19 UTC (rev 18242)
+++ trunk/reactos/subsys/system/regedit/resource.h 2005-10-03
12:39:50 UTC (rev 18243)
@@ -133,6 +133,8 @@
#define IDS_QUERY_DELETE_KEY_ONE 32875
#define IDS_QUERY_DELETE_KEY_MORE 32876
#define IDS_QUERY_DELETE_KEY_CONFIRM 32877
+#define ID_TREE_SUGGESTION_MIN 32878
+#define ID_TREE_SUGGESTION_MAX 32887
#define IDS_FLT_REGFILES 31001
#define IDS_FLT_REGFILES_FLT 31002
@@ -161,6 +163,7 @@
#define IDS_COLLAPSE 31125
#define IDS_NEW_KEY 31126
#define IDS_NEW_VALUE 31127
+#define IDS_GOTO_SUGGESTED_KEY 31128
#define IDD_EDIT_STRING 2000
_____
Modified: trunk/reactos/subsys/system/regedit/treeview.c
--- trunk/reactos/subsys/system/regedit/treeview.c 2005-10-03
12:12:19 UTC (rev 18242)
+++ trunk/reactos/subsys/system/regedit/treeview.c 2005-10-03
12:39:50 UTC (rev 18243)
@@ -28,6 +28,8 @@
#include <tchar.h>
#include <process.h>
#include <stdio.h>
+#include <string.h>
+#include <tchar.h>
#include "main.h"
@@ -558,3 +560,69 @@
}
return hwndTV;
}
+
+BOOL SelectNode(HWND hwndTV, LPCTSTR keyPath)
+{
+ HTREEITEM hRoot, hItem;
+ HTREEITEM hChildItem;
+ TCHAR szPathPart[128];
+ TCHAR szBuffer[128];
+ LPCTSTR s;
+ TVITEM tvi;
+
+ hRoot = TreeView_GetRoot(hwndTV);
+ hItem = hRoot;
+
+ while(keyPath[0])
+ {
+ s = _tcschr(keyPath, '\\');
+ lstrcpyn(szPathPart, keyPath, s ? s - keyPath + 1 :
_tcslen(keyPath) + 1);
+
+ /* Special case for root to expand root key
abbreviations */
+ if (hItem == hRoot)
+ {
+ if (!_tcscmp(szPathPart, TEXT("HKCR")))
+ _tcscpy(szPathPart,
TEXT("HKEY_CLASSES_ROOT"));
+ else if (!_tcscmp(szPathPart, TEXT("HKCU")))
+ _tcscpy(szPathPart,
TEXT("HKEY_CURRENT_USER"));
+ else if (!_tcscmp(szPathPart, TEXT("HKLM")))
+ _tcscpy(szPathPart,
TEXT("HKEY_LOCAL_MACHINE"));
+ else if (!_tcscmp(szPathPart, TEXT("HKU")))
+ _tcscpy(szPathPart, TEXT("HKEY_USERS"));
+ else if (!_tcscmp(szPathPart, TEXT("HKCC")))
+ _tcscpy(szPathPart,
TEXT("HKEY_CURRENT_CONFIG"));
+ else if (!_tcscmp(szPathPart, TEXT("HKDD")))
+ _tcscpy(szPathPart,
TEXT("HKEY_DYN_DATA"));
+ }
+
+ for (hChildItem = TreeView_GetChild(hwndTV, hItem);
hChildItem;
+ hChildItem = TreeView_GetNextSibling(hwndTV,
hChildItem))
+ {
+ memset(&tvi, 0, sizeof(tvi));
+ tvi.hItem = hChildItem;
+ tvi.mask = TVIF_TEXT;
+ tvi.pszText = szBuffer;
+ tvi.cchTextMax = sizeof(szBuffer) /
sizeof(szBuffer[0]);
+
+ TreeView_GetItem(hwndTV, &tvi);
+
+ if (!_tcscmp(szBuffer, szPathPart))
+ break;
+ }
+
+ if (!hChildItem)
+ return FALSE;
+
+ if (!TreeView_Expand(hwndTV, hChildItem, TVE_EXPAND))
+ return FALSE;
+
+ keyPath = s ? s + 1 : "";
+ hItem = hChildItem;
+ }
+
+ TreeView_SelectItem(hwndTV, hItem);
+ TreeView_EnsureVisible(hwndTV, hItem);
+
+ return TRUE;
+}
+