Click here to Skip to main content
15,885,213 members
Articles / Desktop Programming / MFC

Import/Export Registry Sections as XML

Rate me:
Please Sign up or sign in to vote.
4.33/5 (16 votes)
21 Jan 20033 min read 166K   6.1K   73  
Export registry sections as XML to simplify registry diffs
This article details a tool aimed to import/export registry sections in XML format, to make registry diff easier in practice.
#include "stdafx.h"
#include "MainFrame.h"
#include "registryxml.h"
#include "registryxmlDoc.h"

#include "registryxmlTree.h"
#include "baseTypes.h"



#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



/////////////////////////////////////////////////////////////////////////////
// registryxmlTree

IMPLEMENT_DYNCREATE(registryxmlTree, CTreeView)

BEGIN_MESSAGE_MAP(registryxmlTree, CTreeView)
	//{{AFX_MSG_MAP(registryxmlTree)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		ON_WM_CREATE()
		ON_WM_DESTROY()
		ON_NOTIFY_REFLECT(TVN_SELCHANGED,		OnSelChanged)
		ON_NOTIFY_REFLECT(NM_RCLICK,			OnRightClick)
		ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING,	OnExpand)

		ON_COMMAND(ID_EDIT_REFRESH, OnRefresh)

		ON_COMMAND(ID_EXPORTASXML, OnSaveAsXml)
		ON_COMMAND(ID_EXPORTASFAKEDXML, OnSaveAsFakedXml)
		ON_COMMAND(ID_IMPORTFROMXML, OnLoadXml)

		ON_WM_LBUTTONDOWN()
		ON_WM_KEYDOWN()

		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CTreeView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CTreeView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CTreeView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// registryxmlTree construction/destruction

registryxmlTree::registryxmlTree()
{
	// TODO: add construction code here
}

registryxmlTree::~registryxmlTree()
{
}

BOOL registryxmlTree::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	if (!CTreeView::PreCreateWindow(cs)) return FALSE;

	cs.style |= TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS;
	
	return TRUE;
}

int registryxmlTree::OnCreate(LPCREATESTRUCT lpcs)
{
	if (CTreeView::OnCreate(lpcs)==-1) return -1;


	CBitmap my_bitmap;
	my_bitmap.LoadBitmap(IDB_IMAGELIST);

	m_imglDrives.Create(16,16,ILC_COLOR24|ILC_MASK,30,10);
	m_imglDrives.Add(&my_bitmap,RGB(255,0,255));
	GetTreeCtrl().SetImageList(&m_imglDrives,TVSIL_NORMAL);

	m_hItemBOOL = FALSE;

	return 0;
}


void registryxmlTree::OnDestroy()
{
}




/////////////////////////////////////////////////////////////////////////////
//
//
// registryxmlTree populating
//
//


void registryxmlTree::OnInitialUpdate()
{
	CTreeView::OnInitialUpdate();

	Refresh();

}


afx_msg void registryxmlTree::OnRefresh()
{
	Refresh();
}

void registryxmlTree::Refresh()
{

	GetTreeCtrl().DeleteAllItems();

	// add nodes
	HTREEITEM hRoot = GetTreeCtrl().InsertItem( "My Computer", 
									ILI_DEFAULT, 
									ILI_DEFAULT,
									TVI_ROOT,
									TVI_LAST); 


	HTREEITEM h1 = GetTreeCtrl().InsertItem("HKEY_CLASSES_ROOT", ILI_FOLDER, ILI_FOLDERS, hRoot, TVI_LAST);
	GetTreeCtrl().InsertItem(FAKEDITEM, ILI_DEFAULT, ILI_DEFAULT, h1, TVI_LAST);
	HTREEITEM h2 = GetTreeCtrl().InsertItem("HKEY_CURRENT_USER", ILI_FOLDER, ILI_FOLDERS, hRoot, TVI_LAST);
	GetTreeCtrl().InsertItem(FAKEDITEM, ILI_DEFAULT, ILI_DEFAULT, h2, TVI_LAST);
	HTREEITEM h3 = GetTreeCtrl().InsertItem("HKEY_LOCAL_MACHINE", ILI_FOLDER, ILI_FOLDERS, hRoot, TVI_LAST);
	GetTreeCtrl().InsertItem(FAKEDITEM, ILI_DEFAULT, ILI_DEFAULT, h3, TVI_LAST);
	HTREEITEM h4 = GetTreeCtrl().InsertItem("HKEY_USERS", ILI_FOLDER, ILI_FOLDERS, hRoot, TVI_LAST);
	GetTreeCtrl().InsertItem(FAKEDITEM, ILI_DEFAULT, ILI_DEFAULT, h4, TVI_LAST);
	HTREEITEM h5 = GetTreeCtrl().InsertItem("HKEY_CURRENT_CONFIG", ILI_FOLDER, ILI_FOLDERS, hRoot, TVI_LAST);
	GetTreeCtrl().InsertItem(FAKEDITEM, ILI_DEFAULT, ILI_DEFAULT, h5, TVI_LAST);

	m_hItemFirstSel = NULL;	
	m_bCtrlClick = FALSE;
	m_hItemBOOL = FALSE;
}


/////////////////////////////////////////////////////////////////////////////
//
//
// registryxmlTree drawing
//
//


void registryxmlTree::OnDraw(CDC* pDC)
{
	registryxmlDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}


















BOOL registryxmlTree::IsExpanded(HTREEITEM hItem)
{
	BOOL bResult = FALSE;

	TVITEM dragItem;
	dragItem.mask=TVIF_HANDLE | TVIF_STATE;
	dragItem.hItem=hItem;
	dragItem.pszText=NULL;
	if (GetTreeCtrl().GetItem(&dragItem))
		bResult=dragItem.state & TVIS_EXPANDED;

	return bResult;
}













/////////////////////////////////////////////////////////////////////////////
//
//
// registryxmlTree message handlers
//
//
//
//


void registryxmlTree::OnSelChanged(NMHDR *pnmh,LRESULT *pResult)
{
	NM_TREEVIEW *pnmtv=(NM_TREEVIEW *)pnmh;

	CString strPath=GetPathFromNode (pnmtv->itemNew.hItem);
	((CMainFrame*)AfxGetMainWnd())->SetMessageText(strPath);

	OnSelectionChanged(strPath);
}


void registryxmlTree::OnSelectionChanged(CString &strPath)
{
	// red�finir cette fonction dans une classe d�riv�e, afin de
	// r�pondre diff�remment aux changements de s�lection.
	// Ici, UpdateAllViews sert � mettre � jour le compagnon CListView

	GetDocument()->UpdateAllViews(this,(LPARAM) strPath.GetBuffer(0) );
}


// Function name	: registryxmlTree::OnRightClick
// Description	    : NOTIFY clic droit souris : menu contextuel selon type d'item
// Return type		: void 
// Argument         : NMHDR *pnmh
// Argument         : LRESULT *pResult = FALSE  si cela s'est bien pass�
void registryxmlTree::OnRightClick(NMHDR * pNotifyStruct, LRESULT* pResult)
{
	// r�cup�re la souris et met en coordonn�es locales au TreeView
	DWORD dwPos=::GetMessagePos();
	CPoint point ( (int)LOWORD(dwPos),(int)HIWORD(dwPos));
	GetTreeCtrl().ScreenToClient(&point);

	// v�rifie qu'on a cliqu� sur un Item du TreeView
	UINT nFlags;
	m_hItem=FALSE; // m_hItem non significatif a priori
	m_hItem=GetTreeCtrl().HitTest(point,&nFlags);
	if ( nFlags == TVHT_NOWHERE) return;
		
	m_hItemBOOL=TRUE;

	// r�cup�re le coin sup�rieur gauche de mon TreeView
	CRect rect;
	this->GetWindowRect(&rect);
	
	// balance un des menus (variable d�truite quand on sort de la fonction)
	CMenu menu;

	if ( menu.LoadMenu ( IDM_TREEITEM ) )
	{
		CMenu *pContextMenu=menu.GetSubMenu(0);
		if (pContextMenu != NULL)	pContextMenu->TrackPopupMenu(
			TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, point.x+rect.left, point.y+rect.top, this);
	}

	*pResult=FALSE;
}



void registryxmlTree::OnExpand(NMHDR *pnmh,LRESULT *pResult)
{
		NM_TREEVIEW *pnmtv=(NM_TREEVIEW *)pnmh;

	UINT action = pnmtv->action;

	int nExpand = TVE_EXPAND;
	int nCollapse = TVE_COLLAPSE;

	HTREEITEM hItem = pnmtv->itemNew.hItem;

	if (action==TVE_EXPAND) // is being expanded
	{
		HTREEITEM hChildItem = GetTreeCtrl().GetChildItem(hItem);
		if (hChildItem)
		{
			CString szChildName = GetTreeCtrl().GetItemText(hChildItem);
			if ( szChildName.CompareNoCase(FAKEDITEM)==0  ) // there is 
			{
				// remove this child
				GetTreeCtrl().DeleteItem(hChildItem);
				
				if (hItem && GetTreeCtrl().GetParentItem(hItem))
				{
					LockWindowUpdate(); // CWnd member

					SetCursor(LoadCursor(NULL, IDC_WAIT)); // hourglass

					CString szPath = GetPathFromNode(hItem);
					AddChildren(GetTreeCtrl(), hItem, szPath);

					SetCursor(LoadCursor (NULL, IDC_ARROW)); // back to normal cursor

					((CMainFrame*)AfxGetMainWnd())->SetMessageText(szPath);

					UnlockWindowUpdate();  // CWnd member
				}

				
			}
		}
	}
}









CString registryxmlTree::GetPathFromNode(HTREEITEM hItem)
{
	CString szPath;
	
	// build path from item name
	//
	if (hItem==NULL || GetTreeCtrl().GetParentItem(hItem)==NULL) return szPath;

	CString szLastKeyname;
	HTREEITEM hCurItem = hItem;
	HTREEITEM hNextItem;

	while ( (hNextItem=GetTreeCtrl().GetParentItem(hCurItem)) )
	{
		szLastKeyname = GetTreeCtrl().GetItemText(hCurItem);
		if (!szLastKeyname.IsEmpty())
		{
			if (!szPath.IsEmpty())
				szPath = "\\" + szPath;

			szPath = szLastKeyname +  szPath;
		}
		hCurItem = hNextItem;
	} // end while

	return szPath;
}














void registryxmlTree::ClearSelection(HTREEITEM hBaseItem)
{
	// This can be time consuming for very large trees 
	// and is called every time the user does a normal selection
	// If performance is an issue, it may be better to maintain 
	// a list of selected items

	CTreeCtrl *pTC=&GetTreeCtrl();
	if (pTC==NULL) return;

	for ( HTREEITEM hItem=hBaseItem;
			hItem!=NULL; 
			hItem=pTC->GetNextItem( hItem, TVGN_NEXT ) )
	{
			HTREEITEM hChildItem=pTC->GetChildItem(hItem);
			if (hChildItem != NULL)
				ClearSelection(hChildItem);

			if ( pTC->GetItemState( hItem, TVIS_SELECTED ) & TVIS_SELECTED )
				pTC->SetItemState( hItem, 0, TVIS_SELECTED );
	}
}




// SelectItems	- Selects items from hItemFrom to hItemTo. Does not
//		- select child item if parent is collapsed. Removes
//		- selection from all other items// hItemFrom	- item to start selecting from
// hItemTo	- item to end selection at.
BOOL registryxmlTree::SelectItems(HTREEITEM hItemFrom, HTREEITEM hItemTo)
{
	HTREEITEM hItem = GetTreeCtrl().GetRootItem();	// Clear selection upto the first item
	while ( hItem && hItem!=hItemFrom && hItem!=hItemTo )	
	{
		hItem = GetTreeCtrl().GetNextVisibleItem( hItem );		
		GetTreeCtrl().SetItemState( hItem, 0, TVIS_SELECTED );
	}	
	
	if ( !hItem )		
		return FALSE;	// Item is not visible	
	
	GetTreeCtrl().SelectItem( hItemTo );
	
	// Rearrange hItemFrom and hItemTo so that hItemFirst is at top
	if( hItem == hItemTo )	
	{		
		hItemTo = hItemFrom;		
		hItemFrom = hItem;	
	}
	
	// Go through remaining visible items	
	BOOL bSelect = TRUE;	
	
	while ( hItem )	
	{
		// Select or remove selection depending on whether item
		// is still within the range.
		GetTreeCtrl().SetItemState( hItem, bSelect ? TVIS_SELECTED : 0, TVIS_SELECTED );
		// Do we need to start removing items from selection		
		if( hItem == hItemTo ) 
			bSelect = FALSE;		
		
		hItem = GetTreeCtrl().GetNextVisibleItem( hItem );	
	}	
	
	return TRUE;
}



HTREEITEM registryxmlTree::GetFirstSelectedItem()
{
	return GetFirstSelectedItem( GetTreeCtrl().GetRootItem() );
}


HTREEITEM registryxmlTree::GetFirstSelectedItem( HTREEITEM hBaseItem )
{
	CTreeCtrl *pTC=&GetTreeCtrl();

	for ( HTREEITEM hItem=hBaseItem;
			hItem!=NULL; 
			hItem=pTC->GetNextItem( hItem, TVGN_NEXT ) )
	{
			if ( pTC->GetItemState( hItem, TVIS_SELECTED ) & TVIS_SELECTED )
				return hItem;

			HTREEITEM hChildItem=pTC->GetChildItem(hItem);
			if (hChildItem != NULL)
			{
				HTREEITEM hResultItem = GetFirstSelectedItem(hChildItem);
				if (hResultItem) return hResultItem;
			}
	}

	return NULL;
}

HTREEITEM registryxmlTree::GetNextSelectedItem( HTREEITEM hItem )
{
	if (!hItem) return NULL;

	HTREEITEM hChildItem=GetTreeCtrl().GetChildItem(hItem);
	if (hChildItem != NULL)
	{
		HTREEITEM hResultItem = GetFirstSelectedItem(hChildItem);
		if (hResultItem) return hResultItem;
	}
	

	while (1)
	{
		HTREEITEM hNextItem = GetTreeCtrl().GetNextItem( hItem, TVGN_NEXT );

		if (hNextItem) 
		{
			hItem = hNextItem;
			hNextItem = GetFirstSelectedItem(hItem);
			if (hNextItem) return hNextItem; // found
		}
		else
		{
			hItem = GetTreeCtrl().GetParentItem(hItem);
			if (!hItem) return NULL;
		}

	} // end while

	return NULL;
}



int registryxmlTree::GetSelectedCount(HTREEITEM hBaseItem)
{
	long nCount=0;

	CTreeCtrl *pTC=&GetTreeCtrl();
	if (pTC==NULL) return nCount;

	for ( HTREEITEM hItem=hBaseItem;
			hItem!=NULL; 
			hItem=pTC->GetNextItem( hItem, TVGN_NEXT ) )
	{
			HTREEITEM hChildItem=pTC->GetChildItem(hItem);
			if (hChildItem != NULL)
				nCount+=GetSelectedCount(hChildItem);

			if ( pTC->GetItemState( hItem, TVIS_SELECTED ) & TVIS_SELECTED )
				nCount++;
	}

	return nCount;
}




// Function name	: registryxmlTree::OnKeyDown
// Description	    :  r�cup�ration du clavier
// Return type		: void 
// Argument         :  UINT nChar
// Argument         : UINT nRepCnt
// Argument         : UINT nFlags
void registryxmlTree::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags)
{

	if ( (nChar==VK_UP || nChar==VK_DOWN) )	
	{
		if (GetKeyState( VK_SHIFT )&0x8000)
		{
			// Initialize the reference item if this is the first shift selection
			if( !m_hItemFirstSel )		
			{			
				m_hItemFirstSel = GetTreeCtrl().GetSelectedItem();
				ClearSelection(GetTreeCtrl().GetRootItem());		
			}		// Find which item is currently selected
			HTREEITEM hItemPrevSel = GetTreeCtrl().GetSelectedItem();		
			HTREEITEM hItemNext;
			if ( nChar==VK_UP )			
				hItemNext = GetTreeCtrl().GetPrevVisibleItem( hItemPrevSel );		
			else
				hItemNext = GetTreeCtrl().GetNextVisibleItem( hItemPrevSel );		
			
			if ( hItemNext )		
			{
				// Determine if we need to reselect previously selected item
				BOOL bReselect = 
					!( GetTreeCtrl().GetItemState( hItemNext, TVIS_SELECTED ) & TVIS_SELECTED );
				// Select the next item - this will also deselect the previous item
				GetTreeCtrl().SelectItem( hItemNext );			// Reselect the previously selected item
				if ( bReselect )
					GetTreeCtrl().SetItemState( hItemPrevSel, TVIS_SELECTED, TVIS_SELECTED );		
			}		
		}
		else // simple VK_DOWN VK_UP
		{
			m_hItem=GetTreeCtrl().GetSelectedItem();
			if(m_hItemFirstSel != NULL || m_bCtrlClick)		
			{			
				ClearSelection(GetTreeCtrl().GetRootItem());		
				GetTreeCtrl().SelectItem(m_hItem);
				m_hItemFirstSel=NULL;
				m_bCtrlClick=FALSE;
			}
			CTreeView::OnKeyDown(nChar, nRepCnt, nFlags);
		}
	}
	else CTreeView::OnKeyDown(nChar, nRepCnt, nFlags);
}









void registryxmlTree::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// Set focus to control if key strokes are needed.
	// Focus is not automatically given to control on lbuttondown
	
	if(nFlags & MK_CONTROL ) 	
	{
		// Control key is down		
		UINT flag;		
		HTREEITEM hItem = GetTreeCtrl().HitTest( point, &flag );
		if( hItem )		
		{			
			// Toggle selection state			
			UINT uNewSelState = 
				GetTreeCtrl().GetItemState(hItem, TVIS_SELECTED) & TVIS_SELECTED ? 0 : TVIS_SELECTED;            
			// Get old selected (focus) item and state
			HTREEITEM hItemOld = GetTreeCtrl().GetSelectedItem();			
			
			UINT uOldSelState  = hItemOld ? GetTreeCtrl().GetItemState(hItemOld, TVIS_SELECTED) : 0;            			
			
			// Select new item
			if( GetTreeCtrl().GetSelectedItem() == hItem )
				GetTreeCtrl().SelectItem( NULL );		// to prevent edit

			CTreeView::OnLButtonDown(nFlags, point);

			// Set proper selection (highlight) state for new item
			GetTreeCtrl().SetItemState(hItem, uNewSelState,  TVIS_SELECTED);
			// Restore state of old selected item			
			if (hItemOld && hItemOld != hItem)
				GetTreeCtrl().SetItemState(hItemOld, uOldSelState, TVIS_SELECTED);

			m_hItemFirstSel = NULL;			

			m_bCtrlClick=TRUE;
			
			return;		
		}	
	} 	
	else if(nFlags & MK_SHIFT)	
	{
		m_bCtrlClick=FALSE;

		// Shift key is down		
		UINT flag;		
		HTREEITEM hItem = GetTreeCtrl().HitTest( point, &flag );
		// Initialize the reference item if this is the first shift selection
		if( !m_hItemFirstSel )			
			m_hItemFirstSel = GetTreeCtrl().GetSelectedItem();
		// Select new item		
		if( GetTreeCtrl().GetSelectedItem() == hItem )
			GetTreeCtrl().SelectItem( NULL );			// to prevent edit
		
		CTreeView::OnLButtonDown(nFlags, point);		

		if( m_hItemFirstSel )		
		{
			SelectItems( m_hItemFirstSel, hItem );			
			return;		
		}	
	}	
	else	
	{
		// Normal - remove all selection and let default handler do the rest
		if (m_hItemFirstSel!=NULL   || m_bCtrlClick) 
		{
			ClearSelection(GetTreeCtrl().GetRootItem());		
			TRACE ("Clear selection\n");
		}
		m_hItemFirstSel = NULL;	
		m_bCtrlClick = FALSE;
	}

	CTreeView::OnLButtonDown(nFlags, point);
}



/////////////////////////////////////////////////////////////////////////////
//
// registryxmlTree printing
//
//
//


BOOL registryxmlTree::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void registryxmlTree::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void registryxmlTree::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}





/////////////////////////////////////////////////////////////////////////////
//
// registryxmlTree diagnostics
//
//
//


#ifdef _DEBUG
void registryxmlTree::AssertValid() const
{
	CTreeView::AssertValid();
}

void registryxmlTree::Dump(CDumpContext& dc) const
{
	CTreeView::Dump(dc);
}
#endif //_DEBUG

registryxmlDoc* registryxmlTree::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(registryxmlDoc)));
	return (registryxmlDoc*)m_pDocument;
}













///////////////////////////////////////////////////////////////////////////
//
//
//


afx_msg void registryxmlTree::OnSaveAsXml()
{
	OnSaveAsXml(FALSE); // std xml
}

afx_msg void registryxmlTree::OnSaveAsFakedXml()
{
	OnSaveAsXml(TRUE); // faked xml
}

void registryxmlTree::OnSaveAsXml(BOOL bFakedXml)
{

	// default filename
	CString sDefaultFilename;
	if ( GetSelectedCount( GetTreeCtrl().GetRootItem() )==1 )
	{
		if (!m_hItemBOOL) m_hItem = GetTreeCtrl().GetSelectedItem();

		CString szPath = GetPathFromNode(m_hItem);
		int nLastSlash = szPath.ReverseFind('\\');
		if (nLastSlash>-1)
			sDefaultFilename = szPath.Right( szPath.GetLength()-(nLastSlash+1) );
		else
			sDefaultFilename  = szPath;
	}


	CFileDialog my_dialog(FALSE/*SaveAs*/,_T("xml"),
		sDefaultFilename.GetLength()>0 ? sDefaultFilename.GetBuffer(0) : NULL,
		OFN_HIDEREADONLY,
		_T("XML Files (*.xml)|*.xml|All Files (*.*)|*.*||") );

	if (my_dialog.DoModal()!=IDOK) return;


	int nNbSelected = GetSelectedCount( GetTreeCtrl().GetRootItem() );

	HTREEITEM hItem = NULL;

	if (nNbSelected==1)
		hItem = m_hItem;
	else
	{
		hItem = GetFirstSelectedItem();
		if (hItem==NULL) 
		{
			AfxMessageBox(_T("Please select a tree item before"));
			return;
		}
	}


	XmlWriter w;
	w.Open( my_dialog.GetPathName() );


	XmlElement wroot( CString(XML_ROOT) );
	// if we are exporting to the faked xml format, make sure it's not readable as a standard xml
	if (bFakedXml) wroot.SetName( CString(">") + CString(XML_ROOT) );
	wroot.Write(w,1);


	SetCursor(LoadCursor(NULL, IDC_WAIT)); // hourglass cursor

	int nbItemsSelectedToWrite = nNbSelected;

	while ( (nbItemsSelectedToWrite>0) && hItem )
	{
		// write item
		//
		SaveAsXml( w, bFakedXml, GetPathFromNode(hItem) );

		if (nNbSelected!=1)
			hItem = GetNextSelectedItem( hItem );

		nbItemsSelectedToWrite--;
	}

	SetCursor(LoadCursor (NULL, IDC_ARROW)); // back to normal cursor


	wroot.WriteClosingTag(w,-1);

	w.Close();

	// open the resulting xml file (only if it is not faked)
	//
	if (!bFakedXml) 
		::ShellExecute(NULL,
						"open", // default verb
						my_dialog.GetPathName(), // .xml extension (should be handled by MSIE)
						NULL,
						NULL,
						SW_SHOW);


	

}





afx_msg	void registryxmlTree::OnLoadXml()
{

	CFileDialog my_dialog(TRUE/*Load*/,_T("xml"),
		NULL,
		OFN_HIDEREADONLY,
		_T("XML Files (*.xml)|*.xml|All Files (*.*)|*.*||") );

	if (my_dialog.DoModal()!=IDOK) return;

	CString szFilename = my_dialog.GetPathName();

	SetCursor(LoadCursor(NULL, IDC_WAIT)); // hourglass cursor

	XmlReader r;
	LoadAsXml(r, szFilename);

	SetCursor(LoadCursor (NULL, IDC_ARROW)); // back to normal cursor
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
France France
Addicted to reverse engineering. At work, I am developing business intelligence software in a team of smart people (independent software vendor).

Need a fast Excel generation component? Try xlsgen.

Comments and Discussions