前言:

void CSplitterWnd::GetColumnInfo(int col, int& cxCur, int& cxMin) ;在使用拆分窗口时我的需要是想调整窗口大小在一定范围 不允许过小和隐藏,通过文档得知此代码设置窗口的当前宽度和最小宽度,但是在实际使用发现在调整窗口小于设定的cxMin时,竟然让窗口消失了,这完全与我的需求背道而驰,因此通过分析源码找到了 较为完美的解决方案,并记录笔记,欢迎朋友们交流互相学习。

注:CSplitterWndEx是继承的CSplitterWnd 只是分割符更加好看了 没有其它拓展功能。

只能点击 【添加类(C)...】  手动继承CSplitterWndEx, 头文件如下设计 重载两个重要的 方法

#pragma once
#include "afxsplitterwndex.h"
class CUserSplitter :public CSplitterWndEx
{
public:CUserSplitter();virtual ~CUserSplitter();virtual void TrackRowSize(int y, int row);virtual void TrackColumnSize(int x, int col);DECLARE_MESSAGE_MAP()
};

其中TrackRowSize 是根据名称便知是调整行的尺寸的,源码中实现方法如下:

//路径 ..\atlmfc\src\mfc\winsplit.cpp  877行
void CSplitterWnd::TrackRowSize(int y, int row)
{ASSERT_VALID(this);ASSERT(m_nRows > 1);CPoint pt(0, y);ClientToScreen(&pt);GetPane(row, 0)->ScreenToClient(&pt);m_pRowInfo[row].nIdealSize = pt.y;      // new sizeif (pt.y < m_pRowInfo[row].nMinSize){//这里的判断是说如果当前行的新Size小于 设定的nMinSize 则移除这一行 // resized too smallm_pRowInfo[row].nIdealSize = 0; // make it go away    if (GetStyle() & SPLS_DYNAMIC_SPLIT)DeleteRow(row);}else if (m_pRowInfo[row].nCurSize + m_pRowInfo[row+1].nCurSize< pt.y + m_pRowInfo[row+1].nMinSize){//这个判断是说如果当前区域的下一行小于最小的nMinSize则移除下一行// not enough room for other paneif (GetStyle() & SPLS_DYNAMIC_SPLIT)DeleteRow(row + 1);}
}

根据它的判断方式我们便可以最小的改动去实现 限定窗口在一定范围内的缩放

首先重载如下

#include "UserSplitter.h"CUserSplitter::CUserSplitter()
{
}CUserSplitter::~CUserSplitter()
{
}
void CUserSplitter::TrackRowSize(int y, int row)
{ASSERT_VALID(this);ASSERT(m_nRows > 1);CPoint pt(0, y);ClientToScreen(&pt);GetPane(row, 0)->ScreenToClient(&pt);m_pRowInfo[row].nIdealSize = pt.y;      // new sizeif (pt.y < m_pRowInfo[row].nMinSize){// resized too smallm_pRowInfo[row].nIdealSize = m_pRowInfo[row].nMinSize; // 如果小于最小 则设为最小/*if (GetStyle() & SPLS_DYNAMIC_SPLIT)DeleteRow(row);*/}else if (m_pRowInfo[row].nCurSize + m_pRowInfo[row + 1].nCurSize< pt.y + m_pRowInfo[row + 1].nMinSize){//如果挤压旁边太小 则重新设定大小// not enough room for other pane/*if (GetStyle() & SPLS_DYNAMIC_SPLIT)DeleteRow(row + 1);*/m_pColInfo[row].nIdealSize = m_pColInfo[row].nCurSize + m_pColInfo[row + 1].nCurSize- m_pColInfo[row + 1].nMinSize;}
}
void CUserSplitter::TrackColumnSize(int x, int col)
{ASSERT_VALID(this);ASSERT(m_nCols > 1);CPoint pt(x, 0);ClientToScreen(&pt);GetPane(0, col)->ScreenToClient(&pt);m_pColInfo[col].nIdealSize = pt.x;      // new sizeif (pt.x < m_pColInfo[col].nMinSize){// resized too smallm_pColInfo[col].nIdealSize = m_pColInfo[col].nMinSize; // make it go away/*if (GetStyle() & SPLS_DYNAMIC_SPLIT)DeleteColumn(col);*/}else if (m_pColInfo[col].nCurSize + m_pColInfo[col + 1].nCurSize< pt.x + m_pColInfo[col + 1].nMinSize){// not enough room for other pane/*if (GetStyle() & SPLS_DYNAMIC_SPLIT)DeleteColumn(col + 1);*/m_pColInfo[col].nIdealSize = m_pColInfo[col].nCurSize + m_pColInfo[col + 1].nCurSize- m_pColInfo[col + 1].nMinSize;}
}

从上面代码可知,要限定大小则需要m_pColInfo 数组的数据

则使用时可以做如下设计

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{// TODO: 在此添加专用代码和/或调用基类int rec = m_SplitWnd.CreateStatic(this, 1, 2);m_SplitWnd.CreateView(0, 0, RUNTIME_CLASS(CUserTreeView), CSize(100, 100), pContext);m_SplitWnd.CreateView(0, 1, RUNTIME_CLASS(CUserTabView), CSize(100, 100), pContext);return  rec;//return CFrameWndEx::OnCreateClient(lpcs, pContext);
}
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{CFrameWndEx::OnSize(nType, cx, cy);// TODO: 在此处添加消息处理程序代码m_SplitWnd.SetColumnInfo(0, static_cast<int>(cx*0.2), static_cast<int>(cx*0.1));m_SplitWnd.SetColumnInfo(1, static_cast<int>(cx*0.8), static_cast<int>(cx*0.6));m_SplitWnd.RecalcLayout();
}

【MFC】CSplitterWnd 重载限定窗口调整范围相关推荐

  1. MFC 句柄Hwnd 与 窗口Wnd的联系

    CWnd是MFC类库中所有窗口类的基类.微软在MFC中将所有窗口的通用操作都封装到了这个类中,如:ShowWindow等等,同时它也封装了窗口句柄即m_hWnd成员. 由HWnd得到CWnd*: CW ...

  2. mfc 使打开的窗口至于最顶层_MFC界面开发控件BCG帮助文档——功能区设计器(2)

    BCGControlBar ("Business Components Gallery ControlBar")是MFC扩展库,使您可以创建具有完全自定义选项(功能区.可自定义工具 ...

  3. MFC实现从一个窗口向另一个窗口发送消息的两种方法

    实现从一个窗口向另一个窗口发送消息,使用过下面两种方法 /*方法一:通过用SDK的标准API来查找其他对话框窗口返回句柄,并且发送信息 HWND hWnd; //通过SDK的FindWindow函数得 ...

  4. 定制MFC多文档窗口的主框架背景

    问题描述: 如上图所示,这是用MFC创建的多文档程序,可以看到主框架的背景区是灰色的,如果我要在这块区域贴一张图片,应该怎么办呢?最容易想到的是在CMainFrame的OnPaint中对背景进行更改, ...

  5. mfc嵌入matlab绘图窗口,将matlab的图嵌入MFC

    [实例简介] VS调用matlab画图模块编译成的动态链接库,并在MFC显示. [实例截图] [核心代码] 3b0582a3-4ea8-4a61-ba33-e448be563b88 └── 将matl ...

  6. 关于MFC实现圆角矩形窗口

    在文档的框架类中添加WM_SIZE消息响应代码: void CMainFrame::OnSize(UINT nType, int cx, int cy) { CRgn m_rgn; CRect rc; ...

  7. MFC学习笔记--底层窗口

    底层窗口 基本说明 概念 过程 简单实例 文化建设 基本说明 windows应用程序是c语言实现的,所有windows函数都在windows.h中声明 概念 SDK:software developm ...

  8. MFC实现 MSN QQ 窗口抖动

    终于成功了,研究了一上午,呵呵 水平低,实现这么点小功能也蛮有成就感的,一定得加到我毕业设计里 嘿嘿 好了 代码贴出来 说实话这方法我自己都感觉好笨 哪位高手有好方法的,还请指教 void CWind ...

  9. MFC开发之设置窗口最大化、最小化和默认大小

    当没有标题栏后自己写最大化.最小化和默认大小 最大化按钮: static BOOL bMaximum = FALSE; Invalidate();if (bMaximum) { ShowWindow( ...

最新文章

  1. C++:将char*指针强制转换成一个指向结构体的指针
  2. 使用Typescript重写axios
  3. android studio 将文件打包成jar文件
  4. SSH(Struts2+Hibernate+Spring)开发策略
  5. java在画布上画出变量_急..JAVA 在画布上画拖动滚动条可扩大缩小的长方形
  6. Centos7 使用Docker 部署Tomca+mysql+调试联通_02
  7. Redis常见面试题5 -- 持久化方式之RDB(快照模式)
  8. 【注意力机制】SENet(Squeeze-and-Excitation Networks)详解
  9. swift属性观察者机智
  10. 解决linux下javac -version和java -version版本显示不一致
  11. c语言对分求解方程,用C语言对一元二次方程求解
  12. 集合点(lr_rendezvous)
  13. 用小乌龟git解决冲突之后,再提交,出现自己没用动过的文件
  14. LINUX 安装护眼软件
  15. 典故:一文钱难倒英雄汉
  16. 小学计算机课教师教学笔记,小学信息技术教师读书笔记
  17. 网络安全职业规划(笔记)
  18. 治疗脚气、脚臭偏方!
  19. android usb恢复,安卓数据恢复常见问题汇总
  20. Data Analysis 软件(色谱质谱图分析软件)安装步骤

热门文章

  1. rt linux 测试,Ubuntu下测试RT-Linux的性能
  2. html下拉栏加箭头,CSS-下拉菜单上的引导3箭头
  3. 2021年部分漏洞整合+检测工具
  4. 【微信小程序】微信小程序提示Do not have handler in component
  5. 仿简书登录框,可删除内容或显示密码框的内容
  6. mysql 梅花掌_红砂手 梅花掌 红砂掌2
  7. 怎样删除usb计算机连接网络打印机驱动,USB无法识别打印机的解决办法和教程
  8. 故障排查:阿里云轻量应用服务器中的MySQL容器自行停止
  9. R语言实战读书笔记(八)回归
  10. 使用()关键字来创建python的自定义函数_17.python自定义函数