1、MFC Windows应用程序设计,第2章 Windows应用程序的封装,在早期的编程生涯中,程序员采用C语言和Windows API函数进行Windows程序设计。采用这种方式进行程序开发,使得开发过程艰苦、乏味。随着编程技术的不断发展,Windows编程采用了面向对象的程序设计思想(Object Oriented Programming,OOP)。这种思想集抽象性、封装性、集成性和多态性于一体,提高了编程的效率。下面对Windows应用程序中的面向对象思想进行介绍。,第2章 Windows应用程序的封装,Windows应用程序主函数的任务是创建并显示窗口和实现消息循环。 为了形成程序框架,
2、应该声明两个类:应用程序类和窗口类。,2.1 应用程序主函数的C+封装,2.1.1窗口类的声明 class CFrameWnd public: HWND hWnd; public:int RegisterWindow(); void Create(LPCTSTR lpClassName,LPCTSTR lpWindowName); void ShowWindow(int nCmdShow);void UpdateWindow(); ;,2.1 应用程序主函数的C+封装,2.1.1窗口类的声明 int CFrameWnd:RegisterWindow() WNDCLASS wc;wc.style
3、=0;wc.lpfnWndProc=WndProc;wc.cbClsExtra=0;wc.cbWndExtra=0;wc.hInstance=hInstance;wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);wc.hCursor=LoadCursor(NULL,IDC_ARROW);wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName=NULL;wc.lpszClassName=lpszClassName;return RegisterClass( ,2.1 应用程序主函数的C
4、+封装,2.1.1窗口类的声明 void CFrameWnd:Create(LPCTSTR lpClassName,LPCTSTR lpWindowName) RegisterWindow( );hInst = hInstance; hWnd = CreateWindow(lpszClassName,lpWindowName, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); ,2.1 应用程序主函数的C+封装,2.1.1窗口类的声明void CFrameWnd:ShowW
5、indow(int nCmdShow) :ShowWindow(hWnd, nCmdShow); void CFrameWnd:UpdateWindow() :UpdateWindow(hWnd); ,2.1 应用程序主函数的C+封装,2.1.2 应用程序类的声明-CWinAppclass CWinApp public:CFrameWnd *m_pMainWnd; public:BOOL InitInstance (int nCmdShow);int Run(); ;,2.1 应用程序主函数的C+封装,2.1.2 应用程序类的声明-CWinAppBOOL CWinApp:InitInstanc
6、e(int nCmdShow) m_pMainWnd=new CFrameWnd;m_pMainWnd-Create(NULL,“封装的Windows程序“);m_pMainWnd-ShowWindow(nCmdShow);m_pMainWnd-UpdateWindow();return TRUE; ,2.1 应用程序主函数的C+封装,2.1.2 应用程序类的声明-CWinAppint CWinApp:Run() while (GetMessage( ,2.1 应用程序主函数的C+封装,2.1.3 主函数封装后的程序 CWinApp theApp;int APIENTRY WinMain(HI
7、NSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) int ResultCode=-1;theApp.InitInstance(nCmdShow);return ResultCode=theApp.Run(); ,2.1 应用程序主函数的C+封装,2.2 派生类的应用,2.2.1 应用程序类的派生类class CWinApp public:CFrameWnd*m_pMainWnd; public:virtual BOOL InitInstance (int nCmdShow);int Run();CWi
8、nApp(); ;,2.2 派生类的应用,2.2.1 应用程序类的派生类 BOOL CWinApp:InitInstance(int nCmdShow) m_pMainWnd=new CFrameWnd;m_pMainWnd-Create(NULL, “封装的Windows程序“);m_pMainWnd-ShowWindow(nCmdShow);m_pMainWnd-UpdateWindow();return TRUE; ,2.2 派生类的应用,2.2.1 应用程序类的派生类 class CMyApp:public CWinApp public:BOOL InitInstance(int nC
9、mdShow);/重新定义InitInstance函数 ;,2.2 派生类的应用,2.2.1 应用程序类的派生类 CMyApp:InitInstance(int nCmdShow) m_pMainWnd=new CFrameWnd;m_pMainWnd-Create(NULL,“用新的InitInstance函数的程序“);m_pMainWnd-ShowWindow(nCmdShow);m_pMainWnd-UpdateWindow();return TRUE; ,2.2.2 窗口类的派生类,2.2 派生类的应用,2.3.1 消息处理函数的简单封装,2.3 窗口函数的封装-消息映射,class
10、 CFrameWnd public: HWND hWnd; public:int RegisterWindow(); void Create(LPCTSTR lpClassName,LPCTSTR lpWindowName);void ShowWindow(int nCmdShow);void UpdateWindow();int AfxWndProc(HWND,UINT,WPARAM,LPARAM); ;,int CCmdTarget:AfxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) switch (messa
11、ge) case WM_LBUTTONDOWN: On_LButtonDown(hWnd, message, wParam, lParam);break;case WM_PAINT: On_Paint(hWnd, message,wParam, lParam);break;case WM_DESTROY: On_Destroy(hWnd, message, wParam, lParam);break;default:return DefWindowProc(hWnd, message,wParam, lParam);return 0; ,LRESULT CALLBACK WndProc(HWN
12、D hwnd, UINT message, WPARAM wParam,LPARAM lParam) AfxWndProc(hwnd,message,wParam,lParam); ,2.3.1 消息处理函数的简单封装,2.3 窗口函数的封装-消息映射,MFC 用CCmdTarget封装窗口函数 class CCmdTarget public: int AfxWndProc(HWND, UINT, WPARAM, LPARAM );void On_LButtonDown(HWND, UINT, WPARAM, LPARAM );void On_Paint(HWND, UINT, WPARAM,
13、 LPARAM );void On_Destroy(HWND, UINT, WPARAM, LPARAM ); ;,2.3 窗口函数的封装-消息映射,2.3.2 消息映射 1、类的消息处理函数afx_msg void OnLButtonDown();afx_msg void OnDestroy();afx_msg void OnPaint();,2.3 窗口函数的封装-消息映射,2.3.2 消息映射2、类的消息映射表struct MSGMAP_ENTRY UINT nMessage;void (*pfn)(HWND, UINT, WPARAM, LPARAM ); ;,2.3 消息映射,2、类
14、的消息映射表,消息分类Windows消息 :除WM_COMMAND之外,以WM_开头的消息。从CWnd派生的类都可以接收到这类消息。 命令消息: 自菜单、工具条按钮、加速键等用户接口对象的WM_COMMAND通知消息 。在MFC中通过资源项的标识(ID)来区分不同的命令消息。控制通知消息:是控制子窗口送给父窗口的WM_COMMAND通知消息。,2.3.2 消息映射,2、类的消息映射表,struct AFX_MSGMAP_ENTRYUINT nMessage; / Windows消息的ID号UINT nCode; / 为控制消息的通知码UINT nID; / Windows控制消息的IDUINT
15、 nLastID; / 表示如果是一个指定范围的消 息被/映射的,nLastID用来表示它的范围。UINT nSig; / 表示消息的动作标识AFX_PMSG pfn; / 一个指向和该消息相应的执行函数的指针;,2.3 窗口函数的封装-消息映射,2.3.3 消息映射表的声明和实现1、宏DECLARE_MESSAGE_MAP 2、宏BEGIN_MESSAGE_MAP BEGIN_MESSAGE_MAP (类名,基类名),2.3 窗口函数的封装-消息映射,2.3.3 消息映射表的声明和实现 3、ON_ Windows消息的宏 前缀为“ON_WM_”这样的宏不带参数,因为它对应的消息和消息处理函数
16、的函数名称、函数原型是确定的。MFC提供了这类消息处理函数的定义和缺省实现。每个这样的宏处理不同的Windows消息。 ON_WM_LBUTTONDOWN(),2.3 窗口函数的封装-消息映射,2.3.3 消息映射表的声明和实现 3、ON_ 命令消息的宏 :ON_COMMAND 这类宏带有参数,需要通过参数指定命令ID和消息处理函数。这些消息都映射到WM_COMMAND上,也就是将消息映射条目的第一个成员nMessage指定为WM_COMMAND,第二个成员nCode指定为CN_COMMAND(即0)。消息处理函数的原型是void (void),不带参数,不返回值。,2.3 窗口函数的封装-消息映射,2.3.3 消息映射表的声明和实现3、ON_ 控制通知消息的宏 :ON_BN_CLICKED( , ) ON_CBN_DBLCLK(, ),2.3.3 消息映射表的声明和实现 4、END_MESSAGE_MAP,2.3 窗口函数的封装-消息映射,作业:,作业本:P62 2-1,2-2,2-3,2-4,2-5 上机 :在例题2-5的基础上,添加当鼠标左键按下移动鼠标在鼠标所在位置书写姓名,当鼠标左键弹起终止书写姓名。,