CSplitterWnd

article/2025/9/27 14:39:36

MFC支持两种类型的拆分窗口:静态的和动态的。

静态拆分窗口的行列数在拆分窗口被创建时就设置好了,用户不能更改。但是用户可以缩放各行各列。一个静态拆分窗口最多可以包含16行16列。

要找一个使用了静态拆分窗口的应用程序,只要看一下windows管理器即可。

动态拆分窗口最多可以有两行两列,但它们可以相互拆分和合并。Vc就使用了动态拆分窗口使得可以同时编辑源程序文件的两个以上不同的部分。

选择静态或动态拆分的一个准则是是否希望用户能够交互地修改拆分窗口的行列配置。另一个决定因素是计划在拆分窗口中使用的视图种类。

在静态拆分窗口中很容易使用两个以上不同种类的视图,因为您可以在每个窗格中指定所用的视图类型。但是在动态拆分窗口中,MFC管理着视图,

除非从 CsplitterWnd派生一个新类并修改拆分窗口的默认操作性能,否则拆分窗口中的所有视图使用的都是相同的视图类。

静态拆分窗口是用CsplitterWnd::CreateStatic而不是CsplitterWnd::Create创建,并且由于MFC不会自动创建静态拆分窗口中显示的视图,

所以您要亲自在CreateStatic返回之后创建视图。CsplitterWnd为此提供了名为 CreateView的函数。

你应按如下步骤创建一个CSplitterWnd对象:

       1. 在父框架中嵌入一个CSplitterWnd成员变量。

  2. 重载父框架的CFrameWnd::OnCreateClient成员函数。

  3. 从重载的OnCreateClient函数中调用类CSplitterWnd的Create或CreateStatic成员函数,并调用CreateView来创建视图。

 

使用静态拆分窗口的一个优点是由于您自己给窗格添加视图,所以可以控制放入视图的种类。

关键函数

   BOOL CreateStatic( CWnd* pParentWnd, int nRows, int nCols, DWORD dwStyle =WS_CHILD | WS_VISIBLE, UINT nID = AFX_IDW_PANE_FIRST );函数有5个参数,意义如下:● pParentWnd:切分窗口的父窗口指针● nRows:水平方向分隔窗口的数目● nCols:垂直方向分隔窗口的数目● dwStyle:切分窗口的风格● nID:子窗口的ID值,默认为系统定义的AFX_IDW_PANE_FIRST返回值:如果创建成功,返回非零值(TRUE),否则返回0(FALSE)。m_wndSplitter.CreateStatic(this, 2,1); // 切分为2行1列
  virtual BOOL CreateView( int row, int col, CRuntimeClass* pViewClass,
 SIZE sizeInit, CCreateContext* pContext );函数有5个参数,意义如下:● row:窗格的行标,从0开始● col:窗格的列标,从0开始● pViewClass:视图的执行期类CRuntimeClass指针,可以用宏RUNTIME_CLASS获得● sizeInit:一个SIZE(或者CSize)类型的数据,指定窗格的初始大小● pContext:一般是由父窗口传递过来,包含窗口的创建信息返回值:如果创建成功,返回非零值(TRUE),否则返回0(FALSE)。
   m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CTest),CSize(190,100),pContext)

 

image 

实现的关键代码

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
if(!m_wndSplitter.CreateStatic(this,1,2))
{
return FALSE;
}
CRect rect;
GetClientRect(&rect);
if(!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CTest),
                 CSize(rect.Width()/4,rect.Height()),pContext)||
!m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CSplitterSDIView), 
                    CSize(rect.Width()/4*3,rect.Height()),pContext))
{
return FALSE;
}
return TRUE;
}
重载该函数之前需要做的步骤:
1. 在CMainFrame类中添加protected成员CSplitterWnd m_wndSplitter;
2. 建立对话框资源(IDD_FORMVIEW),并以CFormView类为基类建立相应的视类;
3. 重载OnCreateClient函数(如上述代码)。
4. 如果需要更多的划分,则再添加其他的CSplitterWnd成员变量,但在m_wndSplitter2.CreateStatic()
   函数里的第一个参数则采用需要划分的那个子视图,如m_wndSplitter2.CreateStatic(&m_wndSplitter1,
   1, 2, WS_CHILD|WS_VISIBLE, m_wndSplitter1.IdFromRowCol(0,0)) ),当然也需要自己创建需要的所
   有视图。

多视类之间的交互

在MFC程序中,各个视类之间进行数据交互是通过Doc类来完成的,由CDocument类来处理文档,

而由CView类来显示。即将数据存储到CDocument类中,而用到数据的时候再从该类中读取。

处理按钮事件:
void CTest::OnShowInt()
{
// TODO: Add your control notification handler code here
CSplitterSDIDoc* pDoc =(CSplitterSDIDoc*) GetDocument();
UpdateData(TRUE);
pDoc->x=m_int;
pDoc->UpdateAllViews(NULL);
}
在CSplitterSDIView中显示:
void CSplitterSDIView::OnDraw(CDC* pDC)
{
CSplitterSDIDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CString str;
str.Format("%d", pDoc->x);
pDC->TextOut(0,0,str);
}
 

CSplitterWnd类的其他成员信息

有关该类的其他成员函数,可以参考MSDN。

其他信息

锁定切分条
当用户创建好分割窗口后,有时并不希望通过拖动切分条来调节窗口的大小。这时就必须锁定切分条。锁定切分条的最简单的
方法莫过于不让CSplitterWnd来处理WM_LBUTTONDOWN,WM_MOUSEMOVE,WM_SETCURSOR消息,而是将这些消
息交给CWnd窗口进行处理,从而屏蔽掉这些消息。拿WM_LBUTTONDOWN处理过程来说。修改为如下: 
void CXXSplitterWnd::OnLButtonDown(UINT nFlags,CPoint point) {         CWnd::OnLButtonDown(nFlags,point);} 
其余的处理方法类似。 
切分条的定制 
由Window自己生成的切分条总是固定的,没有任何的变化,我们在使用一些软件比如ACDSee的时候却能发现它们的切分条
却是和自动生成的切分条不一样的。那么如何定制自己的切分条呢?通过重载CSplitterWnd的虚方法OnDrawSplitter和
OnInvertTracker可以达到这样的目的。下面的代码生成的效果是分割窗口的边界颜色为红色,分割条的颜色为绿色.代码如下:
void CSplitterWndEx::OnDrawSplitter(CDC *pDC, ESplitType nType, const CRect &rectArg){ 
                 if(pDC==NULL)
                   {
                   RedrawWindow(rectArg,NULL,RDW_INVALIDATE|RDW_NOCHILDREN);
                  return;
                  } 
                  ASSERT_VALID(pDC); 
                 CRect rc=rectArg; 
                 switch(nType)
                   { 
                  case splitBorder: 
                 //重画分割窗口边界,使之为红色 
                          pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0));  
                        rc.InflateRect(-CX_BORDER,-CY_BORDER); 
                          pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); 
                                    return;
                   case splitBox:  
                        pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));
                          rc.InflateRect(-CX_BORDER,-CY_BORDER); 
                          pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0)); 
                         rc.InflateRect(-CX_BORDER,-CY_BORDER);
                          pDC->FillSolidRect(rc,RGB(0,0,0)); 
                          pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0));
                          return; 
                  case splitBar:  
                 //重画分割条,使之为绿色  
                         pDC->FillSolidRect(rc,RGB(255,255,255));
                          rc.InflateRect(-5,-5); 
                          pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); 
                                    return;  
                 default:
                           ASSERT(FALSE);
                   } 
                  pDC->FillSolidRect(rc,RGB(0,0,255));
}
 void CSplitterWndEx::OnInvertTracker(CRect &rect) 
{                   ASSERT_VALID(this); 
                 ASSERT(!rect.IsRectEmpty()); 
                  ASSERT((GetStyle()&WS_CLIPCHILDREN)==0);
                  CRect rc=rect;  
                 rc.InflateRect(2,2);
                  CDC* pDC=GetDC(); 
                  CBrush* pBrush=CDC::GetHalftoneBrush(); 
                 HBRUSH hOldBrush=NULL; 
                 if(pBrush!=NULL) hOldBrush=(HBRUSH)SelectObject(pDC->m_hDC,pBrush->m_hObject);
                  pDC->PatBlt(rc.left,rc.top,rc.Width(),rc.Height(),BLACKNESS);  
                           if(hOldBrush!=NULL)
                   SelectObject(pDC->m_hDC,hOldBrush);
                  ReleaseDC(pDC); 
} 
同样我们只要继承CSplitterWnd中的其余的一些虚拟方法就可以生成具有自己个性的分割窗口了

http://chatgpt.dhexx.cn/article/XIRmKwyn.shtml

相关文章

【UNIX网络编程】|【07】SCTP协议探究

文章目录 1、概述2、接口模型2.1 一到一形式2.2 一到多形式 3、sctp_bindx函数4、sctp_connectx函数5、sctp_getpaddrs函数6、sctp_freepaddrs函数7、sctp_getladdrs函数8、sctp_freelpaddrs9、sctp_sendmsg10、sctp_recvmsg11、sctp_opt_info12、sctp_peeloff函数13、shudown1…

C++网络编程-tcpip协议

目录 1 tcp/ip协议族 1.1 体系结构以及主要协议 1.2 封装 1.3 分用 1.4 测试网络 1.5 arp协议工作原理 1.6 dns工作原理 1.7 socket和tcp/ip协议族的关系 2 ip协议详解 2.1 ip服务特点 2.2 ipv4头部结构 2.3 ip分片 2.4 ip路由 3 tcp协议详解 3.1 tcp服务的特点…

CSP绕过

01 比赛中常见的绕过CSP csp例子&#xff1a; <meta http-equiv"Content-Security-Policy" content"script-src self; object-src none; style-src cdn.example.org third-party.org; child-src https:">目前在比赛中常见的绕过 CSP 一般是: scri…

CS的使用

1&#xff09;首先创建服务端 命令&#xff1a;teamserver 192.168.71.130(主机IP) 123456&#xff08;随便设&#xff09; teamserver 192.168.71.130 123456 >/dev/null 2>&1 & (命令隐藏后台&#xff0c;jobs查看后台&#xff0c;客户端同理&#xff0c;在st…

C/C++Unix网络编程-IPC简介

IPC是进程间通信的简称。 进程、线程与信息共享 Unix进程间的信息共享的方式&#xff1a; (1) 左边的两个进程共享存留于文件系统中某个文件上的某些信息。为访问这些信息、每个进程都得穿越内核(例如read、write、lseek等)。当一个文件有待更新时&#xff0c;某种形式的同步…

CTP For Python

GitHub地址&#xff1a;https://github.com/shizhuolin/PyCTP 这是程序化期货交易上期ctp接口版本.将其包装为python版本. 支持python3 编译需求:vs2010/gcc 编译方法 python setup.py build PyCTP 编译方法 开发环境&#xff1a;windows 10 64bit, python 3.4.3 32bit, Visu…

CSP-S 2021

[CSP-S 2021] 括号序列 题目描述 小 w 在赛场上遇到了这样一个题&#xff1a;一个长度为 n n n 且符合规范的括号序列&#xff0c;其有些位置已经确定了&#xff0c;有些位置尚未确定&#xff0c;求这样的括号序列一共有多少个。 身经百战的小 w 当然一眼就秒了这题&#x…

CyberSploit:1

一、环境搭建 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/cybersploit-1,506/ 二、漏洞复现 探测靶机ip地址&#xff0c;得到靶机IP地址 nmap扫描服务以及端口&#xff0c;发现80和22端口 访问80端口&#xff0c;看到一个页面&#xff0c;查看源码未发现东西 …

[网络安全]dSploit-Android系统下的网络分析和渗透套件的使用

一、准备工作 一台已经获得root权限的安卓手机&#xff0c;并且安卓系统版本在 2.3 以上 busyBox 安装软件 下载地址 BusyBox 是一个集成了一百多个最常用linux命令和工具的软件。&#xff3b;百度百科&#xff3d; 安装这个软件主要是为dsploit软件的运行提供 linux 中…

记一次无线渗透

用到的工具 一台root的安卓手机&#xff08;我这台手机刷了miui9&#xff09; Csploit 安卓渗透神器 下载地址&#xff1a;https://github.com/cSploit/android/releases Kali meterpreter 当然你有Kali的Nethunter设备更好 开始测试 利用万能钥匙找一波wifi&#xff0c;运气好…

为网络安全红队方向提供的资源,工具大合集(渗透测试)

这是一份必备的资源大合集&#xff0c;收录了最优秀的网络安全红队方向&#xff08;渗透测试&#xff09;的资源和工具。 &#xff08;文末领取读者福利&#xff09; 无论您是初学者还是专业人士&#xff0c;都能从中获得所需的技能和知识。 在这个信息化时代&#xff0c;网络…

如何在网站中插入视频

&#xfeff;&#xfeff; 很多新手站长在往自己网站里&#xff0c;添加土豆优酷等视频网站里的视频时&#xff0c;会遇到一些麻烦,珊珊在这里向大家介绍一种简单方法. 1.首先要找到要插入的视频&#xff0c;如下图点击分享给朋友右侧的小按钮. 2.点击按钮后弹出一个窗口点击复…

Word中轻松插入本地视频

场景 在Word文档中插入视频 实现 新建或打开Word文档 找到上面插入菜单栏&#xff0c;点击并选择对象 点击后选择PPT 点击确定 此时会打开PPT&#xff0c;然后再选择上面的插入 选择插入下的视频选项&#xff0c;然后选择PC上的视频 选择视频后点击插入 可以调整视频大小 …

如何在html里插入视频

第一步&#xff1a;首先下载video.js&#xff0c;百度一下就能找到。 这个是下载后的目录。 第二步&#xff1a;先把要用到的js\css\swf都加载到html页面上。 如&#xff1a; 第三步&#xff1a;加入下面的代码&#xff1a; <video id"my_video_1" class"…

制作往图片里插入视频,视频添加到图片上播放

在视频中还有个小视频同时播放&#xff0c;这种画中画的效果以前都学习过&#xff0c;那在图片上插入视频播放&#xff0c;可以用媒体梦工厂中的画中画功能来制作吗&#xff1f;这个肯定是可以的了。下面就来看看怎么的操作的吧。 先来看看图片加视频制作出来的画中画效果 制作…

插入视频--使用<video>标签为网页添加视频

使用方法 举例 显示结果 在网页上添加视频和添加音频的标签属性用法相同。 讲解 1.autoplay:如果出现该属性&#xff0c;则视频在就绪后马上播放。 2.controls:如果出现该属性&#xff0c;则向用户显示控件&#xff0c;比如播放按钮。 3.loop:如果出现该属性&#xff0c;…

视频剪辑工具,如何批量在图片中插入视频

怎么批量在图片中插入视频呢&#xff1f;其实这是一种很常见的效果&#xff0c;那么这种效果是怎么制作的呢&#xff1f;下面随小编一起来操作。 所需工具 多张图片、视频素材 操作步骤 运行媒体梦工厂&#xff0c;将图片导入画中画板块中的“底画”中&#xff0c;多张图片&…

教你给视频画面任意位置插入GIF图

视频怎么添加GIF图片呢&#xff1f;如何在视频任意位置添加的呢&#xff1f;其实很简单。教你这个简单的剪辑方法。一起来试试吧。 准备工具&#xff1a; 视频素材及动图 下载一个视频剪辑高手 开始操作&#xff1a; 运行软件登录上&#xff0c;在多种功能上选择“批量剪辑视…

计算机word如何提交,如何在word添加视频?

您可以从计算机或Internet添加视频以直接在Word文档中播放。 此功能使您(或与您共享文档的人)可以直接观看视频而无需离开文档。 将视频添加到Word文档 将离线视频(或计算机存储中的视频)添加到Word文档的不利之处在于&#xff0c;它们只能在您的PC上播放。 如果您将文档发送给…

如何在html网页中插入视频(以及让视频自动播放的问题)

直接进入正题&#xff1a; 关于视频的插入可使用 video标签 如下图 简单介绍下用到的几个属性 class定义了video类 在style中调整这个类的长度和高度属性&#xff1b; src处引入视频的链接&#xff1b; controls属性&#xff1a;允许用户控制视频的播放&#xff0c;包括音…