From 166145385d63fcbf78fc9b8e9ecfc85f09d43e96 Mon Sep 17 00:00:00 2001 From: "Dimitrie O. Paun" Date: Fri, 12 Dec 2003 04:08:59 +0000 Subject: [PATCH] Remove most string size limitations. Better error handling. Less listview flicker. A bunch of style fixes and improvements. --- programs/regedit/about.c | 8 +- programs/regedit/childwnd.c | 64 ++++++------ programs/regedit/edit.c | 4 +- programs/regedit/framewnd.c | 58 ++++------- programs/regedit/listview.c | 168 +++++++++++++++++-------------- programs/regedit/main.c | 1 + programs/regedit/main.h | 13 +-- programs/regedit/treeview.c | 190 +++++++++++++++++++----------------- 8 files changed, 257 insertions(+), 249 deletions(-) diff --git a/programs/regedit/about.c b/programs/regedit/about.c index d2b5eb7aa7e..fd3238feead 100644 --- a/programs/regedit/about.c +++ b/programs/regedit/about.c @@ -28,18 +28,14 @@ #include "main.h" -extern HINSTANCE hInst; - static INT_PTR CALLBACK AboutDialogWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - HWND hLicenseEditWnd; TCHAR strLicense[0x1000]; switch (message) { case WM_INITDIALOG: - hLicenseEditWnd = GetDlgItem(hDlg, IDC_LICENSE_EDIT); - LoadString(hInst, IDS_LICENSE, strLicense, 0x1000); - SetWindowText(hLicenseEditWnd, strLicense); + LoadString(hInst, IDS_LICENSE, strLicense, COUNT_OF(strLicense)); + SetDlgItemText(hDlg, IDC_LICENSE_EDIT, strLicense); return TRUE; case WM_COMMAND: if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL)) { diff --git a/programs/regedit/childwnd.c b/programs/regedit/childwnd.c index f78983e0095..b76526b6796 100644 --- a/programs/regedit/childwnd.c +++ b/programs/regedit/childwnd.c @@ -20,38 +20,26 @@ #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */ #include -#include #include +#include +#include #include "main.h" -ChildWnd* pChildWnd; +ChildWnd* g_pChildWnd; /******************************************************************************* * Local module support methods */ -/*FIXME: why do we need this, we should remove it, we have already FindRegRoot */ -static void MakeFullRegPath(HWND hwndTV, HTREEITEM hItem, LPTSTR keyPath, int* pPathLen, int max) +static LPCTSTR get_root_key_name(HKEY hRootKey) { - TVITEM item; - item.mask = TVIF_PARAM; - item.hItem = hItem; - if (TreeView_GetItem(hwndTV, &item)) { - if (item.hItem != TreeView_GetRoot(hwndTV)) { - /* recurse */ - MakeFullRegPath(hwndTV, TreeView_GetParent(hwndTV, hItem), keyPath, pPathLen, max); - keyPath[*pPathLen] = _T('\\'); - ++(*pPathLen); - } - item.mask = TVIF_TEXT; - item.hItem = hItem; - item.pszText = &keyPath[*pPathLen]; - item.cchTextMax = max - *pPathLen; - if (TreeView_GetItem(hwndTV, &item)) { - *pPathLen += _tcslen(item.pszText); - } - } + if (hRootKey == HKEY_CLASSES_ROOT) return _T("HKEY_CLASSES_ROOT"); + if (hRootKey == HKEY_CURRENT_USER) return _T("HKEY_CURRENT_USER"); + 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"); + return _T("UKNOWN HKEY, PLEASE REPORT"); } static void draw_splitbar(HWND hWnd, int x) @@ -127,13 +115,15 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static int last_split; - /* ChildWnd* pChildWnd = (ChildWnd*)GetWindowLong(hWnd, GWL_USERDATA); */ + ChildWnd* pChildWnd = g_pChildWnd; switch (message) { case WM_CREATE: - pChildWnd = (ChildWnd*)((LPCREATESTRUCT)lParam)->lpCreateParams; + g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), 0, sizeof(ChildWnd)); if (!pChildWnd) return 0; + _tcsncpy(pChildWnd->szPath, _T("My Computer"), MAX_PATH); pChildWnd->nSplitPos = 250; + pChildWnd->hWnd = hWnd; pChildWnd->hTreeWnd = CreateTreeView(hWnd, pChildWnd->szPath, TREE_WINDOW); pChildWnd->hListWnd = CreateListView(hWnd, LIST_WINDOW/*, pChildWnd->szPath*/); break; @@ -157,6 +147,8 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa } goto def; case WM_DESTROY: + HeapFree(GetProcessHeap(), 0, pChildWnd); + pChildWnd = NULL; PostQuitMessage(0); break; case WM_LBUTTONDOWN: { @@ -234,17 +226,21 @@ LRESULT CALLBACK ChildWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa case TVN_ITEMEXPANDING: return !OnTreeExpanding(pChildWnd->hTreeWnd, (NMTREEVIEW*)lParam); case TVN_SELCHANGED: { - HKEY hKey; - TCHAR keyPath[1000]; - int keyPathLen = 0; - keyPath[0] = _T('\0'); - hKey = FindRegRoot(pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, keyPath, &keyPathLen, sizeof(keyPath)/sizeof(TCHAR)); - RefreshListView(pChildWnd->hListWnd, hKey, keyPath); + LPCTSTR keyPath, rootName; + LPTSTR fullPath; + HKEY hRootKey; - keyPathLen = 0; - keyPath[0] = _T('\0'); - MakeFullRegPath(pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, keyPath, &keyPathLen, sizeof(keyPath)/sizeof(TCHAR)); - SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)keyPath); + keyPath = GetItemPath(pChildWnd->hTreeWnd, ((NMTREEVIEW*)lParam)->itemNew.hItem, &hRootKey); + if (keyPath) { + RefreshListView(pChildWnd->hListWnd, hRootKey, keyPath); + rootName = get_root_key_name(hRootKey); + fullPath = HeapAlloc(GetProcessHeap(), 0, (lstrlen(rootName) + 1 + lstrlen(keyPath) + 1) * sizeof(TCHAR)); + if (fullPath) { + _stprintf(fullPath, "%s\\%s", rootName, keyPath); + SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath); + HeapFree(GetProcessHeap(), 0, fullPath); + } + } } break; default: diff --git a/programs/regedit/edit.c b/programs/regedit/edit.c index 3c9f6f3622c..6b17e3aeb3d 100644 --- a/programs/regedit/edit.c +++ b/programs/regedit/edit.c @@ -33,7 +33,7 @@ #include "regproc.h" #include "resource.h" -static TCHAR* editValueName; +static const TCHAR* editValueName; static TCHAR* stringValueData; void error(HWND hwnd, INT resId, ...) @@ -91,7 +91,7 @@ INT_PTR CALLBACK modify_string_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, L return FALSE; } -BOOL ModifyValue(HWND hwnd, HKEY hKey, LPTSTR valueName) +BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCTSTR valueName) { DWORD valueDataLen; DWORD type; diff --git a/programs/regedit/framewnd.c b/programs/regedit/framewnd.c index 8bcee9eb93f..21865f98acc 100644 --- a/programs/regedit/framewnd.c +++ b/programs/regedit/framewnd.c @@ -38,8 +38,6 @@ static BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */ -static HWND hChildWnd; - /******************************************************************************* * Local module support methods */ @@ -60,7 +58,7 @@ static void resize_frame_rect(HWND hWnd, PRECT prect) GetClientRect(hStatusBar, &rt); prect->bottom -= rt.bottom; } - MoveWindow(hChildWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE); + MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE); } void resize_frame_client(HWND hWnd) @@ -437,21 +435,20 @@ BOOL RefreshView(HWND hWnd) */ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - HKEY hKeyRoot, hKey; - TCHAR keyPath[1000] = { 0 }; - TCHAR valueName[255] = { 0 }; - int keyPathLen = 0, item; + HKEY hKeyRoot = 0, hKey = 0; + LPCTSTR keyPath; + LPCTSTR valueName; BOOL result = TRUE; LONG lRet; - hKeyRoot = FindRegRoot(pChildWnd->hTreeWnd, 0, keyPath, &keyPathLen, sizeof(keyPath)/sizeof(TCHAR)); - lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, KEY_READ, &hKey); - if (lRet != ERROR_SUCCESS) hKey = 0; - item = ListView_GetNextItem(pChildWnd->hListWnd, -1, LVNI_FOCUSED); - if (item != -1) ListView_GetItemText(pChildWnd->hListWnd, item, 0, valueName, sizeof(valueName)/sizeof(TCHAR)); + keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); + valueName = GetValueName(g_pChildWnd->hListWnd); + if (keyPath) { + lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, KEY_READ, &hKey); + if (lRet != ERROR_SUCCESS) hKey = 0; + } switch (LOWORD(wParam)) { - /* Parse the menu selections:*/ case ID_REGISTRY_IMPORTREGISTRYFILE: ImportRegistryFile(hWnd); break; @@ -467,7 +464,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case ID_EDIT_MODIFY: if (ModifyValue(hWnd, hKey, valueName)) - RefreshListView(pChildWnd->hListWnd, hKeyRoot, keyPath); + RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath); break; case ID_EDIT_COPYKEYNAME: CopyKeyName(hWnd, _T("")); @@ -486,22 +483,17 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) case ID_VIEW_REFRESH: RefreshView(hWnd); break; - /* case ID_OPTIONS_TOOLBAR:*/ - /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/ - /* break;*/ + /*case ID_OPTIONS_TOOLBAR:*/ + /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/ + /* break;*/ case ID_VIEW_STATUSBAR: toggle_child(hWnd, LOWORD(wParam), hStatusBar); break; case ID_HELP_HELPTOPICS: - /* WinHelp(hWnd, _T("regedit"), HELP_CONTENTS, 0);*/ WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0); break; case ID_HELP_ABOUT: -#ifdef WINSHELLAPI - /* ShellAbout(hWnd, szTitle, _T(""), LoadIcon(hInst, (LPCTSTR)IDI_REGEDIT));*/ -#else ShowAboutBox(hWnd); -#endif break; default: result = FALSE; @@ -524,23 +516,15 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - static ChildWnd* pChildWnd = NULL; - switch (message) { - case WM_CREATE: { - pChildWnd = HeapAlloc(GetProcessHeap(), 0, sizeof(ChildWnd)); - _tcsncpy(pChildWnd->szPath, _T("My Computer"), MAX_PATH); - hChildWnd = CreateWindowEx(0, szChildClass, _T("regedit child window"), - /* WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE|WS_BORDER,*/ - WS_CHILD|WS_VISIBLE, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - hWnd, (HMENU)0, hInst, pChildWnd); - } + case WM_CREATE: + CreateWindowEx(0, szChildClass, _T("regedit child window"), WS_CHILD | WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + hWnd, (HMENU)0, hInst, 0); break; case WM_COMMAND: - if (!_CmdWndProc(hWnd, message, wParam, lParam)) { + if (!_CmdWndProc(hWnd, message, wParam, lParam)) return DefWindowProc(hWnd, message, wParam, lParam); - } break; case WM_SIZE: resize_frame_client(hWnd); @@ -557,10 +541,6 @@ LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam); break; case WM_DESTROY: - if (pChildWnd) { - HeapFree(GetProcessHeap(), 0, pChildWnd); - pChildWnd = NULL; - } WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0); PostQuitMessage(0); default: diff --git a/programs/regedit/listview.c b/programs/regedit/listview.c index ab97c170958..b67996001ef 100644 --- a/programs/regedit/listview.c +++ b/programs/regedit/listview.c @@ -19,15 +19,13 @@ */ #include +#include #include #include #include #include #include -#include "commctrl.h" - -#include #include "main.h" typedef struct tagLINE_INFO @@ -45,11 +43,37 @@ typedef struct tagLINE_INFO static WNDPROC g_orgListWndProc; static DWORD g_columnToSort = ~0UL; static BOOL g_invertSort = FALSE; +static LPTSTR g_valueName; #define MAX_LIST_COLUMNS (IDS_LIST_COLUMN_LAST - IDS_LIST_COLUMN_FIRST + 1) static int default_column_widths[MAX_LIST_COLUMNS] = { 200, 175, 400 }; static int column_alignment[MAX_LIST_COLUMNS] = { LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_LEFT }; +LPCTSTR GetValueName(HWND hwndLV) +{ + int item, len, maxLen; + LPTSTR newStr; + + if (!g_valueName) g_valueName = HeapAlloc(GetProcessHeap(), 0, 1024); + if (!g_valueName) return NULL; + *g_valueName = 0; + maxLen = HeapSize(GetProcessHeap(), 0, g_valueName); + if (maxLen == (SIZE_T) - 1) return NULL; + + item = ListView_GetNextItem(hwndLV, -1, LVNI_FOCUSED); + if (item == -1) return NULL; + do { + ListView_GetItemText(hwndLV, item, 0, g_valueName, maxLen); + len = _tcslen(g_valueName); + if (len < maxLen - 1) break; + newStr = HeapReAlloc(GetProcessHeap(), 0, g_valueName, maxLen * 2); + if (!newStr) return NULL; + g_valueName = newStr; + maxLen *= 2; + } while (TRUE); + + return g_valueName; +} /******************************************************************************* * Local module support methods @@ -118,7 +142,7 @@ static void AddEntryToList(HWND hwndLV, LPTSTR Name, DWORD dwValType, void* ValB } } -static void CreateListColumns(HWND hWndListView) +static BOOL CreateListColumns(HWND hWndListView) { TCHAR szText[50]; int index; @@ -134,11 +158,9 @@ static void CreateListColumns(HWND hWndListView) lvC.cx = default_column_widths[index]; lvC.fmt = column_alignment[index]; LoadString(hInst, IDS_LIST_COLUMN_FIRST + index, szText, sizeof(szText)/sizeof(TCHAR)); - if (ListView_InsertColumn(hWndListView, index, &lvC) == -1) { - /* TODO: handle failure condition... */ - break; - } + if (ListView_InsertColumn(hWndListView, index, &lvC) == -1) return FALSE; } + return TRUE; } /* OnGetDispInfo - processes the LVN_GETDISPINFO notification message. */ @@ -168,9 +190,6 @@ static void OnGetDispInfo(NMLVDISPINFO* plvdi) case REG_DWORD: plvdi->item.pszText = _T("REG_DWORD"); break; - /* case REG_DWORD_LITTLE_ENDIAN: */ - /* plvdi->item.pszText = _T("REG_DWORD_LITTLE_ENDIAN"); */ - /* break; */ case REG_DWORD_BIG_ENDIAN: plvdi->item.pszText = _T("REG_DWORD_BIG_ENDIAN"); break; @@ -212,8 +231,7 @@ static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSor if (g_columnToSort == 1 && l->dwValType != r->dwValType) return g_invertSort ? (int)r->dwValType - (int)l->dwValType : (int)l->dwValType - (int)r->dwValType; - if (g_columnToSort == 2) - { + if (g_columnToSort == 2) { /* FIXME: Sort on value */ } return g_invertSort ? _tcscmp(r->name, l->name) : _tcscmp(l->name, r->name); @@ -249,8 +267,7 @@ static LRESULT CALLBACK ListWndProc(HWND hWnd, UINT message, WPARAM wParam, LPAR case LVN_COLUMNCLICK: if (g_columnToSort == ((LPNMLISTVIEW)lParam)->iSubItem) g_invertSort = !g_invertSort; - else - { + else { g_columnToSort = ((LPNMLISTVIEW)lParam)->iSubItem; g_invertSort = FALSE; } @@ -332,80 +349,81 @@ HWND CreateListView(HWND hwndParent, int id) WS_VISIBLE | WS_CHILD | LVS_REPORT, 0, 0, rcClient.right, rcClient.bottom, hwndParent, (HMENU)id, hInst, NULL); + if (!hwndLV) return NULL; ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT); /* Initialize the image list, and add items to the control. */ /* - if (!InitListViewImageLists(hwndLV) || - !InitListViewItems(hwndLV, szName)) { - DestroyWindow(hwndLV); - return FALSE; - } - */ - CreateListColumns(hwndLV); + if (!InitListViewImageLists(hwndLV)) goto fail; + if (!InitListViewItems(hwndLV, szName)) goto fail; + */ + if (!CreateListColumns(hwndLV)) goto fail; g_orgListWndProc = SubclassWindow(hwndLV, ListWndProc); return hwndLV; +fail: + DestroyWindow(hwndLV); + return NULL; } -BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPTSTR keyPath) +BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath) { - if (hwndLV != NULL) { - INT count, i; - count = ListView_GetItemCount(hwndLV); - for (i = 0; i < count; i++) - { - LVITEM item; - item.mask = LVIF_PARAM; - item.iItem = i; - ListView_GetItem(hwndLV, &item); - free(((LINE_INFO*)item.lParam)->name); - HeapFree(GetProcessHeap(), 0, (void*)item.lParam); - } - g_columnToSort = ~0UL; - ListView_DeleteAllItems(hwndLV); + DWORD max_sub_key_len; + DWORD max_val_name_len; + DWORD max_val_size; + DWORD val_count; + HKEY hNewKey; + LONG errCode; + INT count, i; + LVITEM item; + + if (!hwndLV) return FALSE; + + SendMessage(hwndLV, WM_SETREDRAW, FALSE, 0); + count = ListView_GetItemCount(hwndLV); + for (i = 0; i < count; i++) { + item.mask = LVIF_PARAM; + item.iItem = i; + ListView_GetItem(hwndLV, &item); + free(((LINE_INFO*)item.lParam)->name); + HeapFree(GetProcessHeap(), 0, (void*)item.lParam); } + g_columnToSort = ~0UL; + ListView_DeleteAllItems(hwndLV); - if (hKey != NULL) { - HKEY hNewKey; - LONG errCode = RegOpenKeyEx(hKey, keyPath, 0, KEY_READ, &hNewKey); - if (errCode == ERROR_SUCCESS) { - DWORD max_sub_key_len; - DWORD max_val_name_len; - DWORD max_val_size; - DWORD val_count; - ShowWindow(hwndLV, SW_HIDE); - /* get size information and resize the buffers if necessary */ - errCode = RegQueryInfoKey(hNewKey, NULL, NULL, NULL, NULL, - &max_sub_key_len, NULL, &val_count, &max_val_name_len, &max_val_size, NULL, NULL); + errCode = RegOpenKeyEx(hKey, keyPath, 0, KEY_READ, &hNewKey); + if (errCode != ERROR_SUCCESS) return FALSE; - #define BUF_HEAD_SPACE 2 /* TODO: check why this is required with ROS ??? */ + /* get size information and resize the buffers if necessary */ + errCode = RegQueryInfoKey(hNewKey, NULL, NULL, NULL, NULL, &max_sub_key_len, NULL, + &val_count, &max_val_name_len, &max_val_size, NULL, NULL); - if (errCode == ERROR_SUCCESS) { - TCHAR* ValName = HeapAlloc(GetProcessHeap(), 0, ++max_val_name_len * sizeof(TCHAR) + BUF_HEAD_SPACE); - DWORD dwValNameLen = max_val_name_len; - BYTE* ValBuf = HeapAlloc(GetProcessHeap(), 0, ++max_val_size/* + BUF_HEAD_SPACE*/); - DWORD dwValSize = max_val_size; - DWORD dwIndex = 0L; - DWORD dwValType; - /* if (RegQueryValueEx(hNewKey, NULL, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) { */ - /* AddEntryToList(hwndLV, _T("(Default)"), dwValType, ValBuf, dwValSize); */ - /* } */ - /* dwValSize = max_val_size; */ - while (RegEnumValue(hNewKey, dwIndex, ValName, &dwValNameLen, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) { - ValBuf[dwValSize] = 0; - AddEntryToList(hwndLV, ValName, dwValType, ValBuf, dwValSize); - dwValNameLen = max_val_name_len; - dwValSize = max_val_size; - dwValType = 0L; - ++dwIndex; - } - HeapFree(GetProcessHeap(), 0, ValBuf); - HeapFree(GetProcessHeap(), 0, ValName); - } - ListView_SortItems(hwndLV, CompareFunc, hwndLV); - ShowWindow(hwndLV, SW_SHOW); - RegCloseKey(hNewKey); + #define BUF_HEAD_SPACE 2 /* FIXME: check why this is required with ROS ??? */ + + if (errCode == ERROR_SUCCESS) { + TCHAR* ValName = HeapAlloc(GetProcessHeap(), 0, ++max_val_name_len * sizeof(TCHAR) + BUF_HEAD_SPACE); + DWORD dwValNameLen = max_val_name_len; + BYTE* ValBuf = HeapAlloc(GetProcessHeap(), 0, ++max_val_size/* + BUF_HEAD_SPACE*/); + DWORD dwValSize = max_val_size; + DWORD dwIndex = 0L; + DWORD dwValType; + /* if (RegQueryValueEx(hNewKey, NULL, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) { */ + /* AddEntryToList(hwndLV, _T("(Default)"), dwValType, ValBuf, dwValSize); */ + /* } */ + /* dwValSize = max_val_size; */ + while (RegEnumValue(hNewKey, dwIndex, ValName, &dwValNameLen, NULL, &dwValType, ValBuf, &dwValSize) == ERROR_SUCCESS) { + ValBuf[dwValSize] = 0; + AddEntryToList(hwndLV, ValName, dwValType, ValBuf, dwValSize); + dwValNameLen = max_val_name_len; + dwValSize = max_val_size; + dwValType = 0L; + ++dwIndex; } + HeapFree(GetProcessHeap(), 0, ValBuf); + HeapFree(GetProcessHeap(), 0, ValName); } + ListView_SortItems(hwndLV, CompareFunc, hwndLV); + RegCloseKey(hNewKey); + SendMessage(hwndLV, WM_SETREDRAW, TRUE, 0); + return TRUE; } diff --git a/programs/regedit/main.c b/programs/regedit/main.c index 529e8e746b3..8df9291840e 100644 --- a/programs/regedit/main.c +++ b/programs/regedit/main.c @@ -46,6 +46,7 @@ UINT nClipboardFormat; LPCTSTR strClipboardFormat = _T("TODO: SET CORRECT FORMAT"); +#define MAX_LOADSTRING 100 TCHAR szTitle[MAX_LOADSTRING]; TCHAR szFrameClass[MAX_LOADSTRING]; TCHAR szChildClass[MAX_LOADSTRING]; diff --git a/programs/regedit/main.h b/programs/regedit/main.h index 5d6b702d210..1509c4514da 100644 --- a/programs/regedit/main.h +++ b/programs/regedit/main.h @@ -28,12 +28,12 @@ #define TREE_WINDOW 2002 #define LIST_WINDOW 2003 -#define MAX_LOADSTRING 100 #define SPLIT_WIDTH 5 -#define MAX_NAME_LEN 500 #define COUNT_OF(a) (sizeof(a)/sizeof(a[0])) +extern HINSTANCE hInst; + /******************************************************************************/ enum OPTION_FLAGS { @@ -55,7 +55,7 @@ typedef struct { WINDOWPLACEMENT pos; TCHAR szPath[MAX_PATH]; } ChildWnd; -extern ChildWnd* pChildWnd; +extern ChildWnd* g_pChildWnd; /******************************************************************************* * Global Variables: @@ -84,14 +84,15 @@ extern void UpdateStatusBar(void); /* listview.c */ extern HWND CreateListView(HWND hwndParent, int id); -extern BOOL RefreshListView(HWND hwndTV, HKEY hKey, LPTSTR keyPath); +extern BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPCTSTR keyPath); +extern LPCTSTR GetValueName(HWND hwndLV); /* treeview.c */ extern HWND CreateTreeView(HWND hwndParent, LPTSTR pHostName, int id); extern BOOL OnTreeExpanding(HWND hWnd, NMTREEVIEW* pnmtv); -extern HKEY FindRegRoot(HWND hwndTV, HTREEITEM hItem, LPTSTR keyPath, int* pPathLen, int max); +extern LPCTSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY* phRootKey); /* edit.c */ -BOOL ModifyValue(HWND hwnd, HKEY hKey, LPTSTR valueName); +BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCTSTR valueName); #endif /* __MAIN_H__ */ diff --git a/programs/regedit/treeview.c b/programs/regedit/treeview.c index 0e260cd4fff..07a822ed5b8 100644 --- a/programs/regedit/treeview.c +++ b/programs/regedit/treeview.c @@ -39,53 +39,72 @@ int Image_Open; int Image_Closed; int Image_Root; +static LPTSTR pathBuffer; + #define CX_BITMAP 16 #define CY_BITMAP 16 #define NUM_BITMAPS 3 - -HKEY FindRegRoot(HWND hwndTV, HTREEITEM hItem, LPTSTR keyPath, int* pPathLen, int max) +static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY* phKey, LPTSTR* pKeyPath, int* pPathLen, int* pMaxLen) { - HKEY hKey = NULL; TVITEM item; - - if (!hItem) hItem = TreeView_GetSelection(hwndTV); + int maxLen, len; + LPTSTR newStr; item.mask = TVIF_PARAM; - item.hItem = TreeView_GetParent(hwndTV, hItem); + item.hItem = hItem; + if (!TreeView_GetItem(hwndTV, &item)) return FALSE; - if (TreeView_GetItem(hwndTV, &item)) { - if (item.lParam == 0) { - /* recurse */ - hKey = FindRegRoot(hwndTV, item.hItem, keyPath, pPathLen, max); - keyPath[*pPathLen] = _T('\\'); - ++(*pPathLen); - item.mask = TVIF_TEXT; - item.hItem = hItem; - item.pszText = &keyPath[*pPathLen]; - item.cchTextMax = max - *pPathLen; - if (TreeView_GetItem(hwndTV, &item)) { - *pPathLen += _tcslen(item.pszText); - } - } else { - /* found root key with valid key value */ - hKey = (HKEY)item.lParam; - item.mask = TVIF_TEXT; - item.hItem = hItem; - /* item.pszText = &keyPath[*pPathLen]; */ - item.pszText = keyPath; - item.cchTextMax = max; - if (TreeView_GetItem(hwndTV, &item)) { - *pPathLen += _tcslen(item.pszText); - } - } + if (item.lParam) { + /* found root key with valid key value */ + *phKey = (HKEY)item.lParam; + return TRUE; } - return hKey; + + if(!get_item_path(hwndTV, TreeView_GetParent(hwndTV, hItem), phKey, pKeyPath, pPathLen, pMaxLen)) return FALSE; + if (*pPathLen) { + (*pKeyPath)[*pPathLen] = _T('\\'); + ++(*pPathLen); + } + + do { + item.mask = TVIF_TEXT; + item.hItem = hItem; + item.pszText = *pKeyPath + *pPathLen; + item.cchTextMax = maxLen = *pMaxLen - *pPathLen; + if (!TreeView_GetItem(hwndTV, &item)) return FALSE; + len = _tcslen(item.pszText); + if (len < maxLen - 1) { + *pPathLen += len; + break; + } + newStr = HeapReAlloc(GetProcessHeap(), 0, *pKeyPath, *pMaxLen * 2); + if (!newStr) return FALSE; + *pKeyPath = newStr; + *pMaxLen *= 2; + } while(TRUE); + + return TRUE; +} + +LPCTSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY* phRootKey) +{ + int pathLen = 0, maxLen; + + if (!pathBuffer) pathBuffer = HeapAlloc(GetProcessHeap(), 0, 1024); + if (!pathBuffer) return NULL; + *pathBuffer = 0; + maxLen = HeapSize(GetProcessHeap(), 0, pathBuffer); + if (maxLen == (SIZE_T) - 1) return NULL; + if (!hItem) hItem = TreeView_GetSelection(hwndTV); + if (!hItem) return NULL; + if (!get_item_path(hwndTV, hItem, phRootKey, &pathBuffer, &pathLen, &maxLen)) return NULL; + printf("hRoot=%p, keyPath='%s'\n", *phRootKey, pathBuffer); + return pathBuffer; } static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPTSTR label, HKEY hKey, DWORD dwChildren) { - HTREEITEM hItem = 0; TVITEM tvi; TVINSERTSTRUCT tvins; @@ -97,11 +116,9 @@ static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPTSTR label, HK tvi.cChildren = dwChildren; tvi.lParam = (LPARAM)hKey; tvins.u.item = tvi; - if (hKey) tvins.hInsertAfter = (HTREEITEM)TVI_LAST; - else tvins.hInsertAfter = (HTREEITEM)TVI_SORT; + tvins.hInsertAfter = (HTREEITEM)(hKey ? TVI_LAST : TVI_SORT); tvins.hParent = hParent; - hItem = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); - return hItem; + return TreeView_InsertItem(hwndTV, &tvins); } @@ -125,24 +142,24 @@ static BOOL InitTreeViewItems(HWND hwndTV, LPTSTR pHostName) tvins.hInsertAfter = (HTREEITEM)TVI_FIRST; tvins.hParent = TVI_ROOT; /* Add the item to the tree view control. */ - hRoot = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); + if (!(hRoot = TreeView_InsertItem(hwndTV, &tvins))) return FALSE; - AddEntryToTree(hwndTV, hRoot, _T("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT, 1); - AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_USER"), HKEY_CURRENT_USER, 1); - AddEntryToTree(hwndTV, hRoot, _T("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE, 1); - AddEntryToTree(hwndTV, hRoot, _T("HKEY_USERS"), HKEY_USERS, 1); - AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG, 1); + if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT, 1)) return FALSE; + if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_USER"), HKEY_CURRENT_USER, 1)) return FALSE; + if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE, 1)) return FALSE; + if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_USERS"), HKEY_USERS, 1)) return FALSE; + if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG, 1)) return FALSE; return TRUE; } + /* * InitTreeViewImageLists - creates an image list, adds three bitmaps * to it, and associates the image list with a tree view control. * Returns TRUE if successful, or FALSE otherwise. * hwndTV - handle to the tree view control. */ - static BOOL InitTreeViewImageLists(HWND hwndTV) { HIMAGELIST himl; /* handle to image list */ @@ -155,20 +172,19 @@ static BOOL InitTreeViewImageLists(HWND hwndTV) /* Add the open file, closed file, and document bitmaps. */ hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_OPEN_FILE)); - Image_Open = ImageList_Add(himl, hbmp, (HBITMAP) NULL); + Image_Open = ImageList_Add(himl, hbmp, NULL); DeleteObject(hbmp); hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_CLOSED_FILE)); - Image_Closed = ImageList_Add(himl, hbmp, (HBITMAP) NULL); + Image_Closed = ImageList_Add(himl, hbmp, NULL); DeleteObject(hbmp); hbmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_ROOT)); - Image_Root = ImageList_Add(himl, hbmp, (HBITMAP) NULL); + Image_Root = ImageList_Add(himl, hbmp, NULL); DeleteObject(hbmp); /* Fail if not all of the images were added. */ - if (ImageList_GetImageCount(himl) < 3) - return FALSE; + if (ImageList_GetImageCount(himl) < 3) return FALSE; /* Associate the image list with the tree view control. */ TreeView_SetImageList(hwndTV, himl, TVSIL_NORMAL); @@ -178,9 +194,11 @@ static BOOL InitTreeViewImageLists(HWND hwndTV) BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW* pnmtv) { - HKEY hKey; - TCHAR keyPath[1000]; - int keyPathLen = 0; + DWORD dwCount, dwIndex, dwMaxSubKeyLen; + HKEY hRoot, hNewKey, hKey; + LPCTSTR keyPath; + LPTSTR Name; + LONG errCode; static int expanding; if (expanding) return FALSE; @@ -189,54 +207,52 @@ BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW* pnmtv) } expanding = TRUE; - /* check if this is either the root or a subkey item... */ - if ((HKEY)pnmtv->itemNew.lParam == NULL) { - keyPath[0] = _T('\0'); - hKey = FindRegRoot(hwndTV, pnmtv->itemNew.hItem, keyPath, &keyPathLen, sizeof(keyPath)/sizeof(TCHAR)); + keyPath = GetItemPath(hwndTV, pnmtv->itemNew.hItem, &hRoot); + if (!keyPath) goto done; + + if (*keyPath) { + errCode = RegOpenKeyEx(hRoot, keyPath, 0, KEY_READ, &hNewKey); + if (errCode != ERROR_SUCCESS) goto done; } else { - hKey = (HKEY)pnmtv->itemNew.lParam; - keyPath[0] = _T('\0'); + hNewKey = hRoot; } - if (hKey != NULL) { - HKEY hNewKey; - LONG errCode = RegOpenKeyEx(hKey, keyPath, 0, KEY_READ, &hNewKey); - if (errCode == ERROR_SUCCESS) { - TCHAR Name[MAX_NAME_LEN]; - DWORD cName = MAX_NAME_LEN; - FILETIME LastWriteTime; - DWORD dwIndex = 0L; - /*ShowWindow(hwndTV, SW_HIDE); */ - while (RegEnumKeyEx(hNewKey, dwIndex, Name, &cName, NULL, NULL, NULL, &LastWriteTime) == ERROR_SUCCESS) { - DWORD dwCount = 0L; - errCode = RegOpenKeyEx(hNewKey, Name, 0, KEY_READ, &hKey); - if (errCode == ERROR_SUCCESS) { - TCHAR SubName[MAX_NAME_LEN]; - DWORD cSubName = MAX_NAME_LEN; - /* if (RegEnumKeyEx(hKey, 0, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { */ - while (RegEnumKeyEx(hKey, dwCount, SubName, &cSubName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - ++dwCount; - } - } - RegCloseKey(hKey); - AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwCount); - cName = MAX_NAME_LEN; - ++dwIndex; - } - /*ShowWindow(hwndTV, SW_SHOWNOACTIVATE); */ - RegCloseKey(hNewKey); - } + errCode = RegQueryInfoKey(hNewKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0); + if (errCode != ERROR_SUCCESS) goto done; + dwMaxSubKeyLen++; /* account for the \0 terminator */ + Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(TCHAR)); + if (!Name) goto done; + + for (dwIndex = 0; dwIndex < dwCount; dwIndex++) { + DWORD cName = dwMaxSubKeyLen, dwSubCount; + FILETIME LastWriteTime; + + errCode = RegEnumKeyEx(hNewKey, dwIndex, Name, &cName, 0, 0, 0, &LastWriteTime); + if (errCode != ERROR_SUCCESS) continue; + errCode = RegOpenKeyEx(hNewKey, Name, 0, KEY_QUERY_VALUE, &hKey); + if (errCode == ERROR_SUCCESS) { + errCode = RegQueryInfoKey(hKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0); + RegCloseKey(hKey); + } + if (errCode != ERROR_SUCCESS) dwSubCount = 0; + printf("dwSubCount=%ld, Name=%s\n", dwSubCount, Name); + AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwSubCount); } + RegCloseKey(hNewKey); + HeapFree(GetProcessHeap(), 0, Name); + +done: expanding = FALSE; + return TRUE; } + /* * CreateTreeView - creates a tree view control. * Returns the handle to the new control if successful, or NULL otherwise. * hwndParent - handle to the control's parent window. */ - HWND CreateTreeView(HWND hwndParent, LPTSTR pHostName, int id) { RECT rcClient;