VC+MFC 学习笔记之一(截止到2016.4.9)
2016-03-14 20:22
323 查看
摘要提示:
//===========================================================================1.子窗体和父窗体的切换
2.子窗体中结合OpenCV显示图片
3.子窗体获取父窗体数据方法&文本框显示
4.子窗体向父窗体传递数据方法之一
5.解决子窗体默认始终在前的方法
6.在子窗体中建立初始化函数的方法
7.点击窗体的关闭按钮,返回的是IDCANCEL消息
8.修改窗体为不能改变大小,在属性的border里面修改,设置为Dialog Frame即可。
10.子窗体使用ComBox控件,不能显示子选项。解决方法
11.获得鼠标的桌面坐标,并且显示。
12.文本框多行显示 和 限制每行的长度和文本框的宽度一一致。
13.文本框输出,焦点设置在字符串最后。
14.MFC使用提示窗输出字符、查看字符串、带参数值。
15.关于进位制的两三事
16.回车不关闭窗体
17.SetTimer使用
18.获取系统时间
=============================================================================//1.子窗体和父窗体的切换
参考:http://blog.csdn.net/HEVC_CJL/article/details/9973169第一、在MFC下新建win32(基本对话框)工程,然后再添加一个子窗体(在资源视图中操作),子窗体设置(属性->行为->Visible->True,其他设置根据需要决定是否设置)。基本准备工作结束。
第二、在子窗体上(鼠标右键->添加类->设置如下图)给子窗口建立一个类。比如类名:CTestDlg
第三、在父窗口所在的(工程名XX) XXDlg.h文件中包含 CTestDlg.h,并且建立CTestDlg类的成员
public:
CTestDlg *m_cTest;
第四、在父窗口的构造函数(构造函数是一种可初始化其类的实例的成员函数。构造函数具有与类相同的名称,没有返回值。)中给CTestDlg类的成员分配资源:
m_cTest = new CTestDlg(this);
第五、在子窗口的函数中使用Create函数:
m_cTest->Create(IDD_DIALOG1, this);//IDD_DIALOG1为子窗口ID
第六、给子窗口添加WM_CLOSE消息。注意:是子窗口代码中(CTestDlg.cpp)添加消息事件。
在生成的OnClose函数中销毁窗口:DestroyWindow();
2.子窗体中结合OpenCV显示图片
父窗体,BOTTON1子窗体,picture control 控件 IDD_PICTURE
第一、在子窗体中,建立初始化函数
在子窗体.h文件的类定义中,建立protected : virtual BOOL OnInitDialog() ; 声明子窗体的初始化函数
在子窗体.cpp文件中,建立BOOL CTestDlg::OnInitDialog(){}子窗体初始化函数的函数体,代码均在此区域中
第二、在子窗体.cpp文件中,建立全局变量
IplImage* src = cvLoadImage("D:\\PERSONAL\\VC++\\OpenCV\\image\\hy2head.jpg"); CRect rect; CDC *pDC; HDC hDC; CWnd *pwnd;
第三、在BOOL CTestDlg::OnInitDialog()中输入
BOOL CTestDlg::OnInitDialog() { // TODO: 在此添加消息处理程序代码和/或调用默认值 pwnd = GetDlgItem(IDC_STATIC); pDC =pwnd->GetDC(); hDC= pDC->GetSafeHdc(); pwnd->GetClientRect(&rect); CvvImage m_CvvImage; m_CvvImage.CopyOf(src,1); m_CvvImage.DrawToHDC(hDC, &rect); return true; }
OK!
其中,CvvImage类的说明,见http://blog.csdn.net/u014488388/article/details/51104179 第3点。
3.子窗体获取父窗体数据方法&文本框显示
第一、文本框的显示方法画好框架后,调用代码如下:
<span style="white-space:pre"> </span>CString str; str.Format(_T("%d"),tx);// tx是int型变量 SetDlgItemText(IDC_EDIT1,str); // <span style="font-family: Arial, Helvetica, sans-serif;">IDC_EDIT1 文本框的ID Num.</span>文本框字符串读取,转化为数字。
void CvariableDlg::OnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 CString ww; GetDlgItemTextW(IDC_EDIT_INPUT,ww); k = _wtoi(ww); m_cTest->tx = k++; m_cTest->Create(IDD_DIALOG_SUB,this); }
第二、数据传递
现在子类.h中定义public : int num,再定义某子类的变量XX,然后在父.cpp中使用XX->num来给num赋值
代码如下:
子类 .h 中
public: int tx;父类 .h 中
Public: <span style="white-space:pre"> </span>CTestDlg *m_cTest;父类 .cpp中消息响应函数添加
void CvariableDlg::OnClickedButton1() { // TODO: 在此添加控件通知处理程序代码 m_cTest->tx = 250; m_cTest->Create(IDD_DIALOG_SUB,this);//IDD_DIALOG_SUB 子类窗体的ID num. }
显示在子类的文本框中: (此两个函数可以在类向导里添加!)
BOOL CTestDlg::OnInitDialog()//子窗体初始化 { CDialogEx::OnInitDialog(); CString str; str.Format(_T("%d"),tx); SetDlgItemText(IDC_EDIT1,str); return true; } void CTestDlg::OnClose()//子窗体关闭以后销毁生成的窗体 { // TODO: 在此添加消息处理程序代码和/或调用默认值 DestroyWindow(); CDialogEx::OnClose(); }
4.子窗体向父窗体传递数据方法之一
参考:http://www.tc5u.com/mfc/1806175.htm使用全局静态变量:在类中名字就是 类成员静态变量,在类外面就是静态变量
首先,在父窗体.cpp中定义
#include "TestDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif int num1;//看这里!注意添加位置!是在其他函数 XX(){}之外的区域
然后,在父窗体.h文件中
#include "TestDlg.h" #pragma once extern int num1;
<span style="font-family: 新宋体, 宋体, Arial;">//看这里!注意添加位置!</span>
在你想要使用num1的.cpp文件的对应.h文件中添加
extern int num1;
这样,在其他子窗体.cpp文件中就都能使用num1了。
还有使用类成员静态变量的方法,待日后再研究~
5.解决子窗体默认始终在前的方法
参考:http://www.xuebuyuan.com/541854.html问题出在:
m_cTest->Create(IDD_DIALOG_SUB,this);
鼠标点击父窗口,但是子窗口始终在前,而子窗体们的前后则可以由鼠标调整。
解决方法,将this 修改为 GetDesktopWindow() 。
m_cTest->Create(IDD_DIALOG_SUB,GetDesktopWindow());
Bingo!
6.在子窗体中建立初始化函数的方法
在默认情况下,MFC的子窗体.cpp中是没有初始化函数的,而且在类向导中也找不到。第一、在子窗体.h文件的class中建立virtual BOOL OnInitDialog(),注意是 protected:
protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 virtual BOOL OnInitDialog();
第二、在子窗体.cpp文件中建立
BOOL CDiff::OnInitDialog() { CDialogEx::OnInitDialog();</span> //在这里之下添加自己的代码 return true; }
注意,一定要有返回值,return true;
在其中添加子窗体的初始化代码即可。
7.点击窗体的关闭按钮,返回的是IDCANCEL消息
8.修改窗体为不能改变大小,在属性的border里面修改,设置为Dialog Frame即可。
10.子窗体使用ComBox控件,不能显示子选项。解决方法
原因一、拉窗体不到位(待定)实测MFC会自己调整下拉框的大小,在绘制控件时没有调整到合适的大小不会影响显示。
但是网上有大量的说法说会影响,可能版本问题吧,VS2012没有这个问题。若是VC6.0的话就不一定啦。
调整方法如下:
and then
原因二、子窗体的初始化函数书写不当(坑爹)
参考阅读:http://bbs.21ic.com/blog-621237-83411.html
注意1,子窗体本身不带初始化函数,要自己写,具体方法见上文所述。
注意2,初始化函数中,CDialogEx::OnInitDialog();是模仿父窗体中的初始化函数,但是解决问题了。用途不大清楚,也希望大家能赐教。
BOOL CSon::OnInitDialog() { CDialogEx::OnInitDialog();//不可缺少,关键所在 return true; }
11.获得鼠标的桌面坐标,并且显示。
在主窗体的.cpp的初始化函数OnInitDialog()中添加:(大循环要在timer中来实现)
SetTimer(1,10,NULL);在OnTimer()中添加:
void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 POINT pMouse; GetCursorPos(&pMouse); SetDlgItemInt(IDC_EDIT_X,pMouse.x); SetDlgItemInt(IDC_EDIT_Y,pMouse.y); CDialogEx::OnTimer(nIDEvent); }
总结两种其他情况:
第一、显示的是在主窗体上的鼠标坐标,原点为主窗体的左上角点。
代码是响应主窗体.cpp下的mousemove()消息,其入口参数point就包含了鼠标的坐标信息,但是是相对于窗体的坐标。
void CMFCApplication1Dlg::OnMouseMove(UINT nFlags, CPoint point)//point入口形参就包含鼠标的坐标值(相对窗体内) { // TODO: 在此添加消息处理程序代码和/或调用默认值 SetDlgItemInt(IDC_EDIT_X,point.x); SetDlgItemInt(IDC_EDIT_Y,point.y); CDialogEx::OnMouseMove(nFlags, point); }
第二、主窗体.cpp下的mousemove()消息是只有鼠标在主窗体区域内才响应的事件。
void CMFCApplication1Dlg::OnMouseMove(UINT nFlags, CPoint point)//point入口形参就包含鼠标的坐标值(相对窗体内) { // TODO: 在此添加消息处理程序代码和/或调用默认值 POINT pMouse; GetCursorPos(&pMouse); SetDlgItemInt(IDC_EDIT_X,pMouse.x); SetDlgItemInt(IDC_EDIT_Y,pMouse.y); CDialogEx::OnMouseMove(nFlags, point); }
12.文本框多行显示 和 限制每行的长度和文本框的宽度一一致。
文本框的属性设置如下:这样就可以支持多行显示,但是文本的一行的宽度一般都会超过文本框的宽度,解决方案如下:
限制一行的宽度
在初始化函数中添加代码:
m_edit1.SetLimitText(1);m_edit1是定义的文本框的控制类型的变量。
13.文本框输出,焦点设置在字符串最后。
CEdit * pEdit = (CEdit*)GetDlgItem(IDC_EDIT1); pEdit->SetSel(-1); pEdit->SetFocus();
14.MFC使用提示窗输出字符、查看字符串、带参数值。
str_ascii.Format(_T("%d,%d"),hexH,hexL); AfxMessageBox(str_ascii);要注意的是_T()是不可以直接带参数的,所以利用CString中的format。
15.关于进位制的两三事
第一、数字在内存之中都是以二进制形式存在。也就是说:int a = 4000; 在内存中,开辟一个“a”的区域,里面存放的是4000的二进制,即1111 1010 0000。
int a = 0x0F4A0; 其实和int a = 4000(十进制默认,不需要0x之类的标识); 是等价的。所以不管是用什么进制的值来给变量赋值,变量里面都是转化为二进制的值。
第二、非十进制中,数字的显示和四则运算,其实很十进制也是一样的。
int a = 4000;
int b = 3000;//和 int b = 0x0BB8等价
a = a - b ; 所以a = 1000。这是十进制下的,没问题。但是
a = a - 0x0BB8;所得到的a也是1000,也是0x03E8。(0x0BB8 是 3000 的十六进制)。
其实,不管是几进制加减几进制,得数都一样,只是在不同进制下的写法不同罢了。
输出可以使用printf(_T("%04X"),a);来查看a的十六进制,%04X表示十六进制有四位。
16.回车不关闭窗体
是一个焦点的问题。重载OnOK消息。OnOK()是窗体类自带的函数,直接 先在头文件中声明,再在.cpp中添加一下函数。
void CcameraDlg::OnOK() { if(GetDlgItem(IDOK)==GetFocus()) { CDialog::OnOK(); } //handle enter key }
17.SetTimer使用
参考:http://www.sx.xinhuanet.com/fwxx/2008-11/17/content_14933678.htm参考:http://blog.csdn.net/libin88211/article/details/25491979
UINT SetTimer(1,100,NULL);
函数反回值就是第一个参数值1,表示此定时器的ID号。
第二个参数表示要等待100毫秒时间再重新处理一次。第三个参数在这种方法中一般用NULL。
注意:设置第二个参数时要注意,如果设置的等待时间比处理时间短,程序就会出问题了。
18.获取系统时间
CString str; //获取系统时间 // str = tm1.Format(_T("现在时间是%Y年%m月%d日 %X")); CTime tm1; tm1 = CTime::GetCurrentTime(); str = tm1.Format("%X");//hh:mm:ss
相关文章推荐
- 面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?
- mac安装nginx步骤
- setuid函数解析
- 二叉树的层次遍历
- 字典树 详解 模板代码 加典型习题
- WebApi与手机客户端通信安全机制
- 最大堆和最小堆
- hdoj_5643 King's Game(约瑟夫环问题变种)----超时版本(自己模拟的循环链表)
- POJ 2155 二维线段树基本操作
- 多张表中数据组合后插入新表的方法
- JS基础回顾,小练习(获取一个对象里面第一层元素的数量)
- 最全git教程
- Matlab实现两个大数相加
- 关于k小的实现及优化(c)
- Java经典设计模式之七大结构型模式(附实例和详解)
- hdu3613 extend-kmp
- 微商之路产品个性化
- [uva1588]Kickdown
- iOS点击完按钮 出现 keyboard 并且屏幕上移
- 浅谈 Android MVP