您的位置:首页 > 其它

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调用源码进行了解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mfc