GME  13
RegistryTree.cpp
Go to the documentation of this file.
00001 // RegistryTree.cpp : implementation file
00002 //
00003 
00004 #include "stdafx.h"
00005 #include "mgautil.h"
00006 #include "RegistryBrowserDlg.h"
00007 #include "resource.h"
00008 #ifdef _DEBUG
00009 #define new DEBUG_NEW
00010 #undef THIS_FILE
00011 static char THIS_FILE[] = __FILE__;
00012 #endif
00013 
00015 // CRegistryTree
00016 
00017 CRegistryTree::CRegistryTree()
00018 {
00019 }
00020 
00021 CRegistryTree::~CRegistryTree()
00022 {
00023 }
00024 
00025 
00026 BEGIN_MESSAGE_MAP(CRegistryTree, CTreeCtrl)
00027         //{{AFX_MSG_MAP(CRegistryTree)
00028         ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
00029         ON_WM_RBUTTONDOWN()
00030         ON_COMMAND(ID_CNTX_ADDNODE, OnCntxAddnode)
00031         ON_COMMAND(ID_CNTX_CLEARNODE, OnCntxClearnode)
00032         ON_COMMAND(ID_CNTX_REMOVEALL, OnCntxRemoveall)
00033         ON_COMMAND(ID_CNTX_REMOVETREE, OnCntxRemovetree)
00034         ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit)
00035         ON_COMMAND(ID_CNTX_RENAMENODE, OnCntxRenamenode)
00036         ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnBeginlabeledit)
00037         ON_WM_KEYDOWN()
00038         //}}AFX_MSG_MAP
00039 END_MESSAGE_MAP()
00040 
00042 // CRegistryTree message handlers
00043 
00044 
00045 
00046 void CRegistryTree::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
00047 {
00048         NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
00049 
00050         CRegistryBrowserDlg *dlg = (CRegistryBrowserDlg *)(GetParent());
00051 
00052         CRegBrwNode *oldnode;
00053         if (pNMTreeView->itemOld.hItem) {
00054                 oldnode = (CRegBrwNode *)GetItemData(pNMTreeView->itemOld.hItem);
00055         
00056                 if (oldnode) {
00057                         dlg->UpdateData(TRUE);
00058                         if (oldnode->status == ATTSTATUS_HERE) {
00059                                 oldnode->value = dlg->m_regnodeValue;
00060                                 oldnode->value.Replace(_T("\r\n"),_T("\n")); // Remove Win32 GUI line ends
00061                         }
00062                 }
00063         }
00064 
00065         CRegBrwNode *newnode;
00066         if (pNMTreeView->itemNew.hItem) {
00067                 newnode = (CRegBrwNode *)GetItemData(pNMTreeView->itemNew.hItem);
00068 
00069                 if (newnode) {
00070                         dlg->m_regnodePath = newnode->path;
00071                         switch (newnode->status) {
00072                         case ATTSTATUS_HERE:
00073                                 dlg->m_regnodeStatus = _T("HERE");
00074                                 break;
00075                         case ATTSTATUS_METADEFAULT:
00076                                 dlg->m_regnodeStatus = _T("METADEFAULT");
00077                                 break;
00078                         case ATTSTATUS_UNDEFINED:
00079                                 dlg->m_regnodeStatus = _T("UNDEFINED");
00080                                 break;
00081                         case ATTSTATUS_INVALID:
00082                                 dlg->m_regnodeStatus = _T("INVALID");
00083                                 break;
00084                         default:
00085                                 CString inherited;
00086                                 inherited.Format(_T("INHERITED (distance: %ld)"), newnode->status);
00087                                 dlg->m_regnodeStatus = inherited;
00088                                 break;
00089                         }
00090                         dlg->m_regnodeValue = newnode->value;
00091                         dlg->m_regnodeValue.Replace(_T("\n"), _T("\r\n")); // Add Win32 GUI line ends
00092                         dlg->UpdateData(FALSE);
00093                 }
00094         }
00095 
00096         *pResult = 0;
00097 }
00098 
00099 
00100 void CRegistryTree::OnRButtonDown(UINT nFlags, CPoint point) 
00101 {
00102         CMenu menu;
00103         menu.LoadMenu(IDR_CNTXMENU_REGBRW);
00104         CMenu* popupMenu = menu.GetSubMenu(0);
00105         popupMenu->EnableMenuItem(ID_CNTX_ADDNODE, MF_ENABLED);
00106         popupMenu->EnableMenuItem(ID_CNTX_CLEARNODE, MF_ENABLED);
00107         popupMenu->EnableMenuItem(ID_CNTX_REMOVETREE, MF_ENABLED);
00108         popupMenu->EnableMenuItem(ID_CNTX_RENAMENODE, MF_ENABLED);
00109 
00110         UINT uFlags;
00111         HTREEITEM hItem = 0, hOldItem = 0;
00112 
00113         hItem = HitTest(point, &uFlags);
00114         if (hItem && (TVHT_ONITEM & uFlags)) {
00115                 hOldItem = GetSelectedItem();
00116                 SelectItem(hItem);
00117                 m_cntxSelected = hItem;
00118         }
00119         else {
00120                 hOldItem = GetSelectedItem();
00121                 hItem = NULL;
00122                 SelectItem(hItem);
00123                 m_cntxSelected = hItem;
00124         }
00125 
00126         if (!hItem) {
00127                 popupMenu->EnableMenuItem(ID_CNTX_CLEARNODE, MF_GRAYED);
00128                 popupMenu->EnableMenuItem(ID_CNTX_REMOVETREE, MF_GRAYED);
00129                 popupMenu->EnableMenuItem(ID_CNTX_RENAMENODE, MF_GRAYED);
00130         }
00131         else {
00132                 CRegBrwNode *node = (CRegBrwNode*)GetItemData(hItem);
00133                 if (node->status != ATTSTATUS_HERE) {
00134                         popupMenu->EnableMenuItem(ID_CNTX_CLEARNODE, MF_GRAYED);
00135                 }
00136                 if ( (node->status != ATTSTATUS_HERE) || ItemHasChildren(hItem)) {
00137                         popupMenu->EnableMenuItem(ID_CNTX_RENAMENODE, MF_GRAYED);
00138                 }
00139         }
00140 
00141 
00142         ClientToScreen(&point);
00143     int command = popupMenu->TrackPopupMenuEx(TPM_RETURNCMD, point.x, point.y, this, NULL);
00144     SendMessage(WM_COMMAND, command, 0);
00145     if (command != ID_CNTX_ADDNODE /* dont interfere with editing label */ && hOldItem)
00146         SelectItem(hOldItem);
00147         
00148         //CTreeCtrl::OnRButtonDown(nFlags, point);
00149 }
00150 
00151 void CRegistryTree::OnCntxAddnode() 
00152 {
00153         HTREEITEM hItem = m_cntxSelected ? m_cntxSelected : TVI_ROOT;
00154         CRegistryBrowserDlg *dlg = (CRegistryBrowserDlg *)(GetParent());
00155         CRegBrwNode *oldNode = (hItem == TVI_ROOT) ? NULL : (CRegBrwNode*)GetItemData(hItem);
00156         
00157         CRegBrwNode *newNode = new CRegBrwNode();
00158         newNode->name = _T("New Node");
00159         newNode->parent = oldNode;
00160         newNode->status = ATTSTATUS_HERE;
00161         newNode->value = _T("");
00162         newNode->path = (hItem == TVI_ROOT) ? newNode->name : oldNode->path + _T("/") + newNode->name;
00163         
00164         int imageNum;
00165         dlg->m_imageMap.Lookup(IDI_ICON_REGHERE, imageNum);
00166         newNode->handle = InsertItem(newNode->name, imageNum, imageNum, hItem, TVI_LAST);
00167         SetItemData((HTREEITEM)newNode->handle, (DWORD) newNode);
00168 
00169         dlg->m_nodes.AddTail(newNode);
00170     if (hItem)
00171         VERIFY(Expand(hItem, TVE_EXPAND));
00172     VERIFY(SelectItem((HTREEITEM)newNode->handle));
00173     //UpdateWindow();
00174 
00175         // Dirty trick...
00176         CEdit *eLabel = EditLabel((HTREEITEM)newNode->handle);
00177         eLabel->SetWindowText(newNode->name);
00178         eLabel->SetSel(0, -1);
00179 }
00180 
00181 void CRegistryTree::OnCntxClearnode() 
00182 {
00183         HTREEITEM hItem = m_cntxSelected;
00184         if (hItem) {
00185                 CRegBrwNode* node= (CRegBrwNode*)GetItemData(hItem);
00186                 node->status = ATTSTATUS_UNDEFINED;
00187                 node->value = _T("");
00188                 CRegistryBrowserDlg *dlg = (CRegistryBrowserDlg *)(GetParent());
00189                 dlg->m_regnodeStatus = _T("UNDEFINED");
00190                 dlg->m_regnodeValue = _T("");
00191                 dlg->UpdateData(FALSE);
00192                 int imageNum;
00193                 dlg->m_imageMap.Lookup(IDI_ICON_REGUNDEF, imageNum);
00194                 SetItemImage(hItem, imageNum, imageNum);
00195                 AfxMessageBox(_T("Inherited nodes will not be shown until you save the changes.\nClick on the OK button, and start the Registry Browser again to see them !"), MB_ICONINFORMATION | MB_OK);
00196         }
00197 }
00198 
00199 void CRegistryTree::OnCntxRemoveall() 
00200 {
00201         if( AfxMessageBox(_T("Would you like to delete all nodes?"), MB_YESNO | MB_ICONWARNING) == IDYES)
00202         {
00203                 HTREEITEM hNextItem, hItem = GetRootItem();
00204                 while ( hItem != NULL)
00205                 {
00206                         hNextItem = GetNextItem( hItem, TVGN_NEXT);
00207                         RemoveSubTree(hItem);
00208                         DeleteItem(hItem);
00209                         hItem = hNextItem;
00210                 }
00211                 AfxMessageBox(_T("Inherited nodes will not be shown until you save the changes.\nClick on the OK button, and start the Registry Browser again to see them !"), MB_ICONINFORMATION | MB_OK);
00212         }
00213 }
00214 
00215 void CRegistryTree::OnCntxRemovetree() 
00216 {
00217         HTREEITEM hItem = m_cntxSelected;
00218         if (hItem) {
00219                 RemoveSubTree(hItem);
00220                 DeleteItem(hItem);
00221                 AfxMessageBox(_T("Inherited nodes will not be shown until you save the changes.\nClick on the OK button, and start the Registry Browser again to see them !"), MB_ICONINFORMATION | MB_OK);
00222         }
00223         
00224 }
00225 
00226 void CRegistryTree::RemoveSubTree(HTREEITEM hItem)
00227 {
00228         CRegBrwNode* node = (CRegBrwNode*)GetItemData(hItem);
00229         node->status = ATTSTATUS_INVALID;
00230 
00231         if (ItemHasChildren(hItem)) {
00232                 HTREEITEM hNextItem;
00233                 HTREEITEM hChildItem = GetChildItem(hItem);
00234 
00235                 while (hChildItem) {
00236                         hNextItem = GetNextItem(hChildItem, TVGN_NEXT);
00237                         RemoveSubTree(hChildItem);
00238                         hChildItem = hNextItem;
00239                 }
00240 
00241         }
00242 }
00243 
00244 void CRegistryTree::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
00245 {
00246         TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
00247         // TODO: Add your control notification handler code here
00248         if (pTVDispInfo->item.pszText) {
00249                 HTREEITEM hItem = pTVDispInfo->item.hItem;
00250                 if (hItem) {
00251                                 CRegBrwNode *node = (CRegBrwNode*)GetItemData(hItem);
00252                                 if (node) {
00253                                         if (CString(pTVDispInfo->item.pszText).Find('/') != -1) {
00254                                                 AfxMessageBox(_T("Cannot rename registry node.\nThe name you specified contains '/' character. Specify a different name!"), MB_ICONSTOP | MB_OK);
00255                                                 *pResult = FALSE;
00256                                                 return;
00257                                         }
00258 
00259                                         if ( (node->status != ATTSTATUS_HERE) || ItemHasChildren(hItem)) {
00260                                                 AfxMessageBox(_T("Only leaf nodes defined in this FCO can be renamed."), MB_ICONSTOP | MB_OK);
00261                                                 *pResult = FALSE;
00262                                                 return;
00263                                         }
00264 
00265                                         HTREEITEM hParent = GetParentItem(hItem);
00266                                         if (!hParent)
00267                                                 hParent = TVI_ROOT;
00268                                         HTREEITEM hNextItem = GetChildItem(hParent);
00269                                         while (hNextItem) {
00270                                                 CString nodeName = GetItemText(hNextItem);
00271                                                 if ((nodeName == pTVDispInfo->item.pszText) && (hNextItem != hItem)) {
00272                                                         AfxMessageBox(_T("Cannot rename registry node.\nA node with the name you specified already exists. Specify a different name!"), MB_ICONSTOP | MB_OK);
00273                                                         CEdit *eLabel = EditLabel(hItem);
00274                                                         eLabel->SetWindowText(pTVDispInfo->item.pszText);
00275                                                         eLabel->SetSel(0,-1);
00276                                                         *pResult = FALSE;
00277                                                         return;
00278                                                 }
00279                                                 hNextItem = GetNextItem(hNextItem, TVGN_NEXT);
00280                                         }
00281 
00282                                         node->name = pTVDispInfo->item.pszText;
00283                                         int dStart = node->path.ReverseFind('/') + 1;
00284                                         int dCount = node->path.GetLength() - dStart;
00285                                         node->path.Delete(dStart, dCount);
00286                                         node->path += pTVDispInfo->item.pszText;
00287 
00288                                         if (GetSelectedItem() == hItem) {
00289                                                 CRegistryBrowserDlg *dlg = (CRegistryBrowserDlg *)(GetParent());
00290                                                 dlg->m_regnodePath = node->path;
00291                                                 dlg->UpdateData(FALSE);
00292                                         }
00293                                 }
00294                 }
00295         }
00296         *pResult = TRUE;
00297 }
00298 
00299 void CRegistryTree::OnCntxRenamenode() 
00300 {
00301         HTREEITEM hItem = m_cntxSelected;
00302         if (hItem) {
00303                 EditLabel(hItem);
00304         }
00305 }
00306 
00307 void CRegistryTree::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
00308 {
00309         TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
00310         HTREEITEM hItem = pTVDispInfo->item.hItem;
00311         if (hItem) {
00312                 CRegBrwNode *node = (CRegBrwNode*)GetItemData(hItem);
00313                 if ( (node->status != ATTSTATUS_HERE) || ItemHasChildren(hItem))
00314                         *pResult = TRUE;
00315                 else
00316                         *pResult = FALSE;
00317         }
00318 
00319 }
00320 
00321 void CRegistryTree::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
00322 {
00323         // TODO: Add your message handler code here and/or call default
00324         if (nChar == VK_DELETE) {
00325                 HTREEITEM hItem = GetSelectedItem();
00326                 if (hItem) {
00327                         m_cntxSelected = hItem;
00328                         SendMessage(WM_COMMAND, ID_CNTX_REMOVETREE);
00329                 }
00330         }
00331     if (nChar == VK_F2) {
00332         HTREEITEM hItem = GetSelectedItem();
00333         if (hItem) {
00334             m_cntxSelected = hItem;
00335             SendMessage(WM_COMMAND, ID_CNTX_RENAMENODE);
00336         }
00337     }
00338     CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
00339 }