mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Regedit: Optimizations to refreshing; refreshing is still slightly slower than Windows regedit
svn path=/trunk/; revision=18124
This commit is contained in:
parent
043d319095
commit
514cdac338
1 changed files with 74 additions and 31 deletions
|
@ -134,21 +134,24 @@ static BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
|
||||||
HTREEITEM childItem;
|
HTREEITEM childItem;
|
||||||
LPCTSTR KeyPath;
|
LPCTSTR KeyPath;
|
||||||
DWORD dwCount, dwIndex, dwMaxSubKeyLen;
|
DWORD dwCount, dwIndex, dwMaxSubKeyLen;
|
||||||
LPSTR Name;
|
LPSTR Name = NULL;
|
||||||
TVITEM tvItem;
|
TVITEM tvItem;
|
||||||
|
LPTSTR pszNodes = NULL;
|
||||||
|
BOOL bSuccess = FALSE;
|
||||||
|
LPTSTR s;
|
||||||
|
|
||||||
KeyPath = GetItemPath(hwndTV, hItem, &hRoot);
|
KeyPath = GetItemPath(hwndTV, hItem, &hRoot);
|
||||||
|
|
||||||
if (*KeyPath) {
|
if (*KeyPath) {
|
||||||
if (RegOpenKeyEx(hRoot, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
|
if (RegOpenKeyEx(hRoot, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
|
||||||
return FALSE;
|
goto done;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hKey = hRoot;
|
hKey = hRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RegQueryInfoKey(hKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS) {
|
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 */
|
/* Set the number of children again */
|
||||||
|
@ -156,22 +159,63 @@ static BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
|
||||||
tvItem.hItem = hItem;
|
tvItem.hItem = hItem;
|
||||||
tvItem.cChildren = dwCount;
|
tvItem.cChildren = dwCount;
|
||||||
if (!TreeView_SetItem(hwndTV, &tvItem)) {
|
if (!TreeView_SetItem(hwndTV, &tvItem)) {
|
||||||
return FALSE;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't have to bother with the rest if it's not expanded. */
|
/* We don't have to bother with the rest if it's not expanded. */
|
||||||
if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDED) == 0) {
|
if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDED) == 0) {
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
return TRUE;
|
bSuccess = TRUE;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwMaxSubKeyLen++; /* account for the \0 terminator */
|
dwMaxSubKeyLen++; /* account for the \0 terminator */
|
||||||
if (!(Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(TCHAR)))) {
|
if (!(Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(TCHAR)))) {
|
||||||
return FALSE;
|
goto done;
|
||||||
}
|
}
|
||||||
tvItem.cchTextMax = dwMaxSubKeyLen;
|
tvItem.cchTextMax = dwMaxSubKeyLen;
|
||||||
if (!(tvItem.pszText = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(TCHAR)))) {
|
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. */
|
/* Now go through all the children in the registry, and check if any have to be added. */
|
||||||
|
@ -184,6 +228,17 @@ static BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found == FALSE) {
|
||||||
/* Find the number of children of the node. */
|
/* Find the number of children of the node. */
|
||||||
dwSubCount = 0;
|
dwSubCount = 0;
|
||||||
if (RegOpenKeyEx(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS) {
|
if (RegOpenKeyEx(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS) {
|
||||||
|
@ -193,27 +248,9 @@ static BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
|
||||||
RegCloseKey(hSubKey);
|
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 (!strcmp(tvItem.pszText, Name)) {
|
|
||||||
found = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found == FALSE) {
|
|
||||||
AddEntryToTree(hwndTV, hItem, Name, NULL, dwSubCount);
|
AddEntryToTree(hwndTV, hItem, Name, NULL, dwSubCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, Name);
|
|
||||||
HeapFree(GetProcessHeap(), 0, tvItem.pszText);
|
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
/* Now go through all the children in the tree, and check if any have to be removed. */
|
/* Now go through all the children in the tree, and check if any have to be removed. */
|
||||||
|
@ -225,8 +262,14 @@ static BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
|
||||||
}
|
}
|
||||||
childItem = nextItem;
|
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)
|
BOOL RefreshTreeView(HWND hwndTV)
|
||||||
|
|
Loading…
Reference in a new issue