MFC学习笔记 (1)
窗口的创建(底层)
1.设计窗口
//1、设计窗口
WNDCLASS winclass;
winclass.cbClsExtra = 0;//类的额外内存
winclass.cbWndExtra = 0;//窗口的的附加内存(额外)
winclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//设置背景
winclass.hCursor = LoadCursor(NULL,IDC_HAND);//设置光标,若第一个参数为null,表示使用系统提供的光标。
winclass.hIcon = LoadIcon(NULL,IDI_ERROR);//设置图表
winclass.hInstance = hInstance; //应用程序的实例句柄,传入winmain的形参
winclass.lpfnWndProc = WindowProc; //窗口过程的函数(回调函数)
winclass.lpszClassName = TEXT("WIN");//指定窗口类名称TEXT字符串
winclass.lpszMenuName = NULL;//菜单名称
winclass.style = 0;//显示风格,0代表默认
2.注册窗口
//2、注册窗口类
RegisterClass(&winclass);
3.创建窗口
//3、创建窗口
/*
lpClassName,类名
lpWindowName, 标题名
dwStyle,WS风格
x, 显示坐标
y,\
nWidth, 宽高
nHeight,
hWndParent,父窗口
hMenu,菜单NULL
hInstance,实例句柄
lpParam附加值 鼠标附加值NULL
*/
HWND hwnd = CreateWindow(winclass.lpszClassName,
TEXT("WINDOWS"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
4.显示和更新
//4、显示和更新
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
5.通过循环取消息
//5、通过循环取消息
/*
HWND hwnd;主窗口句柄
UINT message;具体消息名称
WPARAM wParam;附加消息 键盘消息
LPARAM lParam;附加消息 鼠标消息
DWORD time;消息产生时间
POINT pt;附加消息 鼠标消息 下X,Y
*/
MSG msg;
while (1)
{
//GetMessageW(
// _Out_ LPMSG lpMsg,消息
// _In_opt_ HWND hWnd,捕获窗口 用NULL代表捕获所有的窗口
// _In_ UINT wMsgFilterMin, //最大和最小的消息一般填入0
// _In_ UINT wMsgFilterMax);//代表捕获所有的消息
if (GetMessage(&msg,NULL,0,0) == FALSE)
{
break;
}
//翻译消息
TranslateMessage(&msg);
//分发消息
DispatchMessage(&msg);
}
6.处理消息(窗口过程)
//处理窗口过程
LRESULT CALLBACK WindowProc(
HWND hwnd,//消息所属窗口句柄
UINT uMsg,//具体的消息名称 WM_XXX为消息名
WPARAM wParam,//键盘附加消息
LPARAM lParam//鼠标附加消息
)
{
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(hwnd);//发送另一个消息 WM_DESTROY
case WM_DESTROY:
PostQuitMessage(0);//使得GetMessage==false
case WM_LBUTTONDOWN://鼠标左键按下返回点击坐标
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
char buf[1024];
wsprintf(buf,TEXT("x = %d,y = %d"), xPos, yPos);
MessageBox(hwnd, buf, TEXT("鼠标左键按下"), MB_OK);
break;
}
case WM_KEYDOWN:
MessageBox(hwnd, TEXT("bbb"), TEXT("鼠标左键按下"), MB_OK);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;//绘图结构体
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, TEXT("hello"), strlen("hello"));
EndPaint(hwnd,&ps);
break;
}
default:
break;
}
感觉没啥用。
MFC消息映射机制
消息映射是一个将消息和成员函数相互关联的表。
即:每一个消息传入到系统中,系统对应每一个不同的消息有不同的处理方式,这个对应关系称为消息映射。
通俗来讲,就是对消息(点击,键盘)的响应机制。
使用 此机制需要在代码中声明
Windows字符集
中文字符 一个字符对应多个字节 宽字节 Unicode utf-8 3个字节 GBK 2个字节。
默认unicode为宽字节,(L"aaa")可进行转换。
- 统计字符串长度
int num = 0;
char *p = "aaaa";
num = strlen(p);
- 统计宽字节的字符串长度
wchar_t *p2 = L"bbbb";
num = wcslen(p2);
- char * 与CString之间的转换
char * p3 = "ccc";
CString = str = CString(p3);
CStringA temp;
temp = str;
char * pp = temp.GetBuffer();
利用向导创建mfc项目
注:单文档,MFC标准
- View类
-做显示的类
处理所有的显示的功能。
onDraw()与onPaint()
若已经使用了onDraw则不需要onPaint。否则会被onPaint覆盖。 - APP类
-有需求写,没需求不写 - doc类
-管理文档数据 - Frame类
-作为view类的外层框架存在,墙与墙纸的关系。
注:MFC开发不适用解决方案管理器,使用类视图。 - 一些重要的函数
- InitInstance函数(程序入口)
- PreCreateWindow函数(在产生窗口之前修改窗口外观)
- OnCreate函数(响应窗口创建消息的响应函数)
- Ondraw函数(画图)
基于对话框的编程
MFC项目创建的过程中,使用基于对话框的编程。
笔记:
- 视图->工具箱里面便捷添加各种空间,右键->属性对控件进行各种编辑操作。
- 双击按钮控件,可跳转到单击事件的处理函数之中。
- 调用模态对话框。先创建对话框对象,之后调用modal()函数创建模态对话框。
- 资源视图中对界面的直观的编辑操作。
- 模态对话框调用modal()函数会阻塞,因此不需要考虑对象的生命周期,而非模态的对话框如果是在点击事件中创建,会在点击事件完成之后消失,因此需要在dialog中添加非模态对话框的对象,使其成为成员变量,由此在点击事件完成之后不会消失。
- 继续5.中的问题,若再次打开非模态对话框,会崩溃,因为不能多次创建同一个对话框,因此需要将create()函数写道OnInitDialog()或者构造函数之中。
- 在不同的类文件中编写代码的时候,不要忘记#include所需要的头文件。主要在5,6中。
- 总结添加按钮触发模态对话框的步骤:
- 创建新的窗口,右键资源视图中的dialog文件夹创建新的窗口,并编辑属性内容。之后右键创建类,为新建的窗口创建类。
- 在父窗口中添加需要的按钮,编辑按钮属性。之后双击按钮编写点击事件。
- 模态CDlgExec:在父窗口的类文件中包含子对话框的类,再在点击事件中创建对象,调用modal()即可。
- 非模态CDlgShow:将子对话框的对象写入父对话框的成员变量之中,并在init函数之中对对话框进行创建操作,之后在点击事件之中进行对话框的显示。
.