首先要知道对于一个窗体,什么是客户区,什么是非客户区。例如下面一个窗体:
客户区是指:红色框框所围住的白色区域。
非客户区是指:包括蓝色标题栏、蓝色边框、白色区域在内的整个窗体。
1、客户区绘图:WM_PAINT是客户区显示更新消息,所有客户区绘图都要在此消息回调时绘制,也就是OnPaint()函数中进行绘制,以BeginPaint()开始,以EndPaint()结束。
void CClientDrawDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
PAINTSTRUCT ps;
//获取与客户区关联的绘图句柄
HDC hdc = ::BeginPaint(m_hWnd,&ps);
Rectangle(hdc,0,0,40,40);
Rectangle(hdc,80,80,120,120);
MoveToEx(hdc,20,20,NULL);
LineTo(hdc,100,100);
//结束客户区绘图,和::BeginPaint成对使用
::EndPaint(m_hWnd,&ps);
CDialogEx::OnPaint();
}
}
void CClientDrawDlg::OnNcPaint()
{
// TODO: 在此处添加消息处理程序代码
HDC hdc = ::GetWindowDC(m_hWnd);
RECT rect;
::GetWindowRect(m_hWnd,&rect);
::Rectangle(hdc,80,80,rect.right-rect.left-100,rect.bottom-rect.top-100);
char szstr[200];
sprintf(szstr,"非客户区空间(%d,%d,%d,%d)",rect.left,rect.top,rect.right,rect.bottom);
SetTextColor(hdc,RGB(255,0,0));
TextOut(hdc,0,0,szstr,strlen(szstr));
::ReleaseDC(m_hWnd,hdc);
//CDialogEx::OnNcPaint();
}
3、临时客户区绘图:可以在任何消息响应时绘制,但客户区刷新时,临时客户区绘图被清除。使用GetDC()获取临时客户区句柄,使用ReleaseDC()释放句柄。下面在鼠标左键单击消息中进行临时客户区绘图:
void CClientDrawDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
HDC hdc = ::GetDC(m_hWnd);
Ellipse(hdc,point.x-10,point.y-10,point.x+10,point.y+10);
::ReleaseDC(m_hWnd,hdc);
CDialogEx::OnLButtonDown(nFlags, point);
}