MFC封装API
来源:互联网 发布:手机屏幕录视频软件 编辑:程序博客网 时间:2024/05/22 06:14
一、Win32Application Architecture
一个Win32 Application Architecture的代码结构如下:
LRESULT CALLBACK WinWordsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); //定义回调处理消息函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){
// 创建一个窗口类分为三步:1.设计窗口类 2.注册窗口类 3.创建窗口 4.显示及更新窗口
// 步骤1.设计窗口类
WNDCLASS wc;
……
// 步骤2:注册窗口类
RegisterClass(&wc);
// 步骤3:创建窗口
HWND hw = NULL;
hw = CreateWindow("Icanth2011", "My Fist Win32 Application Project!~", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 600, 400, NULL, NULL, hInstance, NULL);
// 步骤4:显示及更新窗口
ShowWindow(hw, SW_SHOWNORMAL);
UpdateWindow(hw);
// 消息循环
MSG msg;
BOOL bRet;
while((bRet=GetMessage(&msg, NULL, 0, 0))!=0){
if(-1 == bRet){
return -1;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
由此可见,Win32 Application 程序的组成分为如下几个部分:
1. 找到WinMain程序入口,并开始执行
2. 创建并设计窗口类
3. 注册窗口类
4. 创建窗口
5. 显示及更新窗口
6. 循环获取消息,经处理,交还系统让其调用相关回调消息处理函数进行处理。
二、MFCArchitecture
由于Windows API过多,不方便程序员使用,并且非面对象。于是MFC被用于对Windows API进行封装,MFC始终实际运行过程就是Win32 Application程序的运行过程。
1. MFC的项目结构
利用MFC AppWipzard自动生成的项目包括五个文件:CMyFirstMFCApp、CMainFrame、CFirstMFCDoc、CMyFirstCView、CAboutDlg。CMyFirstMFCApp继承自CWinApp,CMainFrame、CMyFirstCView、CAboutDlg都继承自CWnd,CFirstMFCDoc继承自CDocument,体现“文档/视图”结构。其项目结构如下所示:
2. MFC的执行过程
对于MFC框架运行过程进行剖析,最好的资料是MFC源代码,VC6位于“\Microsoft Visual Studio\VC98\MFC\SRC”下。执行过程如下:
定义theApp(:CMyFistMFCApp)
——>执行构造函数:CWinApp()->CMyFistMFCApp()->
——>程序入口_tWinMain (宏,定义为WInMain)
——>执行AftxWinMain
2.1 MFC的WinMain
在\SRC\APPMODUL.CPP中,可找到如下代码:
MFC\SRC\APPMODUL.CPP:
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
而其中_tWinMain其实就是WinMain函数的宏,定义如下:
#define _tmain main
#define _tWinMain WinMain
#ifdef _POSIX_
#define _tenviron environ
由此可见,WinMain中调用AfxWinMain进行处理。MFC包含此文件,故将找到此入口并自动调用执行。
2.2 theApp全局对象
在Project\CMyFirstMFCApp.CPP中,可找到一行代码发下:
Project\CMyFirstMFCApp.CPP:
/////////////////////////////////////////////////////////////////////////////
// The one and only CMyFistMFCApp object
CMyFistMFCApp theApp;
当定义theApp时,将先执行CWinApp(\MFC\SRC\APPCORE.CPP)的构造函数:
\MFC\SRC\APPCORE.CPP:
CWinApp::CWinApp(LPCTSTR lpszAppName) // 有在该类定义时有默认值NULL
{
if (lpszAppName != NULL)
m_pszAppName = _tcsdup(lpszAppName);
else
m_pszAppName = NULL;
// initialize CWinThread state
AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
ASSERT(AfxGetThread() == NULL);
pThreadState->m_pCurrentWinThread = this;
ASSERT(AfxGetThread() == this);
m_hThread = ::GetCurrentThread();
m_nThreadID = ::GetCurrentThreadId();
// initialize CWinApp state
ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
pModuleState->m_pCurrentWinApp = this; // handle,this代表子类CMyFirstMFCApp对象
ASSERT(AfxGetApp() == this);
……
}
2.3 AfxWinMain(WINMAIN.CPP)
1.AfxWindMain定义
\MFC\SRC\WINMAIN.CPP:
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
if (!pThread->InitInstance())
{
if (pThread->m_pMainWnd != NULL)
{
pThread->m_pMainWnd->DestroyWindow();
}
goto InitFailure;
}
nReturnCode = pThread->Run();
}
2.AfxGetThread
AfxGetThread(THRDCORE.CPP)中调用AfxGetApp,和afxGetApp返回同值,代码如下所示:
\MFC\SRC\ THRDCORE.CPP:
CWinThread* AFXAPI AfxGetThread()
{
// check for current thread in module thread state
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
CWinThread* pThread = pState->m_pCurrentWinThread;
// if no CWinThread for the module, then use the global app
if (pThread == NULL)
pThread = AfxGetApp();
return pThread;
}
3.AfxGetApp
AfxGetApp(AFXWIN1.INL)中定义:
AFXWIN1.INL:
_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp(){ return afxCurrentWinApp; }
而afxCurrentWinApp定义位于AFXWIN.H文件中,如下:
AFXWIN.H:
#define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp
即为CWinApp构造函数时初始化为this的m_pCurrentWinApp。
4.InitInstance
类CWinAPP(APPCORE.CPP)中InitInstance函数定义为:
\MFC\SRC\ APPCORE.CPP:
// overrides for implementation
virtual BOOL InitInstance();
类InitInstance即为虚函数,根据多态性,将调用CMyFirstMFCApp类的InitInstance。
2.4 InitInstance(CMyFirstMFCAPP.CPP)
\MFC\SRC\ CMyFirstMFCAPP.CPP:
BOOL CMyFistMFCApp::InitInstance()
{
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMyFistMFCDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CMyFistMFCView));
AddDocTemplate(pDocTemplate);
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
}
2.5 MFC框架窗口
CFirstMyMFC有两个窗口,其中一个是CMainFrame。
2.5.1 设计和注册窗口
1. CMainFrame::PreCreateWindow定义(\Project\CMainFrame.cpp)
\MFC\SRC\ CMyFirstMFCAPP.CPP:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
return TRUE;
}
2. CFrameWnd::PreCreateWindow(CREATESTRUCT& cs) (\MFC\SRC\WINFRM.CPP)
\MFC\SRC\ CMyFirstMFCAPP.CPP:
BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs.lpszClass == NULL)
{
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
}
return TRUE;
}
其中,AfxDeferRegisterClass即为AfxEndDeferRegisterClass的宏定义,位于AFXIMPL.H文件中:
AFXIMPL.H:
#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)
3. AfxEndDeferRegisterClass (位于WINCORE.CPP中)
此处指定DefWindowProc函数来处理回调消息。 (!~)
MFC\SRC\WINCORE.CPP:
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)
{
// mask off all classes that are already registered
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
fToRegister &= ~pModuleState->m_fRegisteredClasses;
if (fToRegister == 0)
return TRUE;
LONG fRegisteredClasses = 0;
// common initialization
WNDCLASS wndcls;
memset(&wndcls, 0, sizeof(WNDCLASS)); // start with NULL defaults
wndcls.lpfnWndProc = DefWindowProc;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hCursor = afxData.hcurArrow;
INITCOMMONCONTROLSEX init;
init.dwSize = sizeof(init);
// work to register classes as specified by fToRegister, populate fRegisteredClasses as we go
if (fToRegister & AFX_WND_REG)
{
// Child windows - no brush, no icon, safest default class styles
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpszClassName = _afxWnd;
if (AfxRegisterClass(&wndcls))
fRegisteredClasses |= AFX_WND_REG;
}
……
}
4. AfxRegisterClass (位于WINCORE.CPP中)
MFC\SRC\WINCORE.CPP:
BOOL AFXAPI AfxRegisterClass(WNDCLASS* lpWndClass)
{
WNDCLASS wndcls;
if (GetClassInfo(lpWndClass->hInstance, lpWndClass->lpszClassName,
&wndcls))
{
// class already registered
return TRUE;
}
if (!::RegisterClass(lpWndClass))
{
TRACE1("Can't register window class named %s\n",
lpWndClass->lpszClassName);
return FALSE;
}
return TRUE;
}
2.5.2 创建窗口
1. CFrameWnd::Create (WINFRM.CPP)
MFC\SRC\WINFRM.CPP:
BOOL CFrameWnd::Create(LPCTSTR lpszClassName,
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);
if ((hMenu = ::LoadMenu(hInst, lpszMenuName)) == NULL)
{
TRACE0("Warning: failed to load menu for CFrameWnd.\n");
PostNcDestroy(); // perhaps delete the C++ object
return FALSE;
}
}
m_strTitle = lpszWindowName; // save title for later
if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext))
{
TRACE0("Warning: failed to create CFrameWnd.\n");
if (hMenu != NULL)
DestroyMenu(hMenu);
return FALSE;
}
return TRUE;
}
3. CWnd:CreateEx (WINCORE.CPP)
MFC\SRC\WINFRM.CPP:
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
CREATESTRUCT cs;
cs.dwExStyle = dwExStyle;
……
if (!PreCreateWindow(cs)) //完成注册窗口类工作
{
PostNcDestroy();
return FALSE;
}
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);
……
}
以下是CREATESTRUCT和CreateWindowEx参数的对比:
由于CREATESTRUCT中的属性都定义为指针,故可在PreCreateWindow中更改属性,在CreateWindowEx中将更改显示。
4. MFC的调用关系
① theApp
theApp(CMyFirstMFCApp.CPP)
——> CWinAPP ::CWinAPP(){ pModuleState->m_pCurrentWinApp = this; }
② _tWinMain(APPMODUL.CPP)
_tWinMain ()
{
AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
③ AfxWinMain(WinMain.CPP)
int AFXAPI AfxWinMain()
{
CWinThread* pThread = AfxGetThread(); //——>return AfxGetApp() (:THRDCORE.CPP)
CWinApp* pApp = AfxGetApp();
//——>return afxCurrentWInApp (:AFXWIN1.INL)
//——>return AfxGetModuleState()->m_pCurrentWinApp (:AFXWIN.H)
AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
pApp->InitApplication();
pThread-> InitInstance ();
//——> CMyFirstMFCApp::InitInstance
//——> AddDocTemplate(pDocTemplate);
//——> m_pMainWnd->ShowWindow(SW_SHOW);
//——> m_pMainWnd->UpdateWindow();
pThread->Run();
}
④ 窗口
设计和注册窗口:
CMainFrame::PreCreateWindow (\Project\ CMainFrame.cpp)
——>CFrameWnd::PreCreateWindow
——>AfxDeferRegisterClass(宏= AfxEndDeferRegisterClass)
——>AfxEndDeferRegisterClass
——>AfxRegisterClass
——>::RegisterClass (SDK)
创建窗口:
CFrameWnd::Create()
——>CFrameWnd::CreateEx()
——>CWnd::CreateEx()
——>virsual CWnd::PreCreateWIndow(虚函数,调用子类中CFrameWnd:: PreCreateWIndow),
:: CreateWIndowEx()
- MFC封装API
- MFC对WinSockt API的封装
- MFC对WinSockt API的封装
- MFC对WinSockt API的封装
- MFC中C++类如何封装API
- 对MFC封装Windows通讯API的研究
- mfc封装
- MFC-窗口封装
- MFC-窗口封装
- MFC wINMain的封装
- MFC封装窗口
- MFC--框架封装
- MFC怎么封装CreateWindow
- MFC SQlite3封装工程
- 1.5 MFC封装思想
- MFC resizer封装
- WinSocket API封装
- 封装delphi Hook Api
- hdu 2665 Kth number(划分树)
- IE下的firebug
- Date日期类型操作
- Valid Sudoku
- Java中Runnable和Thread的区别
- MFC封装API
- 【h5白鹭引擎】如何快速开发一个小游戏
- genymotion5.1启动一直卡在启动界面或者是一直卡在启动优化界面问题处理
- Highcharts使用CSV格式数据绘制图表
- iOS应用在App Store 中审核的过程中不同状态所表示的意义
- linux之绪论理解[读书笔记]
- Unity笔记 2D ROGUELIKE 实例详解
- cocos2dx ActionTimeline setLastFrameCallFunc
- 社説 20150721 主権者教育 政治的中立をどう確保するか