--- 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);
}
}
--- 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;
+}
+