基于MFC实现分栏Splitter

1.效果

SplitterDemo.gif

2.主要代码

主界面类:


// SplitterDemoDlg.h : 头文件
//

#pragma once
#include "FormViewLeft.h"
#include "FormViewRight.h"


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

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_SPLITTERDEMO_DIALOG };
#endif

	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();
	afx_msg void OnSize(UINT nType, int cx, int cy);
	DECLARE_MESSAGE_MAP()

private:
	CSplitterWnd				m_wndSplitter;			// 分栏器
	CFrameWnd*					m_pFrameWnd;			// 框架窗口
	CFormViewLeft*				m_pFormViewLeft;
	CFormViewRight*				m_pFormViewRight;

	
};

 


// SplitterDemoDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "SplitterDemo.h"
#include "SplitterDemoDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


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

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

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

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

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

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

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CSplitterDemoDlg 对话框



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

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

BEGIN_MESSAGE_MAP(CSplitterDemoDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_SIZE()
END_MESSAGE_MAP()


// CSplitterDemoDlg 消息处理程序

BOOL CSplitterDemoDlg::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: 在此添加额外的初始化代码

	CString strMyClass = AfxRegisterWndClass(CS_VREDRAW |
		CS_HREDRAW,
		::LoadCursor(NULL, IDC_ARROW),
		(HBRUSH) ::GetStockObject(WHITE_BRUSH),
		::LoadIcon(NULL, IDI_APPLICATION));

	m_pFrameWnd = new CFrameWnd();
	m_pFrameWnd->Create(strMyClass, "", WS_CHILD, CRect(0, 0, 1, 1), this);
	m_pFrameWnd->ShowWindow(SW_SHOW);
	m_pFrameWnd->MoveWindow(0, 0, 300, 300);

	m_wndSplitter.CreateStatic(m_pFrameWnd, 1, 2);

	CRect rect;
	GetWindowRect(&rect);
	ScreenToClient(&rect);

	m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CFormViewLeft), CSize(rect.Width() / 5 * 1.2, rect.Height()), NULL);
	m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CFormViewRight), CSize(rect.Width() - 5 * 1.2, rect.Height()), NULL);

	m_pFormViewLeft = static_cast<CFormViewLeft*>(m_wndSplitter.GetPane(0, 0));
	m_pFormViewRight = static_cast<CFormViewRight*>(m_wndSplitter.GetPane(0, 1));
	if (m_pFormViewLeft == NULL || m_pFormViewRight == NULL)
	{
		MessageBox("创建资源失败", "提示", MB_OK | MB_ICONERROR);
		PostMessage(WM_CLOSE);
		return 0;
	}

	GetClientRect(rect);
	m_pFrameWnd->MoveWindow(&rect);
	m_pFrameWnd->ShowWindow(SW_SHOW);
	m_wndSplitter.MoveWindow(0, 0, rect.Width(), rect.Height());
	m_wndSplitter.ShowWindow(SW_SHOW);

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

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

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

void CSplitterDemoDlg::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 CSplitterDemoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CSplitterDemoDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码

	if (m_pFrameWnd != NULL)
	{
		CRect rect;
		GetClientRect(rect);
		m_pFrameWnd->MoveWindow(&rect);
		m_wndSplitter.MoveWindow(0, 0, rect.Width(), rect.Height());
	}

}

 

分栏左边视图类

/*************************************************
File Name	: FormViewLeft.h
Author		: shaoyiju
Version		: v1.00
DateTime	: 2019-08-20
Description : 分栏左边的设备树的父窗口
*************************************************/

#pragma once
#include "afxcmn.h"
#include "TabWndDisplay.h"
#include "TabWndSignal.h"
#include "afxwin.h"
#include "CommonDataDef.h"


// CFormViewLeft 窗体视图

class CFormViewLeft : public CFormView
{
	DECLARE_DYNCREATE(CFormViewLeft)

protected:
	CFormViewLeft();           // 动态创建所使用的受保护的构造函数
	virtual ~CFormViewLeft();

public:
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_FORMVIEW_LEFT };
#endif
#ifdef _DEBUG
	virtual void AssertValid() const;
#ifndef _WIN32_WCE
	virtual void Dump(CDumpContext& dc) const;
#endif
#endif

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

	DECLARE_MESSAGE_MAP()

	// 去掉滚动条
	void OnInitialUpdate();

public:
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnBnClickedButtonDisplay();
	afx_msg void OnBnClickedButtonSignal();

	void DealSelChanged(int nIndex);

	// 是否空白
	bool IsEmpty();

	// 清空当前内容
	void ClearAll();


private:
	bool						m_bInit;
	CTabWndDisplay				m_tabWndDisplay;
	CTabWndSignal				m_tabWndSignal;
	vector<CWnd*>				m_vctTabWnd;

	CButton						m_btnDisplay;
	CButton						m_btnSignal;
	vector<CWnd*>				m_vctBtn;

};


 

// FormViewLeft.cpp : 实现文件
//

#include "stdafx.h"
#include "FormViewLeft.h"



// CFormViewLeft

IMPLEMENT_DYNCREATE(CFormViewLeft, CFormView)

CFormViewLeft::CFormViewLeft()
	: CFormView(IDD_FORMVIEW_LEFT)
	, m_bInit(false)
{
	
}

CFormViewLeft::~CFormViewLeft()
{
}

void CFormViewLeft::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON_DISPLAY, m_btnDisplay);
	DDX_Control(pDX, IDC_BUTTON_SIGNAL, m_btnSignal);
}

void CFormViewLeft::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();
	m_nMapMode = -1;

	m_tabWndDisplay.Create(IDD_DIALOG_DISPLAY, this);
	m_tabWndSignal.Create(IDD_DIALOG_SIGNAL, this);

	m_vctTabWnd.push_back(&m_tabWndDisplay);
	m_vctTabWnd.push_back(&m_tabWndSignal);

	m_vctBtn.push_back(&m_btnDisplay);
	m_vctBtn.push_back(&m_btnSignal);

	OnBnClickedButtonDisplay();

	m_bInit = true;
}

BEGIN_MESSAGE_MAP(CFormViewLeft, CFormView)
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_BUTTON_DISPLAY, &CFormViewLeft::OnBnClickedButtonDisplay)
	ON_BN_CLICKED(IDC_BUTTON_SIGNAL, &CFormViewLeft::OnBnClickedButtonSignal)
END_MESSAGE_MAP()


// CFormViewLeft 诊断

#ifdef _DEBUG
void CFormViewLeft::AssertValid() const
{
	CFormView::AssertValid();
}

#ifndef _WIN32_WCE
void CFormViewLeft::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
#endif
#endif //_DEBUG


// CFormViewLeft 消息处理程序


void CFormViewLeft::OnSize(UINT nType, int cx, int cy)
{
	CFormView::OnSize(nType, cx, cy);

	if (!m_bInit)
	{
		return;
	}

	CRect rc;
	GetClientRect(rc);

	CRect rcBtn;
	m_btnDisplay.GetClientRect(rcBtn);
	CSize btnSize = rcBtn.Size();
	for (int i = 0; i < m_vctBtn.size(); i++)
	{
		rcBtn.left = rc.left;
		rcBtn.right = rcBtn.left + btnSize.cx;
		rcBtn.top = rc.top + btnSize.cy * i;
		rcBtn.bottom = rcBtn.top + btnSize.cy;
		m_vctBtn[i]->MoveWindow(rcBtn);
	}

	CRect rcTab(rc);
	rcTab.left = rcBtn.right;
	m_tabWndDisplay.MoveWindow(rcTab);
	m_tabWndSignal.MoveWindow(rcTab);
}


void CFormViewLeft::OnBnClickedButtonDisplay()
{
	// TODO: 在此添加控件通知处理程序代码

	DealSelChanged(0);
}


void CFormViewLeft::OnBnClickedButtonSignal()
{
	// TODO: 在此添加控件通知处理程序代码

	DealSelChanged(1);
}

void CFormViewLeft::DealSelChanged(int nIndex)
{
	const int nSize = m_vctTabWnd.size();
	if (nIndex < 0 || nIndex > nSize - 1)
	{
		return;
	}

	// 先显示再隐藏
	m_vctTabWnd[nIndex]->ShowWindow(SW_SHOW);

	for (int i = 0; i < nSize; i++)
	{
		if (i == nIndex)
		{
			continue;
		}
		else
		{
			m_vctTabWnd[i]->ShowWindow(SW_HIDE);
		}
	}
}

 

分栏右边视图类

/*************************************************
File Name	: FormViewRight.h
Author		: shaoyiju
Version		: v1.00
DateTime	: 2019-08-20
Description : 分栏右边的组屏Tab的父窗口
*************************************************/

#pragma once
#include "MFCTabCtrlEx.h"
#include "CommonDataDef.h"


class CDisplayPanel;
typedef map<string, CDisplayPanel*>	MapDisplayPanel;


// CFormViewRight 窗体视图

class CFormViewRight : public CFormView
{
	DECLARE_DYNCREATE(CFormViewRight)

protected:
	CFormViewRight();           // 动态创建所使用的受保护的构造函数
	virtual ~CFormViewRight();

public:
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_FORMVIEW_RIGHT };
#endif
#ifdef _DEBUG
	virtual void AssertValid() const;
#ifndef _WIN32_WCE
	virtual void Dump(CDumpContext& dc) const;
#endif
#endif

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

	DECLARE_MESSAGE_MAP()

	// 去掉滚动条
	void OnInitialUpdate();

public:
	// 添加虚拟屏
	afx_msg void OnVirtualDisplayAdd();
	afx_msg void OnVirtualDisplayModify();
	afx_msg void OnVirtualDisplayDelete();


private:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
	afx_msg LRESULT OnDeleteTab(WPARAM wParam, LPARAM lParam);
	

	string AddSpace(string strName);


	CMFCTabCtrlEx								m_wndTab;				// Tab
	MapDisplayPanel								m_mapDisplayPanel;		// Tab窗口队列

	
	
	
	
};


 

// FormViewRight.cpp : 实现文件
//

#include "stdafx.h"
#include "FormViewRight.h"

#define IDC_XTP_WALLTABCTROL			4651
#define TIMER_ID_HIDE_TAB				8654

// CFormViewRight

IMPLEMENT_DYNCREATE(CFormViewRight, CFormView)

CFormViewRight::CFormViewRight()
	: CFormView(IDD_FORMVIEW_RIGHT)
{

}

CFormViewRight::~CFormViewRight()
{
	for (auto& pWnd : m_mapDisplayPanel)
	{
		if (pWnd.second != NULL)
		{
			delete pWnd.second;
			pWnd.second = NULL;
		}
	}
	m_mapDisplayPanel.clear();
}

void CFormViewRight::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
}

void CFormViewRight::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();

	m_nMapMode = -1;
}



BEGIN_MESSAGE_MAP(CFormViewRight, CFormView)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_MESSAGE(WN_MSG_DELETE_TAB, &CFormViewRight::OnDeleteTab)
	ON_WM_RBUTTONDOWN()
	ON_WM_TIMER()
END_MESSAGE_MAP()


// CFormViewRight 诊断

#ifdef _DEBUG
void CFormViewRight::AssertValid() const
{
	CFormView::AssertValid();
}

#ifndef _WIN32_WCE
void CFormViewRight::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
#endif
#endif //_DEBUG


// CFormViewRight 消息处理程序


int CFormViewRight::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFormView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码

	CRect rectTab;
	GetClientRect(&rectTab);

	// STYLE_3D、STYLE_3D_ROUNDED 不带关闭按钮
	m_wndTab.Create(CMFCTabCtrl::STYLE_3D_ONENOTE, rectTab, this, WM_USER + 521, CMFCTabCtrl::LOCATION_TOP, TRUE);

	// 背景色不好看,先隐藏
	m_wndTab.ShowWindow(SW_HIDE);

	return 0;
}

void CFormViewRight::OnVirtualDisplayAdd()
{
}

void CFormViewRight::OnVirtualDisplayModify()
{
}

void CFormViewRight::OnVirtualDisplayDelete()
{
}

void CFormViewRight::OnSize(UINT nType, int cx, int cy)
{
	CFormView::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码

	if (IsWindow(m_wndTab.m_hWnd))
	{
		CRect rect;
		GetClientRect(&rect);
		m_wndTab.MoveWindow(&rect);
	}

}




void CFormViewRight::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CFormView::OnRButtonDown(nFlags, point);

	OnVirtualDisplayAdd();
}

LRESULT CFormViewRight::OnDeleteTab(WPARAM wParam, LPARAM lParam)
{
	OnVirtualDisplayDelete();

	return 0;
}

string CFormViewRight::AddSpace(string strName)
{
	return "  " + strName + "  ";
}

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、 分割控件类:CSplitterControl SplitterControl.h SplitterControl.cpp 2、创建对象、增加资源 class xx { ... private: CSplitterControl m_wndSplitter1; // 上下分割 IDC_SPLITTER_TOP 分割线资源更改资源可见属性为不可见,防止出现2条线 void DoResize1(int delta); CSplitterControl m_wndSplitter2; // 左右分割 IDC_SPLITTER_LEFT void DoResize2(int delta); } 3、初始化 BOOL CT1Dlg::OnInitDialog() { ... // TODO: Add extra initialization here {//m_wndSplitter1 CRect rc; CWnd* pWnd; pWnd = GetDlgItem(IDC_SPLITTER_TOP); pWnd->GetWindowRect(rc); ScreenToClient(rc); m_wndSplitter1.Create(WS_CHILD | WS_VISIBLE, rc, this, IDC_SPLITTER_TOP); CRect rc2; GetDlgItem(IDOK)->GetWindowRect(&rc2); ScreenToClient(&rc2); CRect rc3; GetDlgItem(IDCANCEL)->GetWindowRect(&rc3); ScreenToClient(&rc3); m_wndSplitter1.SetRange(rc2.bottom, rc3.top); } {// m_wndSplitter2 CRect rc; CWnd* pWnd; pWnd = GetDlgItem(IDC_SPLITTER_LEFT); pWnd->GetWindowRect(rc); ScreenToClient(rc); m_wndSplitter2.Create(WS_CHILD | WS_VISIBLE, rc, this, IDC_SPLITTER_LEFT); CRect rc2; GetDlgItem(IDC_BUTTON1)->GetWindowRect(&rc2); ScreenToClient(&rc2); CRect rc3; GetDlgItem(IDC_BUTTON2)->GetWindowRect(&rc3); ScreenToClient(&rc3); m_wndSplitter2.SetRange(rc2.right+1, rc3.left-1); } return TRUE; // return TRUE unless you set the focus to a control } LRESULT CT1Dlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class if (message == WM_NOTIFY) { if (wParam == IDC_SPLITTER_TOP) { SPC_NMHDR* pHdr = (SPC_NMHDR*) lParam; DoResize1(pHdr->delta); } else if (wParam == IDC_SPLITTER_LEFT) { SPC_NMHDR* pHdr = (SPC_NMHDR*) lParam; DoResize2(pHdr->delta); } } return CDialog::DefWindowProc(message, wParam, lParam); } void CT1Dlg::DoResize1(int delta) { CSplitterControl::ChangeHeight(GetDlgItem(IDC_BUTTON1),delta); CSplitterControl::ChangeHeight(GetDlgItem(IDC_BUTTON2), -delta, CW_BOTTOMALIGN); Invalidate();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值