基本控件-上(Num30)
目录
一、静态文本:
超链接(Static Text):
使用:
修改颜色:
修改字体:
二、单选按钮:
使用:
添加一个按键进行操作:
默认选中项操作:
如果需要额外的判断:
三、多选按钮:
使用:
选中复选按钮执行某操作(单选按钮不可以这样干):
切换鼠标的光标:
名字+Dlg.h文件中定义变量:
名字+Dlg.cpp文件中:
构造类中初始化变量:
OnInitDialog中设置默认光标:
创建的OnSetCursor函数中:
供切换的两个按钮的消息处理:
插入:文档的查找
四、编辑框及按钮:
编辑框:
使用:
消除回车自动关闭窗口:
编辑
让编辑框有多行:
设置内容:
获取内容:
弹出登录框:
输入文本,点击其他地方消掉:
五、按钮:
带限制条件的按钮:
设置小图标:
画复杂的线条:
一、静态文本:
超链接(Static Text):
- 准备1个静态文本控件,修改ID,绑定控件变量
- 通过类向导添加自定义类,继承CStatic类
- 在类内添加超链接函数,鼠标左键按下消息响应函数
- 在窗口类.h文件中导入自定义类的.h文件
- 修改控件变量的类型为自定义类
- 在初始化位置打开超链接
使用:
- 工具箱右键将Static Text拖入对话框中:
- 先修改属性的ID,再对控件添加变量,命名一下:
- 绑定了一个控件变量,就可以认为这个控件的产生是由控键变量定义在类中的:
public:CStatic m_link;
产生的
打开类向导->添加MFC类 (基类选择CStatic类):
- 名字+Dlg.h文件中引入继承于CStatic的头文件,将定义类改为继承的类:
#include"MyStatic.h"MyStatic m_link;//将定义类改为继承类将毫无影响
- 现在,要打开超链接,给MyStatic添加点击的响应,然后打开超链接:
- 静态文本不提供点击,所以先写一个setLink来接收点击的操作 :
继承于CStatic类的MyStatiac.h文件:
//公共类中 void setLink(BOOL isLink);
继承于CStatic类的MyStatiac.cpp文件:
void MyStatic::setLink(BOOL isLink) {if (isLink){//增加了一个可以点击的风格ModifyStyle(0, SS_NOTIFY);//要删除的窗口风格,要添加的窗口风格}else{//反之不添加任何风格,将点击的风格移除掉ModifyStyle(SS_NOTIFY,0);} }
- 打开类向导,换到类名MyStatic,消息中添加WM_LBUTTONDOWN,写OnLButtonDown函数中的东西:
void MyStatic::OnLButtonDown(UINT nFlags, CPoint point)
{// TODO: 在此添加消息处理程序代码和/或调用默认值CString str;//现在是在自己的类中获取自己对话框类中的文本GetWindowText(str);//打开文本的内容ShellExecute(NULL,_T("open"),str,NULL,NULL,SW_NORMAL);CStatic::OnLButtonDown(nFlags, point);
}
- 接着调用我们之前写的SetLink函数:
- ###一定要在 名字+Dlg.cpp 文件中的初始化函数进行初始化:
BOOL CMFCApplication2Dlg::OnInitDialog()
- ### 其中有一个类的构造,不要在这里面初始化,这个相当于以前的create窗口创建消息,是在窗口创建之前被响应的,对话框还没创建是不能对对话框进行操作的,如果是类中的数据初始化就可以在构造函数中初始化
CMFCApplication2Dlg::CMFCApplication2Dlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_MFCAPPLICATION2_DIALOG, pParent) {m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); }
- 在下面的消息处理函数中进行初始化:
m_link.setLink(true);
修改颜色:
- 选择名字+Dlg类,选择消息WM_CTLCOLOR
- 名字+Dlg.cpp文件中:
HBRUSH CMFCApplication2Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {//CDC是MFC把win32的GDI封装成类的DCHBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);// TODO: 在此更改 DC 的任何特性// TODO: 如果默认的不是所需画笔,则返回另一个画笔//指定去画ID为谁的控件if (IDC_STATIC_LINK == pWnd->GetDlgCtrlID()){pDC->SetTextColor(RGB(255, 0, 0));//红色pDC->SetBkMode(TRANSPARENT);//背景透明}return hbr; }
修改字体:
- 先在类中定义一个字体,设置一个字体的类型(名字+Dlg.h文件中):
//先在类中设置一个字体的类型CFont m_font;
- 在名字+Dlg.cpp文件中的OnInitDialog函数书写:
CFont* pFont = m_link.GetFont();//得到字体LOGFONT lf;//保存了字体相关的属性pFont->GetLogFont(&lf);//得到当前字体的相关属性lf.lfHeight = 80;//字体大小lf.lfUnderline = true;//下划线lf.lfItalic = true;//倾斜lf.lfWeight = 900;//粗细m_font.CreatePointFontIndirect(&lf);//创建一个新的字体属性m_link.SetFont(&m_font);//再把它设置回文本
- 窗口的属性栏也有字体(这样改会把页面中的全改了):
二、单选按钮:
- 打开编辑器,从工具箱里拖入几个单选按钮,注意拖入的顺序
- 对连续拖入的单选按钮进行分组处理,将每组首个按钮设为组头。例如123 | 456 | 789,147为组头
- 设置按钮文本及其他属性,双击可生成点击事件响应函数
使用:
- 将工具栏中的Radio Button拖进页面(拖进来的时候记一下顺序,默认是拖进来几个就是这几个中选择一个)
- 选中更改的按钮,属性的杂项中,找到组选true则改按钮后面的为一组
###做项目的话建议ID都改一改
添加一个按键进行操作:
- 双击按键创建按键对应的消息处理,一条消息使用弹窗进行处理
void CMFCApplication2Dlg::OnBnClickedButton1() {// TODO: 在此添加控件通知处理程序代码//获取这一组中选中了谁switch (GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO2)){case IDC_RADIO1:MessageBox(_T("男"));break;case IDC_RADIO2:MessageBox(_T("女"));break;} }
多组选项时,使用字符串进行存储,最后再使用弹窗进行输出
void CMFCApplication2Dlg::OnBnClickedButton1() {// TODO: 在此添加控件通知处理程序代码CString str;//获取这一组中选中了谁switch (GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO2)){case IDC_RADIO1:str += _T("性别:男");break;case IDC_RADIO2:str += _T("性别:男");break;}switch (GetCheckedRadioButton(IDC_RADIO3, IDC_RADIO5)){case IDC_RADIO3:str += "\r\n";//在win32中\r\n才是换行str += _T("学历:小学");break;case IDC_RADIO4:str += "\r\n";str += _T("学历:高中");break;case IDC_RADIO5:str += "\r\n";str += _T("学历:初中");break;}MessageBox(str); }
默认选中项操作:
- 在名字+Dlg.cpp文件中的OnInitDialog函数书写:
//默认选中项,改成GetCheck也能用,因为((CButton*)GetDlgItem(IDC_RADIO1))就相当于获取到控件变量((CButton*)GetDlgItem(IDC_RADIO1))->SetCheck(1);//将它强转为具体的控件对象,再指向成员//((CButton*)GetDlgItem(IDC_RADIO1))->SetCheck(BST_CHECKED);//这个是选中的意思,另一个ON是不选中
如果需要额外的判断:
- 右键选中要判断的按钮,添加控制变量,绑定了一个控制变量
void CMFCApplication2Dlg::OnBnClickedButton1() {// TODO: 在此添加控件通知处理程序代码//仅判断单键的是否被选中GetCheck会返回选中状态if (m_radioHeight.GetCheck()){MessageBox(_T("选中了男"));}else {MessageBox(_T("未中男"));} }
- 双击控件得到的就是之前说的单次点击的操作:
void CMFCApplication2Dlg::OnBnClickedRadio4() {// TODO: 在此添加控件通知处理程序代码MessageBox(_T("你点击了高中")); }
三、多选按钮:
- 打开编辑器,从工具箱里拖入复选框
- 编辑按钮ID,设置按钮文本与属性
- 绑定按钮变量(按钮只有控件变量)
- 双击编辑器的按钮控件,生成点击事件处理函数
- 在窗口初始化位置,通过绑定的变量初始化按钮
使用:
工具箱中将Check Box选项拖入页面
- 使用函数写, 右键选中要判断的按钮,添加控制变量,绑定了一个控制变量
void CMFCApplication2Dlg::OnBnClickedButton2() {// TODO: 在此添加控件通知处理程序代码//假设有三种状态,需要定义一个变量来接收这三种状态int state = m_check.GetCheck();switch (state){case 0://没有选中break;case 1://选中break;case 2://不确定break;} }
void CMFCApplication2Dlg::OnBnClickedButton2() {//只有两种状态1/0,不使用创建对象,因为创建对象需要绑定控件变量CString str;if (IsDlgButtonChecked(IDC_CHECK1))str += _T("设备1\r\n");if (IsDlgButtonChecked(IDC_CHECK2))str += _T("设备2\r\n");if (IsDlgButtonChecked(IDC_CHECK3))str += _T("设备3\r\n");MessageBox(str); }
选中复选按钮执行某操作(单选按钮不可以这样干):
void CMFCApplication2Dlg::OnBnClickedCheck1()
{// TODO: 在此添加控件通知处理程序代码if (IsDlgButtonChecked(IDC_CHECK1))SetDlgItemText(IDC_CHECK1, _T("设备1打开"));elseSetDlgItemText(IDC_CHECK1, _T("设备1关闭"));
}
切换鼠标的光标:
- 资源视图中 右键 添加 资源 导入.CUR文件
- 打开类向导,消息中找到设置光标WM_SETCURSOR,一定要找对类名的位置
名字+Dlg.h文件中定义变量:
int type;
名字+Dlg.cpp文件中:
构造类中初始化变量:
type = 0;
OnInitDialog中设置默认光标:
((CButton*)GetDlgItem(IDC_RADIO6))->SetCheck(1);
创建的OnSetCursor函数中:
BOOL CMFCApplication2Dlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{// TODO: 在此添加消息处理程序代码和/或调用默认值switch (type){case 1:HCURSOR cursor = LoadCursor(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDC_CURSOR1));::SetCursor(cursor);return true;}//默认光标return CDialogEx::OnSetCursor(pWnd, nHitTest, message);
}
供切换的两个按钮的消息处理:
void CMFCApplication2Dlg::OnBnClickedRadio6()
{// TODO: 在此添加控件通知处理程序代码type = 0;
}void CMFCApplication2Dlg::OnBnClickedRadio7()
{// TODO: 在此添加控件通知处理程序代码type = 1;
}
插入:文档的查找
右键复选按钮发现是CButton类型,就在文档中搜索CButton即可找到相关的函数
四、编辑框及按钮:
编辑框:
1、打开编辑器,从工具箱里拖入编辑框
或者点击工具箱中的编辑框,通过鼠标画出控件
2、设置控件ID,为控件绑定变量
值变量-保存控件中输入的信息
控件变量-用来编辑对应类型控件的控件对象
3、设置控件属性,直至满足设计需求
例如,只读-true,多行-false
使用:
消除回车自动关闭窗口:
- 工具箱->Edit Control
- 运行时按回车会直接关掉,是因为虚函数中有一个OnOk,双击它创建
- 名字+Dlg.cpp文件中(将里面的一行代码注释掉,再按回车就不会自动关闭窗口了):
void CMFCApplication2Dlg::OnOK()
{// TODO: 在此添加专用代码和/或调用基类//CDialogEx::OnOK();
}
让编辑框有多行:
- 将属性中的 1.左侧滚动条条 2.多行 3.想要返回 设置为true即可
设置内容:
- 右键编辑框,添加控件变量
- 单纯的文本的获取->使用值变量,设置名称
- 添加一个按键->双击创建
名字+Dlg.cpp文件中的OnBnClickedButton3(真正改动的只有最后几行,其余的都是之前获取信息的):
void CMFCApplication2Dlg::OnBnClickedButton3()
{// TODO: 在此添加控件通知处理程序代码CString str;//获取这一组中选中了谁switch (GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO2)){case IDC_RADIO1:str += _T("性别:男");break;case IDC_RADIO2:str += _T("性别:男");break;}switch (GetCheckedRadioButton(IDC_RADIO3, IDC_RADIO5)){case IDC_RADIO3:str += "\r\t";//在win32中\r\n才是换行str += _T("学历:小学");break;case IDC_RADIO4:str += "\r\t";str += _T("学历:高中");break;case IDC_RADIO5:str += "\r\t";str += _T("学历:初中");break;}if (IsDlgButtonChecked(IDC_CHECK1))str += _T("设备1\r\t");if (IsDlgButtonChecked(IDC_CHECK2))str += _T("设备2\r\t");if (IsDlgButtonChecked(IDC_CHECK3))str += _T("设备3\r\t");str += "\r\n";//将得到的值赋值给值变量,然后再UpdateData传参为假//m_str = str;//每次进行拼接改为+=m_str += str;UpdateData(FALSE);//win32和mfc中真假一般写成大写的
}
获取内容:
- 三个Edit Control和两个Static Text(输入两个数得到和)
- 给三个编辑框都右键添加变量(以此类推,变量类型改为int类型)
- 第三个编辑框不需要修改,属性中找到 只读,改为true
- 双击编辑前两个框创建(Edit这里不是点击处理而是文本内容发生改变)
名字+Dlg.cpp文件中:
//文本内容发生改变
void CMFCApplication2Dlg::OnEnChangeEdit2()
{// TODO: 如果该控件是 RICHEDIT 控件,它将不// 发送此通知,除非重写 CDialogEx::OnInitDialog()// 函数并调用 CRichEditCtrl().SetEventMask(),// 同时将 ENM_CHANGE 标志“或”运算到掩码中。// TODO: 在此添加控件通知处理程序代码//传参为真,把控件里面的内容更新到环境的值变量上UpdateData(TRUE);m_v3 = m_v1 + m_v2;//传参为假,把内容更新到控件上UpdateData(FALSE);
}void CMFCApplication2Dlg::OnEnChangeEdit3()
{// TODO: 如果该控件是 RICHEDIT 控件,它将不// 发送此通知,除非重写 CDialogEx::OnInitDialog()// 函数并调用 CRichEditCtrl().SetEventMask(),// 同时将 ENM_CHANGE 标志“或”运算到掩码中。// TODO: 在此添加控件通知处理程序代码//传参为真,把控件里面的内容更新到环境的值变量上UpdateData(TRUE);m_v3 = m_v1 + m_v2;//传参为假,把内容更新到控件上UpdateData(FALSE);
}
弹出登录框:
- 添加一个按钮Button,双击创建
- Dialog中插入一个对话框,双击新建的对话框,添加新的MFC类
- 先在原 名字+Dlg.h文件中添加头文件
#include"LogDlg.h"
- 原 名字+Dlg.cpp文件中使用模态对话框
void CMFCApplication2Dlg::OnBnClickedButton4()
{// TODO: 在此添加控件通知处理程序代码//使用模态对话框LogDlg ld;ld.DoModal();
}
- 回到新建的对话框中,添加两个Static Text和两个Edit Control
- 密码后面的编辑框选中属性中有一个密码更改为true,密码就会变成。。。的形式
- 再添加一个登录按钮
- 用户名和密码都添加变量,获取值变量
- 登录双击创建
- 原 名字+Dlg.cpp文件的OnBnClickedButton1中
void LogDlg::OnBnClickedButton1()
{// TODO: 在此添加控件通知处理程序代码UpdateData(TRUE);if (m_name == _T("123") && m_password == _T("123"))MessageBox(_T("成功"));elseMessageBox(_T("失败"));
}
输入文本,点击其他地方消掉:
- 再初始对话框创建一个编辑框,右键添加控件变量,命名创建
- 先将其隐藏 ,在名字+Dlg.cpp文件的OnInitDialog中
m_strEdit.ShowWindow(SW_HIDE);//默认是隐藏
- 添加按钮,双击创建
- 在名字+Dlg.cpp文件的OnBnClickedButton5中
void CMFCApplication2Dlg::OnBnClickedButton5()
{// TODO: 在此添加控件通知处理程序代码//需要把静态文本相对于窗口的rect结构算出来RECT r1 = { 0 };//得到客户端的RECT结构,相对于窗口的坐标m_link.GetWindowRect(&r1);RECT r2 = { 0 };m_link.GetWindowRect(&r2);r1.top -= r2.top;r1.left -= r2.left;RECT r3 = { 0 };m_link.GetClientRect(&r3);r1.right = r1.left + r3.right;r1.bottom = r1.left + r3.bottom;m_strEdit.ShowWindow(SW_SHOW);m_strEdit.MoveWindow(&r1);
}
- 打开类向导,对编辑框选择EN_KILLFOCUS双击创建
- 在名字+Dlg.cpp文件的OnKillfocusEdit6中
void CMFCApplication2Dlg::OnKillfocusEdit6()
{// TODO: 在此添加控件通知处理程序代码CString str;//得到Edit中的内容m_strEdit.GetWindowText(str);//把Edit中的内容设出去m_link.SetWindowText(str);//最后再隐藏m_strEdit.ShowWindow(SW_HIDE);
}
五、按钮:
带限制条件的按钮:
- 在对话框类中创建按钮,对之前的修改网址按钮添加控件变量
- 双击按钮创建(激活与非激活操作)
void CMFCApplication2Dlg::OnBnClickedButton6()
{// TODO: 在此添加控件通知处理程序代码static int x = 1;if (x){m_strbutton.EnableWindow(FALSE); //非激活x = 0;}else{m_strbutton.EnableWindow(TRUE); //激活x = 0;}
}
设置小图标:
- 设置一个Icon在名字+Dlg.cpp文件的OnInitDialog中
m_strbutton.SetIcon(m_hIcon);//设置一个小图标
- 设置的小一点,从资源中加载
//从资源当中加载
HICON ico = (HICON)LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
m_strbutton.SetIcon(ico);//设置一个小图标
- 右键类向导添加一个类继承button
- 在继承的Button中虚函数中进行下拉,找到DreamItem双击进行确定
- 再创建一个按钮,拉大一点 ,右键添加控件变量
- 在原 名字+Dlg.cpp文件中要对MyButton头文件进行声明 ,用MyButton把底下的CButton替换掉
#include"MyButton.h"MyButton m_dreamButton;
- 这个按钮属性中所有者描述必须设置为真(这样绘制才会生效)
画复杂的线条:
-
在MyButton.h文件中进行初始化,声明函数initButton
void initButton();
MyButton.cpp文件中:
void MyButton::initButton()
{SetTimer(1001, 100,NULL);
}
- 右键类向导,消息中找到WM_TIMER计时器消息双击创建
- 书写MyButton.cpp文件:
// MyButton.cpp: 实现文件
//#include "pch.h"
#include "MFCApplication2.h"
#include "MyButton.h"// MyButtonIMPLEMENT_DYNAMIC(MyButton, CButton)MyButton::MyButton()
{//SetTimer(1001, 100, NULL); //构造函数中不要设置计时器
}MyButton::~MyButton()
{
}BEGIN_MESSAGE_MAP(MyButton, CButton)ON_WM_TIMER()
END_MESSAGE_MAP()// MyButton 消息处理程序double a1;
double b1;
double a2;
double b2;void MyButton::DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
{CDC* pdc = GetDC();RECT rect = { 0 };GetClientRect(&rect);pdc->Ellipse(&rect);pdc->MoveTo(a1, b1);pdc->LineTo(a2, b2);// TODO: 添加您的代码以绘制指定项
}void MyButton::initButton()
{SetTimer(1001, 100, NULL);
}
double pi = 3.1415926;
double angle1 = 0, angle2 = 180; //角度void MyButton::OnTimer(UINT_PTR nIDEvent)
{// TODO: 在此添加消息处理程序代码和/或调用默认值RECT rect = { 0 };GetClientRect(&rect);int r = min(rect.right, rect.bottom);int x = rect.right / 2;int y = rect.bottom / 2;if (angle1 >= 360){angle1 = 0;angle2 = 180;}angle1++;angle2++;a1 = x + r / 2 * cos(angle1 * pi / 180);b1 = y + r / 2 * sin(angle1 * pi / 180);a2 = x + r / 2 * cos(angle2 * pi / 180);b2 = y + r / 2 * sin(angle2 * pi / 180);//不停的产生绘制消息this->InvalidateRect(&rect, 0);CButton::OnTimer(nIDEvent);
}
- 原 名字+Dlg.cpp文件中,初始化一下按钮
//初始化按钮,为了启动计时器
m_dreamButton.initButton();
###注意构造的时候还没有窗口,不能启动计时器进行绘制