您的位置:首页 > 编程语言 > C语言/C++

MFC学习笔记(3)——Windows程序类的封装 中

2016-12-08 13:31 393 查看
派生类的应用

如果把窗口类CFrameWnd和应用程序类CWinApp预先定义后并内置在一个类库中,那么我们就可以使用这些类来定义对象,没有必要再由自己来声明类了。可是,直接调用的话,其代价就是程序设计的灵活性将会变差,很难实现应用程序的一些个性化要求。为解决这个代价,可以利用C++类的继承性和多态性来解决,即程序员可以找现有类的基础上派生自己的类。这样,程序员就可以在派生类中通过添加成员,或对基类函数进行重新定义的手段来满足个性化需求。

1.应用程序类的派生类

为了可以在派生类中重新定义基类的某些成员函数,可以在基类中把它们声明为虚函数。用CWinApp1的派生类CMyApp编写的程序如下:

//CWinApp1类的声明
class CWinApp1
{
public:
CFrameWnd1*m_pMainWnd;
public:
virtual BOOL InitInstance(int nCmdShow);//声明为虚函数
int Run();
~CWinApp1();
};
//由CWinApp1类派生CMyApp类
class CMyApp:public CWinApp1
{
public:
BOOL InitInstance(int nCmdShow); //重新定义InitInstance函数
};
//重新定义的成员函数InitInstance
BOOL CMyApp::InitInstance(int nCmdShow)
{
m_pMainWnd = new CFrameWnd1;
m_pMainWnd->Create(NULL, "用新的InitInstance函数的程序");
m_pMainWnd->ShowWindow(nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
CMyApp theApp1;
其结果如下图所示:



2.窗口类的派生类

窗口类的派生此处就不详细介绍,由于在应用程序类CWinApp中定义的窗体对象m_pMainWnd是CFrameWnd类型的,而现在要用CFrameWnd的派生类来定义窗体对象。因此,在应用程序类派生类中的InitInstance函数中,需要先定义一个窗体的派生类对象,然后再把它赋给m_pMainWnd。由窗口类派生类和应用程序类派生类构成的Windows程序结构如下图:



下面附上窗体和应用程序类的派生类的完整程序清单:

#include "stdafx.h"
#include "afxwinappex.h"
#include "afxdialogex.h"
#include "MFCTest.h"
#include<Windows.h>
//定义全局变量和函数
HINSTANCE hInstance;
HINSTANCE hInst;
MSG msg;
char lpszClassName[] = "window_class";
char* ShowText;

//声明函数原型
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//窗口函数
void OnLButtonDown(HWND hWnd, UINT message,WPARAM wParam,LPARAM lParam);
void OnPaint(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void OnDestroy(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
//窗口类
class CFrameWnd1
{
public:
HWND hWnd;
public:
int RegisterWindow();
void Create(LPCTSTR lpClassName, LPCTSTR lpWindowName);
void ShowWindow(int nCmdShow);
void UpdateWindow();
};
//窗口类成员函数
int CFrameWnd1::RegisterWindow()
{
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.style = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = lpszClassName;
wc.lpszMenuName = NULL;
return RegisterClass(&wc);
}

void CFrameWnd1::Create(LPCTSTR lpClassName, LPCTSTR lpWindowName)
{
RegisterWindow();
hInst = hInstance;
hWnd = CreateWindow(lpszClassName, lpWindowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
}

void CFrameWnd1::ShowWindow(int nCmdShow)
{
::ShowWindow(hWnd, nCmdShow);
}

void CFrameWnd1::UpdateWindow()
{
::UpdateWindow(hWnd);
}

//CWinApp1类的声明
class CWinApp1
{
public:
CWinApp1*m_pCurrentWinApp;
public:
CWinApp1();
~CWinApp1();
public:
CFrameWnd1*m_pMainWnd;
public:
virtual BOOL InitInstance(int nCmdShow);//声明为虚函数
int Run();
};

CWinApp1::CWinApp1()
{
m_pCurrentWinApp = this;
}

BOOL CWinApp1::InitInstance(int nCmdShow)
{
m_pMainWnd = new CFrameWnd1;
m_pMainWnd->Create(NULL, "封装的Windows程序");
m_pMainWnd->ShowWindow(nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}

int CWinApp1::Run()
{
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

CWinApp1::~CWinApp1()
{
delete m_pMainWnd;
}

//程序员派生的窗口类
class CMyWnd :public CFrameWnd1
{

};
//由CWinApp1类派生CMyApp类
class CMyApp:public CWinApp1
{
public:
BOOL InitInstance(int nCmdShow); //重新定义InitInstance函数
};
//重新定义的成员函数InitInstance
BOOL CMyApp::InitInstance(int nCmdShow)
{
CMyWnd*pMainWnd;
pMainWnd = new CMyWnd;                            //应用窗体的派生类定义窗体对象
pMainWnd->Create(NULL, "应用窗体的派生类的程序");
pMainWnd->ShowWindow(nCmdShow);
pMainWnd->UpdateWindow();
m_pMainWnd = pMainWnd;                            //把CMyWnd类的对象赋给m_pMainWnd
return TRUE;
}
//程序员定义的CWinApp的对象MyApp
CMyApp MyApp;
//全局函数AfxGetApp()
CWinApp1*AfxGetApp1()
{
return MyApp.m_pCurrentWinApp;
}
//主函数
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
int ResultCode = -1;
CWinApp1* pApp;
pApp = AfxGetApp1();
pApp->InitInstance(nCmdShow);
return ResultCode = pApp->Run();
}
//窗口函数的实现
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_LBUTTONDOWN:
OnLButtonDown(hWnd, message, wParam, lParam);
break;
case WM_PAINT:
OnPaint(hWnd, message, wParam, lParam);
break;
case WM_DESTROY:
OnDestroy(hWnd, message, wParam, lParam);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

void OnLButtonDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
ShowText = "Hello!";
InvalidateRect(hWnd, NULL, 1);
}

void OnPaint(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 50, 50, ShowText, 6);
EndPaint(hWnd, &ps);
}

void OnDestroy(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PostQuitMessage(0);
}
其结果如下图:





此节终了。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息