[REGEDIT]

Adam Kachwalla <geekdundee@gmail.com>
- "Load Hive..." and "Unload Hive..." menu items implemented
- Make address bar case-insensitive
- Remove trailing slashes in address bar when at root keys (e.g. "HKEY_LOCAL_MACHINE\" or "HKEY_CURRENT_USER\")
- Address "go" button added
- Removed ~8px slack from bottom of the app (not needed and looks better)
- Factored out error displaying functions into error.c file.

See issue #5711 for more details.

svn path=/trunk/; revision=49465
This commit is contained in:
Aleksey Bragin 2010-11-04 12:05:35 +00:00
parent 3872d5db6c
commit 2bb39272f6
9 changed files with 205 additions and 38 deletions

View file

@ -67,19 +67,21 @@ static void draw_splitbar(HWND hWnd, int x)
static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy)
{
HDWP hdwp = BeginDeferWindowPos(2);
RECT rt, rs;
HDWP hdwp = BeginDeferWindowPos(3);
RECT rt, rs, rb;
const int tHeight = 18;
SetRect(&rt, 0, 0, cx, cy);
cy = 0;
if (hStatusBar != NULL) {
GetWindowRect(hStatusBar, &rs);
cy = rs.bottom - rs.top + 8;
cy = rs.bottom - rs.top;
}
GetWindowRect(pChildWnd->hAddressBtnWnd, &rb);
cx = pChildWnd->nSplitPos + SPLIT_WIDTH/2;
DeferWindowPos(hdwp, pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left, 23, SWP_NOZORDER|SWP_NOACTIVATE);
DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + 25, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx , rt.top + 25, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
DeferWindowPos(hdwp, pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left - tHeight-2, tHeight, SWP_NOZORDER|SWP_NOACTIVATE);
DeferWindowPos(hdwp, pChildWnd->hAddressBtnWnd, 0, rt.right - tHeight, rt.top, tHeight, tHeight, SWP_NOZORDER|SWP_NOACTIVATE);
DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + tHeight+2, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx, rt.top + tHeight+2, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE);
EndDeferWindowPos(hdwp);
}
@ -259,7 +261,7 @@ static void SuggestKeys(HKEY hRootKey, LPCTSTR pszKeyPath, LPTSTR pszSuggestions
/* Check CLSID key */
if (RegOpenKey(hRootKey, pszKeyPath, &hSubKey) == ERROR_SUCCESS)
{
if (QueryStringValue(hSubKey, TEXT("CLSID"), NULL, szBuffer,
if (QueryStringValue(hSubKey, TEXT("CLSID"), NULL, szBuffer,
COUNT_OF(szBuffer)) == ERROR_SUCCESS)
{
lstrcpyn(pszSuggestions, TEXT("HKCR\\CLSID\\"), (int) iSuggestionsLength);
@ -324,29 +326,35 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
/* load "My Computer" string */
LoadString(hInst, IDS_MY_COMPUTER, buffer, sizeof(buffer)/sizeof(TCHAR));
g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 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->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP,
pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hWnd, (HMENU)0, hInst, 0);
pChildWnd->hAddressBtnWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Button"), _T("»"), WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_DEFPUSHBUTTON,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hWnd, (HMENU)0, hInst, 0);
pChildWnd->hTreeWnd = CreateTreeView(hWnd, pChildWnd->szPath, (HMENU) TREE_WINDOW);
pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, pChildWnd->szPath*/);
SetFocus(pChildWnd->hTreeWnd);
/* set the address bar font */
if (pChildWnd->hAddressBarWnd)
/* set the address bar and button font */
if ((pChildWnd->hAddressBarWnd) && (pChildWnd->hAddressBtnWnd))
{
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
SendMessage(pChildWnd->hAddressBarWnd,
WM_SETFONT,
(WPARAM)hFont,
0);
SendMessage(pChildWnd->hAddressBtnWnd,
WM_SETFONT,
(WPARAM)hFont,
0);
}
/* Subclass the AddressBar */
oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_WNDPROC);
SetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_USERDATA, (DWORD_PTR)oldproc);
@ -354,7 +362,10 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
break;
}
case WM_COMMAND:
if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
if(HIWORD(wParam) == BN_CLICKED){
PostMessage(pChildWnd->hAddressBarWnd, WM_KEYUP, VK_RETURN, 0);
}
else if (!_CmdWndProc(hWnd, message, wParam, lParam)) {
goto def;
}
break;
@ -477,10 +488,28 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
rootName = get_root_key_name(hRootKey);
fullPath = HeapAlloc(GetProcessHeap(), 0, (_tcslen(rootName) + 1 + _tcslen(keyPath) + 1) * sizeof(TCHAR));
if (fullPath) {
_stprintf(fullPath, _T("%s\\%s"), rootName, keyPath);
/* set (correct) the address bar text */
if(keyPath[0] != '\0')
_stprintf(fullPath, _T("%s\\%s"), rootName, keyPath);
else
fullPath = _tcscpy(fullPath, rootName);
SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath);
SendMessage(pChildWnd->hAddressBarWnd, WM_SETTEXT, 0, (LPARAM)fullPath);
HeapFree(GetProcessHeap(), 0, fullPath);
HeapFree(GetProcessHeap(), 0, fullPath);
/* disable hive manipulation items temporarily (enable only if necessary) */
EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_UNLOADHIVE, MF_BYCOMMAND | MF_GRAYED);
/* compare the strings to see if we should enable/disable the "Load Hive" menus accordingly */
if (!(_tcsicmp(rootName, TEXT("HKEY_LOCAL_MACHINE")) &&
_tcsicmp(rootName, TEXT("HKEY_USERS"))))
{
// enable the unload menu item if at the root
// otherwise enable the load menu item if there is no slash in keyPath (ie. immediate child selected)
if(keyPath[0] == '\0')
EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_ENABLED);
else if(!_tcschr(keyPath, _T('\\')))
EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_UNLOADHIVE, MF_BYCOMMAND | MF_ENABLED);
}
{
HKEY hKey;

View file

@ -59,19 +59,10 @@ void error(HWND hwnd, INT resId, ...)
static void error_code_messagebox(HWND hwnd, DWORD error_code)
{
LPTSTR lpMsgBuf;
DWORD status;
TCHAR title[256];
static const TCHAR fallback[] = TEXT("Error displaying error message.\n");
if (!LoadString(hInst, IDS_ERROR, title, COUNT_OF(title)))
lstrcpy(title, TEXT("Error"));
status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error_code, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
if (!status)
lpMsgBuf = (LPTSTR)fallback;
MessageBox(hwnd, lpMsgBuf, title, MB_OK | MB_ICONERROR);
if (lpMsgBuf != fallback)
LocalFree(lpMsgBuf);
ErrorMessageBox(hwnd, title, error_code);
}
void warning(HWND hwnd, INT resId, ...)

View file

@ -0,0 +1,14 @@
#include <regedit.h>
void ErrorMessageBox(HWND hWnd, LPCTSTR title, DWORD code)
{
LPTSTR lpMsgBuf;
DWORD status;
static const TCHAR fallback[] = TEXT("Error displaying error message.\n");
status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, code, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
if (!status)
lpMsgBuf = (LPTSTR)fallback;
MessageBox(hWnd, lpMsgBuf, title, MB_OK | MB_ICONERROR);
if (lpMsgBuf != fallback)
LocalFree(lpMsgBuf);
}

View file

@ -282,6 +282,105 @@ static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
return TRUE;
}
static INT_PTR CALLBACK LoadHive_KeyNameInHookProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static LPTSTR sKey = NULL;
static INT sLength = 0;
switch(uMsg)
{
case WM_INITDIALOG:
sKey = (LPTSTR)lParam;
sLength = 128; /* FIXME: Ugly hack! */
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDOK:
if(GetDlgItemText(hWndDlg, IDC_EDIT_KEY, sKey, sLength))
return EndDialog(hWndDlg, -1);
else
return EndDialog(hWndDlg, 0);
case IDCANCEL:
return EndDialog(hWndDlg, 0);
}
break;
}
return FALSE;
}
static BOOL LoadHive(HWND hWnd)
{
OPENFILENAME ofn;
TCHAR Caption[128];
LPCTSTR pszKeyPath;
TCHAR xPath[128];
HKEY hRootKey;
TCHAR Filter[1024];
FILTERPAIR filter;
/* get the item key to load the hive in */
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
/* initialize the "open file" dialog */
InitOpenFileName(hWnd, &ofn);
/* build the "All Files" filter up */
filter.DisplayID = IDS_FLT_ALLFILES;
filter.FilterID = IDS_FLT_ALLFILES_FLT;
BuildFilterStrings(Filter, &filter, sizeof(filter));
ofn.lpstrFilter = Filter;
/* load and set the caption and flags for dialog */
LoadString(hInst, IDS_LOAD_HIVE, Caption, COUNT_OF(Caption));
ofn.lpstrTitle = Caption;
ofn.Flags |= OFN_ENABLESIZING;
/* ofn.lCustData = ;*/
/* now load the hive */
if (GetOpenFileName(&ofn))
{
if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_LOADHIVE), hWnd, &LoadHive_KeyNameInHookProc, (LPARAM)xPath))
{
LONG regLoadResult = RegLoadKey(hRootKey, xPath, ofn.lpstrFile);
if(regLoadResult == ERROR_SUCCESS)
{
/* refresh tree and list views */
RefreshTreeView(g_pChildWnd->hTreeWnd);
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
}
else
{
ErrorMessageBox(hWnd, Caption, regLoadResult);
return FALSE;
}
}
} else {
CheckCommDlgError(hWnd);
}
return TRUE;
}
static BOOL UnloadHive(HWND hWnd)
{
TCHAR Caption[128];
LPCTSTR pszKeyPath;
HKEY hRootKey;
/* get the item key to unload */
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
/* load and set the caption and flags for dialog */
LoadString(hInst, IDS_UNLOAD_HIVE, Caption, COUNT_OF(Caption));
/* now unload the hive */
LONG regUnloadResult = RegUnLoadKey(hRootKey, pszKeyPath);
if(regUnloadResult == ERROR_SUCCESS)
{
/* refresh tree and list views */
RefreshTreeView(g_pChildWnd->hTreeWnd);
pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
}
else
{
ErrorMessageBox(hWnd, Caption, regUnloadResult);
return FALSE;
}
return TRUE;
}
static BOOL ImportRegistryFile(HWND hWnd)
{
OPENFILENAME ofn;
@ -316,7 +415,6 @@ static BOOL ImportRegistryFile(HWND hWnd)
return TRUE;
}
static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
HWND hwndExportAll;
@ -397,7 +495,7 @@ BOOL ExportRegistryFile(HWND hWnd)
if (GetSaveFileName(&ofn)) {
BOOL result;
DWORD format;
if (ofn.nFilterIndex == 1)
format = REG_FORMAT_5;
else
@ -758,6 +856,12 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
UNREFERENCED_PARAMETER(message);
switch (LOWORD(wParam)) {
case ID_REGISTRY_LOADHIVE:
LoadHive(hWnd);
return TRUE;
case ID_REGISTRY_UNLOADHIVE:
UnloadHive(hWnd);
return TRUE;
case ID_REGISTRY_IMPORTREGISTRYFILE:
ImportRegistryFile(hWnd);
return TRUE;

View file

@ -274,6 +274,10 @@ BEGIN
ID_REGISTRY_IMPORTREGISTRYFILE "Imports a text file into the registry"
ID_REGISTRY_EXPORTREGISTRYFILE
"Exports all or part of the registry to a text file"
ID_REGISTRY_LOADHIVE
"Loads a hive file into the registry"
ID_REGISTRY_UNLOADHIVE
"Unloads a hive from the registry"
ID_REGISTRY_CONNECTNETWORKREGISTRY
"Connects to a remote computer's registry"
ID_REGISTRY_DISCONNECTNETWORKREGISTRY
@ -330,6 +334,8 @@ BEGIN
IDS_MY_COMPUTER "My Computer"
IDS_IMPORT_REG_FILE "Import Registry File"
IDS_EXPORT_REG_FILE "Export Registry File"
IDS_LOAD_HIVE "Load Hive"
IDS_UNLOAD_HIVE "Unload Hive"
IDS_INVALID_DWORD "(invalid DWORD value)"
END
@ -392,6 +398,20 @@ BEGIN
EDITTEXT IDC_EXPORT_BRANCH_TEXT,30,34,335,12
END
//
// Dialog resources
//
IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34
STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Load Hive"
FONT 8, "Ms Shell Dlg"
{
LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT
EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13
DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14
PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14
}
IDD_ADDFAVORITES DIALOGEX DISCARDABLE 0, 0, 186, 46
STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Add to Favorites"

View file

@ -58,6 +58,7 @@ typedef struct {
HWND hTreeWnd;
HWND hListWnd;
HWND hAddressBarWnd;
HWND hAddressBtnWnd;
int nFocusPanel; /* 0: left 1: right */
int nSplitPos;
WINDOWPLACEMENT pos;
@ -88,6 +89,9 @@ extern void ShowAboutBox(HWND hWnd);
/* childwnd.c */
extern LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
/* error.c */
extern void ErrorMessageBox(HWND hWnd, LPCTSTR title, DWORD code);
/* find.c */
extern void FindDialog(HWND hWnd);
extern BOOL FindNext(HWND hWnd);

View file

@ -23,6 +23,7 @@
<file>hexedit.c</file>
<file>listview.c</file>
<file>main.c</file>
<file>error.c</file>
<file>regedit.c</file>
<file>regproc.c</file>
<file>security.c</file>

View file

@ -137,9 +137,11 @@
#define IDS_ERR_RENVAL_CAPTION 32856
#define IDS_ERR_RENVAL_TOEMPTY 32857
#define IDS_BAD_KEY 32858
#define IDS_LOAD_HIVE 32859
#define IDS_UNLOAD_HIVE 32860
#define ID_EDIT_NEW_MULTISTRINGVALUE 32860
#define ID_EDIT_NEW_EXPANDABLESTRINGVALUE 32861
#define ID_EDIT_NEW_MULTISTRINGVALUE 32861
#define ID_EDIT_NEW_EXPANDABLESTRINGVALUE 32862
#define ID_SWITCH_PANELS 32871
#define ID_EDIT_PERMISSIONS 32872
@ -199,6 +201,8 @@
#define IDC_EXPORT_BRANCH 2009
#define IDC_EXPORT_BRANCH_TEXT 2010
#define IDD_LOADHIVE 2500
#define IDC_EDIT_KEY 2501
#define IDC_FAVORITENAME 2011
#define IDC_FAVORITESLIST 2012

View file

@ -633,7 +633,7 @@ BOOL SelectNode(HWND hwndTV, LPCTSTR keyPath)
TVITEM tvi;
/* Total no-good hack */
if (!_tcsncmp(keyPath, _T("My Computer\\"), 12))
if (!_tcsnicmp(keyPath, _T("My Computer\\"), 12))
keyPath += 12;
hRoot = TreeView_GetRoot(hwndTV);
@ -647,17 +647,17 @@ BOOL SelectNode(HWND hwndTV, LPCTSTR keyPath)
/* Special case for root to expand root key abbreviations */
if (hItem == hRoot)
{
if (!_tcscmp(szPathPart, TEXT("HKCR")))
if (!_tcsicmp(szPathPart, TEXT("HKCR")))
_tcscpy(szPathPart, TEXT("HKEY_CLASSES_ROOT"));
else if (!_tcscmp(szPathPart, TEXT("HKCU")))
else if (!_tcsicmp(szPathPart, TEXT("HKCU")))
_tcscpy(szPathPart, TEXT("HKEY_CURRENT_USER"));
else if (!_tcscmp(szPathPart, TEXT("HKLM")))
else if (!_tcsicmp(szPathPart, TEXT("HKLM")))
_tcscpy(szPathPart, TEXT("HKEY_LOCAL_MACHINE"));
else if (!_tcscmp(szPathPart, TEXT("HKU")))
else if (!_tcsicmp(szPathPart, TEXT("HKU")))
_tcscpy(szPathPart, TEXT("HKEY_USERS"));
else if (!_tcscmp(szPathPart, TEXT("HKCC")))
else if (!_tcsicmp(szPathPart, TEXT("HKCC")))
_tcscpy(szPathPart, TEXT("HKEY_CURRENT_CONFIG"));
else if (!_tcscmp(szPathPart, TEXT("HKDD")))
else if (!_tcsicmp(szPathPart, TEXT("HKDD")))
_tcscpy(szPathPart, TEXT("HKEY_DYN_DATA"));
}
@ -672,7 +672,7 @@ BOOL SelectNode(HWND hwndTV, LPCTSTR keyPath)
(void)TreeView_GetItem(hwndTV, &tvi);
if (!_tcscmp(szBuffer, szPathPart))
if (!_tcsicmp(szBuffer, szPathPart))
break;
}