CRect之DeflateRect及CPaintDC, CClientDC与CWindowDC区别

void DeflateRect(int x,int y);

  void DeflateRect(SIZE size);

  void DeflateRect(LPCRECT lpRect);

  void DeflateRect(int l,int t,int b);

  参数:

  x 指定要向左或向右移动CRect边的数量

  y 指定要向上或向下移动CRect边的数量

  size 指定CRect移动数量的SIZE或CSize。

  cx 指定移动左右边的数;

  cy 指定移动上下边的数;

  lpRect 指向一个指定每边数量的RECT结构或者CRect。

  说明: DeflateRect 通过设置向矩形中心移动边。

如:

CRect rect(10, 10, 50, 50);

rect.DeflateRect(1, 2);

ASSERT(rect.left == 11 && rect.right == 49);
ASSERT(rect.top == 12 && rect.bottom == 48);

CRect rect2(10, 10, 50, 50);
CRect rectDeflate(1, 2, 3, 4);

rect2.DeflateRect(&rectDeflate);
ASSERT(rect2.left == 11 && rect2.right == 47);
ASSERT(rect2.top == 12 && rect2.bottom == 46);
2-------------------------------------------------------------------------------------------------

CClientDC(客户区设备上下文)用于客户区的输出,它在构造函数中封装了GetDC(),在析构函数中封装了ReleaseDC()函数。一般在响应非窗口重画消息(如键盘输入时绘制文本、鼠标绘图)绘图时要用到它。用法是:

 

CClientDC dc(this);//this一般指向本窗口或当前活动视图

dc.TextOut(10,10,str,str.GetLength());

 

//利用dc输出文本,如果是在CScrollView中使用,还要注意调

//用OnPrepareDC(&dc)调整设备上下文的坐标。

 

CPaintDC用于响应窗口重绘消息(WM_PAINT)是的绘图输出。CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。CPaintDC也只能用在WM_PAINT消息处理之中。

 使用CPaintDC、CClientDC、CWindowDC的方法。 首先,定义一个这些类的实例变量,通常在栈中定义。然后,使用它。

例如,MFC中CView对WM_PAINT消息的实现方法如下: 

void CView::OnPaint()

{

// standard paint routine

CPaintDC dc(this);

OnPrepareDC(&dc);

OnDraw(&dc);

}

 在栈中定义了CPaintDC类型的变量dc,随着构造函数的调用获取了设备描述表;设备描述表使用完毕,超出其有效范围就被自动地清除,随着析构函数的调用,其获取的设备描述表被释放。

 如果希望在堆中创建,例如

 CPaintDC *pDC;

pDC = new CPaintDC(this)

则在使用完毕时,用delete删除pDC:

delete pDC;

  

直接使用CDC

 

需要注意的是:在生成CDC对象的时候,并不像它的派生类那样,在构造函数里获取相应的Windows设备描述表。最好不要使用::GetDC等函数来获取一个设备描述表,而是创建一个设备描述表。其构造函数如下:

 

CDC::CDC()

{

m_hDC = NULL;

m_hAttribDC = NULL;

m_bPrinting = FALSE;

}

 

其析构函数如下:

CDC::~CDC()

{

if (m_hDC != NULL)

::DeleteDC(Detach());

}

 

在CDC析构函数中,如果设备描述表句柄不空,则调用DeleteDC删除它。这是直接使用CDC时最好创建Windows设备描述表的理由。如果设备描述表不是创建的,则应该在析构函数被调用前分离出设备描述表句柄并用::RealeaseDC释放它,释放后m_hDC为空,则在析构函数调用时不会执行::DeleteDC。当然,不用担心CDC的派生类的析构函数调用CDC的析构函数,因为CDC::~CDC()不是虚拟析构函数。

 

直接使用CDC的例子是内存设备上下文,例如:

 

CDC dcMem; //声明一个CDC对象

dcMem.CreateCompatibleDC(&dc); //创建设备描述表

pbmOld = dcMem.SelectObject(&m_bmBall);//更改设备描述表属性

//作一些绘制操作

 

dcMem.SelectObject(pbmOld);//恢复设备描述表的属性

dcMem.DeleteDC(); //可以不调用,而让析构函数去删除设备描述表

它们的作用域不一样的CPaintDC作用于窗口,CClientDC作用于客户区。 

你可能感兴趣的:(windows,活动,null,delete,mfc)