• 【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));
      }
     }

  • 相关阅读:
    android 发短信
    如何判断一个Div是否可视区域,判断div是否可见
    java arrayCopy
    Java 正则表达式 向前、向后匹配
    postgres 正则表达式
    java 分析方法调用过程
    chrome 模拟点击
    Java获取NTP网络时间
    Android对话框与Activity共存时的异常
    Android代码混淆
  • 原文地址:https://www.cnblogs.com/huty/p/8518699.html
Copyright © 2020-2023  润新知