MFC 窗口基本框架
2015-08-01 11:09
225 查看
MFC 窗口基本框架
由于在mfc的实际操作中,基本上编译器均会提供已封装好的窗口,我们实际使用时并不需要了解其窗口的实现,为了对mfc框架及底层更好地了解,我们先对窗口框架做一个简单的了解(下面我们将对vs所提供的源代码进行分析):搭建窗口需要的几个类
windows程序的入口函数:int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int cCmdShow ) { 实现对窗口类的初始化,注册,创建窗口,展示窗口,更新窗口,以及消息循环(消息转换和处理) }
窗口过程函数(回调函数):
LRESULT CALLBACK WinProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { 操作系统调用回调函数进行信息处理及响应 }
代码块
代码块语法遵循标准markdown代码,例如:对句柄的解释可参照:http://blog.sina.com.cn/s/blog_4cccd8d301015jhr.html
#include "stdafx.h" #include "Learn_3_MFC_03.h" #define MAX_LOADSTRING 100 // 全局变量的声明 HINSTANCE hInst; // 当前实例,我们这里的实例就是指我们的窗口 TCHAR szTitle[MAX_LOADSTRING]; // 窗口标题 TCHAR szWindowClass[MAX_LOADSTRING]; // 窗口类名 // 函数声明: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); // windows程序的入口函数 int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; // 初始化全局string变量,根据用户创建mfc工程时的选择初始化 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_LEARN_3_MFC_03, szWindowClass, MAX_LOADSTRING); // 向操作系统注册窗口类,调用MyRegisterClass()函数 MyRegisterClass(hInstance); // 窗口的初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_LEARN_3_MFC_03)); // 消息循环 while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { // 将接收到的输入消息装换为字符消息存储到队列当中 TranslateMessage(&msg); // 将消息抛给操作系统,操作系统调用回调函数,处理消息动作 DispatchMessage(&msg); } } return (int) msg.wParam; } // // 功能: MyRegisterClass() // // 目的: 注册窗口类. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; // 创建窗口类对象 wcex.cbSize = sizeof(WNDCLASSEX); // 水平和垂直重画 wcex.style = CS_HREDRAW | CS_VREDRAW; // 窗口过程,指向回调函数(函数指针) wcex.lpfnWndProc = WndProc; // 增加类附加内存空间(不需要赋值为0) wcex.cbClsExtra = 0; // 增加窗口附加内存空间(不需要赋值为0) wcex.cbWndExtra = 0; // 当前应用程序实例号(操作系统给出) wcex.hInstance = hInstance; // 图标句柄 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LEARN_3_MFC_03)); // 光标句柄 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); // 窗口背景初始化 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 菜单名称 wcex.lpszMenuName = MAKEINTRESOURCE(IDC_LEARN_3_MFC_03); // 窗口类名 wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); // 注册窗口类并返回 return RegisterClassEx(&wcex); } // // 功能: InitInstance(HINSTANCE, int) // // 目的: 保存当前实例手柄并创建窗口 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // 存储全局变量的实例句柄 // 创建窗口 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } // 展现更新窗口 ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 功能: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: 处理窗口消息. // // WM_COMMAND - 处理程序菜单 // WM_PAINT - 窗口画笔 // WM_DESTROY - 发布退出消息和返回 // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: // dialog窗口 DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: // 销毁并退出窗口 DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // about的消息处理回调. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
总结
由于窗口建立需要调用和执行的步骤基本上都相类似,为了用户方便,微软将其封装起来,以减轻用户开发的负担。vs中mfc窗口也是进行上述类似的封装,通过对底层的了解,可以帮助我们更好的进行学习。有兴趣的可以查看vs调用源码进行了解。相关文章推荐
- Visual C++中MFC消息的分类
- MFC中Radio Button的用法详解
- MFC对话框中添加状态栏的方法
- MFC创建右键弹出菜单的方法
- MFC中动态创建控件以及事件响应实现方法
- C++ 关于MFC多线程编程的注意事项
- MFC程序对文件的处理方法
- MFC自定义消息的实现方法
- MFC之ComboBox控件用法实例教程
- MFC绘制不规则窗体的方法
- IE8引发 VS2005/2008 MFC向导出错的解决方案
- MFC实现全屏功能代码实例
- 使用VS2010创建MFC ActiveX工程项目
- C++中MFC Tab Control控件的使用详解
- MFC程序设计常用技巧汇总
- MFC扩展DLL中导出类和对话框的实现方法
- VC中SDK与MFC的区别浅析
- 浅谈MFC 改变控件大小和位置
- VC MFC非模态对话框的实现方法
- MFC程序执行过程深入剖析