ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

treeview.c
Go to the documentation of this file.
00001 /*
00002  * Regedit treeview
00003  *
00004  * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <regedit.h>
00022 
00023 /* Global variables and constants  */
00024 /* Image_Open, Image_Closed, and Image_Root - integer variables for indexes of the images.  */
00025 /* CX_ICON and CY_ICON - width and height of an icon.  */
00026 /* NUM_ICON - number of icons to add to the image list.  */
00027 static int Image_Open = 0;
00028 static int Image_Closed = 0;
00029 static int Image_Root = 0;
00030 
00031 static LPTSTR pathBuffer;
00032 
00033 #define NUM_ICONS    3
00034 
00035 static BOOL get_item_path(HWND hwndTV, HTREEITEM hItem, HKEY* phKey, LPTSTR* pKeyPath, int* pPathLen, int* pMaxLen)
00036 {
00037     TVITEM item;
00038     size_t maxLen, len;
00039     LPTSTR newStr;
00040 
00041     item.mask = TVIF_PARAM;
00042     item.hItem = hItem;
00043     if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
00044 
00045     if (item.lParam)
00046     {
00047         /* found root key with valid key value */
00048         *phKey = (HKEY)item.lParam;
00049         return TRUE;
00050     }
00051 
00052     if(!get_item_path(hwndTV, TreeView_GetParent(hwndTV, hItem), phKey, pKeyPath, pPathLen, pMaxLen)) return FALSE;
00053     if (*pPathLen)
00054     {
00055         (*pKeyPath)[*pPathLen] = _T('\\');
00056         ++(*pPathLen);
00057     }
00058 
00059     do
00060     {
00061         item.mask = TVIF_TEXT;
00062         item.hItem = hItem;
00063         item.pszText = *pKeyPath + *pPathLen;
00064         maxLen = *pMaxLen - *pPathLen;
00065         item.cchTextMax = (int) maxLen;
00066         if (!TreeView_GetItem(hwndTV, &item)) return FALSE;
00067         len = _tcslen(item.pszText);
00068         if (len < maxLen - 1)
00069         {
00070             *pPathLen += (int) len;
00071             break;
00072         }
00073         newStr = HeapReAlloc(GetProcessHeap(), 0, *pKeyPath, *pMaxLen * 2);
00074         if (!newStr) return FALSE;
00075         *pKeyPath = newStr;
00076         *pMaxLen *= 2;
00077     }
00078     while(TRUE);
00079 
00080     return TRUE;
00081 }
00082 
00083 LPCTSTR GetItemPath(HWND hwndTV, HTREEITEM hItem, HKEY* phRootKey)
00084 {
00085     int pathLen = 0, maxLen;
00086 
00087     *phRootKey = NULL;
00088     if (!pathBuffer) pathBuffer = HeapAlloc(GetProcessHeap(), 0, 1024);
00089     if (!pathBuffer) return NULL;
00090     *pathBuffer = 0;
00091     maxLen = (int) HeapSize(GetProcessHeap(), 0, pathBuffer);
00092     if (maxLen == -1) return NULL;
00093     if (!hItem) hItem = TreeView_GetSelection(hwndTV);
00094     if (!hItem) return NULL;
00095     if (!get_item_path(hwndTV, hItem, phRootKey, &pathBuffer, &pathLen, &maxLen))
00096     {
00097         return NULL;
00098     }
00099     return pathBuffer;
00100 }
00101 
00102 BOOL DeleteNode(HWND hwndTV, HTREEITEM hItem)
00103 {
00104     if (!hItem) hItem = TreeView_GetSelection(hwndTV);
00105     if (!hItem) return FALSE;
00106     return TreeView_DeleteItem(hwndTV, hItem);
00107 }
00108 
00109 /* Add an entry to the tree. Only give hKey for root nodes (HKEY_ constants) */
00110 static HTREEITEM AddEntryToTree(HWND hwndTV, HTREEITEM hParent, LPTSTR label, HKEY hKey, DWORD dwChildren)
00111 {
00112     TVITEM tvi;
00113     TVINSERTSTRUCT tvins;
00114 
00115     if (hKey)
00116     {
00117         if (RegQueryInfoKey(hKey, 0, 0, 0, &dwChildren, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
00118         {
00119             dwChildren = 0;
00120         }
00121     }
00122 
00123     tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
00124     tvi.pszText = label;
00125     tvi.cchTextMax = lstrlen(tvi.pszText);
00126     tvi.iImage = Image_Closed;
00127     tvi.iSelectedImage = Image_Open;
00128     tvi.cChildren = dwChildren;
00129     tvi.lParam = (LPARAM)hKey;
00130     tvins.item = tvi;
00131     tvins.hInsertAfter = (HTREEITEM)(hKey ? TVI_LAST : TVI_FIRST);
00132     tvins.hParent = hParent;
00133     return TreeView_InsertItem(hwndTV, &tvins);
00134 }
00135 
00136 BOOL RefreshTreeItem(HWND hwndTV, HTREEITEM hItem)
00137 {
00138     HKEY hRoot, hKey, hSubKey;
00139     HTREEITEM childItem;
00140     LPCTSTR KeyPath;
00141     DWORD dwCount, dwIndex, dwMaxSubKeyLen;
00142     LPTSTR Name = NULL;
00143     TVITEM tvItem;
00144     LPTSTR pszNodes = NULL;
00145     BOOL bSuccess = FALSE;
00146     LPTSTR s;
00147     BOOL bAddedAny;
00148 
00149     KeyPath = GetItemPath(hwndTV, hItem, &hRoot);
00150 
00151     if (*KeyPath)
00152     {
00153         if (RegOpenKeyEx(hRoot, KeyPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
00154         {
00155             goto done;
00156         }
00157     }
00158     else
00159     {
00160         hKey = hRoot;
00161     }
00162 
00163     if (RegQueryInfoKey(hKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
00164     {
00165         goto done;
00166     }
00167 
00168     /* Set the number of children again */
00169     tvItem.mask = TVIF_CHILDREN;
00170     tvItem.hItem = hItem;
00171     tvItem.cChildren = dwCount;
00172     if (!TreeView_SetItem(hwndTV, &tvItem))
00173     {
00174         goto done;
00175     }
00176 
00177     /* We don't have to bother with the rest if it's not expanded. */
00178     if (TreeView_GetItemState(hwndTV, hItem, TVIS_EXPANDED) == 0)
00179     {
00180         RegCloseKey(hKey);
00181         bSuccess = TRUE;
00182         goto done;
00183     }
00184 
00185     dwMaxSubKeyLen++; /* account for the \0 terminator */
00186     if (!(Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(TCHAR))))
00187     {
00188         goto done;
00189     }
00190     tvItem.cchTextMax = dwMaxSubKeyLen;
00191     /*if (!(tvItem.pszText = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(TCHAR)))) {
00192         goto done;
00193     }*/
00194 
00195     /* Get all of the tree node siblings in one contiguous block of memory */
00196     {
00197         DWORD dwPhysicalSize = 0;
00198         DWORD dwActualSize = 0;
00199         DWORD dwNewPhysicalSize;
00200         LPTSTR pszNewNodes;
00201         DWORD dwStep = 10000;
00202 
00203         for (childItem = TreeView_GetChild(hwndTV, hItem); childItem;
00204                 childItem = TreeView_GetNextSibling(hwndTV, childItem))
00205         {
00206 
00207             if (dwActualSize + dwMaxSubKeyLen + 1 > dwPhysicalSize)
00208             {
00209                 dwNewPhysicalSize = dwActualSize + dwMaxSubKeyLen + 1 + dwStep;
00210 
00211                 if (pszNodes)
00212                     pszNewNodes = (LPTSTR) HeapReAlloc(GetProcessHeap(), 0, pszNodes, dwNewPhysicalSize * sizeof(TCHAR));
00213                 else
00214                     pszNewNodes = (LPTSTR) HeapAlloc(GetProcessHeap(), 0, dwNewPhysicalSize * sizeof(TCHAR));
00215                 if (!pszNewNodes)
00216                     goto done;
00217 
00218                 dwPhysicalSize = dwNewPhysicalSize;
00219                 pszNodes = pszNewNodes;
00220             }
00221 
00222             tvItem.mask = TVIF_TEXT;
00223             tvItem.hItem = childItem;
00224             tvItem.pszText = &pszNodes[dwActualSize];
00225             tvItem.cchTextMax = dwPhysicalSize - dwActualSize;
00226             if (!TreeView_GetItem(hwndTV, &tvItem))
00227                 goto done;
00228 
00229             dwActualSize += (DWORD) _tcslen(&pszNodes[dwActualSize]) + 1;
00230         }
00231 
00232         if (pszNodes)
00233             pszNodes[dwActualSize] = '\0';
00234     }
00235 
00236     /* Now go through all the children in the tree, and check if any have to be removed. */
00237     childItem = TreeView_GetChild(hwndTV, hItem);
00238     while (childItem)
00239     {
00240         HTREEITEM nextItem = TreeView_GetNextSibling(hwndTV, childItem);
00241         if (RefreshTreeItem(hwndTV, childItem) == FALSE)
00242         {
00243             (void)TreeView_DeleteItem(hwndTV, childItem);
00244         }
00245         childItem = nextItem;
00246     }
00247 
00248     /* Now go through all the children in the registry, and check if any have to be added. */
00249     bAddedAny = FALSE;
00250     for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
00251     {
00252         DWORD cName = dwMaxSubKeyLen, dwSubCount;
00253         BOOL found;
00254 
00255         found = FALSE;
00256         if (RegEnumKeyEx(hKey, dwIndex, Name, &cName, 0, 0, 0, NULL) != ERROR_SUCCESS)
00257         {
00258             continue;
00259         }
00260 
00261         /* Check if the node is already in there. */
00262         if (pszNodes)
00263         {
00264             for (s = pszNodes; *s; s += _tcslen(s) + 1)
00265             {
00266                 if (!_tcscmp(s, Name))
00267                 {
00268                     found = TRUE;
00269                     break;
00270                 }
00271             }
00272         }
00273 
00274         if (found == FALSE)
00275         {
00276             /* Find the number of children of the node. */
00277             dwSubCount = 0;
00278             if (RegOpenKeyEx(hKey, Name, 0, KEY_QUERY_VALUE, &hSubKey) == ERROR_SUCCESS)
00279             {
00280                 if (RegQueryInfoKey(hSubKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0) != ERROR_SUCCESS)
00281                 {
00282                     dwSubCount = 0;
00283                 }
00284                 RegCloseKey(hSubKey);
00285             }
00286 
00287             AddEntryToTree(hwndTV, hItem, Name, NULL, dwSubCount);
00288             bAddedAny = TRUE;
00289         }
00290     }
00291     RegCloseKey(hKey);
00292 
00293     if (bAddedAny)
00294         SendMessage(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM) hItem);
00295 
00296     bSuccess = TRUE;
00297 
00298 done:
00299     if (pszNodes)
00300         HeapFree(GetProcessHeap(), 0, pszNodes);
00301     if (Name)
00302         HeapFree(GetProcessHeap(), 0, Name);
00303     return bSuccess;
00304 }
00305 
00306 BOOL RefreshTreeView(HWND hwndTV)
00307 {
00308     HTREEITEM hItem;
00309     HTREEITEM hSelectedItem;
00310     HCURSOR hcursorOld;
00311 
00312     hSelectedItem = TreeView_GetSelection(hwndTV);
00313     hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
00314     SendMessage(hwndTV, WM_SETREDRAW, FALSE, 0);
00315 
00316     hItem = TreeView_GetChild(hwndTV, TreeView_GetRoot(hwndTV));
00317     while (hItem)
00318     {
00319         RefreshTreeItem(hwndTV, hItem);
00320         hItem = TreeView_GetNextSibling(hwndTV, hItem);
00321     }
00322 
00323     SendMessage(hwndTV, WM_SETREDRAW, TRUE, 0);
00324     SetCursor(hcursorOld);
00325 
00326     /* We reselect the currently selected node, this will prompt a refresh of the listview. */
00327     (void)TreeView_SelectItem(hwndTV, hSelectedItem);
00328     return TRUE;
00329 }
00330 
00331 HTREEITEM InsertNode(HWND hwndTV, HTREEITEM hItem, LPTSTR name)
00332 {
00333     TCHAR buf[MAX_NEW_KEY_LEN];
00334     HTREEITEM hNewItem = 0;
00335     TVITEMEX item;
00336 
00337     /* Default to the current selection */
00338     if (!hItem)
00339     {
00340         hItem = TreeView_GetSelection(hwndTV);
00341         if (!hItem)
00342             return FALSE;
00343     }
00344 
00345     memset(&item, 0, sizeof(item));
00346     item.hItem = hItem;
00347     item.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_STATE;
00348     if (!TreeView_GetItem(hwndTV, &item))
00349         return FALSE;
00350 
00351     if ((item.state & TVIS_EXPANDEDONCE) && (item.cChildren > 0))
00352     {
00353         hNewItem = AddEntryToTree(hwndTV, hItem, name, 0, 0);
00354         SendMessage(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM) hItem);
00355     }
00356     else
00357     {
00358         item.mask = TVIF_CHILDREN | TVIF_HANDLE;
00359         item.hItem = hItem;
00360         item.cChildren = 1;
00361         if (!TreeView_SetItem(hwndTV, &item))
00362             return FALSE;
00363     }
00364 
00365     (void)TreeView_Expand(hwndTV, hItem, TVE_EXPAND);
00366     if (!hNewItem)
00367     {
00368         for(hNewItem = TreeView_GetChild(hwndTV, hItem); hNewItem; hNewItem = TreeView_GetNextSibling(hwndTV, hNewItem))
00369         {
00370             item.mask = TVIF_HANDLE | TVIF_TEXT;
00371             item.hItem = hNewItem;
00372             item.pszText = buf;
00373             item.cchTextMax = COUNT_OF(buf);
00374             if (!TreeView_GetItem(hwndTV, &item)) continue;
00375             if (lstrcmp(name, item.pszText) == 0) break;
00376         }
00377     }
00378     if (hNewItem) (void)TreeView_SelectItem(hwndTV, hNewItem);
00379 
00380     return hNewItem;
00381 }
00382 
00383 HWND StartKeyRename(HWND hwndTV)
00384 {
00385     HTREEITEM hItem;
00386 
00387     if(!(hItem = TreeView_GetSelection(hwndTV))) return 0;
00388     return TreeView_EditLabel(hwndTV, hItem);
00389 }
00390 
00391 static BOOL InitTreeViewItems(HWND hwndTV, LPTSTR pHostName)
00392 {
00393     TVITEM tvi;
00394     TVINSERTSTRUCT tvins;
00395     HTREEITEM hRoot;
00396 
00397     tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM;
00398     /* Set the text of the item.  */
00399     tvi.pszText = pHostName;
00400     tvi.cchTextMax = lstrlen(tvi.pszText);
00401     /* Assume the item is not a parent item, so give it an image.  */
00402     tvi.iImage = Image_Root;
00403     tvi.iSelectedImage = Image_Root;
00404     tvi.cChildren = 5;
00405     /* Save the heading level in the item's application-defined data area.  */
00406     tvi.lParam = (LPARAM)NULL;
00407     tvins.item = tvi;
00408     tvins.hInsertAfter = (HTREEITEM)TVI_FIRST;
00409     tvins.hParent = TVI_ROOT;
00410     /* Add the item to the tree view control.  */
00411     if (!(hRoot = TreeView_InsertItem(hwndTV, &tvins))) return FALSE;
00412 
00413     if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_CLASSES_ROOT"), HKEY_CLASSES_ROOT, 1)) return FALSE;
00414     if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_USER"), HKEY_CURRENT_USER, 1)) return FALSE;
00415     if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_LOCAL_MACHINE"), HKEY_LOCAL_MACHINE, 1)) return FALSE;
00416     if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_USERS"), HKEY_USERS, 1)) return FALSE;
00417     if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_CURRENT_CONFIG"), HKEY_CURRENT_CONFIG, 1)) return FALSE;
00418 
00419     if (GetVersion() & 0x80000000)
00420     {
00421         /* Win9x specific key */
00422         if (!AddEntryToTree(hwndTV, hRoot, _T("HKEY_DYN_DATA"), HKEY_DYN_DATA, 1)) return FALSE;
00423     }
00424 
00425     /* expand and select host name */
00426     (void)TreeView_Expand(hwndTV, hRoot, TVE_EXPAND);
00427     (void)TreeView_Select(hwndTV, hRoot, TVGN_CARET);
00428     return TRUE;
00429 }
00430 
00431 
00432 /*
00433  * InitTreeViewImageLists - creates an image list, adds three bitmaps
00434  * to it, and associates the image list with a tree view control.
00435  * Returns TRUE if successful, or FALSE otherwise.
00436  * hwndTV - handle to the tree view control.
00437  */
00438 static BOOL InitTreeViewImageLists(HWND hwndTV)
00439 {
00440     HIMAGELIST himl;  /* handle to image list  */
00441     HICON hico;       /* handle to icon  */
00442 
00443     /* Create the image list.  */
00444     if ((himl = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
00445                                  GetSystemMetrics(SM_CYSMICON),
00446                                  ILC_MASK | ILC_COLOR32,
00447                                  0,
00448                                  NUM_ICONS)) == NULL)
00449     {
00450         return FALSE;
00451     }
00452 
00453     /* Add the open file, closed file, and document bitmaps.  */
00454     hico = LoadImage(hInst,
00455                      MAKEINTRESOURCE(IDI_OPEN_FILE),
00456                      IMAGE_ICON,
00457                      GetSystemMetrics(SM_CXSMICON),
00458                      GetSystemMetrics(SM_CYSMICON),
00459                      0);
00460     if (hico)
00461     {
00462         Image_Open = ImageList_AddIcon(himl, hico);
00463         DestroyIcon(hico);
00464     }
00465 
00466     hico = LoadImage(hInst,
00467                      MAKEINTRESOURCE(IDI_CLOSED_FILE),
00468                      IMAGE_ICON,
00469                      GetSystemMetrics(SM_CXSMICON),
00470                      GetSystemMetrics(SM_CYSMICON),
00471                      0);
00472     if (hico)
00473     {
00474         Image_Closed = ImageList_AddIcon(himl, hico);
00475         DestroyIcon(hico);
00476     }
00477 
00478     hico = LoadImage(hInst,
00479                      MAKEINTRESOURCE(IDI_ROOT),
00480                      IMAGE_ICON,
00481                      GetSystemMetrics(SM_CXSMICON),
00482                      GetSystemMetrics(SM_CYSMICON),
00483                      0);
00484     if (hico)
00485     {
00486         Image_Root = ImageList_AddIcon(himl, hico);
00487         DestroyIcon(hico);
00488     }
00489 
00490     /* Fail if not all of the images were added.  */
00491     if (ImageList_GetImageCount(himl) < NUM_ICONS)
00492     {
00493         ImageList_Destroy(himl);
00494         return FALSE;
00495     }
00496 
00497     /* Associate the image list with the tree view control.  */
00498     (void)TreeView_SetImageList(hwndTV, himl, TVSIL_NORMAL);
00499 
00500     return TRUE;
00501 }
00502 
00503 BOOL OnTreeExpanding(HWND hwndTV, NMTREEVIEW* pnmtv)
00504 {
00505     DWORD dwCount, dwIndex, dwMaxSubKeyLen;
00506     HKEY hRoot, hNewKey, hKey;
00507     LPCTSTR keyPath;
00508     LPTSTR Name;
00509     LONG errCode;
00510     HCURSOR hcursorOld;
00511 
00512     static int expanding;
00513     if (expanding) return FALSE;
00514     if (pnmtv->itemNew.state & TVIS_EXPANDEDONCE )
00515     {
00516         return TRUE;
00517     }
00518     expanding = TRUE;
00519     hcursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
00520     SendMessage(hwndTV, WM_SETREDRAW, FALSE, 0);
00521 
00522     keyPath = GetItemPath(hwndTV, pnmtv->itemNew.hItem, &hRoot);
00523     if (!keyPath) goto done;
00524 
00525     if (*keyPath)
00526     {
00527         errCode = RegOpenKeyEx(hRoot, keyPath, 0, KEY_READ, &hNewKey);
00528         if (errCode != ERROR_SUCCESS) goto done;
00529     }
00530     else
00531     {
00532         hNewKey = hRoot;
00533     }
00534 
00535     errCode = RegQueryInfoKey(hNewKey, 0, 0, 0, &dwCount, &dwMaxSubKeyLen, 0, 0, 0, 0, 0, 0);
00536     if (errCode != ERROR_SUCCESS) goto done;
00537     dwMaxSubKeyLen++; /* account for the \0 terminator */
00538     Name = HeapAlloc(GetProcessHeap(), 0, dwMaxSubKeyLen * sizeof(TCHAR));
00539     if (!Name) goto done;
00540 
00541     for (dwIndex = 0; dwIndex < dwCount; dwIndex++)
00542     {
00543         DWORD cName = dwMaxSubKeyLen, dwSubCount;
00544 
00545         errCode = RegEnumKeyEx(hNewKey, dwIndex, Name, &cName, 0, 0, 0, 0);
00546         if (errCode != ERROR_SUCCESS) continue;
00547         errCode = RegOpenKeyEx(hNewKey, Name, 0, KEY_QUERY_VALUE, &hKey);
00548         if (errCode == ERROR_SUCCESS)
00549         {
00550             errCode = RegQueryInfoKey(hKey, 0, 0, 0, &dwSubCount, 0, 0, 0, 0, 0, 0, 0);
00551             RegCloseKey(hKey);
00552         }
00553         if (errCode != ERROR_SUCCESS) dwSubCount = 0;
00554         AddEntryToTree(hwndTV, pnmtv->itemNew.hItem, Name, NULL, dwSubCount);
00555     }
00556 
00557     SendMessage(hwndTV, TVM_SORTCHILDREN, 0, (LPARAM)pnmtv->itemNew.hItem);
00558 
00559     RegCloseKey(hNewKey);
00560     HeapFree(GetProcessHeap(), 0, Name);
00561 
00562 done:
00563     SendMessage(hwndTV, WM_SETREDRAW, TRUE, 0);
00564     SetCursor(hcursorOld);
00565     expanding = FALSE;
00566 
00567     return TRUE;
00568 }
00569 
00570 
00571 BOOL CreateNewKey(HWND hwndTV, HTREEITEM hItem)
00572 {
00573     TCHAR szNewKeyFormat[128];
00574     TCHAR szNewKey[128];
00575     LPCTSTR pszKeyPath;
00576     int iIndex = 1;
00577     LONG nResult;
00578     HKEY hRootKey = NULL, hKey = NULL, hNewKey = NULL;
00579     BOOL bSuccess = FALSE;
00580     DWORD dwDisposition;
00581     HTREEITEM hNewItem;
00582 
00583     pszKeyPath = GetItemPath(hwndTV, hItem, &hRootKey);
00584     if (pszKeyPath[0] == TEXT('\0'))
00585         hKey = hRootKey;
00586     else if (RegOpenKey(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
00587         goto done;
00588 
00589     if (LoadString(hInst, IDS_NEW_KEY, szNewKeyFormat, sizeof(szNewKeyFormat) / sizeof(szNewKeyFormat[0])) <= 0)
00590         goto done;
00591 
00592     /* Need to create a new key with a unique name */
00593     do
00594     {
00595         wsprintf(szNewKey, szNewKeyFormat, iIndex++);
00596         nResult = RegCreateKeyEx(hKey, szNewKey, 0, NULL, 0, KEY_WRITE, NULL, &hNewKey, &dwDisposition);
00597         if (hNewKey && dwDisposition == REG_OPENED_EXISTING_KEY)
00598         {
00599             RegCloseKey(hNewKey);
00600             hNewKey = NULL;
00601         }
00602         else if (!hNewKey)
00603         {
00604             TCHAR sz[256];
00605             wsprintf(sz, TEXT("Cannot create new key!\n\nError Code: %d"), nResult);
00606             MessageBox(hFrameWnd, sz, NULL, MB_ICONERROR);
00607             goto done;
00608         }
00609     }
00610     while(!hNewKey);
00611 
00612     /* Insert the new key */
00613     hNewItem = InsertNode(hwndTV, hItem, szNewKey);
00614     if (!hNewItem)
00615         goto done;
00616 
00617     /* The new key's name is probably not appropriate yet */
00618     (void)TreeView_EditLabel(hwndTV, hNewItem);
00619 
00620     bSuccess = TRUE;
00621 
00622 done:
00623     if (hKey != hRootKey && hKey)
00624         RegCloseKey(hKey);
00625     if (hNewKey)
00626         RegCloseKey(hNewKey);
00627     return bSuccess;
00628 }
00629 
00630 
00631 /*
00632  * CreateTreeView - creates a tree view control.
00633  * Returns the handle to the new control if successful, or NULL otherwise.
00634  * hwndParent - handle to the control's parent window.
00635  */
00636 HWND CreateTreeView(HWND hwndParent, LPTSTR pHostName, HMENU id)
00637 {
00638     RECT rcClient;
00639     HWND hwndTV;
00640 
00641     /* Get the dimensions of the parent window's client area, and create the tree view control.  */
00642     GetClientRect(hwndParent, &rcClient);
00643     hwndTV = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, NULL,
00644                             WS_VISIBLE | WS_CHILD | WS_TABSTOP | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_EDITLABELS,
00645                             0, 0, rcClient.right, rcClient.bottom,
00646                             hwndParent, id, hInst, NULL);
00647     /* Initialize the image list, and add items to the control.  */
00648     if (!InitTreeViewImageLists(hwndTV) || !InitTreeViewItems(hwndTV, pHostName))
00649     {
00650         DestroyWindow(hwndTV);
00651         return NULL;
00652     }
00653     return hwndTV;
00654 }
00655 
00656 void DestroyTreeView()
00657 {
00658     if (pathBuffer)
00659         HeapFree(GetProcessHeap(), 0, pathBuffer);
00660 }
00661 
00662 BOOL SelectNode(HWND hwndTV, LPCTSTR keyPath)
00663 {
00664     HTREEITEM hRoot, hItem;
00665     HTREEITEM hChildItem;
00666     TCHAR szPathPart[128];
00667     TCHAR szBuffer[128];
00668     LPCTSTR s;
00669     TVITEM tvi;
00670 
00671     /* Total no-good hack */
00672     if (!_tcsnicmp(keyPath, _T("My Computer\\"), 12))
00673         keyPath += 12;
00674 
00675     hRoot = TreeView_GetRoot(hwndTV);
00676     hItem = hRoot;
00677 
00678     while(keyPath[0])
00679     {
00680         s = _tcschr(keyPath, TEXT('\\'));
00681         lstrcpyn(szPathPart, keyPath, s ? s - keyPath + 1 : _tcslen(keyPath) + 1);
00682 
00683         /* Special case for root to expand root key abbreviations */
00684         if (hItem == hRoot)
00685         {
00686             if (!_tcsicmp(szPathPart, TEXT("HKCR")))
00687                 _tcscpy(szPathPart, TEXT("HKEY_CLASSES_ROOT"));
00688             else if (!_tcsicmp(szPathPart, TEXT("HKCU")))
00689                 _tcscpy(szPathPart, TEXT("HKEY_CURRENT_USER"));
00690             else if (!_tcsicmp(szPathPart, TEXT("HKLM")))
00691                 _tcscpy(szPathPart, TEXT("HKEY_LOCAL_MACHINE"));
00692             else if (!_tcsicmp(szPathPart, TEXT("HKU")))
00693                 _tcscpy(szPathPart, TEXT("HKEY_USERS"));
00694             else if (!_tcsicmp(szPathPart, TEXT("HKCC")))
00695                 _tcscpy(szPathPart, TEXT("HKEY_CURRENT_CONFIG"));
00696             else if (!_tcsicmp(szPathPart, TEXT("HKDD")))
00697                 _tcscpy(szPathPart, TEXT("HKEY_DYN_DATA"));
00698         }
00699 
00700         for (hChildItem = TreeView_GetChild(hwndTV, hItem); hChildItem;
00701                 hChildItem = TreeView_GetNextSibling(hwndTV, hChildItem))
00702         {
00703             memset(&tvi, 0, sizeof(tvi));
00704             tvi.hItem = hChildItem;
00705             tvi.mask = TVIF_TEXT | TVIF_CHILDREN;
00706             tvi.pszText = szBuffer;
00707             tvi.cchTextMax = sizeof(szBuffer) / sizeof(szBuffer[0]);
00708 
00709             (void)TreeView_GetItem(hwndTV, &tvi);
00710 
00711             if (!_tcsicmp(szBuffer, szPathPart))
00712                 break;
00713         }
00714 
00715         if (!hChildItem)
00716             return FALSE;
00717 
00718         if (tvi.cChildren > 0)
00719         {
00720             if (!TreeView_Expand(hwndTV, hChildItem, TVE_EXPAND))
00721                 return FALSE;
00722         }
00723 
00724         keyPath = s ? s + 1 : _T("");
00725         hItem = hChildItem;
00726     }
00727 
00728     (void)TreeView_SelectItem(hwndTV, hItem);
00729     (void)TreeView_EnsureVisible(hwndTV, hItem);
00730 
00731     return TRUE;
00732 }
00733 
00734 

Generated on Mon May 28 2012 04:17:24 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.