- A+
一、Win32项目设计
类似于console控制台程序,win32窗口程序的入口函数类似于main()函数,称之为WinMain函数:
int WINAPI wWinMain( HINSTANCE hInstance, //实例句柄 HINSTANCE hPrevInstance,//前一个实例句柄 PWSTR pCmdLine, //命令行参数,字符串指针 int nCmdShow) //窗口显示方法,一系列的宏
在此函数之中执行以下的步骤进行一个Win32项目窗口的创建
1.设计窗口
WNDCLASS wndcls; wndcls.cbClsExtra = 0; wndcls.cbWndExtra = 0;// 附加内存 wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//背景 wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);//光标 wndcls.hInstance = hInstance;//实例句柄 wndcls.lpfnWndProc = WinMyProc;//窗口过程,消息处理函数 wndcls.lpszClassName = TEXT("类名"); wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);//图标 wndcls.lpszMenuName = NULL;//菜单 wndcls.style = CS_HREDRAW | CS_VREDRAW;//水平垂直重画
2.注册窗口
RegisterClass(&wndcls);
3.创建窗口
void CreateWindowW(lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
HWND hwnd = CreateWindow(TEXT("类名"), TEXT("标题"), WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, NULL, NULL, hInstance, NULL);
4.显示与更新窗口
//显示窗口 ShowWindow(hwnd, SW_SHOWNORMAL); UpdateWindow(hwnd);
5.消息循环
//取得消息,分发消息 MSG msg; while (GetMessage(&msg, hwnd, 0, 0)) { TranslateMessage(&msg);//翻译,虚拟按键转化为字符消息 DispatchMessage(&msg);//分发消息 }
Windows处理消息过程:
消息发出:
os:维护一个消息队列,将消息加入队列
app:从消息队列取消息GetMessage
app:告知os,TranslateMessage(&msg);//翻译 DispatchMessage(&msg);//分发消息
os:窗口过程,消息处理 WinMyProc
二、MFC单文档与Win32程序的映射
利用向导生成MFC项目自动生成的四个类:
CMainFrame //框架类 CMyApp //应用程序类 CMyDoc //文档类 CMyView //视图类
其中,MainFrame和View视图类都继承于CWnd类,View类为整个窗体的子窗口,Frame作为框架使用,包含菜单和工具栏。
MFC作为了封装了Win32的程序的框架,同样遵从上述的窗口创建过程的方法,只不过在程序中我们无法查看。
MFC窗口的创建过程:
1.App类创建全局变量,唯一一个App的全局对象
2.进入WinMain函数(在MFC源代码中可查到)
3.WinMain() -> afxWinMain(),WinMain()函数中向下调函数
4.afxWinMain() -> InitInstance() ,利用父类指针调用虚函数,多态性使得子类方法得以调用
5.InitInstance会调一些父类方法实现了窗口的设计
6.接下来进入窗口的注册,这部分在Frame类中的PreCreateWindow中得以体现,调基类方法注册窗口
7.进入CFrame的Create方法中,多次调用CreateEx函数创建了整个窗体(包含工具和菜单)
8.Create中调PreCreateWindow方法,多态性使得其调用子类方法
9.继而在mainwnd中进行showwindow和updatewindow
MFC的消息循环:
MFC编程中,添加一个消息处理函数的过程中,1会在类中(.h)声明一个消息处理函数,2会在(.cpp)中实现,3会在(.cpp)中
BEGIN_MESSAGE_MAP()
ON_WM_CREATE() END_MESSAGE_MAP()
之间添加宏。
消息映射,为了解决大规模虚表的问题。
MFC的消息映射:主要是在WinThread::Run中体现
句柄 关联 对象指针 <----->一个静态函数可以通过句柄获取该对象指针
对象指针 传 基类
基类 调用 WdnProc(虚函数) <---->消息循环
wndproc内部由onwndmsg实现,主要关注两个方面1.是否存在消息函数。2.是否存在MAP中的宏
如果存在的话,调子类的消息处理函数,否则执行默认窗口过程。