一、基本的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的定制使用的更多相关文章

  1. iOS 9应用开发教程之定制应用程序图标以及真机测试

    iOS 9应用开发教程之定制应用程序图标以及真机测试 定制ios9应用程序图标 在图1.12中可以看到应用程序的图标是网状白色图像,它是iOS模拟器上的应用程序默认的图标.这个图标是可以进行改变的.以 ...

  2. VR定制开发、AR定制开发(长年承接虚拟现实、增强现实应用、VR游戏定制开发,北京公司,可签合同)

    Cardboard SDK for Unity的使用 上一篇文章作为系列的开篇,主要是讲了一些虚拟现实的技术和原理,本篇就会带领大家去看一看谷歌的Cardboard SDK for Unity,虽然目 ...

  3. Android开发学习之 定制界面风格

    统一的用户界面是可以使得应用程序更友好.要做到用户界面的统一,我们就必须用到风格(style)和主题(theme).OPhone系统提供了很多系统默认的风格和主题,但是很多情况下,这些不能满足我们的需 ...

  4. Android开发:怎样定制界面风格

    统一的用户界面是可以使得应用程序更友好.要做到用户界面的统一,我们就必须用到风格(style)和主题(theme).OPhone系统提供了很多系统默认的风格和主题,但是很多情况下,这些不能满足我们的需 ...

  5. [js插件开发教程]一步步开发一个可以定制配置的隔行变色小插件

    隔行变色功能,不用js,直接用css伪类就可以做,这个实例可以作为js插件开发很好的入门级实例.本文实现的隔行变色包括以下功能: 1,支持2种常用结构共存( div元素 和 表格类型 ) 2,一个页面 ...

  6. 提供VR定制开发、AR定制开发(VR游戏定制、应用定制)

    设置输出路径 添加烘培输出的贴图类型 添加“LightingMap”类型 设置烘培贴图大小和目标贴图位置为“自发光” 设置烘培材质,选择“输出到源” 点击“渲染”即可 24.标准材质贴图的烘培光影处理 ...

  7. 张高兴的 UWP 开发笔记:定制 ContentDialog 样式

    我需要一个背景透明的 ContentDialog,像下图一样.如何定制?写了一个简单的示例(https://github.com/ZhangGaoxing/uwp-demo/tree/master/C ...

  8. 开发socketserver 以及定制开发自己的FTP服务器

    socket server 示例 #服务端程序 import socketserver class TcpHandler(socketserver.BaseRequestHandler): def h ...

  9. C#软件开发实例.个人定制自己的屏幕抓图工具(八)加入了截图功能键盘

    章文件夹 (一)功能概览 (二)创建项目.注冊热键.显示截图主窗体 (三)托盘图标及菜单的实现 (四)基本截图功能实现 (五)针对拖拽时闪烁卡顿现象的优化 (六)加入配置管理功能 (七)加入放大镜的功 ...

随机推荐

  1. Codeforces Round #509 (Div. 2) E. Tree Reconstruction(构造)

    题目链接:http://codeforces.com/contest/1041/problem/E 题意:给出n - 1对pair,构造一颗树,使得断开其中一条边,树两边的最大值为 a 和 b . 题 ...

  2. RecursiveTask和RecursiveAction的使用 以及java 8 并行流和顺序流(转)

    什么是Fork/Join框架        Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架. 我 ...

  3. [Debug] Debugger Statements

    For example you have the following code; function reverse(str) { let reversed = ""; for (l ...

  4. maven插件生成可执行jar包

    <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assem ...

  5. Codevs 3012 线段覆盖 4

    3012 线段覆盖 4 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description 数轴上有n条线段,线段的两端都是整数坐标,坐标范围在0~100 ...

  6. 洛谷P2634 [国家集训队]聪聪可可 点分治模板

    题意 在一棵树上任意选两个点,求它们距离模3为0的概率. 分析 树分治模板 Code #include<bits/stdc++.h> #define fi first #define se ...

  7. 阿里云Ubuntu安装LNMP环境之Mysql

    在QQ群很多朋友问阿里云服务器怎么安装LNMP环境,怎么把项目放到服务器上面去,在这里,我就从头开始教大家怎么在阿里云服务器安装LNMP环境. 在这之前,我们先要知道什么是LNMP. L: 表示的是L ...

  8. docker部署项目: centos+python+redis+mysql+uwsgi+nginx

    一.Centos7安装docker 1.1 环境配置 先测试是否下载了docker:查看镜像:docker images没有下载,就依次执行以下环境的安装 ①curl http://mirrors.a ...

  9. 【Elasticsearch】Docker 安装 Elasticsearch 2.4.4 版本(高版本方式不同)

    1. 下载  elasticsearch docker pull docker.elastic.co/elasticsearch/elasticsearch:6.4.3 2.启动 elasticsea ...

  10. LightGBM新特性总结

    LightGBM提出两种新方法:Gradient-based One-Side Sampling (GOSS) 和Exclusive Feature Bundling (EFB)(基于梯度的one-s ...