090908(星期二):学习MFC
来源:互联网 发布:mac os x 好用吗 编辑:程序博客网 时间:2024/05/21 22:04
一、win32程序基础
Windows程序必须在开始之前做些初始化工作,CreateWindow之前把窗口的外貌和行为在WNDCLASS里设置好,并进行注册:RegisterClass(&wc);
CreateWindow只是创建窗口,之后再利用ShowWindow进行显示。
RegisterClass封装在InitApplication函数中,
CreateWindow封装在InitInstance函数中。这样的封装方式主要是出于历史原因,Windows3.x时代,窗口类只需要注册一次就可以供多个实例instance使用。在MFC在,Init的两个函数封装为CWinApp类的两个虚函数。
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
UNREFERENCED_PARAMETER(lpCmdLine); // 避免編譯時的警告
if (!hPrevInstance)
if (!InitApplication(hInstance))
return (FALSE);
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
//初始化完成后,winmain进入消息循环:
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg); // 分发到个窗口的WndProc中处理。
}
return (msg.wParam); // 傳回 PostQuitMessage 的參數
}
另外,MFC程序的入口函数,在MFC/SRC/APPMODULE.cpp中
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
二、Message Map的雏形
消息处理的最原始函数:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
switch (message) {
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(_hInst,
"AboutBox", // 對話盒資源名稱
hWnd, // 父視窗
(DLGPROC)About // 對話盒函式名稱
);
break;
case IDM_EXIT:
// 使用者想結束程式。處理方式與 WM_CLOSE 相同。
DestroyWindow (hWnd);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
break;
case WM_DESTROY: // 視窗已經被摧毀 (程式即將結束)。
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0);
}
大量的switch case语句,可扩展性不好。
是否可以更加模块化呢?定义一个MSGMAP_ENTRY的结构和dim宏:
struct MSGMAP_ENTRY {
UINT nMessage;
LONG (*pfn)(HWND, UINT, WPARAM, LPARAM);
};
#define dim(x) (sizeof(x) / sizeof(x[0]))
定义数组:
// 分别是消息和这个消息的处理函数
struct MSGMAP_ENTRY _messageEntries[] =
{
WM_CREATE, OnCreate,
WM_PAINT, OnPaint,
WM_SIZE, OnSize,
WM_COMMAND, OnCommand,
WM_SETFOCUS, OnSetFocus,
WM_CLOSE, OnClose,
WM_DESTROY, OnDestroy,
} ;
这样以来大量switch的WndProc函数可以变成:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
int i;
for(i=0; i < dim(_messageEntries); i++) { // 遍历对照表,找到就给对应的处理函数,时间复杂度一点都不会增加
if (message == _messageEntries[i].nMessage)
return((*_messageEntries[i].pfn)(hWnd, message, wParam, lParam));
}
return(DefWindowProc(hWnd, message, wParam, lParam));
}
于是WndProc就不需要对用户公开了,有新的消息及其处理,直接加在_messageEntries[]数组之中。
三、dialogue的运行
doModel和modeless。
1, dialog template,在rc文档中定义的外观属性
2, dialog procedure,类似WndProc。
四、Windows程序的生存过程
1,初始化时,CreateWindow创建一个Window;
2,WinMain函数不断的消息循环,使用GetMessage在消息队列中获取Msg;
3, 获取后DispatchMessage,传给对应的WndProc函数;
4, 重复2,3
5, 当按下Close命令时,送出WM_CLOSE,进入WndProc的DefWindowProc处理;
6, DefWindowProc收到WM_CLOSE调用DestroyWindow销毁窗口,同时送出WM_DESTROY;
7, PostQuitMessage
8, PostQuitMessage消息送出WM_QUIT给WinMain,WinMain退出消息循环。
- 090908(星期二):学习MFC
- 090915(星期二):MFC消息映射2
- 091013(星期二)MFC的消息映射机制复习
- 星期二
- 星期二
- 090922(星期二):MFC消息路由7, Frame8代码分析,消息链表的访问
- 091020(星期二)MFC线程消息循环3,GetMessage函数msdn描述
- 今天星期二了(12.14)
- 090929(星期二):理解控件消息
- 学习MFC(一)
- 学习MFC(二)
- 学习MFC(1)
- MFC学习(1)
- MFC学习(一)
- MFC学习(一)
- MFC学习(二)
- MFC学习(读MFC深入浅出)
- MFC入门学习(1)了解MFC
- C++拷贝构造函数和operator=
- 今天的收获....
- Visual C++/MFC入门教程
- 求平方根函数
- 如何编译linux第一个模块 hello.c(Centos5.3)
- 090908(星期二):学习MFC
- Linux系统下Oracle的自动启动服务创建
- c#委托
- CentOS 5.3上的中文乱码(方块字)解决方法
- 盈利模式决定你挣钱多少
- Windows下使用VIM&Cygwin,搭建Mainframe开发环境(六)---用awk/sed合并PLI/Cobol编译结果
- 谈谈本人做广告联盟的经验
- [GL]OpenGL 开发环境配置
- SHA-1算法的Java实现