导航
  • 主页
  • VC综合技术
  • 互联网技术
  • MFC AppLauncher
  • .NET 技术
  • 界面
  • 进程
  • 算法
  • 硬件/系统
  • 数据库
  • VC++技术资源

MFC

devilFredo 2009-08-21 08:21:26
MFC 单文档程序(代码全VC6.0自动生成,主要是看MFC运行机制)中CTestApp::InitInstance哪一个语句调用WINCORE.CPP中的AfxEndDeferRegisterClass()函数的??
也就是在CTestApp::InitInstance()函数中具体哪一个语句加载注册窗口类函数的??
...全文
119 点赞 收藏 12
写回复
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
axlshn 2010-03-22
[Quote=引用 10 楼 heiheizh618 的回复:]

建议楼主看深入浅出MFC第6章。
281页开始看,从 “CFrameWnd::Create产生主窗口(并先注册窗口类)”这小节开始看起,这里介绍得是楼主所要了解的东西,这个API就是InitInstance所调用的函数,并在这里完成窗口类注册操作。
这本书的电子版到处都有,可以随便下下来看看~
[/Quote]

看了,不一样。
回复

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);

int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();
CWinApp* pApp = AfxGetApp();

// AFX internal initialization
if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))
goto InitFailure;

// App global initializations (rare)
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;

// Perform specific initializations
if (!pThread->InitInstance())//这里调用的.
{
if (pThread->m_pMainWnd != NULL)
{
TRACE0("Warning: Destroying non-NULL m_pMainWnd\n");
pThread->m_pMainWnd->DestroyWindow();
}
nReturnCode = pThread->ExitInstance();
goto InitFailure;
}
nReturnCode = pThread->Run();

InitFailure:
#ifdef _DEBUG
// Check for missing AfxLockTempMap calls
if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
{
TRACE1("Warning: Temp map lock count non-zero (%ld).\n",
AfxGetModuleThreadState()->m_nTempMapLock);
}
AfxLockTempMaps();
AfxUnlockTempMaps(-1);
#endif

AfxWinTerm();
return nReturnCode;
}
回复
churenxh 2009-08-22
把这些都看掉吧,对你理解MFC机制有好处
回复
churenxh 2009-08-22
完成WinMain函数主要完成窗口产生过程,即:

设计窗口,注册窗口,构造窗口,显示窗口,更新窗口,消息循环,处理消息。

1.CWinApp内部运行机制

CWinApp---在appmodul.cpp中

具体的可以参考CWinApp函数。

1)

pThreadState->m_pCurrentWinThread = this;

这里的this指针是指向CWinApp子类CTestApp对象theApp的指针;

2)

CWinApp运行完成,即基类构造函数完成,从而基子类CTestApp构造函数也初始化完成,然后

为子类CTestApp对象theApp分配完内存空间。接下来,进入入口函数WinMain中。

CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

2.WinMain 即(_tWinMain()函数)函数

WinMain函数---在appcore.cpp中

AfxWinMain函数---在winmain.cpp中

(以Afx开头的是全局函数,可以被其它对象调用)

WinMain函数主要完成窗口产生过程,即:

设计窗口,注册窗口,构造窗口,显示窗口,更新窗口,消息循环,处理消息。

1)注册窗口前的初始化工作

由pThread->InitInstance()完成

AfxWinMain函数下面方法:

CWinThread* pThread = AfxGetThread();

CWinApp* pApp = AfxGetApp();

AfxGetThread()和 AfxGetApp() 都是获得在CWinApp中构造函数内赋给 pThreadState->m_pCurrentWinThread 对象

的this指针,也即是获得指向子类CTestApp对象theApp的指针,保存在pThread与pApp中。所以实际上pThread与pApp

都是保存的theApp指针。

pThread与pApp 共调用了三个方法,即子类对象theApp调用了三个方法:

pApp->InitApplication() MFC内部初始化管理所调用的函数

pThread->InitInstance() 因CWinThread类中InitInstance()为虚函数,由多态原理,所以这里调用的是子类CTestApp中的InitInstance()

pThread->Run() 完成消息循环

其中

pThread->InitInstance() 初始化完成后,即开始注册窗口

CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

--_tWinMain()在appmodul.cpp中--AfxWinMain()中的pThread->InitInstance()在winmain.cpp中--调用CTestApp::InitInstance()在当前项目

--设计注册窗口

2)设计窗口

 AfxEndDeferRegisterClass()完成(有很多if语句中).

AfxEndDeferRegisterClass()---在wincore.cpp中.

MFC中默认定义了几种窗口类,只是调用函数AfxEndDeferRegisterClass()就可以完成设计窗口过程。

在里面会根据应用程序要求的不同窗口类型设计不同的窗口,在很多if条件语句中。

3)注册窗口

在AfxEndDeferRegisterClass()函数中,由AfxRegisterClass()完成.

AfxEndDeferRegisterClass()---在wincore.cpp中.

在AfxRegisterClass()函数中

AfxCtxGetClassInfo() 判断要注册的窗口是否已经注册.

注意:

单文档结构和多文档结构在注册窗口上有不同的顺序.

单文档结构:先就调用AfxEndDeferRegisterClass() 进行窗口注册

多文档结构:先调用

子类CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

再调用基类CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)

再调用AfxEndDeferRegisterClass()进行窗口注册

4)产生窗口之前

(单文档结构)

CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

--_tWinMain()在appmodul.cpp中--AfxWinMain()中的pThread->InitInstance()在winmain.cpp中--调用CTestApp::InitInstance()在当前项目

--设计窗口AfxEndDeferRegisterClass()在wincore.cpp中--注册窗口AfxEndDeferRegisterClass()中的AfxRegisterClass()在wincore.cpp中

--产生窗口之前调用子类CMainFrame::PreCreateWindow(CREATESTRUCT& cs)在MainFrm.cpp中--产生窗口之前调用基类CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)在winfrm.cpp中

--注册窗口AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)在wincore.cpp中

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) 在当前工程的MainFrm.cpp中

BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs) 在winfrm.cpp中

调用AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG) 判断当然窗口类型有没有注册,实际是调用AfxDeferRegisterClass(fClass)

AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)--在afximpl.h中

#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass) 是一个宏

产生两个窗口:CMainFrame和子窗口CTestView

CMainFrame--CFrameWnd--CWnd 凡是从CWnd派生出来的类都是窗口类

子窗口CTestView--CView--CWnd 子窗口也是一个窗口类

CMainFrame产生的窗口是框架窗口,其内部还可以有子窗口.

5)创建窗口

CreateWindow Function

CreateWindowEx Function

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

)

在wincore.cpp中

BOOL CFrameWnd::Create(LPCTSTR lpszClassName,

LPCTSTR lpszWindowName,

DWORD dwStyle,

const RECT& rect,

CWnd* pParentWnd,

LPCTSTR lpszMenuName,

DWORD dwExStyle,

CCreateContext* pContext

)

在winfrm.cpp中

CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

--_tWinMain()在appmodul.cpp中--AfxWinMain()中的pThread->InitInstance()在winmain.cpp中--调用CTestApp::InitInstance()在当前项目

--设计窗口AfxEndDeferRegisterClass()在wincore.cpp中--注册窗口AfxEndDeferRegisterClass()中的AfxRegisterClass()在wincore.cpp中

--产生窗口之前调用子类CMainFrame::PreCreateWindow(CREATESTRUCT& cs)在MainFrm.cpp中--产生窗口之前调用基类CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)在winfrm.cpp中

--注册窗口AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)在wincore.cpp中

--创建窗口调用子类BOOL CFrameWnd::Create()在winfrm.cpp中--创建窗口调用基类BOOL CWnd::CreateEx()在wincore.cpp中(--循环产生窗口--)

BOOL CWnd::CreateEx()在wincore.cpp中,调用PreCreateWindow(cs)和::AfxCtxCreateWindowEx(),为了在创建窗口之前,有机会修改窗口的外观样式.

PreCreateWindow在afxwn.h中定义为:

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

所以这里调用的是子类的BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs),

AfxCtxCreateWindowEx是宏:

#define AfxCtxCreateWindowEx AfxCtxCreateWindowExW 在afxcomctl32.h中

在afxcomctl32.h中,AFX_ISOLATIONAWARE_STATICLINK_FUNC(HWND ,CreateWindowExW,(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam),(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam),NULL)

CreateWindowEx也是宏:

#define CreateWindowEx CreateWindowExW

CREATESTRUCT与CreateWindowEx的定义:

typedef struct tagCREATESTRUCT {

LPVOID lpCreateParams;

HINSTANCE hInstance;

HMENU hMenu;

HWND hwndParent;

int cy;

int cx;

int y;

int x;

LONG style;

LPCTSTR lpszName;

LPCTSTR lpszClass;

DWORD dwExStyle;

} CREATESTRUCT;

HWND CreateWindowEx(

DWORD dwExStyle,

LPCTSTR lpClassName,

LPCTSTR lpWindowName,

DWORD dwStyle,

int x,

int y,

int nWidth,

int nHeight,

HWND hWndParent,

HMENU hMenu,

HINSTANCE hInstance,

LPVOID lpParam

);

CREATESTRUCT中成员变量与CreateWindowEx中的参数是一致的,不过顺序相反.

利用CREATESTRUCT结构体主要为了产生窗口之前,有机会修改窗口外观.

6)显示窗口和更新窗口

在Test.cpp中的BOOL CTestApp::InitInstance()中.

当Test.cpp中ProcessShellCommand(cmdInfo)成功执行完后,表示窗口创建已经完成.

再通过:

m_pMainWnd->ShowWindow(SW_SHOW);

m_pMainWnd->UpdateWindow();

来完成窗口显示和窗口更新

m_pMainWnd是指向CMainFrm框架窗口对象的一个指针

7)消息循环

CWinThread::Run在THRDCORE.CPP中.

do while中的PumpMessage()--->CWinThread::PumpMessage()-->BOOL AFXAPI AfxInternalPumpMessage()再重复do while中的PumpMessage()

CWinApp在appcore.cpp中--全局对象theApp--子类构造函数调用CTestApp()--基类构造函数调用CWinApp()在appcore.cpp中

--_tWinMain()在appmodul.cpp中--AfxWinMain()中的pThread->InitInstance()在winmain.cpp中--调用CTestApp::InitInstance()在当前项目

--设计窗口AfxEndDeferRegisterClass()在wincore.cpp中--注册窗口AfxEndDeferRegisterClass()中的AfxRegisterClass()在wincore.cpp中

--产生窗口之前调用子类CMainFrame::PreCreateWindow(CREATESTRUCT& cs)在MainFrm.cpp中--产生窗口之前调用基类CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)在winfrm.cpp中

--注册窗口AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG)在wincore.cpp中

--创建窗口调用子类BOOL CFrameWnd::Create()在winfrm.cpp中--创建窗口调用基类BOOL CWnd::CreateEx()在wincore.cpp中(--循环产生窗口--)

--显示窗口调用BOOL CTestApp::InitInstance()中的m_pMainWnd->ShowWindow(SW_SHOW)在Test.cpp(应用程序类)中;

--更新窗口调用BOOL CTestApp::InitInstance()中的m_pMainWnd->UpdateWindow()在Test.cpp(应用程序类)中;

--do while中的PumpMessage()--->CWinThread::PumpMessage()-->BOOL AFXAPI AfxInternalPumpMessage()(--再重复do while中的PumpMessage()--)

回复
churenxh 2009-08-22
孙鑫VC++讲座笔记-(3)MFC程序框架的剖析 附1-SDI程序流程图 收藏

//AfxWinMain()函数在WINMAIN.CPP文件中,它主要调用以下函数

AfxWinInit();

pApp->InitApplication(); //内部初始化管理

pThread->InitInstance(); //调用子类中的InitInstance()

CTestApp::InitInstance();

┣━ProcessShellCommand(cmdInfo); //对命令行进行解释

┃ CTestDoc::CTestDoc(); //构造文档类对象

┃ CMainFrame::CMainFrame(); //构造框架窗口对象

┃ CFrameWnd::LoadFrame(); //WINFRM.CPP

┃ ┣━AfxEndDeferRegisterClass(); //WINCORE.CPP,注册窗口类

┃ ┃ AfxRegisterClass(); //WINCORE.CPP

┃ ┣━CMainFrame::PreCreateWindow();

┃ ┃ CFrameWnd::PreCreateWindow();

┃ ┃ AfxEndDeferRegisterClass();

┃ ┣━AfxRegisterClass();

┃ ┗━CFrameWnd::Create(); //创建CMainFrame窗口

┃ CWnd::CreateEx();

┃ CMainFrame::PreCreateWindow();

┃ CFrameWnd::PreCreateWindow();

┃ CTestView::CTestView(); //构造CTestView对象

┃ CWnd::CreateEx(); //创建CTestView窗口

┃ AfxEndDeferRegisterClass();

┃ AfxEndDeferRegisterClass();

┃ CWnd::CreateEx(); //创建CToolBar工具栏

┃ AfxEndDeferRegisterClass();

┃ CWnd::CreateEx(); //创建CStatusBar状态栏

┃ AfxEndDeferRegisterClass();

┃ AfxRegisterClass();

┃ CWnd::CreateEx(); //创建CDockBar

┃ AfxEndDeferRegisterClass();

┃ CWnd::CreateEx(); //创建CDockBar

┃ AfxEndDeferRegisterClass();

┃ CWnd::CreateEx(); //创建CDockBar

┃ AfxEndDeferRegisterClass();

┃ CWnd::CreateEx(); //创建CDockBar

┣━m_pMainWnd->ShowWindow(SW_SHOW); //显示窗口

┗━m_pMainWnd->UpdateWindow(); //更新窗口

nReturnCode = pThread->Run(); //进入消息循环

从这上面看,是它注册窗体类函数,你虚调试跟踪可以看到,都被封装到MFC库里了
回复
lzh9955 2009-08-22
好久没碰那玩意了!
回复
skydreamsky 2009-08-22
来学习的
回复
heiheizh618 2009-08-22
建议楼主看深入浅出MFC第6章。
281页开始看,从 “CFrameWnd::Create产生主窗口(并先注册窗口类)”这小节开始看起,这里介绍得是楼主所要了解的东西,这个API就是InitInstance所调用的函数,并在这里完成窗口类注册操作。
这本书的电子版到处都有,可以随便下下来看看~
回复
devilFredo 2009-08-22
回复churenxh兄:你说的那个MFC哪个执行好了再执行哪个函数,我知道。我想知道的是,前一个函数执行好了再执行后一个,这个前一个函数中是调用其中的哪个语句来进入后一个函数的??
不过你的回复很好,真的很感谢
回复
devilFredo 2009-08-22
回复akirya兄:我知道“!pThread->InitInstance())//这里调用的.”进入InitInstance()。我是问InitInstance()函数中哪个语句调用进入AfxEndDeferRegisterClass()这个函数中去的???谢谢
回复
klkvc386 2009-08-22
Mark
回复
mengde007 2009-08-21
单步跟踪下;
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……