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)