本文将给出一个源程序,实现在一个对话框中的TreeCtrl中用树的形式枚举窗口。
这是头文件
// WinList.h : header file //
/////////////////////////////////////////////////////////////////////////////
// CWinList dialog
class CWinList : public CDialog { // Construction public: HWND m_hSelected; CWinList(CWnd* pParent = NULL); // standard constructor static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam); static BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam); void BuiltTree(HWND hWnd);
// Dialog Data //{{AFX_DATA(CWinList) enum { IDD = ID_WINLIST }; CTreeCtrl m_Tree; //}}AFX_DATA
// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CWinList) public: virtual BOOL DestroyWindow(); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL
// Implementation protected: void DrawFlash(HWND hWnd); void Refresh();
// Generated message map functions //{{AFX_MSG(CWinList) virtual BOOL OnInitDialog(); afx_msg void OnRefresh(); afx_msg void OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: CFont TreeFont; TV_INSERTSTRUCT TreeItem; int RootPt; HTREEITEM RootArray[10]; };
下面是实现文件
// WinList.cpp : implementation file //
#include "stdafx.h" #include "mfc.h" #include "WinList.h" #include "mfcApi.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
/////////////////////////////////////////////////////////////////////////////
// CWinList dialog
CWinList::CWinList(CWnd* pParent /*=NULL*/) : CDialog(CWinList::IDD, pParent) { //{{AFX_DATA_INIT(CWinList) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT }
void CWinList::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CWinList) DDX_Control(pDX, IDTREE, m_Tree); //}}AFX_DATA_MAP }
BEGIN_MESSAGE_MAP(CWinList, CDialog) //{{AFX_MSG_MAP(CWinList) ON_BN_CLICKED(IDREFRESH, OnRefresh) ON_NOTIFY(TVN_SELCHANGED, IDTREE, OnSelchangedTree) //}}AFX_MSG_MAP END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWinList message handlers
static CDWordArray WinArray; static unsigned long Level; static int Ignore[10]; static HWND hPrevWnd;
BOOL CALLBACK CWinList::EnumChildProc(HWND hwnd,LPARAM lParam) { Ignore[Level]++; if (Ignore[Level+1]) Ignore[Level+1]--; else { WinArray.Add((unsigned long)((Level<<16)|(unsigned long)hwnd)); Level++;Ignore[Level+1]=0; EnumChildWindows(hwnd,EnumChildProc,(long)0); Level--; }
return TRUE; }
BOOL CALLBACK CWinList::EnumWindowsProc(HWND hwnd, LPARAM lParam) { WinArray.Add((unsigned long)hwnd); Level=1;Ignore[Level+1]=0; EnumChildWindows(hwnd,EnumChildProc,(long)0); return TRUE; }
void CWinList::BuiltTree(HWND hWnd) { char Temp[90]; char Text[50]; char Name[20];
TreeItem.hParent=RootArray[RootPt];
::GetWindowText(hWnd,Text,50); ::GetClassName(hWnd,Name,20); sprintf(Temp,"[%04x]:{%s}:%s",hWnd,Name,Text); TreeItem.item.pszText=Temp; TreeItem.item.lParam=(unsigned long)hWnd; HTREEITEM TempItem=m_Tree.InsertItem(&TreeItem); RootArray[RootPt+1]=TempItem; }
void CWinList::DrawFlash(HWND hWnd) { HDC hDC; RECT rc; HPEN hPen;
::GetWindowRect(hWnd, &rc); hDC=::GetWindowDC(hWnd); ::SetROP2(hDC,R2_NOT);
hPen=::CreatePen(PS_INSIDEFRAME,5*GetSystemMetrics(SM_CXBORDER),RGB(255,0,0)) ; ::SelectObject(hDC,hPen); ::SelectObject(hDC,GetStockObject(NULL_BRUSH)); ::Rectangle(hDC,0,0,rc.right-rc.left,rc.bottom-rc.top); ::ReleaseDC(hWnd,hDC); ::DeleteObject(hPen); }
void CWinList::Refresh() { RootArray[0]=TVI_ROOT; RootPt=0;
TreeItem.hInsertAfter=TVI_LAST; TreeItem.item.mask=TVIF_TEXT|TVIF_PARAM; WinArray.RemoveAll(); m_Tree.SetFont(&TreeFont); m_Tree.DeleteAllItems(); Level=0; for(int j=0;j<10;j++) Ignore[j]=0; EnumWindows(EnumWindowsProc,(long)0);
for(int i=0;i/td> { RootPt=(int)((WinArray[i]&0xFFFF0000)>>16); BuiltTree((HWND)(WinArray[i]&0x0000FFFF)); } }
BOOL CWinList::OnInitDialog() { CDialog::OnInitDialog();
// TODO: Add extra initialization here m_hSelected=NULL; hPrevWnd=NULL; Refresh(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }
void CWinList::OnRefresh() { // TODO: Add your control notification handler code here Refresh(); }
void CWinList::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here
HWND hWnd=(HWND)pNMTreeView->itemNew.lParam; m_hSelected=hWnd; if (hPrevWnd) DrawFlash(hPrevWnd); hPrevWnd=hWnd; DrawFlash(hWnd);
*pResult = 0; }
BOOL CWinList::DestroyWindow() { // TODO: Add your specialized code here and/or call the base class if (hPrevWnd) DrawFlash(hPrevWnd); return CDialog::DestroyWindow(); }
/////////////////////////////////////////////////////////////////////////////
// DLL Export Interface
extern "C" HWND FAR PASCAL EXPORT SearchWindow() { CWinList WinList; if (WinList.DoModal()==IDOK) return WinList.m_hSelected; else return (HWND)NULL; } |
|