【VS开发】CSplitterWnd的定制使用
一、基本的CSplitterWnd的使用
1. 在CMainFrame中添加一个CSplitterWnd成员:
CSplitterWnd m_splitterwnd1;
2. 基于CView创建两个新的视图类,CViewLeft和CViewRight,一个用于在左边显示,一个用于在右边显示。
3. 重载CMainFrame的OnCreateClient函数,在并其中调用CSplitterWndr的CreateStatic函数创建该分割窗口,CreateView函数创建左右两个视图,SetColumnInfo设定分割窗口的列的宽度:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
//
TODO: 在此添加专用代码和/或调用基类
m_mysplitter1.CreateStatic(this,
1, 2); //创建一个一行二列的分割窗口
m_mysplitter1.CreateView(0,
0, RUNTIME_CLASS(CViewLeft), CSize(0, 0),
pContext); //建立第0行第0列的视图
m_mysplitter1.CreateView(0, 1, RUNTIME_CLASS(CViewRight), CSize(0, 0),
pContext); //建立第0行第1列的视图
m_mysplitter1.SetColumnInfo(0,
250, 10); //设定某列的宽度,这里表示设定第0列的理想宽度为250像素,最小宽度为10像素(什么是最小宽度?没弄明白)
return
TRUE;
//return
CFrameWnd::OnCreateClient(lpcs, pContext);
}
运行后就可以看到生成了分割为左右两个视图的窗口。
二、为分割窗添加一些自己需要的功能
从系统的CSplitterWnd类派生一个新类。
在类视图中右键,选择“添加”->“类”,在弹出窗口中选择MFC类,输入新类的名字CMySplitter,基类选择为CWnd(这里基类的选项里面没有CSplitterWnd,所以要先选择Cwnd)。然后把生成的MySplitter.h和MySplitter.cpp里面的三个地方的“Cwnd”改成“CSplitterWnd”。
MySplitter.h中:
class CMySplitter : public
CSplitterWnd
Mysplitter.cpp中:
IMPLEMENT_DYNAMIC(CMySplitter,
CSplitterWnd)
BEGIN_MESSAGE_MAP(CMySplitter,
CSplitterWnd)
1. 双击分隔栏展开或者收起左边的一栏
重载OnLButtonDblClk函数:
void CMySplitterWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
{
//
TODO: 在此添加消息处理程序代码和/或调用默认值
//CSplitterWnd::OnLButtonDblClk(nFlags,
point);
int left, min;
GetColumnInfo(0, left, min); //得到第0栏(即左边的一栏)的宽度
if(left == 0 || left == min) //如果当前已经是收起的状态
{
SetColumnInfo(0,
250, 10); //重新设置左边一栏的宽度,这里设置为250,即展开
}
else
{
SetColumnInfo(0,
0, 10); //重新设置左边一栏的宽度,这里设置为0,即收起
}
RecalcLayout(); //重新构建窗口布局
}
2. 设置分隔栏的宽度
在CMySplitter的构造函数中(这里是把宽度设为11像素):
m_cxSplitterGap = 11;
m_cxSplitter = 11;
几个相关变量的意义:
//int m_cxSplitter, m_cySplitter; // size of splitter bar
//int m_cxBorderShare, m_cyBorderShare; // space on either side of splitter
//int m_cxSplitterGap, m_cySplitterGap; // amount of space between panes
//int m_cxBorder, m_cyBorder; // borders in client area
3. 禁止拖动分隔栏的位置
(1)重载OnLButtonDown函数,改成什么都不做:
void CMySplitter::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//CSplitterWnd::OnLButtonDown(nFlags, point);
}
(2)重载OnMouseMove函数,也改成什么都不做:
void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//CSplitterWnd::OnMouseMove(nFlags, point);
}
使用CSplitterWnd分割窗口(二)
4. 在分隔栏上添加一个”按钮“
(1)在资源视图中导入两张位图资源,分另是一个向左的箭头和一个向右的箭头,图片大小为(6*31)像素:IDB_BITMAP_LEFT,IDB_BITMAP_RIGHT
(2)为CMySplitter类添加显示该“按钮”相关的成员:
CBitmap m_bitmapleft; //左箭头位图
CBitmap m_bitmapright; //右箭头位图
CDC m_dcMem; //
CRect m_rectImgBtn; //显示该“按钮”的矩形区域
(3)添加一个成员函数得到显示该“按钮”的矩形区域:
//这个函数用来得到显示该按钮的矩形区域
void CMySplitter::GetImgBtnRect(void)
{
CRect r;
int left, min;
GetWindowRect(&r);
GetColumnInfo(0, left, min);
m_rectImgBtn.SetRect(left+2+2, r.Height()/2-16,
left+2+8, r.Height()/2+15); //这里这么写是根据WindowsXP显示的分隔栏来确定的,要用绘图软件测一下
if(left == 250) //这里用到了正常显示下的左栏是250像素宽
{
if(m_dcMem != NULL)
{
m_dcMem.SelectObject(m_bitmapleft); //这个DC选择左箭头的图片
}
}
else
{
if(m_dcMem != NULL)
{
m_dcMem.SelectObject(m_bitmapright); //这个DC选择右箭头的图片
}
}
}
(4)重载OnDrawSplitter函数,画出该按钮:
void CMySplitter::OnDrawSplitter(CDC* pDC, ESplitType nType,
const CRect& rect)
{
// TODO: 在此添加专用代码和/或调用基类
CSplitterWnd::OnDrawSplitter(pDC, nType, rect); //本来的画分隔栏
if(pDC != NULL)
{
if(m_dcMem == NULL)
{
m_dcMem.CreateCompatibleDC(NULL); //CreateCompatibleDC参数为NULL表示创建一个与当前显示器兼容的DC
}
GetImgBtnRect();
pDC->BitBlt(m_rectImgBtn.left, m_rectImgBtn.top,
m_rectImgBtn.Width(), m_rectImgBtn.Height(),
&m_dcMem, 0, 0, SRCCOPY); //从m_dcMem中把图片复制到pDC中并画出来(大概是这个意思)
}
}
}
(5)重载OnLButtonUp函数,使得点击该“按钮”时可以收起或者展开左栏
void CMySplitter::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
GetImgBtnRect();
if(m_rectImgBtn.PtInRect(point)) //如果鼠标当前是在“按钮”区域内
{
//这里判断一下左栏是否收起了,如果是,隐藏左栏;不是则显示左栏
//通过GetColumnInfo和SetColumnInfo
}
else
{
CSplitterWnd::OnLButtonUp(nFlags, point);
}
}
(6)重载OnMouseMove函数,当鼠标移动到“按钮”上时,把鼠标形状变成手形
void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
GetImgBtnRect();
if(m_rectImgBtn.PtInRect(point))
{
::SetCursor(LoadCursor(NULL, IDC_HAND));
}
else
{
::SetCursor(LoadCursor(NULL, IDC_ARROW));
}
}
【VS开发】CSplitterWnd的定制使用的更多相关文章
- iOS 9应用开发教程之定制应用程序图标以及真机测试
iOS 9应用开发教程之定制应用程序图标以及真机测试 定制ios9应用程序图标 在图1.12中可以看到应用程序的图标是网状白色图像,它是iOS模拟器上的应用程序默认的图标.这个图标是可以进行改变的.以 ...
- VR定制开发、AR定制开发(长年承接虚拟现实、增强现实应用、VR游戏定制开发,北京公司,可签合同)
Cardboard SDK for Unity的使用 上一篇文章作为系列的开篇,主要是讲了一些虚拟现实的技术和原理,本篇就会带领大家去看一看谷歌的Cardboard SDK for Unity,虽然目 ...
- Android开发学习之 定制界面风格
统一的用户界面是可以使得应用程序更友好.要做到用户界面的统一,我们就必须用到风格(style)和主题(theme).OPhone系统提供了很多系统默认的风格和主题,但是很多情况下,这些不能满足我们的需 ...
- Android开发:怎样定制界面风格
统一的用户界面是可以使得应用程序更友好.要做到用户界面的统一,我们就必须用到风格(style)和主题(theme).OPhone系统提供了很多系统默认的风格和主题,但是很多情况下,这些不能满足我们的需 ...
- [js插件开发教程]一步步开发一个可以定制配置的隔行变色小插件
隔行变色功能,不用js,直接用css伪类就可以做,这个实例可以作为js插件开发很好的入门级实例.本文实现的隔行变色包括以下功能: 1,支持2种常用结构共存( div元素 和 表格类型 ) 2,一个页面 ...
- 提供VR定制开发、AR定制开发(VR游戏定制、应用定制)
设置输出路径 添加烘培输出的贴图类型 添加“LightingMap”类型 设置烘培贴图大小和目标贴图位置为“自发光” 设置烘培材质,选择“输出到源” 点击“渲染”即可 24.标准材质贴图的烘培光影处理 ...
- 张高兴的 UWP 开发笔记:定制 ContentDialog 样式
我需要一个背景透明的 ContentDialog,像下图一样.如何定制?写了一个简单的示例(https://github.com/ZhangGaoxing/uwp-demo/tree/master/C ...
- 开发socketserver 以及定制开发自己的FTP服务器
socket server 示例 #服务端程序 import socketserver class TcpHandler(socketserver.BaseRequestHandler): def h ...
- C#软件开发实例.个人定制自己的屏幕抓图工具(八)加入了截图功能键盘
章文件夹 (一)功能概览 (二)创建项目.注冊热键.显示截图主窗体 (三)托盘图标及菜单的实现 (四)基本截图功能实现 (五)针对拖拽时闪烁卡顿现象的优化 (六)加入配置管理功能 (七)加入放大镜的功 ...
随机推荐
- CodeForces 837D - Round Subset | Educational Codeforces Round 26
/* CodeForces 837D - Round Subset [ DP ] | Educational Codeforces Round 26 题意: 选k个数相乘让末尾0最多 分析: 第i个数 ...
- learning gcc #pragma once
referenc: https://zh.wikipedia.org/wiki/Pragma_once 在C和C++编程语言中,#pragma once是一个非标准但是被广泛支持的前置处理符号, 会让 ...
- SVN - Subversion
Subversion yum install -y subversion 或者 subversion Edge 下载: # wget https://downloads-guests.open.col ...
- 在 CentOS 7 上安装 RabbitMQ
RabbitMQ 服务器在安装之前需要安装 erlang. 最新版本的 RabbitMQ 3.8.0 需要 Erlang 21.3 以上的版本支持. 在这里,我们需要在你的 CentOS 中安装 Er ...
- 【csp模拟赛2】 爆搜 方格加数
[题目描述] xyz1048576正在玩一个关于矩阵的游戏. 一个n*m的矩阵,矩阵中每个数都是[1,12]内的整数.你可以执行下列两个操作任意多次: (1)指定一行,将该行所有数字+1. (2)指定 ...
- Django-内置的auth模块
一.auth认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Django作为一个 ...
- elasticsearch+logstash+kibana部署
这篇博客讲的是elasticsearch+logstash+kibana部署的方法. 内容大纲: 1.elasticsearch+logstash+kibana部署 2.收集Tomcat日志 3.收集 ...
- go 两个数组取并集
实际生产中,对不同数组取交集.并集.差集等场景很常用,下面来说下两个数组取差集 直接上代码: //两个集合取并集 package main import "fmt" //思想: / ...
- Linux设备驱动程序 之 ioctl
ioctl 除了读取和写入设备之外,大部分驱动程序还需要另外一种能力,即通过设备驱动程序执行各种类型的硬件控制,通常这种需求使用ioctl方法支持,该方法实现了同名的系统调用: 在用户空间,ioctl ...
- 微服务RESTful 接口设计规范
1.RESTful发展背景及简介 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......).因此,必须有一种统一的机制,方便不同的前 ...