* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
-#include <windows.h>
-#include <commctrl.h>
-#include <tchar.h>
-#include <stdio.h>
-
-#include "main.h"
+#include <regedit.h>
ChildWnd* g_pChildWnd;
HBITMAP SizingPattern = 0;
HBRUSH SizingBrush = 0;
+static TCHAR Suggestions[256];
/*******************************************************************************
* Local module support methods
if (hRootKey == HKEY_LOCAL_MACHINE) return _T("HKEY_LOCAL_MACHINE");
if (hRootKey == HKEY_USERS) return _T("HKEY_USERS");
if (hRootKey == HKEY_CURRENT_CONFIG) return _T("HKEY_CURRENT_CONFIG");
+ if (hRootKey == HKEY_DYN_DATA) return _T("HKEY_DYN_DATA");
return _T("UKNOWN HKEY, PLEASE REPORT");
}
static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
ChildWnd* pChildWnd = g_pChildWnd;
- switch (LOWORD(wParam)) {
+ HTREEITEM hSelection;
+ HKEY hRootKey;
+ LPCTSTR keyPath, s;
+ WORD wID = LOWORD(wParam);
+
+ switch (wID) {
/* Parse the menu selections: */
case ID_REGISTRY_EXIT:
DestroyWindow(hWnd);
case ID_VIEW_REFRESH:
/* TODO */
break;
+ case ID_TREE_EXPANDBRANCH:
+ TreeView_Expand(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd), TVE_EXPAND);
+ break;
+ case ID_TREE_COLLAPSEBRANCH:
+ TreeView_Expand(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd), TVE_COLLAPSE);
+ break;
+ case ID_TREE_RENAME:
+ SetFocus(pChildWnd->hTreeWnd);
+ TreeView_EditLabel(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd));
+ break;
+ case ID_TREE_DELETE:
+ hSelection = TreeView_GetSelection(pChildWnd->hTreeWnd);
+ keyPath = GetItemPath(pChildWnd->hTreeWnd, hSelection, &hRootKey);
+
+ if (keyPath == 0 || *keyPath == 0)
+ {
+ MessageBeep(MB_ICONHAND);
+ } else
+ if (DeleteKey(hWnd, hRootKey, keyPath))
+ DeleteNode(g_pChildWnd->hTreeWnd, 0);
+ break;
+ case ID_TREE_EXPORT:
+ ExportRegistryFile(pChildWnd->hTreeWnd);
+ break;
+ case ID_EDIT_FIND:
+ FindDialog(hWnd);
+ break;
+ case ID_EDIT_COPYKEYNAME:
+ hSelection = TreeView_GetSelection(pChildWnd->hTreeWnd);
+ keyPath = GetItemPath(pChildWnd->hTreeWnd, hSelection, &hRootKey);
+ CopyKeyName(hWnd, hRootKey, keyPath);
+ break;
+ case ID_EDIT_NEW_KEY:
+ CreateNewKey(pChildWnd->hTreeWnd, TreeView_GetSelection(pChildWnd->hTreeWnd));
+ break;
+ case ID_EDIT_NEW_STRINGVALUE:
+ case ID_EDIT_NEW_BINARYVALUE:
+ case ID_EDIT_NEW_DWORDVALUE:
+ SendMessage(hFrameWnd, WM_COMMAND, wParam, lParam);
+ break;
case ID_SWITCH_PANELS:
pChildWnd->nFocusPanel = !pChildWnd->nFocusPanel;
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;
}
+/*******************************************************************************
+ *
+ * Key suggestion
+ */
+
+#define MIN(a,b) ((a < b) ? (a) : (b))
+
+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)
+ {
+ /* Sanity check this key; it cannot be empty, nor can it be a
+ * loop back */
+ if ((szBuffer[0] != '\0') && _tcsicmp(szBuffer, pszKeyPath))
+ {
+ if (RegOpenKey(hRootKey, szBuffer, &hOtherKey) == ERROR_SUCCESS)
+ {
+ lstrcpyn(pszSuggestions, TEXT("HKCR\\"), iSuggestionsLength);
+ i = _tcslen(pszSuggestions);
+ pszSuggestions += i;
+ iSuggestionsLength -= i;
+
+ lstrcpyn(pszSuggestions, szBuffer, iSuggestionsLength);
+ i = MIN(_tcslen(pszSuggestions) + 1, iSuggestionsLength);
+ pszSuggestions += i;
+ iSuggestionsLength -= i;
+ RegCloseKey(hOtherKey);
+
+ bFound = TRUE;
+ _tcscpy(szLastFound, szBuffer);
+ pszKeyPath = szLastFound;
+ }
+ }
+ }
+ }
+ while(bFound && (iSuggestionsLength > 0));
+
+ /* 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 = MIN(_tcslen(pszSuggestions) + 1, iSuggestionsLength);
+ pszSuggestions += i;
+ iSuggestionsLength -= i;
+ }
+ RegCloseKey(hSubKey);
+ }
+ }
+}
+
/*******************************************************************************
*
* FUNCTION: ChildWndProc(HWND, unsigned, WORD, LONG)
* WM_DESTROY - post a quit message and return
*
*/
-LRESULT CALLBACK
-ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static short last_split;
BOOL Result;
/* load "My Computer" string */
LoadString(hInst, IDS_MY_COMPUTER, buffer, sizeof(buffer)/sizeof(TCHAR));
- g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), 0, sizeof(ChildWnd));
+ g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd));
+
if (!pChildWnd) return 0;
_tcsncpy(pChildWnd->szPath, buffer, MAX_PATH);
pChildWnd->nSplitPos = 250;
pChildWnd->hWnd = hWnd;
- pChildWnd->hTreeWnd = CreateTreeView(hWnd, pChildWnd->szPath, TREE_WINDOW);
- pChildWnd->hListWnd = CreateListView(hWnd, LIST_WINDOW/*, pChildWnd->szPath*/);
+ pChildWnd->hTreeWnd = CreateTreeView(hWnd, pChildWnd->szPath, (HMENU) TREE_WINDOW);
+ pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, pChildWnd->szPath*/);
SetFocus(pChildWnd->hTreeWnd);
break;
}
}
goto def;
case WM_DESTROY:
+ DestroyTreeView();
+ DestroyListView(pChildWnd->hListWnd);
+ DestroyMainMenu();
HeapFree(GetProcessHeap(), 0, pChildWnd);
pChildWnd = NULL;
PostQuitMessage(0);
POINTS pt;
pt = MAKEPOINTS(lParam);
GetClientRect(hWnd, &rt);
- pt.x = min(max(pt.x, SPLIT_MIN), rt.right - SPLIT_MIN);
+ pt.x = (SHORT) min(max(pt.x, SPLIT_MIN), rt.right - SPLIT_MIN);
draw_splitbar(hWnd, last_split);
last_split = -1;
pChildWnd->nSplitPos = pt.x;
pt = MAKEPOINTS(lParam);
GetClientRect(hWnd, &rt);
- pt.x = min(max(pt.x, SPLIT_MIN), rt.right - SPLIT_MIN);
+ pt.x = (SHORT) min(max(pt.x, SPLIT_MIN), rt.right - SPLIT_MIN);
if(last_split != pt.x)
{
rt.left = last_split-SPLIT_WIDTH/2;
_stprintf(fullPath, _T("%s\\%s"), rootName, keyPath);
SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath);
HeapFree(GetProcessHeap(), 0, fullPath);
+
+ {
+ HKEY hKey;
+ TCHAR szBuffer[MAX_PATH];
+ _sntprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), _T("My Computer\\%s\\%s"), rootName, keyPath);
+
+ if (RegOpenKey(HKEY_CURRENT_USER,
+ _T("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit"),
+ &hKey) == ERROR_SUCCESS)
+ {
+ RegSetValueEx(hKey, _T("LastKey"), 0, REG_SZ, (LPBYTE) szBuffer, _tcslen(szBuffer) * sizeof(szBuffer[0]));
+ RegCloseKey(hKey);
+ }
+ }
}
}
}
case NM_SETFOCUS:
pChildWnd->nFocusPanel = 0;
break;
+ case TVN_ENDLABELEDIT:
+ {
+ LPCTSTR keyPath;
+ HKEY hRootKey;
+ LPNMTVDISPINFO ptvdi;
+ LONG lResult;
+
+ ptvdi = (LPNMTVDISPINFO) lParam;
+ if (ptvdi->item.pszText)
+ {
+ keyPath = GetItemPath(pChildWnd->hTreeWnd, ptvdi->item.hItem, &hRootKey);
+ lResult = RegRenameKey(hRootKey, keyPath, ptvdi->item.pszText);
+ return lResult == ERROR_SUCCESS;
+ }
+ }
default:
return 0;
}
{
goto def;
}
+ return Result;
break;
}
}
TrackPopupMenu(mnu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hFrameWnd, NULL);
}
}
+ else if ((HWND)wParam == pChildWnd->hTreeWnd)
+ {
+ TVHITTESTINFO hti;
+ 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;
+ hti.pt.y = pt.y;
+ ScreenToClient(pChildWnd->hTreeWnd, &hti.pt);
+ TreeView_HitTest(pChildWnd->hTreeWnd, &hti);
+
+ if ((hti.flags & TVHT_ONITEM) != 0)
+ {
+ hContextMenu = GetSubMenu(hPopupMenus, PM_TREECONTEXT);
+ TreeView_SelectItem(pChildWnd->hTreeWnd, hti.hItem);
+
+ memset(&item, 0, sizeof(item));
+ item.mask = TVIF_STATE | TVIF_CHILDREN;
+ 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;
+ 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);
+ }
+ }
break;
}