您的位置:首页 > 其它

读书时间 2011/10/23

2011-10-23 11:38 274 查看
Chap 6. 框架中的窗口

1. 窗口框架总结

* example.cpp中定义theApp

CMyApp theApp;

Q:此步骤中,有没有任何初始化动作完成?

A:Yes。对模块变量参数进行初始化,在THREAD_LOCAL中保存,如主窗口指针等等。

* WinMain.cpp中的WinMain()是入口

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

ASSERT(hPrevInstance == NULL);

int nReturnCode = -1;

CWinThread* pThread = AfxGetThread(); ////// 这些函数生效的原因是在WinApp::WinApp()中相关thread/app指针已经存储在THREAD_LOCAL中

CWinApp* pApp = AfxGetApp();

// 类库框架内部的初始化

if(!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))

goto InitFailure;

// 应用程序的全局初始化

if(pApp != NULL && !pApp->InitApplication())

goto InitFailure;

// 主线程的初始化:完成窗口类注册,窗口生成,窗口显示/更新

if(!pThread->InitIntance())

{

nReturnCode = pThread->ExitInstance();

goto InitFailure;

}

// 开始与用户交互,运行消息循环

nReturnCode = pThread->Run();

InitFailure:

return nReturnCode;

}

注:若CMyApp对象未定义,在主线程初始化的时候会出错,原因其实是pthread为空指针:Access Violation.

* CMyApp::InitInstance()

BOOL CMyApp::InitInstance()

{

m_pMainWnd = new CMyWnd;

::ShowWindow(*m_pMainWnd, this->m_nCmdShow);

::UpdateWindow(*m_pMainWnd);

return TRUE; // 返回TRUE进入消息循环

}

注:CMyWnd()实例化的时候,完成对窗口类注册

* CMyWnd::CMyWnd()

CMyWnd::CMyWnd()

{

LPCTSTR lpszClassName = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,

::LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_3DFACE+1));

CreateEx(WS_EX_CLIENTEDGE, lpszClassName,

"框架程序创建的窗口", WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL);

}

注1:AfxRegisterWndClass()完成窗口类注册,并把窗口函数指向::DefaultWindowProc

注2:CreateEx()通过hook,完成了当前生成窗口函数的修改,指向::AfxWndProc函数,此函数实现了消息处理函数的分派 --------- 即调用CWnd::WindowProc()函数的功能

* WINCORE.CPP::AfxWndProc()

///////////////////////////////////////////////

// 分发消息

LRESULT __stdcall AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)

{

CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);

ASSERT(pWnd != NULL);

ASSERT(pWnd->m_hWnd == hWnd);

return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);

}

2. 消息映射

* CCmdTarget

#_AFXWIN.h

////////////////////////////////////////////////////

// CCmdTarget类(命令目标)

class CCmdTarget : public CObject

{

DECLARE_DYNCREATE(CCmdTarget);

public:

CCmdTarget();

DECLARE_MESSAGE_MAP()

};

#cmdtarg.cpp

CCmdTarget::CCmdTarget()

{ }

/////////////////////////////////

// 实现消息映射的代码

const AFX_MSGMAP* CCmdTarget::GetMessageMap () const

{

return &CCmdTarget::messageMap ;

}

const AFX_MSGMAP CCmdTarget::messageMap =

{ NULL, &CCmdTarget::_messageEntries[0] };

const AFX_MSGMAP_ENTRY CCmdTarget::_messageEntries[] =

{

// 一个消息也不处理

{ 0, 0, 0, 0, 0, (AFX_PMSG)0 }

};

注:由于CCmdTarget是顶层类,没有父类,故不能使用BEGIN_MESSAGE_MAP()及END_MESSAGE_MAP()两个宏。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: