读书时间 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()两个宏。
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()两个宏。
相关文章推荐
- N年时间下来读书的感觉差异
- 读书的时间哪里来?
- 读书时间 2011/11/16 读书时间
- 读书时间 2012/01/04 Linux C/iuPhone/iPad
- 读书时间《JavaScript高级程序设计》五:DOM
- 读书时间 2010-12-20
- 【读书感悟】关于时间管理和学习
- 读书时间:《美国的本质》
- 读书时间 2012/01/13 iPhone/iPad
- 好想有个自己真正读书的时间
- 读书时间《JavaScript高级程序设计》七:表单
- 【打发时间之US脚本】读书笔记1
- 读书时间 2012-12-13
- 读书时间--互联网草根革命
- 读书时间2011/12/26 iPhone/iPad
- 读书时间 05/08/2011 Windows Programming V2
- 读书的时间哪里来?
- 读书时间 C++ Standard Lib 2012/05/19
- 读书时间 2010-12-12
- 读书时间 2010-12-17