本文共 9524 字,大约阅读时间需要 31 分钟。
当前许多应用程序都在使用树型控件时为其添加了背景位图,增强的控件的魅力,然而对于Visual C++编程爱好者来说,使用Visual C++MFC提供的树型控件(CTreeCtrl)本身就是一个难点,至于如何使该控件能够带有背景位图,那就更加是一个令人困惑的问题了。本实例对CTreeCtrl类进行了增强,不仅使它带有背景位图,而且解决了在点击树型控件时背景位图闪动的问题,另外,通过在对话框中使用该控件来显示三级目录,演示了树型控件的基本使用方法。下图为程序编译后的运行效果图:
图一、带背景图的树型控件效果图 |
BOOL CMyTreeCtrl::SetBKImage(LPCTSTR LpszResource)void CMyTreeCtrl::OnPaint() void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) void CMyTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) BOOL CMyTreeCtrl::OnEraseBkgnd(CDC* pDC) |
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED,OnItemexpanded) ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding) |
afx_msg void OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult);afx_msg void OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult); |
/#if !defined(AFX_TREEDLG_H__D82DB384_F574_44A7_96DA_6EC9068E22B1__INCLUDED_)#define AFX_TREEDLG_H__D82DB384_F574_44A7_96DA_6EC9068E22B1__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000/// CTreeDlg dialog#include "MyTreeCtrl.h"class CTreeDlg : public CDialog{ // Construction public: CTreeDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data //{ {AFX_DATA(CTreeDlg) enum { IDD = IDD_TREE_DIALOG }; CMyTreeCtrl m_CtrlTree; //}}AFX_DATA // ClassWizard generated virtual function overrides //{ {AFX_VIRTUAL(CTreeDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; // Generated message map functions //{ {AFX_MSG(CTreeDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); //}}AFX_MSG DECLARE_MESSAGE_MAP()};#endif // MyTreeCtrl.cpp : implementation file#include "StdAfx.h"#include "Tree.h"#include "MyTreeCtrl.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif// CMyTreeCtrlCMyTreeCtrl::CMyTreeCtrl(){}CMyTreeCtrl::~CMyTreeCtrl(){}BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl) //{ {AFX_MSG_MAP(CMyTreeCtrl) ON_WM_PAINT() ON_WM_ERASEBKGND() ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded) ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding) //}}AFX_MSG_MAPEND_MESSAGE_MAP()/// CMyTreeCtrl message handlersBOOL CMyTreeCtrl::SetBKImage(LPCTSTR LpszResource){ // if this is not the first call then delete gdi objects if( m_bitmap.m_hObject != NULL ) m_bitmap.DeleteObject(); HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), LpszResource, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE); if( hbmp == NULL ) return FALSE; m_bitmap.Attach( hbmp ); return TRUE;}LRESULT CMyTreeCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class return CTreeCtrl::WindowProc(message, wParam, lParam);}void CMyTreeCtrl::OnPaint() { CPaintDC dc(this); // device context for painting CRect rcclient; GetClientRect(&rcclient); // create a compatible memory dc CDC memdc; memdc.CreateCompatibleDC(&dc); CBitmap bitmap; bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height()); memdc.SelectObject( &bitmap ); CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0); CDC maskdc; maskdc.CreateCompatibleDC(&dc); CBitmap maskbitmap; maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL); maskdc.SelectObject( &maskbitmap ); maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc, rcclient.left, rcclient.top, SRCCOPY); CBrush brush; brush.CreatePatternBrush(&m_bitmap); dc.FillRect(rcclient, &brush); memdc.SetBkColor(RGB(0,0,0)); memdc.SetTextColor(RGB(255,255,255)); memdc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND); dc.SetBkColor(RGB(255,255,255)); dc.SetTextColor(RGB(0,0,0)); dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND); dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &memdc, rcclient.left, rcclient.top,SRCPAINT); brush.DeleteObject();}BOOL CMyTreeCtrl::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default return TRUE;}void CMyTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here Invalidate(); SetRedraw(TRUE); *pResult = 0;}void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here SetRedraw(FALSE); *pResult = 0;}///BOOL CTreeDlg::OnInitDialog(){ CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon // TODO: Add extra initialization here m_CtrlTree.SetBKImage("IDB_BITMAP1"); SetIcon(m_hIcon, FALSE); // Set small icon TVINSERTSTRUCT tvInsert; tvInsert.hParent = NULL; tvInsert.hInsertAfter = NULL; tvInsert.item.mask = TVIF_TEXT; tvInsert.item.pszText = _T("Visual C++编程实例"); HTREEITEM hCountry = m_CtrlTree.InsertItem(&tvInsert); HTREEITEM hPA = m_CtrlTree.InsertItem(TVIF_TEXT, _T("文章中心"), 0, 0, 0, 0, 0, hCountry, NULL); HTREEITEM hWA = m_CtrlTree.InsertItem(_T("代码中心"),0, 0, hCountry, hPA); m_CtrlTree.InsertItem(_T("全屏幕程序的实现"), hPA, TVI_SORT); m_CtrlTree.InsertItem(_T("实现窗口的任意分割"), hPA, TVI_SORT); m_CtrlTree.InsertItem(_T("实现菜单的自绘"), hPA, TVI_SORT); m_CtrlTree.InsertItem(_T("实现全屏幕显示的代码"), hWA, TVI_SORT); m_CtrlTree.InsertItem(_T("窗口任意分割的代码"), hWA, TVI_SORT); m_CtrlTree.InsertItem(_T("菜单自绘代码"), hWA, TVI_SORT); m_CtrlTree.Expand(hCountry,TVE_EXPAND); return TRUE; // return TRUE unless you set the focus to a control} |
转载地址:http://souli.baihongyu.com/