这个就是学习时候用的,杂七杂八堆起来,希望我还能 捋清楚。
1、窗体分割,一般选择单文档,但是我又想要对话框那种按钮界面,于是就找资料,查到了这个窗体分割,然后把对话框嵌入窗体,就是一半是对话框,一半是单文档。
先放链接:MFC单文档窗体分割,分割后的窗体使用对话框嵌入表示 (也可以看看吧,感觉不是很好,这个 VC++—— 一档多视:)
。。。。还是这个吧,这个最好 --(MFC单文档窗口分割(拆分))
很简单的代码,LeftWin是我的对话框 ,CMy0727MfcTestAppView是视图
然后运行代码,就可以看到左边是对话框右边是原本的单文档的样子,
这里为什么用CSize(rect.Width() / 2, rect.Height() / 2),而不用固定的数字?当然是因为我发现用数字它竟然不会改变大小?就很奇怪,于是我就调成了rect。。。。。那么问题何在?原来它会把上一次的结构记录到注册表,然后下一次按上次结束的样子打开,这。。显然不是我想要的,我就要每次一样,于是找方案,后来学到了删除注册表信息,。。。去App类中的ExitInstance函数里面,
加上CleanState(); //清除程序在注册表写入的状态信息
然后就可以改变大小了,(改变大小当然是去CMainFrame::PreCreateWindow(CREATESTRUCT& cs)里面了,百度百度)(这里是说怎么改变界面大小)
2、RichEdit控件,前面不是被CRichEditView折磨的很惨很惨?这不就是来报仇了,View搞不定,搞定一个控件总可以的吧。
有一说一,很幸运,完全可以实现拖拽功能,和之前网上说的方案一样,此处用的EN_DROPFILES消息,在自动添加的注释里面告诉我们,
// TODO: 控件将不发送此通知,除非您重写
// CFormView::OnInitDialog() 函数,以将 EM_SETEVENTMASK 消息发送
// 到该控件,同时将 ENM_DROPFILES 标志“或”运算到 lParam 掩码中。
那就按照他说的做,( LeftWin::OnInitialUpdate()函数里加上这一句 -- 初始化嘛,都一样,因为继承的基类有点点不同,继承的Dialog就去找OnInitDialog(),问题不大)(忘记有没有问题了,可以试一下,哦,好像还是不一样的,CFrowView不是对话框,欸,没试过,反正遇到都可以试试,无妨)(可以去查CFromView,差不多就明白了)
m_richedit.SetEventMask(m_richedit.GetEventMask() | ENM_SCROLL | ENM_CHANGE | ENM_SELCHANGE | ENM_DROPFILES); //就这样设置
然后去函数里面响应拖拽就可以了,至于怎么响应,当然是去翻txt之CRichEditView了;MFC实现Txt03之CRichEditView实现文本拖拽功能
这里什么文本同步/画线/画刷,都是一样的操作,无非是画刷和画线需要在View中添加鼠标移动的处理函数罢了,毕竟需要跟着鼠标移动痕迹绘制出来,仅此而已,其实这里的自由画刷就是前面文章 :MFC画刷绘图,双缓冲,在此就不赘述
1、窗体分割,一般选择单文档,但是我又想要对话框那种按钮界面,于是就找资料,查到了这个窗体分割,然后把对话框嵌入窗体,就是一半是对话框,一半是单文档。
先放链接:MFC单文档窗体分割,分割后的窗体使用对话框嵌入表示 (也可以看看吧,感觉不是很好,这个 VC++—— 一档多视:)
。。。。还是这个吧,这个最好 --(MFC单文档窗口分割(拆分))
很简单的代码,LeftWin是我的对话框 ,CMy0727MfcTestAppView是视图
1 // 设置左右两个窗口大小 2 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 3 { 4 // TODO: 在此添加专用代码和/或调用基类 5 CRect rect; 6 7 GetClientRect(rect); 8 9 m_wndSplitter.CreateStatic(this, 1, 2); 10 11 m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(LeftWin), CSize(rect.Width() / 2, rect.Height() / 2), pContext); 12 //// m_splitter.CreateView(0, 0, RUNTIME_CLASS(CLeftShowDlg), CSize(rect.Width() / 2, rect.Height() / 2), pContext); 13 m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CMy0727MfcTestAppView), CSize(rect.Width() / 2, rect.Height() / 2), pContext); 14 15 16 return TRUE; 17 }
这肯定是要加头文件的:这里肯定会有人摔沟里,(说的就是我。。。)Doc.h必须在View.h前面,不然就是卡着你不让你过,原因很简单,因为View中需要Doc变量,你不给就是没法用,所以千万千万注意这两个头文件的顺序,不妨去看
#include "LeftWin.h" #include "0727MfcTestAppDoc.h" #include "0727MfcTestAppView.h"
这里为什么用CSize(rect.Width() / 2, rect.Height() / 2),而不用固定的数字?当然是因为我发现用数字它竟然不会改变大小?就很奇怪,于是我就调成了rect。。。。。那么问题何在?原来它会把上一次的结构记录到注册表,然后下一次按上次结束的样子打开,这。。显然不是我想要的,我就要每次一样,于是找方案,后来学到了删除注册表信息,。。。去App类中的ExitInstance函数里面,
加上CleanState(); //清除程序在注册表写入的状态信息
然后就可以改变大小了,(改变大小当然是去CMainFrame::PreCreateWindow(CREATESTRUCT& cs)里面了,百度百度)(这里是说怎么改变界面大小)
2、RichEdit控件,前面不是被CRichEditView折磨的很惨很惨?这不就是来报仇了,View搞不定,搞定一个控件总可以的吧。
有一说一,很幸运,完全可以实现拖拽功能,和之前网上说的方案一样,此处用的EN_DROPFILES消息,在自动添加的注释里面告诉我们,
// TODO: 控件将不发送此通知,除非您重写
// CFormView::OnInitDialog() 函数,以将 EM_SETEVENTMASK 消息发送
// 到该控件,同时将 ENM_DROPFILES 标志“或”运算到 lParam 掩码中。
那就按照他说的做,( LeftWin::OnInitialUpdate()函数里加上这一句 -- 初始化嘛,都一样,因为继承的基类有点点不同,继承的Dialog就去找OnInitDialog(),问题不大)(忘记有没有问题了,可以试一下,哦,好像还是不一样的,CFrowView不是对话框,欸,没试过,反正遇到都可以试试,无妨)(可以去查CFromView,差不多就明白了)
m_richedit.SetEventMask(m_richedit.GetEventMask() | ENM_SCROLL | ENM_CHANGE | ENM_SELCHANGE | ENM_DROPFILES); //就这样设置
然后去函数里面响应拖拽就可以了,至于怎么响应,当然是去翻txt之CRichEditView了;MFC实现Txt03之CRichEditView实现文本拖拽功能
3、View间数据传递:
现在有两个View,一个是普通CView,一个是CFromView,装载着一个对话框,我现在怎让这两个View进行沟通呢?这显然就是得用到MFC的文档视图结构了(其实我只是意会),反正就是数据丢在Doc中,然后View去Doc中存取数据就完事,说的什么MCV三层架构,什么Doc/View结构都差不多,就是分工合作,各干各的事。
简单来说就是,需要沟通传递的数据我存在Doc里,两个View分别读写Doc的数据,就可以了,简单;(记得加上Doc头文件)
就这样,当点击leftwin中的按钮时,就改变变量的值,然后强制刷新,(因为不刷新,其他地方根本不知道数据变化了,就没有效果,所以强制刷新,大家同步更换,出现设置的效果)右边的View在刷新过程中就可以根据新的数据值做出对应的变化了。问题解决。如下,
1 // 五角星 -- 这是一个按钮的事件处理程序哦 2 void LeftWin::OnBnClickedButton1() 3 { 4 // TODO: 在此添加控件通知处理程序代码 5 CMy0727MfcTestAppDoc *pDoc = (CMy0727MfcTestAppDoc*)GetDocument();// 获取文档 6 pDoc->DrawFivePointedStar = true; 7 8 // UpdateAllViews()是在DOC / VIEW结构中,当一个视图的数据改变后,通知所有视图作相应的改变,和重画毫无关系 9 // 而UpdateAllViews()是文档与视之间的联系,调用从它会使程序与此文档相关的所有视的UpdateView被调用 10 // 至于是否重画以及怎么画是由各视的UpdateView来决定的。 11 // Invalidate()是使窗口无效,使系统向其发WM_PAINT消息,使的程序的OnPaint被调用重画客户区。 12 pDoc->UpdateAllViews(NULL);// 更新数据 13 } 14 15 16 void CMy0727MfcTestAppView::OnDraw(CDC* pDC) 17 { 18 CMy0727MfcTestAppDoc* pDoc = GetDocument(); 19 ASSERT_VALID(pDoc); 20 if (!pDoc) 21 return; 22 // TODO: 在此处为本机数据添加绘制代码 23 // Draw a Five Pointed Star 绘制五角星 24 if (pDoc->DrawFivePointedStar) 25 { 26 pDC->MoveTo(CPoint(100, 200)); 27 pDC->LineTo(CPoint(300, 200)); 28 pDC->MoveTo(CPoint(100, 200)); 29 pDC->LineTo(CPoint(250, 350)); 30 31 pDC->MoveTo(CPoint(200, 100)); 32 pDC->LineTo(CPoint(150, 350)); 33 pDC->MoveTo(CPoint(200, 100)); 34 pDC->LineTo(CPoint(250, 350)); 35 36 pDC->MoveTo(CPoint(300, 200)); 37 pDC->LineTo(CPoint(150, 350)); 38 } 39 }
4、画图:这还是看一下 MFC画刷绘图 ,这里怎么绘图也说了一些了
5、属性表单+向导:emmmmm,懒,这个网上挺多的;
6、对话框伸缩:
首先拉一个Picture Control 控件,把它拉成一条线,(主要就是为了分割对话框,全显和半显,)
然后添加事件处理程序,通过点击按钮实现对话框的展开/收缩;代码如下:
1 // Dialog2 消息处理程序 2 void Dialog2::OnBnClickedButton1() 3 { 4 // TODO: 在此添加控件通知处理程序代码 5 CString str; 6 // 改变按钮上的字符 -- 显示当前功能 7 if (GetDlgItemText(IDC_BUTTON1, str), str == _T("收缩<<")) 8 { 9 SetDlgItemText(IDC_BUTTON1, _T("扩展>>")); 10 } 11 else 12 { 13 SetDlgItemText(IDC_BUTTON1, _T("收缩<<")); 14 } 15 16 static CRect rectLarge; 17 static CRect rectSmall; 18 19 // 获取矩形大小 -- 装载对话框 20 if (rectLarge.IsRectNull()) 21 { 22 CRect rectSeparator; 23 GetWindowRect(&rectLarge); 24 GetDlgItem(IDC_SEPARATOR)->GetWindowRect(&rectSeparator); 25 26 rectSmall.left = rectLarge.left; 27 rectSmall.top = rectLarge.top; 28 rectSmall.right = rectSeparator.right; 29 rectSmall.bottom = rectLarge.bottom; 30 } 31 32 if (str == _T("收缩<<")) 33 { 34 // MessageBox(_T("收缩<<变小变小变小")); 35 // 是最后一个参数的问题,查一下MSDN 36 SetWindowPos(NULL, 0, 0, rectSmall.Width(), rectSmall.Height(), SWP_NOMOVE | SWP_NOZORDER); 37 } 38 else 39 { 40 SetWindowPos(NULL, 0, 0, rectLarge.Width(), rectLarge.Height(), SWP_NOMOVE | SWP_NOZORDER); 41 } 42 }
2022-09-19