深入浅出MFC笔记(5)
1.MFC的外围环境:
Windows C Runtime函数库:LIBC.LIB静态联结MSVCRT.LIB动态联结MSVCRTD.LIB使用Debug模式
DLL Import 函数库:GDI 32.LIB USER32.LIB KERNEL32.LIB
MFC 函数库(AFX 函数库):可静态联结或动态联结,是application framework的本体。MFCXXX.LIB
SDK 程序只要包含WINDOWS.H 就好,所有API 的函数声明、消息定义、常数定义、宏定义。
MFC需要的头文件:
Precompiled header 就是将.H 档第一次编译后的结果保存,第二次再编译时就可以直接从取出来用。
STDAFX.H-这个文件用来做为Precompiled header file,其内只包含其它的MFC 头文件,包含AFXWIN.H。
AFXWIN.H-以及它所包含的文件声明了所有的MFC类别。内含AFX.H,后者又包含AFXVER_.H,后者又包含AFXV_W32.H,后者又包含WINDOWS.H
AFXEXT.H-工具栏、状态列AFXDLGS.H -通用型对话框(Common Dialog)内包COMMDLG.H。
AFXCMN.H-通用型控制组件(Common Control)AFXCOLL.H-Collections Classes
AFXDLLX.H-MFC extension DLLs AFXRES.H -RC 文件必须包含此档。 对于标准资源(例如File、Edit 等菜单项目)的ID 都有默认值,定义于此文件中,例如:
所有MFC 头文件均置于\MSVC\MFC\INCLUDE中。这些文件连同Windows SDK 的包含档WINDOWS.H、COMMDLG.H、TOOLHELP.H、DDEML.H... 每每在编译过程中耗费大量的时间,因此你绝对有必要设定Precompiled header。
2.SDK 程序设计的第一要务是了解最重要的数个API 函数的意义和用法,像RegisterClass、CreateWindow、GetMessage、DispatchMessage,以及消息的获得与分配。
MFC 程序设计的第一要务则是熟记MFC 的类别阶层架构,并清楚知晓其中几个一定会用到的类别。
3.CWinApp-取代 WinMain的地位
CWinApp 之中的成员变量将因为theApp这个全域对象的诞生而获得配置与初值。称为application object,CWinApp 本身就代表一个程式本体。一个程序的本体是与程序本身有关而不与视窗有关的资料或动作:
系统传进来的四个WinMain参数、InitApplication 和InitInstance、消息循环。
class CWinApp : public CWinThread{// Attributes// Startup args (do not change)
HINSTANCE m_hInstance;HINSTANCE m_hPrevInstance;LPTSTR m_lpCmdLine;int m_nCmdShow;
// Running args (can be changed in InitInstance)
CWnd* m_pMainWnd; // main window (optional)记录主窗口的handle
CWnd* m_pActiveWnd; // active main window (may not be m_pMainWnd)
public:
virtual BOOL InitApplication();// hooks for your initialization code
virtual BOOL InitInstance();// overrides for implementation
virtual int Run();// overrides for implementation
——节录自AFXWIN.H的CWinApp 声明
// in APPMODUL.CPP
extern "C" int WINAPI //_tWinMain是为了支持Unicode 而准备的一个宏。
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow){
return AfxWinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
int AFXAPI AfxWinMain ( //源代码可从MFC 的WINMAIN.CPP 中获得稍加整理去芜存菁
HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow){
int nReturnCode = -1;
CWinApp* pApp = AfxGetApp();//一个指向theApp的指针和四个动作
AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
pApp->InitApplication();
pApp->InitInstance();
nReturnCode = pApp->Run();
AfxWinTerm();
return nReturnCode;
}//AfxGetApp 是一个全域函数,定义于AFXWIN1.INL中
_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp(){ return afxCurrentWinApp; }
#define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp//定义于AFXWIN.H
CWinApp::CWinApp(LPCTSTR lpszAppName){
m_pszAppName = lpszAppName;
AFX_MODULE_THREAD_STATE* pThreadState = AfxGetModuleThreadState(); // initialize CWinThread state
pThreadState->m_pCurrentWinThread = this;
m_hThread = ::GetCurrentThread();
m_nThreadID = ::GetCurrentThreadId();
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();// initialize CWinApp state
pModuleState->m_pCurrentWinApp = this; ...//所以this是theApp对象
}
AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE(); //实际情况
#ifdef _AFXDLL
#define _AFX_CMDTARGET_GETSTATE() (m_pModuleState)
#else
#define _AFX_CMDTARGET_GETSTATE() (AfxGetModuleState())
#endif
以上说明CWinApp* pApp = AfxGetApp();返回的指针是指向子类对象theApp,在WinMain中调用的函数:
CWinApp::InitApplication(); //CMyWinApp 只改写CWinApp中的 InitInstance
CMyWinApp::InitInstance();//通常它不改写InitApplication和 Run
CWinApp::Run();
①AfxWinInit--AFX 内部初始化动作
节录自APPINIT.CPP |
节录自THRDCORE.CPP |
BOOL AFXAPI AfxWinInit(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow){ ASSERT(hPrevInstance == NULL); // set resource handles AFX_MODULE_STATE* pState = AfxGetModuleState(); pState->m_hCurrentInstanceHandle = hInstance; pState->m_hCurrentResourceHandle = hInstance; // fill in the initial state for the application CWinApp* pApp = AfxGetApp(); if (pApp != NULL){ // Windows specific initialization (not done if no CWinApp) pApp->m_hInstance = hInstance; pApp->m_hPrevInstance = hPrevInstance; pApp->m_lpCmdLine = lpCmdLine; pApp->m_nCmdShow = nCmdShow; pApp->SetCurrentHandles(); } // initialize thread specific data (for main thread) if (!afxContextIsDLL) AfxInitThread(); return TRUE; } |
void AFXAPI AfxInitThread(){ if (!afxContextIsDLL){ // attempt to make the message queue bigger for (int cMsg = 96; !SetMessageQueue(cMsg) && (cMsg -= 8); ); // set message filter proc _AFX_THREAD_STATE* pThreadState = AfxGetThreadState(); ASSERT(pThreadState->m_hHookOldMsgFilter == NULL); pThreadState->m_hHookOldMsgFilter =::SetWindowsHookEx (WH_MSGFILTER,_AfxMsgFilterHook, NULL, ::GetCurrentThreadId()); // intialize CTL3D for this thread _AFX_CTL3D_STATE* pCtl3dState = _afxCtl3dState; if (pCtl3dState->m_pfnAutoSubclass != NULL) (*pCtl3dState->m_pfnAutoSubclass)(AfxGetInstanceHandle()); // allocate thread local _AFX_CTL3D_THREAD just for automatic termination _AFX_CTL3D_THREAD* pTemp = _afxCtl3dThread; } } |
WinMain 一开始即调用AfxWinInit,注册四个窗口类别
②BOOL CWinApp::InitApplication(){//在APPCORE.CPP中(大部份情况下不需改写它)
if (CDocManager::pStaticDocManager != NULL){
if (m_pDocManager == NULL) m_pDocManager = CDocManager::pStaticDocManager;
CDocManager::pStaticDocManager = NULL;
}
if (m_pDocManager != NULL) m_pDocManager->AddDocTemplate(NULL);
else CDocManager::bStaticInit = FALSE;
return TRUE;
}
③pApp->InitInstance();在CWinApp 中只是个空函数,没有任何内建(预设)动作。
BOOL CMyWinApp::InitInstance(){
m_pMainWnd = new CMyFrameWnd();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
CMyFrameWnd::CMyFrameWnd(){//由new引发的构造式
Create(NULL, "Hello MFC", WS_OVERLAPPEDWINDOW, rectDefault, NULL,"MainMenu");
}//Create只有前两个参数必须指定
BOOL CFrameWnd::Create(LPCTSTR lpszClassName ,// WINFRM.CPP
LPCTSTR lpszWindowName,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
LPCTSTR lpszMenuName,
DWORD dwExStyle,
CCreateContext* pContext){
HMENU hMenu = NULL;
if (lpszMenuName != NULL){
// load in a menu that will get destroyed when window gets destroyed
HINSTANCE hInst = AfxFindResourceHandle(lpszMenuName, RT_MENU);
hMenu = ::LoadMenu(hInst, lpszMenuName);
}
m_strTitle = lpszWindowName; // save title for later
CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext);
return TRUE;
}
‹
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,int x, int y, int nWidth, int nHeight,HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam){// allow modification of several common create parameters WINCORE.CPP
CREATESTRUCT cs;
cs.dwExStyle = dwExStyle;cs.lpszClass = lpszClassName;cs.lpszName = lpszWindowName;cs.style = dwStyle;
cs.x = x;cs.y = y;cs.cx = nWidth;cs.cy = nHeight;cs.hwndParent = hWndParent;cs.hMenu = nIDorHMenu;
cs.hInstance = AfxGetInstanceHandle();cs.lpCreateParams = lpParam;
PreCreateWindow(cs);
AfxHookWindowCreate(this);
HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
...
}
BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs){ //WINFRM.CPP
if (cs.lpszClass == NULL){
AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG);
cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
}
...
}
#define AfxDeferRegisterClass(fClass) \
((afxRegisteredClasses & fClass) ? TRUE : AfxEndDeferRegisterClass(fClass))// in AFXIMPL.H
#define afxRegisteredClasses AfxGetModuleState()->m_fRegisteredClasses// in AFXWIN.H
BOOL AFXAPI AfxEndDeferRegisterClass(short fClass) // in WINCORE.CPP
4.CFrameWnd-取代WndProc的地位
class CMyFrameWnd : public CFrameWnd{//MFC中
public:
CMyFrameWnd();
afx_msg void OnPaint();//处理WM_PAINT
afx_msg void OnAbout();//WM_COMMAND 的IDM _ABOUT
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
ON_WM_PAINT()
ON_COMMAND(IDM_ABOUT, OnAbout)
END_MESSAGE_MAP()
long FAR PASCAL WndProc(HWND hWnd, UNIT msg, WORD wParam, LONG lParam){ switch(msg) {
case WM_COMMAND :switch(wParam) {case IDM_ABOUT :OnAbout(hWnd, wParam, lParam);break;}break;
case WM_PAINT :OnPaint(hWnd, wParam, lParam);break;
default :DefWindowProc(hWnd, msg, wParam, lParam);
}//传统的SDK 窗口函数
}
深入浅出MFC笔记(5)相关推荐
- 深入浅出MFC学习笔记
深入浅出MFC学习笔记 ithzhang CSDN博客:http://blog.csdn.net/ithzhang/article/category/1159054 转载于:https://blog. ...
- 21、深入浅出MFC学习笔记,Application Framework简介
1.Application Framework是一个完整的程序模型:是一组合作无间的对象,彼此藉消息的流动而沟通,并且互相调用对方的函数以求完成任务.<?xml:namespace prefix ...
- 28、深入浅出MFC学习笔记,View功能的加强和重绘效率的提高
1.同一份Document的多个views,在Document的一个view改变了后,如何同步其它view呢? 让所有的Views 同步更新资料的关键在于两个函数: 1)CDocument::Upda ...
- 不要看《深入浅出MFC》!
开篇先声明一点,<深入浅出MFC>是一本不错的书,对于MFC原码的剖析,十分到位,特别是前面对于MFC六大关键技术的总结和演示程序,尤其精彩.那为什么我要说不要看这本书呢? 我是站 ...
- 徐无忌深入浅出网络笔记:什么是OSI七层网络模型
徐无忌深入浅出网络笔记:什么是OSI七层网络模型 完成:第一遍 1.什么是OSI? OSI即开放式系统互联(Open System Interconnection) 是期望的标准框架 2.OSI自下向 ...
- 玩转MFC文档视图架构编程1——深入浅出MFC文档/视图架构之基本概念深入浅出MFC文档/视图架构之文档
原创地址: 深入浅出MFC文档/视图架构之基本概念 http://iis.xrtvu.com/Tech/ShowArticle.asp?ArticleID=276 深入浅出MFC文档/视图架构之文档模 ...
- 《深入浅出MFC》观后有感
<深入浅出MFC>观后有感 本文原创,如需转载,请注明出处! 好几年前我曾经买过这本书,知道它是本好书,在匆匆走马观看一遍后,便将它束之高阁,后来有友人借之,不想几经辗转,最终不知我的这本 ...
- 重提“不要看《深入浅出mfc》!”一文
上次写了"不要看<深入浅出MFC>!"一文后,没想到会引起这么大的反响,看了大家的评论后,我觉得有些朋友误解了我的意思,我有必要在这里重新说一下. 首先就是为什么起这个 ...
- 产品经理深入浅出学习笔记
@TOC产品经理深入浅出学习笔记 发现市场需求 -> 商业需求文档(BRD)-> 组织团队头脑风暴(关键节点把控,梳理思路)-> 面对团队中出现的各种阻力与不同意见.能有效的化解与统 ...
- 读侯俊杰的《深入浅出MFC》小记
1.程序必须在产生窗口之前先利用API函数RegisterClass设定属性(我们称此操作为注册窗口类) 2.消息循环中的TranslateMessage是为了将键盘消息转化,DispatchMess ...
最新文章
- Verilog语言中如何将memory型变量转换为普通变量
- 查看LoadRunner脚本请求日志和服务器返回值方法
- JAVA面向对象程序设计(第二版) 袁绍欣 第四章答案
- undefined reference to `vtable for XX::XX'
- 从 Flink Forward Asia 2021,看Flink未来开启新篇章
- 将 Excel 导入到 SharePoint 列表
- 第二章 面向对象的编程风格
- 没有聘礼,男友向我要一台奥迪汽车做陪嫁,房子是他婚前财产,正常吗?
- Leetcode309. Best time to sell stock with cooldown
- [转载] JAVA从菜鸟【入门】到新手【实习】一一一一Python 内置函数,标准库与第三方库(拓展库),常用框架
- NYOJ-97兄弟郊游问题
- python字符串与数字转换,python 字符串和整数的转换方法
- C# 学习笔记-Chart控件使用
- stm32f103r8t6的晶振频率_STM32F103R8T6
- java画一张笑脸_java swing应用(1):画一个眨眼珠的笑脸
- mac 删除Microsoft office word中的空白页的方法
- 【CSS】CSS 层叠样式表 ② ( CSS 引入方式 - 内嵌样式 )
- 全球首位AI评委亮相“83行代码挑战赛”,评分“快准狠”
- python中常用英语口语_常用英语口语100句(超实用)_
- easyUI之LinkButton(按钮)