树控件(Tree Control),标签控件(tab control)

Posted 狂奔~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树控件(Tree Control),标签控件(tab control)相关的知识,希望对你有一定的参考价值。

树控件

 

基于对话框创建工程

// 01_TreeCtrlDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "01_TreeCtrl.h"
#include "01_TreeCtrlDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
    CAboutDlg();

// 对话框数据
    enum { IDD = IDD_ABOUTBOX };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CMy01_TreeCtrlDlg 对话框



CMy01_TreeCtrlDlg::CMy01_TreeCtrlDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(CMy01_TreeCtrlDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMy01_TreeCtrlDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_TREE1, m_treeCtrl);
}

BEGIN_MESSAGE_MAP(CMy01_TreeCtrlDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()


// CMy01_TreeCtrlDlg 消息处理程序

BOOL CMy01_TreeCtrlDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 将“关于...”菜单项添加到系统菜单中。

    // IDM_ABOUTBOX 必须在系统命令范围内。
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
    //  执行此操作
    SetIcon(m_hIcon, TRUE);            // 设置大图标
    SetIcon(m_hIcon, FALSE);        // 设置小图标

    // TODO:  在此添加额外的初始化代码

    //加载图标
    HICON icon[3];
    icon[0] = AfxGetApp()->LoadIconW(IDI_ICON1);
    icon[1] = AfxGetApp()->LoadIconW(IDI_ICON2);
    icon[2] = AfxGetApp()->LoadIconW(IDI_ICON3);


    //图像列表,程序完毕不能释放, 创建
    //30, 30: 图片的宽度和高度
    //ILC_COLOR32:样式
    // 3, 3: 有多少图片写多少
    m_imageList.Create(30, 30, ILC_COLOR32, 3, 3);

    //给图像列表添加图片
    for (int i = 0; i < 3; i++)
    {
        //图片列表加载图标
        m_imageList.Add(icon[i]);
    }

    //树控件设置图片列表
    m_treeCtrl.SetImageList(&m_imageList, TVSIL_NORMAL);

    //给树创建节点
    //根节点,父节点,子节点
    HTREEITEM root = m_treeCtrl.InsertItem(TEXT("根节点"), 0, 0, NULL);


    HTREEITEM fathter = m_treeCtrl.InsertItem(TEXT("父节点"), 1, 1, root);

    HTREEITEM son = m_treeCtrl.InsertItem(TEXT("子节点"), 2, 2, fathter);

    HTREEITEM root2 = m_treeCtrl.InsertItem(TEXT("根节点"), 0, 0, NULL);


    HTREEITEM fathter2 = m_treeCtrl.InsertItem(TEXT("父节点"), 1, 1, root2);

    HTREEITEM son2 = m_treeCtrl.InsertItem(TEXT("子节点"), 2, 2, fathter2);

    //设置某个节点被选中
    m_treeCtrl.SelectItem(fathter);

    m_treeCtrl.SelectItem(son2);



    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CMy01_TreeCtrlDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::OnSysCommand(nID, lParam);
    }
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CMy01_TreeCtrlDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // 用于绘制的设备上下文

        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

        // 使图标在工作区矩形中居中
        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;

        // 绘制图标
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
    }
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMy01_TreeCtrlDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}

 

// 01_TreeCtrlDlg.h : 头文件
//

#pragma once
#include "afxcmn.h"


// CMy01_TreeCtrlDlg 对话框
class CMy01_TreeCtrlDlg : public CDialogEx
{
// 构造
public:
    CMy01_TreeCtrlDlg(CWnd* pParent = NULL);    // 标准构造函数

// 对话框数据
    enum { IDD = IDD_MY01_TREECTRL_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持


// 实现
protected:
    HICON m_hIcon;

    // 生成的消息映射函数
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()


private:
    CImageList m_imageList; //图像列表
    CTreeCtrl m_treeCtrl;
};

标签控件(tab control)

 

 

 

 

// CMy02_TabCtrlDlg 消息处理程序

BOOL CMy02_TabCtrlDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 将“关于...”菜单项添加到系统菜单中。

    // IDM_ABOUTBOX 必须在系统命令范围内。
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
    //  执行此操作
    SetIcon(m_hIcon, TRUE);            // 设置大图标
    SetIcon(m_hIcon, FALSE);        // 设置小图标

    // TODO:  在此添加额外的初始化代码

    //给tab控件添加对话框
    //对话框设置为子对话框,默认是单独对话框
    m_tabCtrl.AddPage(TEXT("设置"), &dlg1, IDD_DIALOG1);
    m_tabCtrl.AddPage(TEXT("测试"), &dlg2, IDD_DIALOG2);


    //显示tab控件
    m_tabCtrl.Show();


    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

 

// 02_TabCtrlDlg.h : 头文件
//

#pragma once
#include "TabSheet.h"
#include "MyDlg1.h"
#include "MyDlg2.h"


// CMy02_TabCtrlDlg 对话框
class CMy02_TabCtrlDlg : public CDialogEx
{
// 构造
public:
    CMy02_TabCtrlDlg(CWnd* pParent = NULL);    // 标准构造函数

// 对话框数据
    enum { IDD = IDD_MY02_TABCTRL_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持


// 实现
protected:
    HICON m_hIcon;

    // 生成的消息映射函数
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
private:
    CTabSheet m_tabCtrl;

    MyDlg1 dlg1;
    MyDlg2 dlg2;

};

 

// TabSheet.cpp : implementation file
//

#include "stdafx.h"
//#include "Property5.h"
#include "TabSheet.h"

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

/////////////////////////////////////////////////////////////////////////////
// CTabSheet

CTabSheet::CTabSheet()
{
    m_nNumOfPages = 0;
    m_nCurrentPage = 0;
}

CTabSheet::~CTabSheet()
{
}


BEGIN_MESSAGE_MAP(CTabSheet, CTabCtrl)
    //{{AFX_MSG_MAP(CTabSheet)
    ON_WM_LBUTTONDOWN()
    ON_WM_HSCROLL()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTabSheet message handlers

BOOL CTabSheet::AddPage(LPCTSTR title, CDialog *pDialog,UINT ID)
{
    if( MAXPAGE == m_nNumOfPages )
        return FALSE;

    m_nNumOfPages++;

    m_pPages[m_nNumOfPages-1] = pDialog;
    m_IDD[m_nNumOfPages-1] = ID;
    m_Title[m_nNumOfPages-1] = title;

    return TRUE;
}

void CTabSheet::SetRect()
{
    CRect tabRect, itemRect;
    int nX, nY, nXc, nYc;

    GetClientRect(&tabRect);
    GetItemRect(0, &itemRect);

    nX=itemRect.left;
    nY=itemRect.bottom+1;
    nXc=tabRect.right-itemRect.left-2;
    nYc=tabRect.bottom-nY-2;

    m_pPages[0]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_SHOWWINDOW);
    for( int nCount=1; nCount < m_nNumOfPages; nCount++ )
        m_pPages[nCount]->SetWindowPos(&wndTop, nX, nY, nXc, nYc, SWP_HIDEWINDOW);

}

void CTabSheet::Show()
{
    int i = 0;
    for( i=0; i < m_nNumOfPages; i++ )
    {
        m_pPages[i]->Create( m_IDD[i], this );
        if (AfxGetMainWnd())
            InsertItem( i, m_Title[i] );
        else
            return;
    }

    m_pPages[0]->ShowWindow(SW_SHOW);
    for( i=1; i < m_nNumOfPages; i++)
        m_pPages[i]->ShowWindow(SW_HIDE);

    SetRect();

}

void CTabSheet::OnLButtonDown(UINT nFlags, CPoint point) 
{
    CTabCtrl::OnLButtonDown(nFlags, point);

    if(m_nCurrentPage != GetCurFocus())
    {
        m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
        m_nCurrentPage=GetCurFocus();
        m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
//        m_pPages[m_nCurrentPage]->SetFocus();

        //AfxMessageBox("бЁжа"); wbm test
    }
    
}

int CTabSheet::SetCurSel(int nItem)
{
    if( nItem < 0 || nItem >= m_nNumOfPages)
        return -1;

    int ret = m_nCurrentPage;

    if(m_nCurrentPage != nItem )
    {
        m_pPages[m_nCurrentPage]->ShowWindow(SW_HIDE);
        m_nCurrentPage = nItem;
        m_pPages[m_nCurrentPage]->ShowWindow(SW_SHOW);
//        m_pPages[m_nCurrentPage]->SetFocus();
        CTabCtrl::SetCurSel(nItem);
    }

    return ret;
}

int CTabSheet::GetCurSel()
{
    return CTabCtrl::GetCurSel();
}

void CTabSheet::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
    // TODO: Add your message handler code here and/or call default
    
    CTabCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}
TabSheet.cpp

 

#if !defined(AFX_TABSHEET_H__42EE262D_D15F_46D5_8F26_28FD049E99F4__INCLUDED_)
#define AFX_TABSHEET_H__42EE262D_D15F_46D5_8F26_28FD049E99F4__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// TabSheet.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CTabSheet window
#define MAXPAGE 16

class CTabSheet : public CTabCtrl
{
    // Construction
public:
    CTabSheet();
    
    // Attributes
public:
    
    // Operations
public:
    
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CTabSheet)
    //}}AFX_VIRTUAL
    
    // Implementation
public:
    int GetCurSel();
    int SetCurSel(int nItem);
    void Show();
    void SetRect();
    BOOL AddPage(LPCTSTR title, CDialog *pDialog, UINT ID);
    virtual ~CTabSheet();
    
    // Generated message map functions
protected:
    LPCTSTR m_Title[MAXPAGE];
    UINT m_IDD[MAXPAGE];
    CDialog* m_pPages[MAXPAGE];
    int m_nNumOfPages;
    int m_nCurrentPage;
    //{{AFX_MSG(CTabSheet)
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    //}}AFX_MSG
    
    DECLARE_MESSAGE_MAP()
};

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

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_TABSHEET_H__42EE262D_D15F_46D5_8F26_28FD049E99F4__INCLUDED_)
TabSheet.h

 

以上是关于树控件(Tree Control),标签控件(tab control)的主要内容,如果未能解决你的问题,请参考以下文章

VC6.0中基于对话框的MFC EXE中的Tab Control控件如何使用???

关于MFC中Tree Control控件中的OnSelchanged消息是不是有bug?

VC6.0中的Tree Control控件,如何给有的节点设checkbox,而有的节点不设?具体代码如何实现?

VC6.0中基于对话框的MFC EXE中的Tab Control控件如何使用???

vue中使用树控件el-tree如何实现添加加虚线展开树节点样式

React+AntDesign使用Tree树控件完整展现其中的层级关系,并具有展开收起选择等交互功能