Chapter 3.GDI/DirectDraw Internal Data Structures

时间:2023-03-08 21:43:43
Chapter 3.GDI/DirectDraw Internal Data Structures

说明,在这里决定跳过第二章,实在是因为里面涉及的内容太理论,对我而言又太艰深

3.1 HANDLES AND OBJECT-ORIRNTED PROGRAMMING

In normal object-oriented programming practice,information hiding is achieved by declaring certain members as private or protected,so the client side code can't access them directly.But the compiler still needs to know perfectly well all members,their types,names,and orders in a class.At least,the compiler needs to know the exact size of an instance of an object for memory allocation.This can cause lots of problems for the modular development of programs,Every time a data member or member function is changed,the whole program needs to be recompiled.Programs complied with older versions of class definition would not work with newer version.To solve this problem,there is the abstract bass class.The abstract bass class,which uses virtual functions to define the interface the clien-side program can see while completely hiding away the implementation,improves information hiding and the modularity of programs even further...For hiding the implementation away from the client side of a class, normally a special function is provided to create an instance of a derived class,including memory allocation; another special function is provided to destroy an instance,including freeing its memory.

Objects in the Win32 API can be seen as being implemented using abstract base class with no data members. The data representation of an object is completely hidden from the user application...the perfect information hiding provided by the Win32 API greatly improves the portability of programs. GDI normally provides several functions to create an instance of an object and several functions to destroy them.

To illustrate our comparison between object-roiented programming and the Win32 API,let's try to provide some minimum pseudo-implementation of GDI using C++.

//gdi.h

#include<windows.h>
class _GdiObj
{
public:
virtual int GetObjectType(void) = ;
virtual int GetObject(int cbBuffer, void * pBuffer) =;
virtual bool DeleteObject(void) = ;
virtual bool UnrealizeObject(void) = ;
}; class _Pen:public _GdiObj
{
public:
virtual int GetObjectType(void)
{
return OBJ_PEN;
}
virtual int GetObject(int cbBuffer,void *pBuff)=;
virtual bool DeleteObject(void)=; virtual bool UnrealizeObject(void)
{
return true;
}
}; _Pen * _CreatePen(int fnPenStyle, int nWidth, COLORREF crColor);
//gdi.cpp

#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "gdi.h"
class _RealPen : public _Pen
{
LOGPEN m_LogPen;
public:
_RealPen(int fnPenStyle, int nWidth, COLORREF crColor)
{
m_LogPen.lopnStyle = fnPenStyle;
m_LogPen.lopnWidth.x = nWidth;
m_LogPen.lopnWidth.y = ;
m_LogPen.lopnColor = crColor;
}
int GetObject(int cbBuffer, void * pBuffer)
{
if ( pBuffer==NULL )
return sizeof(LOGPEN);
else if ( cbBuffer>=sizeof(m_LogPen) )
{
memcpy(pBuffer, & m_LogPen, sizeof(m_LogPen));
return sizeof(LOGPEN);
}
else
{
SetLastError(ERROR_INVALID_PARAMETER);
return ;
}
}
bool DeleteObject(void)
{
if ( this )
{
delete this;
return true;
}
else
return false;
}
};
_Pen * _CreatePen(int fnPenStyle, int nWidth, COLORREF crColor)
{
return new _RealPen(fnPenStyle, nWidth, crColor);
}
//test.cpp

#include "gdi.h"

void Test(void)
{
_Pen * pPen = _CreatePen(PS_SOLID, , RGB(, , 0xFF));
////
pPen->DeleteObject();
}
int WINAPI WinMain(HINSTANCE hInsatcne,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
return ;
}

这个程序定义_GdiObj这样一个抽象基类,紧接着派生出_Pen类,同为抽象基类,在_Pen类的子类_RealPen中才将纯虚函数一一实现。另外从这个程序中也可以看出,创建画笔对象调用的函数,其实是填充一个LOGPEN结构类型数据的几个字段