MFC 框架技术简单研讨
引用:http://www.cnblogs.com/chinazhangjie/archive/2011/09/20/2181986.html
正文:
第一讲 Win32 App 和 MFC Framework
Win32 App 程序生与死:
(1)注册窗口
(2)创建窗口
(3)显示并更新窗口
(4)消息循环( WM_QUIT 结束循环)
(5)退出
实例代码:
#include <windows.h> ATOM RegisterWndClass( HINSTANCE hInstance , LPCWSTR className);
LRESULT CALLBACK WindowProc(HWND ,UINT, WPARAM, LPARAM); /* WinMain parameters:
* hInstance : A handle to the current instance of the application.
* hPrevInstance : A handle to the previous instance of the application.
* This parameter is always NULL. ...
* lpCmdLine : The command line for the application, excluding(不包括) the program name.
* To retrieve(获取) the entire(全部) command line, use the GetCommandLine function.
* nCmdShow : Controls how the window is to be shown. eg. SW_HIDE, SW_MAXIMIZE
*
* return value: If the function succeeds, terminating when it receives a WM_QUIT message,
* it should return the exit value contained in that message's wParam parameter.
* If the function terminates before entering the message loop,
* it should return zero.
*/
int CALLBACK WinMain(
__in HINSTANCE hInstance,
__in HINSTANCE hPrevInstance,
__in LPSTR lpCmdLine,
__in int nCmdShow )
{
// (1)注册窗口
LPCWSTR className = TEXT("FirstWnd");
if (!RegisterWndClass(hInstance, className)) {
::MessageBox(NULL, TEXT("Register class failed"),
TEXT("Error"), MB_OK | MB_ICONEXCLAMATION);
return0;
} // (2)创建窗口
HWND hWnd; // 窗口句柄
hWnd = CreateWindow(
className, // 窗口类名称
TEXT("A simple Win32 Application"), // 窗口标题
WS_OVERLAPPEDWINDOW, // 窗口风格
100, // 窗口位置的 x 坐标 , CW_USEDEFAULT
100, // 窗口位置的 y 坐标 , CW_USEDEFAULT
400, // 窗口的宽度 , CW_USEDEFAULT
300, // 窗口的高度 , CW_USEDEFAULT
NULL, // 父窗口句柄
NULL, // 菜单句柄
hInstance, // 应用程序句柄
NULL); // 窗口创建数据指针, WM_CREATE lParam
if (!hWnd) {
::MessageBox(NULL, TEXT("Register class failed"),
TEXT("Error"), MB_OK | MB_ICONEXCLAMATION);
return0;
} // (3)显示并更新窗口
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd); // (4)进入消息循环
MSG msg;
// 如果 msg 消息为 WM_QUIT , GetMessage 返回为 0 ,退出循环
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
} // 程序结束
return msg.wParam;
} // 注册窗口
ATOM RegisterWndClass( HINSTANCE hInstance , LPCWSTR className)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; //
wc.lpfnWndProc = (WNDPROC)WindowProc; // A pointer to the window procedure.
wc.cbClsExtra =0; //
wc.cbWndExtra =0; //
wc.hInstance = hInstance; //
wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION ); // A handle to the class icon.
wc.hCursor = LoadCursor( NULL, IDC_ARROW ); // A handle to the class cursor.
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // A handle to the class background brush.
wc.lpszMenuName = NULL; // The resource name of the class menu,
wc.lpszClassName = className; // A pointer to a null-terminated string or is an atom.
return RegisterClass( &wc );
} // 窗口过程
LRESULT CALLBACK WindowProc(
__in HWND hWnd, // A handle to the window.
__in UINT uMsg, // The message.
__in WPARAM wParam, // Additional message information
__in LPARAM lParam // Additional message information
)
{
HDC hDC;
PAINTSTRUCT ps; switch (uMsg)
{
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
RECT rc;
rc.bottom =100;
rc.left =100;
rc.right =300;
rc.top =400;
::SetTextColor(hDC, RGB(255, 0, 0));
SetBkMode(hDC, TRANSPARENT);
::TextOut(hDC, 30, 30, TEXT("This is my first Win32 App !"),
strlen("This is my first Win32 App !"));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
MessageBox(NULL, TEXT("Window will be closed"), TEXT("Message"), MB_OK);
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN:
MessageBox(NULL, TEXT("left button down"), TEXT("Message"), MB_OK);
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
思考:
1. Console App 入口点 是 main ; Win32 App 入口点是 WinMain ;那么 MFC 入口点在哪里 ?
2. 相对简洁的 Win32 App ,复杂的 MFC Framework 强大在哪里 ?
3. 大量的虚函数、复杂的宏,或者说 MFC Framework 背着我们用户做了哪些事情 ?
第二讲 MFC 六大关键技术
2.1 MFC 程序的初始化过程
2.2 RTTI(运行时类型识别)
2.3 Dynamic Creation(动态创建)
C++动态创建对象的困难在于,无法在程序执行期间,根据动态获得的一个类名称,要求程序产生一个对象。
在 RTTI 中,CRuntimeClass 对象记录了类的 CreateObject 函数,在程序执行期间获得类名称,遍历链表找到名称匹配项,调用 CreateObject ,产生新对象。
C++ 动态类型相关
(1) typeid 运算子
(2)宏 [ RTTI ]
(3)模板实参演绎 [STL iterator_traits]
C++在动态对象创建上一直是一个缺陷,据我说知,C# 有一项技术支持(反射)。
2.4 Persistence(永久保存)机制
Persistence:将对象永久保留下来(写入文件),Persistence 机制,也就是Serialize(数据读写)。
Persistence 简介
(1) MFC 提供 CObList 、CDWordArray 等类来支持 Persistence 。
(2) MFC 利用
DECLARE_SERIAL/IMPLIMENT_SERIAL
两个宏来实现 Persistence 机制。
(3)个人觉得,Persistence 只不过限定了一种文件格式来存储。普通程序员也可以很快设定一种文件格式来存储,不用受框架的限制,灵活性高且调试方便。
2.5 Message Mapping(消息映射)与Command Routing(命令传递)
Windows 程序本质系事借着消息来维持脉动(消息驱动),并以 WM_ 开头的常量开表示。
消息循着 Application Framework 规定的路线,游走于各个对象之间,直到找到它的归宿(消息处理函数)。找不到的话,Framework 最终把它交给 :DefWindowProc 函数处理。
MFC 消息分类
命令消息(WM_COMMAND):“使用者命令程序做些操作”。凡是 UI 对象产生的消息都是这种命令消息,可能来自菜单或者加速键或工具栏按钮,并且都以 WM_COMMAND 呈现。SDK 程序主要靠 wParam 识别之,MFC 程序则主要靠菜单项的识别码( menu ID)识别——其实两者是一样的。
凡是派生自 CCmdTarget 的类,都由资格接受命令消息。
标准消息:除 WM_COMMAND 之外,任何以 WM_ 开头的都算这一类,均可接受此消息。
Control Notification:由控件产生,为的是向父类窗口通知某种情况。例如当你在 ListBox 上选择其中一个项目,ListBox 就会产生 LBN_SELCHANGE 传送给父窗口。这类消息是以 WM_COMMAND 形式呈现。
第三讲 MFC 多线程技术简介
MFC 线程分类:Work Thread,UI Thread
区别:Work Thread 没有消息循环
UI Thread 有自己的消息和队列循环
Work Thread:通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等
UI Thread:一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。
4.1 Work Thread的创建
CWinThread*
AfxBeginThread(AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
nPriority=THREAD_PRIORITY_NORMAL,
UINT nStackSize=0,
DWORD dwCreateFlags=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
线程函数类型:
UINT ExecutingFunction(LPVOID pParam);
4.2 UI Thread的创建
CWinThread* AfxBeginThread(CRuntimeClass* pThreadClass,
int nPriority=THREAD_PRIORITY_NORMAL,
UINT nStackSize=0,
DWORD dwCreateFlags=0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs=NULL);
具体请看:多线程编程之二——MFC中的多线程开发
第五讲 MFC 常用技术
略(幻灯片中讲了一些,但是比较杂碎,就不在这里列出来了……)
MFC 框架技术简单研讨的更多相关文章
- 在MFC框架中使用OpenGL的简单实例
引言 我们知道,在MFC框架中,用于绘图的接口是GDI.但GDI只能绘制简单的2D图形,要想制作精美的3D图形,一个可行的办法是使用OpenGL或者Direct3D等第三方库. 由于最近在给导师的一个 ...
- .NET Web开发技术简单整理
在最初学习一些编程语言.一些编程技术的时候,做的更多的是如何使用该技术,如何更好的使用该技术解决问题,而没有去关注它的相关性.关注它的理论支持,这种学习技术的方式是短平快.其实工作中有时候也是这样,公 ...
- Hibernate 系列 01 - 框架技术 (介绍Hibernate框架的发展由来)
引导目录: Hibernate 系列教程 目录 本篇导航: 为什么学习框架技术 框架的概念 主流框架的介绍 1.为什么学习框架技术 如何制作一份看上去具有专业水准的PPT文档呢?一个简单的方法就是使用 ...
- MFC框架
第一点:类别型录网的搭建: 类别型录网搭建的目的是为了实现所谓的"执行期类型识别",也就是在程序运行的时候识别出某个对象是否是某个类的实例(基类也可以).这里还不是很明白为什么需要 ...
- 转载:.NET Web开发技术简单整理
在最初学习一些编程语言.一些编程技术的时候,做的更多的是如何使用该技术,如何更好的使用该技术解决问题,而没有去关注它的相关性.关注它的理论支持,这种学习技术的方式是短平快.其实工作中有时候也是这样,公 ...
- PHP ORM框架与简单代码实现(转)
对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据 ...
- 框架原理第三讲,RTTCreate,运行时类型创建.(以MFC框架讲解)
框架原理第三讲,RTTCreate,运行时类型创建.(以MFC框架讲解) 通过昨天的讲解,我们已经理解了运行时类型识别是什么. 比如 CObject * pthis = (Cobject *)Cre ...
- 框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解)
框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解) 一丶什么是RTTI,以及RTTI怎么设计 通过第一讲,我们知道了怎么样升成一个窗口了,以及简单的消息循环. 第二讲则是主要讲解RTTI ...
- MFC应用技术之CTreeControl的使用
MFC应用技术之CTreeControl的使用 一丶MFC添加树控件.添加父节点跟子节点. MFC上面放一个树控件.并未这个树控件绑定变量.然后添加一个按钮.按钮的作用就是添加父节点跟子节点. PS: ...
随机推荐
- 项目管理gitflow的用法(转)
在这里主要讲一下我在项目中用到的关于gitflow的用法. 公司的项目中,专门有一台用来存放版本库的服务器,路径是在默认的安装目录/opt/git/,那么在使用的时候,如果你是一个功能模块或者是一 ...
- PHP curl 模拟POST 上传文件(含php 5.5后CURLFile)
<?php /** * Email net.webjoy@gmail.com * author jackluo * 2014.11.21 * */ //* function curl_post( ...
- java分享第五天(数组)
1 声明数组变量: double[] mylist; or double mylist[]; 2 创建数组: 可以通过使用new运算符使用以下语法创建一个数组: arrayRefVar=new ...
- js从身份证号中获取出生日期和性别
今天,在做移动端的项目中,按照设计稿的要求,是可以让用户自己输入出生日期的,我还很认真的用了刚刚知道的html5表单的日期类型,本想着终于不用日期插件就可以实现用户选择自己的出生日期了,可结果老大说, ...
- Java.lang.NoSuchFieldError: INSTANCE异常
解决方案: java.lang.NoSuchFieldError: INSTANCE异常. 1.jar包重复了. 2.版本还不相同,如果包的版本不同也会报相应的错,不过一般情况自己导入的jar包主要看 ...
- Trie字典树 动态内存
Trie字典树 #include "stdio.h" #include "iostream" #include "malloc.h" #in ...
- Material Design - CollapsingToolbarLayout
一.概述 CollapsingToolbarLayout是Material Design的一个Layout,直接继承于FrameLayout. 二.使用 1.导包 2.使用 - 设置相关属性 三.参考 ...
- [LintCode] Gray Code 格雷码
The gray code is a binary numeral system where two successive values differ in only one bit. Given a ...
- js流程控制语句
do...while语句 do...while语句是一种先运行,后判断的循环语句.也就是说,不管条件是否满足,至少先运行一次循环体. var box = 1; ...
- 8点需要注意的Web编程小细节