首先要知道对于一个窗体,什么是客户区,什么是非客户区。例如下面一个窗体:
客户区是指:红色框框所围住的白色区域。
非客户区是指:包括蓝色标题栏、蓝色边框、白色区域在内的整个窗体。
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); }