使用绘图句柄HDC在客户区、非客户区、临时客户区绘图

首先要知道对于一个窗体,什么是客户区,什么是非客户区。例如下面一个窗体:


客户区是指:红色框框所围住的白色区域。

非客户区是指:包括蓝色标题栏、蓝色边框、白色区域在内的整个窗体。


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();
	}
}


2、非客户区绘图: WM_NCPAINT是非客户区显示更新消息,所有非客户区绘图都要在此消息回调时绘制,也就是 OnNcPaint()函数中进行绘制,使用GetWindowDC()获取非客户区的句柄。

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);
}



猜你喜欢

转载自blog.csdn.net/u012372584/article/details/77876831