mfc 字符

字符集

  1. 多字节字符集(8位的ANSI字符集)
    在Windows98以及以前的版本使用8位ANSI字符集,它类似于我们程序员熟悉的ASCII字符集。
char sz[] = "ABCDEFG";
char *psz = "ABCDEFG";
int len = strlen(sz);
  1. 宽字符集(16位的Unicode字符集)
    在WindowsNT和Windows2000后开始使用16位的Unicode字符集,它是ANSI字符集的一个超集。Unicode适用于国际市场销售的应用程序,因为它包含各种各样来自非U.S.字母表的字符,比如中文,日文,韩文,西欧语言等。
//在字符串前加字母L表示将ANSI字符集转换成Unicode字符集。
wchar_t wsz[] = L"ABCDEFG"; 
wchar_t *pwsz = L"ABCDEFG";
int len = wcslen(wsz); //测试宽字节字符串的长度
  1. TEXT(_T)宏
    MFC中的TEXT宏可以自动适应字符类型,如果定义了预处理器程序符号_UNICODE,那么编译器将使用Unicode字符,如果没用定义该预处理器程序符号,那么编译器将使用ANSI字符。
	MessageBox(TEXT("鼠标左键"));
	MessageBox(_T("鼠标左键"));
  1. TCHAR类型
    如果定义了_UNICODE符号TCHAR将变为wchar_t类型。如果没用定义_UNICODE符号,TCHAR将变为普通古老的char类型。

TCHAR字符串操作函数:
_tcslen(str) 获得字符串长度
_tcsrchr(str, L'\') 反向搜索获得最后一个TCHAR的位置
_tsprintf(TCHAR *buffer,const TCHAR *format [,argument] ... )获得一个格式化字符串

_tcscpy 拷贝字符串

mfc中函数以A结尾或以W结尾:

Windows一般代码格式(Windows code page),用A来指代ANSI。
Unicode格式,用W来指代宽字符(Wide)。

string wstring CString

string是C++提供的标准字符串操作类.wstring是操作宽字符串的类.

CString是对string(字符串)和wstring(宽字符串)的一个封装,常用在mfc中.用来解决编码问题的.

二.转换

string或者wstring转换到CString:

要把std::string或者std::wstring类型的数据存放到CString中,直接调用string::c_str()或者wstring::c_str()就行了.

1 string 转为 CString   
	CString.format("%s",string.c_str()); 

2 CString 转为 string
	string str(CString.GetBuffer(str.GetLength()));
//CString ->TCHAR*
CString cs(_T"this is a test");
TCHAR * ts = new TCHAR[cs.GetLength()+1];
_tcscpy(ts,cs.GetLength()+1,cs);

//char* -> CString:
char*p="test";
CString cs(p);

//CString ->char*:
CStringA temp = cs;
char * p = cs.GetBuffer();

CString 常用操作:

● 格式化字符串:Format 方法
● 长度:GetLength();
● 是否为空,即不含字符:IsEmpty();
● 清空字符串:Empty();
● 转换大小写:MakeUpper、MakeLower
● 转换顺序:MakeReverse
● 字符串的连接:+、+=
● 字符串的比较:==、!=、(<、>、<=、>= 不常用)、Compare(区分大小写)、CompareNoCase(不区分大小写)
● Find、ReverseFind、FindOneOf 三个函数可以实现字符串的查找操作
Find 从指定位置开始查找指定的字符或者字符串,返回其位置,找不到返回 -1;

Replace 替换 CString 对象中的指定的字符或者字符串,返回替换的个数,无匹配字符返回 0;
CString str(_T("abcdabc"));
int num = str.Replace('b', 'k'); //str == akcdakc, num == 2
CString str(_T("abcdabc"));
int num = str.Replace(_T("bc"), _T("kw")); //str == akwdakw, num == 2

Remove 删除 CString 对象中的指定字符,返回删除字符的个数,有多个时都会删除;
CString str(_T("abcdabcb"));
int num = str.Remove('b'); //str == acdac, num == 3

Delete 删除 CString 对象中的指定位置的字符,返回处理后的字符串长度;
CString str(_T("abcd"));
int num = str.Delete(1, 3); //str == a, num == 1

Left、Mid、Right 三个函数分别实现从 CString 对象的 左、中、右 进行字符串的提取操作;
strResult = str.Mid(0, 2); //strResult == ab

消息

消息分类

标准消息
除WM_COMMAND之外,所有以WM开头的消息。如WM_CREATE、WM_CLOSE
从CWnd派生的类都可以接收到这类消息。在单文档应用程序中,框架类和视图类可以接受标准消息。

命令消息
来自菜单、加速键或工具栏按钮的消息。这类消息都以WM_COMMAND:呈现。在MFC中,通过标识(ID)来区分不同的命令消息;在SDK中,通过消息的wParam参数识别。
从CCmdTarget派生的类,都可以接收到这类消息。
在单文档应用程序中,应用类、文档类、框架类和视图类都可以接受命令消息

通告消息
由控件产生的消息,例如,按钮的单击,列表框的选择等均产生此类消息

常用消息

键盘
WM_KEYDOWN、WM_KEYUP:按下、释放非系统键产生的消息。
WM_CHAR:输入非系统字符时产生的消息。

鼠标
WM_MOUSEMOVE:鼠标移动时产生的消息。
WM_RBUTTONDOWM:鼠标右键按下时产生的消息。
WM_LBUTTONDOWN:鼠标左键按下时产生的消息。
WM_LBUTTONDBLCLICK:鼠标双击时产生的消息。

窗口
WM_TIMER:定时器	SetTimer()设置定时器    KillTimer()销毁定时器
WM_CREATE:创建窗口
WM_PAINT:窗口重绘
WM_WINDOWPOSCHANGING:窗口位置发生变化(超始点坐标变化)
WM_SETFOCUS:窗口得到焦点
WM_KILLFOCUS:窗口失去焦点
WM_CLOSE:关闭窗口
WM_DESTROY:关闭程序
WM_MOVE 窗口的移动
WM_SIZE 窗口大小的改变
WM_DROPFILES 拖动文件到窗口里面,可以获取文件路径
WM_CONTEXTMENU 用户右击窗口 发生了一次右键按下和一次右键弹起
WM_SETCURSOR     鼠标切换了位置(从一个控件移动到另一个控件)

消息映射

1.在类定义中添加消息处理函数的原型声明

class ...{

DECLARE_MESSAGE_MAP()
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
        
}

2.在类的实现文件中(不是在函数中),在消息映射表中添加消息映射宏

BEGIN_MESSAGE_MAP(CwinFirstView, CView)
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

3.在类的实现文件中添加消息处理函数的实现

void CwinFirstView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	CView::OnLButtonDown(nFlags, point);
}

命令(菜单栏)消息

处理顺序:视图类-> 文档类->框架类->应用类

消息首先收到的是框架类,框架类交给视图类处理,没找到消息映射视图类就交给文档类处理,没有响应就交还给视图类,视图交还给框架类,框架类没有响应就交给应用类处理。

添加菜单栏:资源视图-> menu->直接添加菜单栏,菜单项->修改菜单项ID;

处理菜单命令消息:在资源视图menu中选中菜单项,鼠标右击,添加事件处理程序 ,消息类型为COMMAND

​ 或者 在类向导中命令中搜索对应ID,消息类型为COMMAND

处理菜单更新消息:与处理菜单命令消息相同,只是消息类型为UPDATE_COMMAND_UI

在菜单编辑器中设置菜单项快捷键的步骤:

(1)在菜单编辑器中,选择要设置快捷键的菜单项,打开属性对话框

(2)在 Caption 文本框输入:菜单项名称+转义字符\t+快捷键,如退出程序的快捷键:退出\tCtrl+Shift+X,又如重命名文档名的快捷键:重命名\t+Ctrl+R

(3)然后在快捷键(Accelerator)编辑器中创建快捷键条目,并分配标识符为菜单项标识符。

OnPaint OnDraw

OnPaint 响应 WM_PAINT ,并调用 OnDraw

* CClientDC子类

CClientDC类只能在客户区绘图;
所谓客户区指窗口区域中去掉边框、标题栏、菜单栏、工具栏、状态栏等之外的部分,它是用户可以操作的区域;
在使用CClientDC进行绘图时,一般要调用 GetClientRect()函数来获取客户区域的大小;
CClientDC类在构造函数中调用WindowsAPI函数 GetDC(),在析构时响应 ReleaseDC();
entDC类的窗口句柄保存在成员变量m_hWnd,为构造CClientDC,需将CWnd作为参数传递给构造函数。

* CWindowDC子类

CWindowDC对象在构造时调用Windows API函数GetWindowDC,在析构时调用相应的API函数ReleaseDC,这意味着CWindowDC对象可访问CWnd所指向的为整个全屏幕区域;
CWindowDC允许在显示器的任意位置绘图。坐标原点在整个窗口的左上角。
在使用CWindowDC进行绘图时,一般要调用GetWindowRect函数来获取整个应用程序窗口区域的大小;
CWindowDC类的窗口句柄保存在成员变量m_hWnd,为构造CClientDC,需将CWnd作为参数传递给构造函数。

* CPaintDC子类

通常CPaintDC用来响应WM_PAINT消息。一般应用在OnPaint函数.
CClientDC也是从CDC派生出来的.构造时自动调用GetDC函数,析构时自动调用ReleaseDC函数.一般应用于客户区窗口的绘制.
CPaintDC只能在WM_PAINT消息中使用, 用于有重画消息发出时才使用的内存设备环境, 而CClientDC和客户区相关,有重画消息发出时才使用的内存设备环境, 可在任何地方使用.
在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。

示例:

CDC*pdc = GetDC();//得到与视图窗口相关联的cdc
pdc->MoveTo(0,0);
pdc->LineTo(400,400);
ReleaseDc(pdc);
等价
CClientDc ccdc(this);//起点是在客户区左上角
ccdc.MoveTo(0,0);
ccdc.LineTo(400,400);


CWindowDC wdc( GetParent());//得到父窗口CDC cview的父窗口是CFrame
//起点实在窗口左上角
wdc.MoveTo(0,0);
wdc.LineTo(400,400);

CWindowDC wdc( GetDesktopWindow());//获得整个桌面句柄,起点是在桌面最左上角
wdc.MoveTo(0,0);
wdc.LineTo(400,400);

   

TextOut 设置字体和颜色

//设置字体
CFont ft;
ft.CreatePointFont(200, L"楷体");
cdc->SelectObject(ft);//绑定字体

//设置文本颜色
cdc->SetTextColor(RGB(255,0,0));

cdc->TextOutW(100, 300, L"我希望通过这门课,可以用MFC制作简单的图形界面程序");

笔和刷子

任何一块画布,缺省情况下笔画出的线就是一个像素宽、黑色的实心线。刷子默认是白色的;
CPen  pen; //申明一支笔
pen.CreatePen(PS_SOLID,4,RGB(255,0,0));
 //创建这支笔的属性为实心,4个像素宽,红色的
CBrush brush(RGB(0,255,0));//绿色的刷子
CClientDC  dc(this); //申明一块与视窗窗口相关的画布
CPen*pOldPen = dc.SelectObject(&pen);
CBrush * pOldBrush = dc.selectObject(&brush);
 //把笔选进该画布,后续的画线都是该笔画出的,是4像素宽,红色的实心线。

获得透明画刷的方法
CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

要得到窗口的大小
CRect rect;   //声明一个矩形类对象
GetClientRect(&rect); //得到窗口的大小存放在rect中。
//利用rect.Width()和rect.Height()分别可求得窗口的宽度和高度  

CDC常用函数

int SetROP2( int nDrawMode ); //设置绘图模式 R2_NOT屏幕反显色;R2_COPYPEN pen的颜色
MoveTo();	//将笔移动到
LineTo()	//从当前点画线到

CDC::AlphaBlen()	显示具有透明或半透明像素的位图
CDC::AngleArc() 绘制线段和弧线,将当前位置移动到弧的终
CDC::Arc() 绘制弧
CDC::DrawIcon() 绘制图
CDC::Ellipse() 绘制椭圆
CDC::Polygon() 绘制由两个或多个点组成的多边形, (线) 顶点。
CDC::Polyline() 绘制一组连接指定点的线
CDC::Rectangle() 使用当前笔绘制矩形,然后使用当前画笔填充
CDC::SetBkColor() 设置当前背景

通过直线画sin函数

int points_num = 180;
int circle_len;/一个周期长度
int x = start_x,y = start_y;
cdc.MoveTo(x, y);
for(int i = 0; i<points_num; i++){
    x = start_x + circle_len  *i/points_num;
    y = start_y + height* sin(2*PI *i/points_num);
    cdc.LineTo(x,y);
}

窗口重画

​ Invalidate()是强制系统进行重画,但是不一定就马上进行重画。因为Invalidate()只是通知系统,此 时的窗口已经变为无效。强制系统调用WM_PAINT,而这个消息只是Post就是将该消息放入消息队列。当执行到WM_PAINT消息时才会对敞口进行重绘。

UpdateWindow只向窗体发送WM_PAINT消息,在发送之前判断GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送WM_PAINT。

 RedrawWindow()则是具有Invalidate()和UpdateWindow()的双特性。声明窗口的状态为无效,并立即更新窗口,立即调用WM_PAINT消息处理。

对话框

DoDataExchange函数:该函数主要完成对话框数据的交换和校验。
OnInitDialog函数:相当于对对话框进行初始化处理。

模态对话框

当模态对话框显示时,程序会暂停执行,直到关闭这个模态对话框之后,才能执行程序中的其他任务。
实现模态对话框的创建需要调用CDialog类的成员函数CDialog::DoModel,该函数的功能就是创建并显示一个对话框:

普通对话框

当非模态对话框显示时,运行转而执行程序中的其他任务,而不用关闭这个对话框。

先创建(CDialog::Create)一次,然后再显示(CWnd::ShowWindow)。关闭时只是隐藏,而非销毁

m_dlg.Create(IDD_DIALOG_SHOW); //IDD_DIALOG_SHOW为对话框ID
m_dlg.ShowWindow(SW_SHOWNORMAL); //显示非模态对话框

使用对话框

在资源中添加Dialog -> 将dialog添加为mfc类 -> 通过添加的类使用;

可以为dialog中的控件关联变量;

控件

静态文本框 CStatic

静态文本框的重要属性有:

ID:所有静态文本框的缺省ID都是IDC_STATIC,静态ID,不响应任何消息(事件)

Caption:修改显示的内容

常用接口:

接口 功能
CWnd::SetWindowText 设置控件内容
CWnd::GetWindowText 获取控件内容
CStatic::SetBitmap 设置位图(后缀为bmp的图片)

*关联控件变量:*

由于XXX_STATIC静态ID是不能关联变量,故需把ID修改后,再关联变量:

//设置静态控件内容为Tom
	m_label.SetWindowText(TEXT("Tom"));

	//获取静态控件的内容
	CString str;
	m_label.GetWindowText(str);
	MessageBox(str);

	//设置静态控件窗口风格为位图居中显示
	m_label.ModifyStyle(0xf, SS_BITMAP | SS_CENTERIMAGE);

	//通过路径获取bitmap句柄
	#define HBMP(filepath,width,height) (HBITMAP)LoadImage(AfxGetInstanceHandle(),filepath,IMAGE_BITMAP,width,height,LR_LOADFROMFILE|LR_CREATEDIBSECTION)

	//静态控件设置bitmap
	m_label.SetBitmap(HBMP(TEXT("./1.bmp"), 300, 250));

按钮 CButton

按钮的主要属性是Caption,来设置在按钮上显示的文本。

按钮处理的最多的消息是:BN_CLICKED,双击按钮即可跳转到处理函数。或者,通过按钮属性 -> 控制事件 -> 选择所需事件,添加处理函数:

*接口* *功能*
CWnd::SetWindowText 设置控件内容
CWnd::GetWindowText 获取控件内容
CWnd::EnableWindow 设置控件是否变灰

编辑框 CEdit

常用属性设置:

*属性* *含义*
Number True只能输入数字
Password True密码模式
Want return True接收回车键,自动换行,只有在多行模式下,才能换行
Multiline True多行模式
Auto VScroll True 当垂直方向字符太多,自动出现滚动条,同时设置Vertical Scroll才有效
Vertical Scroll True当垂直方向字符太多,自动出现滚动条,和Auto VScroll配合使用
Horizontal Scroll True当垂直方向字符太多,自动出现滚动条,和Auto HScroll配合使用
Read Only True 只读

常用接口:

*接口* *功能*
CWnd::SetWindowText 设置控件内容
CWnd::GetWindowText 获取控件内容

若一个编辑框连接了一个Value类别的变量,则该变量就表示这个编辑框,编辑框中显示的内容就是变量的值。

但是,改变了编辑框的内容并不会自动更新对应的变量的值,同样,改变了变量的值也不会自动刷新编辑框的内容。若要保持一致,需要使用UpdateData()函数更新:

UpdateData(TRUE) 对话框数据->变量

UpdateData(FALSE) 变量->对话框数据

control类型变量自动同步

消息

EN_CHANGE 	在编辑框中按下一个字符时,字符显示之后触发  
		updatedata(false)不会触发,SetDlgItemText()会触发
EN_UPDATE	在编辑框中按下一个字符时,没显示之前触发     同上
DoDataExchange(CDataExchange* pDX)

OnInitDialog() 

GetDlgItem(ID)->GetWindowText()
GetDlgItemText(ID)/SetDlgItemText()
GetDlgItemInt(ID)/SetDlgItemInt()

若CEdit和spin contol关联,自动绑定时CEdit的初始值无效,

分析: 因为在创建第一个微调按钮时(还没在对话框上显示),它是和红色编辑框自动绑定并且是整型,所以给红色编辑框传递值,此时编辑框的内容发生变化。会触发红色编辑框的EN_CHANGE消息。

解决: 只要在红色框的EN_CHANGE中添加下面的代码就可以

CEdit *pedit=(CEdit *)this->GetDlgItem(IDC_EDIT_RED);
if(pedit->IsWindowVisible()){  //控件可见,就是在对话框中已显示
    this->UpdateData();
	//this->red = GetDlgItemInt(IDC_EDIT_RED);
}
/*就是在对话框中控件已显示才会将控件值更新到变量,
这样就避免了微调按钮自动绑定时触发EN_CHANGE消息,将初始值覆盖掉
*/

CEdit和slider绑定时,设置edit的初始值时要同时设置slider的初始pos;

微调按钮(spin control),滑动条

属性

属性 含义
Auto Buddy 自动绑定(Tab Order顺序前一个)
set buddy integer 设置绑定控件值为int
alignment 与绑定控件的对齐方式(right常用)

CSpinButtonCtrl

消息:UDN_DELTAPOS 点起微调按钮触发

方法

SetRang();	GetRang();	SetPos();	GetPos()
SetAccel()//设置增量(步长)

UDACCEL accel;
accel.nSec =1;//设置按住几秒钟时间开始快速增长
accel.nInc =3;//步长
SetAccel(1,&accel);

CSliderCtrl

消息:NM_CUSTOMDRAW 滑块滑动触发

setRange();	GetRang();	SetPos();	GetPos();
SetLineSize();//设置滑块增量

下拉框CComboBox

常用属性设置:

*属性* *含义*
data 设置内容,不同内容间用英文的分号“;”分隔
type 显示风格
Sort True 内容自动排序

常用接口:

*接口* *功能*
CComboBox::AddString 组合框添加一个字符串
CComboBox::SetCurSel 设置当前选择项(当前显示第几项),下标从0开始
CComboBox::GetCurSel 获取组合框中当前选中项的下标
CComboBox::GetLBText 获取指定位置的内容
CComboBox::DeleteString 删除指定位置的字符串
CComboBox::InsertString 在指定位置插入字符串

组合框常用的事件为:CBN_SELCHANGE,当选择组合框某一项时,自动触发此事件。

列表控件 CListCtrl

常用属性设置:view -> Report(报表方式)

常用接口:

*接口* *功能*
CListCtrl::SetExtendedStyle 设置列表风格
CListCtrl::GetExtendedStyle 获取列表风格
CListCtrl::InsertColumn 插入某列内容,主要用于设置标题
CListCtrl::InsertItem 在某行插入新项内容
CListCtrl::SetItemText 设置某行某列的子项内容
CListCtrl::GetItemText 获取某行某列的内容
//设置风格样式
	//LVS_EX_GRIDLINES 网格
	//LVS_EX_FULLROWSELECT 选中整行
	m_list.SetExtendedStyle(m_list.GetExtendedStyle()
		| LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

	//插入标题
	CString head[] = { TEXT("姓名"), TEXT("年龄"), TEXT("性别") };

	//插入列
	m_list.InsertColumn(0, head[0], LVCFMT_LEFT, 100);
	m_list.InsertColumn(1, head[1], LVCFMT_LEFT, 100);
	m_list.InsertColumn(2, head[2], LVCFMT_LEFT, 100);

	//插入正文内容,先确定行,再确定列
	for (int i = 0; i < 10; i++)
	{
		CString str;
		str.Format(TEXT("张三_%d"), i );

		//确定行
		m_list.InsertItem(i, str);

		//设置列
		int j = 0;
		m_list.SetItemText(i, ++j, TEXT("男"));
		m_list.SetItemText(i, ++j, TEXT("23"));
	}

树控件 CTreeCtrl

常用属性设置:

*属性* *含义*
has buttons True 有展开按钮
has lines True 有展开线
lines at root True 有根节点

常用接口:

*接口* *功能*
AfxGetApp() 获取应用程序对象指针
CWinApp::LoadIcon 加载自定义图标
CImageList::Create 创建图像列表
CImageList::Add 图像列表追加图标
CTreeCtrl::SetImageList 设置图形状态列表
CTreeCtrl::InsertItem 插入节点
CTreeCtrl::SelectItem 设置默认选中项
CTreeCtrl::GetSelectedItem 获取选中项
CTreeCtrl::GetItemText 获取某项内容

标签控件 CTabCtrl

posted @ 2022-03-07 18:47  awei666  阅读(223)  评论(0编辑  收藏  举报