Click here to Skip to main content
15,886,033 members
Articles / Desktop Programming / MFC

ShowWindowTree Utility

Rate me:
Please Sign up or sign in to vote.
2.77/5 (10 votes)
19 Jan 20021 min read 57.5K   804   21  
Display the hierarchy of windows (hidden or not) on your system along with a few options to modifiy them
// ShowWindowTreeDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ShowWindowTree.h"
#include "ShowWindowTreeDlg.h"
#include "sizer.h"

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

/////////////////////////////////////////////////////////////////////////////
// CShowWindowTreeDlg dialog

CShowWindowTreeDlg::CShowWindowTreeDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CShowWindowTreeDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CShowWindowTreeDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CShowWindowTreeDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CShowWindowTreeDlg)
	DDX_Control(pDX, IDC_BUILDFROM, m_BuildFrom);
	DDX_Control(pDX, IDC_TREE, m_Tree);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CShowWindowTreeDlg, CDialog)
	//{{AFX_MSG_MAP(CShowWindowTreeDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_SCAN, OnScan)
	ON_BN_CLICKED(IDC_SAVEIT, OnSaveit)
	ON_BN_CLICKED(IDC_LOAD, OnLoad)
	ON_NOTIFY(NM_RCLICK, IDC_TREE, OnRclickTree)
	//}}AFX_MSG_MAP
	ON_COMMAND_RANGE(IDM_SHOWWINDOWTOGGLE,IDM_ENABLEWINDOWTOGGLE,OnTreeMenu )
	ON_WM_SIZE()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CShowWindowTreeDlg message handlers


BOOL CShowWindowTreeDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	MyList.Create(IDB_SIGNALS,12,0,RGB(255,255,255));
	m_Tree.SetImageList(&MyList,TVSIL_NORMAL);
	m_ValidHwnds=FALSE;	
	return TRUE;  
}

void CShowWindowTreeDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CShowWindowTreeDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

CString GetOurClassString(HWND hWnd)
{
	CString s;
	char *buf;

	buf=s.GetBuffer(256);
	GetClassName(hWnd,buf,255);
	s.ReleaseBuffer();
	return(s);
}

CString GetOurWindowString(HWND hWnd)
{
	CString s;
	char *buf;

	buf=s.GetBuffer(256);
	GetWindowText(hWnd,buf,255);
	s.ReleaseBuffer();
	return(s);
}

void CShowWindowTreeDlg::OnScan() 
{
	CString cszFrom;
	HWND hWnd;

	// TODO: Add your control notification handler code here
	m_BuildFrom.GetWindowText((CString&)cszFrom);
	hWnd=NULL;
	if(cszFrom!="")
	{
		hWnd=::FindWindow(NULL,cszFrom);
		if(hWnd==NULL)
		{
		 	AfxMessageBox("No Window Starting Window Found",MB_OK);
			return;
		}
	} else hWnd=::GetDesktopWindow();
	hWnd=::GetWindow(hWnd,GW_CHILD);
	m_Tree.DeleteAllItems();

	TV_INSERTSTRUCT TreeCtrlItem;

	TreeCtrlItem.hParent = TVI_ROOT;
	TreeCtrlItem.hInsertAfter = TVI_LAST;
	TreeCtrlItem.item.mask = TVIF_TEXT | TVIF_PARAM;
	TreeCtrlItem.item.pszText = "Desktop";
	TreeCtrlItem.item.lParam = NULL;
	HTREEITEM hNewNode = m_Tree.InsertItem(&TreeCtrlItem);
	ScanWindow(hWnd,hNewNode);
	m_Tree.Expand(hNewNode,TVE_EXPAND); 
	m_ValidHwnds=TRUE;
}

void CShowWindowTreeDlg::ScanWindow(HWND hStart,HTREEITEM htiCurrentNode)
{
	HWND hWnd,hWnd1;
	CString cszClassString;
	CString cszWindowString;
	CString cszTemp;

	TV_INSERTSTRUCT TreeCtrlItem;

	hWnd=hStart;
	while(hWnd!=NULL)
	{
		char buf[256];
		::SendMessage(hWnd,WM_GETTEXT,250,(LPARAM) buf);
		cszWindowString=GetOurWindowString(hWnd);
		cszClassString=GetOurClassString(hWnd);
		cszTemp.Format("\"%s\"  \"%s\"",
			(LPCTSTR) cszClassString,buf);//(LPCTSTR) cszWindowString);

		TreeCtrlItem.hParent = htiCurrentNode;
		TreeCtrlItem.hInsertAfter = TVI_LAST;
		TreeCtrlItem.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
		TreeCtrlItem.item.iImage = ::IsWindowVisible(hWnd)==TRUE ? 1 : 0;
		TreeCtrlItem.item.iSelectedImage = TreeCtrlItem.item.iImage;
		TreeCtrlItem.item.pszText = (LPSTR) (LPCSTR) cszTemp;
		TreeCtrlItem.item.lParam = (LPARAM) hWnd;
		HTREEITEM htiNewNode = m_Tree.InsertItem(&TreeCtrlItem);

		// Do Next Window
		if((hWnd1=::GetWindow(hWnd,GW_CHILD))!=NULL) 
			ScanWindow(hWnd1,htiNewNode);
		hWnd=::GetWindow(hWnd,GW_HWNDNEXT);		// Get Next Window
	}
	return;
}

void CShowWindowTreeDlg::SaveBranch(HTREEITEM h,CFile& f,CTreeCtrl& m_Tree)
{
	do
	{
		// Output node
		CString cszText=m_Tree.GetItemText(h);
		int i,s;
		m_Tree.GetItemImage(h,i,s);
		BOOL Child=m_Tree.ItemHasChildren(h);
		f.Write(Child ? "C" : "N",1);	// Node or Child marker
		f.Write(!i ? "H" : " ",1);		// Hidden flag
		long len=cszText.GetLength();
		f.Write(&len,sizeof(long));
		f.Write((LPCSTR) cszText,len);
		if(Child) SaveBranch(m_Tree.GetChildItem(h),f,m_Tree); // Write Out children
	} while((h=m_Tree.GetNextSiblingItem(h))!=NULL);
	f.Write("*",1);				// Write out end of node marker
}

void CShowWindowTreeDlg::LoadBranch(HTREEITEM h,CFile& f,CTreeCtrl& m_Tree)
{
	TV_INSERTSTRUCT TreeCtrlItem;

	while(1)
	{
		long len;
		char letter;
		char hidden;
		char buf[4096];

		f.Read(&letter,1);
		if(letter=='*') break;

		f.Read(&hidden,1);

		f.Read(&len,sizeof(long));
		f.Read(buf,len);
		buf[len]=0;

		TreeCtrlItem.hParent = h;
		TreeCtrlItem.hInsertAfter = TVI_LAST;
		TreeCtrlItem.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
		TreeCtrlItem.item.iImage = hidden=='H' ? 0 : 1;
		TreeCtrlItem.item.iSelectedImage = TreeCtrlItem.item.iImage;
		TreeCtrlItem.item.pszText = buf;
		HTREEITEM hNewNode = m_Tree.InsertItem(&TreeCtrlItem);

		// If child then do children
		if(letter=='C') LoadBranch(hNewNode,f,m_Tree);
	}
	return;
}

void CShowWindowTreeDlg::OnSaveit() 
{
	// construct CString for filter
	CString cszFilter("RJD Files (*.RJD)|*.rjd||");

	// constructs an object of CFileDialog
	CFileDialog filedlg(FALSE,"rjd","WinData.rjd",OFN_EXPLORER | OFN_SHAREAWARE |
		OFN_NONETWORKBUTTON | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_ENABLESIZING,cszFilter);

	// displays file dialog box
	if(filedlg.DoModal()!=IDOK) return;

	POSITION pos;
	if((pos=filedlg.GetStartPosition())==NULL) return;
	
	CString cszFilename=filedlg.GetNextPathName(pos);

	CFile f;

	f.Open(cszFilename,CFile::modeCreate|CFile::modeWrite|CFile::shareDenyNone);

	HTREEITEM r=m_Tree.GetRootItem();
	SaveBranch(r,f,m_Tree);
	f.Close();
}

void CShowWindowTreeDlg::OnLoad() 
{
	// construct CString for filter
	CString cszFilter("RJD Files (*.RJD)|*.rjd||");

	// constructs an object of CFileDialog
	CFileDialog filedlg(TRUE,"rjd",NULL,
		OFN_EXPLORER | OFN_SHAREAWARE | OFN_FILEMUSTEXIST | OFN_ENABLESIZING |
		OFN_NONETWORKBUTTON | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,cszFilter);

	// displays file dialog box
	if(filedlg.DoModal()!=IDOK) return;

	POSITION pos;
	if((pos=filedlg.GetStartPosition())==NULL) return;
	
	CString cszFilename=filedlg.GetNextPathName(pos);

	CFile f;

	m_ValidHwnds=FALSE;
	f.Open(cszFilename,CFile::modeRead|CFile::shareDenyNone);
	m_Tree.DeleteAllItems();

	HTREEITEM r=m_Tree.GetRootItem();
	LoadBranch(TVI_ROOT,f,m_Tree);
	f.Close();
	m_Tree.Expand(m_Tree.GetRootItem(),TVE_EXPAND); 
}


void CShowWindowTreeDlg::OnRclickTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	CPoint pt(GetMessagePos());
	
	CMenu menu;
	VERIFY(menu.LoadMenu(IDR_TREEMENU));

	CMenu* pPopup = menu.GetSubMenu(1);		// RIGHT BUTTON
	ASSERT(pPopup != NULL);

	CWnd* pWndPopupOwner = this;
	while(pWndPopupOwner->GetStyle() & WS_CHILD)
		pWndPopupOwner=pWndPopupOwner->GetParent();
	pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x,pt.y,
		pWndPopupOwner,NULL);
	*pResult = 0;
}

void CShowWindowTreeDlg::OnTreeMenu(UINT nID)
{
	switch(nID)
	{
		case IDM_SHOWWINDOWTOGGLE :
			if(m_ValidHwnds)
			{
				HTREEITEM hti=m_Tree.GetSelectedItem();
				HWND hWnd=(HWND) m_Tree.GetItemData(hti);
				if(!::IsWindow(hWnd)) break;
				if(::IsWindowVisible(hWnd))
				{
					::ShowWindow(hWnd,SW_HIDE);
					m_Tree.SetItemImage(hti,0,0);
				}
				else
				{
					::ShowWindow(hWnd,SW_SHOW);
					m_Tree.SetItemImage(hti,1,1);
				}
			}
			break;


		case IDM_ENABLEWINDOWTOGGLE :
			if(m_ValidHwnds)
			{
				HTREEITEM hti=m_Tree.GetSelectedItem();
				HWND hWnd=(HWND) m_Tree.GetItemData(hti);
				if(!::IsWindow(hWnd)) break;
				if(::IsWindowEnabled(hWnd))
				{
					::EnableWindow(hWnd,FALSE);
				}
				else
				{
					::EnableWindow(hWnd,TRUE);
				}
			}
			break;


		case IDM_COPYTOCLIPBOARD : 
			{
				if(!OpenClipboard()) break;
				if(!EmptyClipboard()) break;
				HTREEITEM hti=m_Tree.GetSelectedItem();
				CString ws=m_Tree.GetItemText(hti);
				HANDLE mem=GlobalAlloc(GMEM_DDESHARE,ws.GetLength()+2);
				ASSERT(mem!=NULL);
				char *s=(char *) GlobalLock(mem);
				ASSERT(s!=NULL);
				memcpy(s,ws,ws.GetLength()+1);
				GlobalUnlock(mem);
				SetClipboardData(CF_TEXT,mem);
				CloseClipboard();
			}
			break;

		case IDM_SIZER :
			if(m_ValidHwnds)
			{
				HTREEITEM hti=m_Tree.GetSelectedItem();
				HWND hWnd=(HWND) m_Tree.GetItemData(hti);
				if(!::IsWindow(hWnd)) break;
				Sizer dlg;
				::GetWindowRect(hWnd,&dlg.m_Rect);
				if(dlg.DoModal()==IDOK)
				{
					CPoint pt=dlg.m_Rect.TopLeft();
					::ScreenToClient(::GetParent(hWnd),&pt);
					::SetWindowPos(hWnd,NULL,
						pt.x,pt.y,
//						dlg.m_cx-dlg.m_x,dlg.m_cy-dlg.m_y,
						dlg.m_Rect.Width(),dlg.m_Rect.Height(),
						SWP_NOACTIVATE|SWP_NOZORDER);
				}
			}
			break;
	}
}

void CShowWindowTreeDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);
	CRect r;
	if(m_Tree.m_hWnd!=NULL)
	{
		m_Tree.GetWindowRect(&r);
		ScreenToClient(&r);
		m_Tree.MoveWindow(r.left,r.top,cx-r.left,cy-r.top);	
	}
}

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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
President
United States United States
Computer geek since the beginning of time, well, at least since 1981. Started with the Commodore VIC-20 with 3.5K RAM. Past two decades spent with C/C++, MFC and now totally consumed with .NET and C#.

Business owner here in beautiful southern Oregon with mountains, clean air and pure water. Great outdoors to enjoy when I can get away from the computers.

Web sites of interest:

HintsAndTips.com
TheAwakening.com
My Blog: www.ReflectedThought.com
www.SilverlightCity.com
www.TheSaintsInLight.com
www.TheSilverlightDirectory.com
www.TheWPFDirectory.com

Comments and Discussions