Regedit: Optimizations to refreshing; refreshing is still slightly
slower than Windows regedit
Modified: trunk/reactos/subsys/system/regedit/treeview.c
_____
Modified: trunk/reactos/subsys/system/regedit/treeview.c
--- trunk/reactos/subsys/system/regedit/treeview.c 2005-09-27
13:42:20 UTC (rev 18123)
+++ trunk/reactos/subsys/system/regedit/treeview.c 2005-09-27
13:47:46 UTC (rev 18124)
@@ -134,21 +134,24 @@
HTREEITEM childItem;
LPCTSTR KeyPath;
DWORD dwCount, dwIndex, dwMaxSubKeyLen;
- LPSTR Name;
+ LPSTR Name = NULL;
TVITEM tvItem;
-
+ LPTSTR pszNodes = NULL;
+ BOOL bSuccess = FALSE;
+ LPTSTR s;
+
KeyPath = GetItemPath(hwndTV, hItem, &hRoot);
if (*KeyPath) {
if (RegOpenKeyEx(hRoot, KeyPath, 0, KEY_READ, &hKey) !=
ERROR_SUCCESS) {
- return FALSE;
+ goto done;
}
} else {
hKey = hRoot;
}
if (RegQueryInfoKey(hKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0,
0, 0, 0, 0) != ERROR_SUCCESS) {
- return FALSE;
+ goto done;
}
/* Set the number of children again */
@@ -156,24 +159,65 @@
tvItem.hItem = hItem;
tvItem.cChildren = dwCount;
if (!TreeView_SetItem(hwndTV, &tvItem)) {
- return FALSE;
+ goto done;
}
/* We don't have to bother with the rest if it's not expanded. */
if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDED) == 0) {
RegCloseKey(hKey);
- return TRUE;
+ bSuccess = TRUE;
+ goto done;
}
dwMaxSubKeyLen++; /* account for the \0 terminator */
if (!(Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen *
sizeof(TCHAR)))) {
- return FALSE;
+ goto done;
}
tvItem.cchTextMax = dwMaxSubKeyLen;
if (!(tvItem.pszText = HeapAlloc(GetProcessHeap(), 0,
dwMaxSubKeyLen * sizeof(TCHAR)))) {
- return FALSE;
+ goto done;
}
+ /* Get all of the tree node siblings in one contiguous block of
memory */
+ {
+ DWORD dwPhysicalSize = 0;
+ DWORD dwActualSize = 0;
+ DWORD dwNewPhysicalSize;
+ LPTSTR pszNewNodes;
+ DWORD dwStep = 10000;
+
+ for (childItem = TreeView_GetChild(hwndTV, hItem); childItem;
+ childItem = TreeView_GetNextSibling(hwndTV, childItem))
{
+
+ if (dwActualSize + dwMaxSubKeyLen + 1 > dwPhysicalSize)
+ {
+ dwNewPhysicalSize = dwActualSize + dwMaxSubKeyLen + 1 +
dwStep;
+
+ if (pszNodes)
+ pszNewNodes = (LPTSTR)
HeapReAlloc(GetProcessHeap(), 0, pszNodes, dwNewPhysicalSize *
sizeof(TCHAR));
+ else
+ pszNewNodes = (LPTSTR) HeapAlloc(GetProcessHeap(),
0, dwNewPhysicalSize * sizeof(TCHAR));
+ if (!pszNewNodes)
+ goto done;
+
+ dwPhysicalSize = dwNewPhysicalSize;
+ pszNodes = pszNewNodes;
+ }
+
+ tvItem.mask = TVIF_TEXT;
+ tvItem.hItem = childItem;
+ tvItem.pszText = &pszNodes[dwActualSize];
+ tvItem.cchTextMax = dwPhysicalSize - dwActualSize;
+ if (!TreeView_GetItem(hwndTV, &tvItem))
+ goto done;
+
+ dwActualSize += _tcslen(&pszNodes[dwActualSize]) + 1;
+ }
+
+ if (pszNodes)
+ pszNodes[dwActualSize] = '\0';
+ }
+
/* Now go through all the children in the registry, and check if
any have to be added. */
for (dwIndex = 0; dwIndex < dwCount; dwIndex++) {
DWORD cName = dwMaxSubKeyLen, dwSubCount;
@@ -184,36 +228,29 @@
continue;
}
- /* Find the number of children of the node. */
- dwSubCount = 0;
- if (RegOpenKeyEx(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey) ==
ERROR_SUCCESS) {
- if (RegQueryInfoKey(hSubKey, 0, 0, 0, &dwSubCount, 0, 0, 0,
0, 0, 0, 0) != ERROR_SUCCESS) {
- dwSubCount = 0;
+ /* Check if the node is already in there. */
+ if (pszNodes) {
+ for (s = pszNodes; *s; s += _tcslen(s) + 1) {
+ if (!strcmp(s, Name)) {
+ found = TRUE;
+ break;
+ }
}
- RegCloseKey(hSubKey);
}
- /* Check if the node is already in there. */
- for (childItem = TreeView_GetChild(hwndTV, hItem); childItem;
- childItem = TreeView_GetNextSibling(hwndTV, childItem))
{
- tvItem.mask = TVIF_TEXT;
- tvItem.hItem = childItem;
- if (!TreeView_GetItem(hwndTV, &tvItem)) {
- return FALSE;
+ if (found == FALSE) {
+ /* Find the number of children of the node. */
+ dwSubCount = 0;
+ if (RegOpenKeyEx(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey)
== ERROR_SUCCESS) {
+ if (RegQueryInfoKey(hSubKey, 0, 0, 0, &dwSubCount, 0,
0, 0, 0, 0, 0, 0) != ERROR_SUCCESS) {
+ dwSubCount = 0;
+ }
+ RegCloseKey(hSubKey);
}
- if (!strcmp(tvItem.pszText, Name)) {
- found = TRUE;
- break;
- }
- }
-
- if (found == FALSE) {
AddEntryToTree(hwndTV, hItem, Name, NULL, dwSubCount);
}
}
- HeapFree(GetProcessHeap(), 0, Name);
- HeapFree(GetProcessHeap(), 0, tvItem.pszText);
RegCloseKey(hKey);
/* Now go through all the children in the tree, and check if any
have to be removed. */
@@ -225,8 +262,14 @@
}
childItem = nextItem;
}
+ bSuccess = TRUE;
- return TRUE;
+done:
+ if (pszNodes)
+ HeapFree(GetProcessHeap(), 0, pszNodes);
+ if (Name)
+ HeapFree(GetProcessHeap(), 0, Name);
+ return bSuccess;
}
BOOL RefreshTreeView(HWND hwndTV)