Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentreeview.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
1.7.6.1
|