黑马程序员MFC学习第一天
一、
老师刚开始并没有直接讲MFC,而是讲了一下MFC的一些底层实现,这是我从视频里抠的一张图,讲的是消息与消息队列
每一个 Windows 应用程序开始执行后, 系统都会为该程序创建一个消息队列, 这个消息队列用来存放该程序创建的窗口的消息。
二、
编译器:vs2010
首先是底层win32写的:
代码如下:
#include <windows.h> //6、处理函数// LRESULT WINAPI WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch(uMsg) { case WM_CLOSE: //所有以xxxWindow结尾的方法都不会进入消息队列中,而是直接执行//,所以说关闭窗口后DestroyWindow执行时,消息并不会进入消息队列// DestroyWindow(hwnd); //发送WM_DESTORY消息// break; case WM_DESTROY: PostQuitMessage(0);//发送关闭消息// break; case WM_LBUTTONDOWN: //鼠标左键按下// { int xPos = LOWORD(lParam); int yPos = HIWORD(lParam); char buffer[0x100]; wsprintf(buffer,TEXT("x = %d,y = %d"),xPos,yPos); MessageBox(hwnd,buffer,NULL,MB_OK); break; } case WM_KEYDOWN://键盘// MessageBox(hwnd,TEXT("键盘按下"),NULL,MB_OK); break; case WM_PAINT://绘图// { PAINTSTRUCT ps ;//绘图结构体 HDC hdc = BeginPaint(hwnd,&ps); //该调用BeginPaint函数准备指定的窗口绘画和填充一个PAINTSTRUCT结构有关绘画的信息// TextOut(hdc,150,150,TEXT("_TLSN"),strlen("_TLSN")); EndPaint(hwnd,&ps); //该调用EndPaint函数标记指定窗口画的结束。每次调用BeginPaint函数时都需要此函数,但仅在绘制完成后才需要// break; } } return DefWindowProc(hwnd,uMsg,wParam,lParam); } int WINAPI WinMain( HINSTANCE hInstance,//应用程序实例 HINSTANCE hPrevInstance,//上一个应用的程序句柄 LPSTR lpCmdLine, int nShowCmd)//显示命令 最大化,最小化,关闭等等 { //1、设计窗口 WNDCLASS wc; HWND hwnd; MSG msg; wc.cbClsExtra = 0; //类的额外内存// wc.cbWndExtra = 0; //窗口额外内存// wc.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);//设置一个背景// wc.hCursor = LoadCursor(NULL,IDC_HAND);//设置光标,如果第一个参数为NULL,则使用系统光标// wc.hIcon = LoadIcon(NULL,IDI_WARNING);//图标// wc.hInstance = hInstance;//应用程序的实例句柄// wc.lpfnWndProc = WindowProc;//回调函数// wc.lpszClassName = TEXT("_TLSN");//指定窗口名 wc.lpszMenuName = NULL;//菜单名// wc.style =0; //风格,0代表默认// //2、注册窗口// RegisterClass(&wc); //3、创建窗口// hwnd = CreateWindow(wc.lpszClassName,TEXT("_TLSN"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL); /* lpClassName ,类名 lpWindowName ,标题名 dwStyle,分格 x, y,坐标 nWidth,宽 CW_USEDEFAULT默认值 nHeight hWndParent,父窗口 hMenu,菜单 hInstance,实例句柄 lparam 鼠标的附加值 */ //4、显示与更新// ShowWindow(hwnd,SW_SHOWNORMAL);//用哪种方式展开// UpdateWindow(hwnd); //5、通过循环取消息// /* HWND hwnd 主窗口 UINT message 具体消息名 wParam 附加消息,键盘消息 lParam 附加消息,鼠标消息 time 消息参生时间 POINT pt ,附加消息 ,鼠标消息 x,y的位置 */ /* GetMessage() LPMSG lpMsg, // message information ,消息 HWND hWnd, // handle to window ,捕获窗口,NULL代表捕获所有窗口 UINT wMsgFilterMin, // first message ,最小和最大的过滤消息,一般填0,填0代表捕获所有消息 UINT wMsgFilterMax // last message, 如果函数检索WM_QUIT以外的消息,则返回值非零。如果该函数检索WM_QUIT消息,则返回值为零。——MS */ while(1) { if(GetMessage(&msg,NULL,0,0) == FALSE) { break; } else { //翻译消息// TranslateMessage(&msg);//再次扔到消息队列 //分发消息// DispatchMessage(&msg); } } return 0; }
这是用空项目写的MFC:
头文件
#include <afxwin.h> class MyApp:public CWinApp //应用程序基类,所有基于MFC的应用程序都会继承这个类// { public: //程序入口// virtual BOOL InitInstance();//MFC程序的入口函数 }; class MyFrame:public CFrameWnd //窗口框架类 { public: MyFrame(); //声明宏 提供消息映射机制// DECLARE_MESSAGE_MAP(); //定义消息处理函数// afx_msg void OnLButtonDown(UINT, CPoint); afx_msg void OnChar(UINT, UINT, UINT); afx_msg void OnPaint(); //ON_WM_PAINT() 的处理函数 };
源码.c
#include "mfc.h" MyApp app; //全局应用程序对象有且只有一个// BOOL MyApp::InitInstance() { //创建窗口// MyFrame* frame = new MyFrame; //显示和更新// frame->ShowWindow(SW_SHOWNORMAL); frame->UpdateData(); m_pMainWnd = frame;//保存指向应用程序的主窗口的指针 return TRUE;//返回正常值// } //分界宏 BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd) ON_WM_LBUTTONDOWN() //鼠标左键按下 ON_WM_CHAR() //键盘 ON_WM_PAINT() //绘图 END_MESSAGE_MAP() //构造函数.. MyFrame::MyFrame() { Create(NULL,TEXT("_TLSN")); } void MyFrame::OnLButtonDown(UINT,CPoint point) { CString str; str.Format(TEXT("x = %d \t y = %d \n"),point.x,point.y); MessageBox(str); } void MyFrame::OnChar(UINT key, UINT, UINT) { CString str; str.Format(TEXT("按下了%c 键"), key); MessageBox(str); } void MyFrame::OnPaint() { CPaintDC dc(this);//CDC里找可以画的图形 dc.TextOutW(100, 100, TEXT("_TLSN")); //画椭圆 dc.Ellipse(10, 20, 100, 100); }
这样就建造了一个win32程序
三、
解决vs2010不能使用MFC模块的问题:
四、
关于UTF-8编码:
UTF-8不是固定字长编码的,而是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。‘
五、char* ,CString,string的转化:(手懒,直接扣的图)