客户区自绘:
在绘制背景的时候,如果窗体没有标题栏,需要重绘一个(9宫格最上面的3格当做标题栏):
void CSWDialog::DoPaint()
{
CPaintDC dc(this);
if (m_brBkgr.GetSafeHandle() == NULL && m_pBkgrBitmap == NULL)
return ;
CRect rcClient;
GetClientRect(rcClient);
if (m_pBkgrBitmap == NULL)
{
if (m_brBkgr.GetSafeHandle() != NULL)
dc.FillRect(rcClient, &m_brBkgr);
return;
}
ASSERT(m_sizeBkgrBitmap != CSize(0, 0));
sw::CMemDC dcMem(dc, this);
Gdiplus::Graphics g(dcMem);
// 左上
{
if (!m_bHasTitleBar)
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.right = m_rcImageClient.left;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
}
// 左中
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = m_rcImageClient.top;
rcClipImage.right = m_rcImageClient.left;
rcClipImage.bottom = m_rcImageClient.bottom;
CRect rcShowImage = rcClipImage;
if (m_bHasTitleBar)
rcShowImage.top = 0;
else
rcShowImage.top = m_rcImageClient.top - m_rcImageWindow.top;
rcShowImage.bottom = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 左下
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = m_rcImageClient.bottom;
rcClipImage.right = m_rcImageClient.left;
rcClipImage.bottom = m_rcImageWindow.bottom;
CRect rcShowImage = rcClipImage;
rcShowImage.top = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
rcShowImage.bottom = rcClient.bottom;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 右上
{
if (!m_bHasTitleBar)
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = 0;// m_rcImageClient.top - m_rcImageWindow.top;
rcClipImage.left = m_rcImageClient.right;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
rcShowImage.left = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.right = rcClient.right;
rcShowImage.bottom = m_rcImageClient.top;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
}
// 右中
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = m_rcImageClient.top;
rcClipImage.left = m_rcImageClient.right;
rcClipImage.bottom = m_rcImageClient.bottom;
CRect rcShowImage = rcClipImage;
if (m_bHasTitleBar)
rcShowImage.top = 0;
else
rcShowImage.top = m_rcImageClient.top - m_rcImageWindow.top;
rcShowImage.left = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.right = rcClient.right;
rcShowImage.bottom = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 右下
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.left = m_rcImageClient.right;
rcClipImage.top = m_rcImageClient.bottom;
rcClipImage.bottom = m_rcImageWindow.bottom;
CRect rcShowImage = rcClipImage;
rcShowImage.left = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.right = rcClient.right;
rcShowImage.top = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
rcShowImage.bottom = rcClient.bottom;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 中上
{
if (!m_bHasTitleBar)
{
CRect rcClipImage = m_rcImageWindow;
rcClipImage.top = 0;// m_rcImageClient.top - m_rcImageWindow.top;
rcClipImage.left = m_rcImageClient.left;
rcClipImage.right = m_rcImageClient.right;
rcClipImage.bottom = m_rcImageClient.top;
CRect rcShowImage = rcClipImage;
rcShowImage.right = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.bottom = m_rcImageClient.top;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
}
// 中中
{
CRect rcClipImage = m_rcImageClient;
CRect rcShowImage = rcClipImage;
if (m_bHasTitleBar)
rcShowImage.top = 0;
else
rcShowImage.top = m_rcImageClient.top - m_rcImageWindow.top;
rcShowImage.right = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.bottom = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
// 中下
{
CRect rcClipImage = m_rcImageClient;
rcClipImage.top = m_rcImageClient.bottom;
rcClipImage.bottom = m_rcImageWindow.bottom;
CRect rcShowImage = rcClipImage;
rcShowImage.right = rcClient.right - (m_rcImageWindow.right - m_rcImageClient.right);
rcShowImage.top = rcClient.bottom - (m_rcImageWindow.bottom - m_rcImageClient.bottom);
rcShowImage.bottom = rcClient.bottom;
if (!rcShowImage.IsRectEmpty())
g.DrawImage(m_pBkgrBitmap, RectF(rcShowImage.left, rcShowImage.top, rcShowImage.Width(), rcShowImage.Height()), rcClipImage.left, rcClipImage.top, rcClipImage.Width(), rcClipImage.Height(), UnitPixel, NULL, NULL, NULL);
}
if (!m_bHasTitleBar)
DrawSysMenu(g);
}
由于没有标题栏,所以窗体没法通过拖拽边缘来改变窗口大小,所以需要额外处理以下消息:
#define RESIZE_REGION_SIZE 5
LRESULT CSWDialog::OnNcHitTest(CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
RECT rcWindow;
::GetWindowRect(m_hWnd, &rcWindow);
// 最好将四个角的判断放在前面
if (point.x <= rcWindow.left + RESIZE_REGION_SIZE && point.y <= rcWindow.top + RESIZE_REGION_SIZE)
return HTTOPLEFT;
else if (point.x >= rcWindow.right - RESIZE_REGION_SIZE && point.y <= rcWindow.top + RESIZE_REGION_SIZE)
return HTTOPRIGHT;
else if (point.x <= rcWindow.left + RESIZE_REGION_SIZE && point.y >= rcWindow.bottom - RESIZE_REGION_SIZE)
return HTBOTTOMLEFT;
else if (point.x >= rcWindow.right - RESIZE_REGION_SIZE && point.y >= rcWindow.bottom - RESIZE_REGION_SIZE)
return HTBOTTOMRIGHT;
else if (point.x <= rcWindow.left + RESIZE_REGION_SIZE)
return HTLEFT;
else if (point.x >= rcWindow.right - RESIZE_REGION_SIZE)
return HTRIGHT;
else if (point.y <= rcWindow.top + RESIZE_REGION_SIZE)
return HTTOP;
else if (point.y >= rcWindow.bottom - RESIZE_REGION_SIZE)
return HTBOTTOM;
//return HTCAPTION;
return CDialog::OnNcHitTest(point);
}
BOOL CSWDialog::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch (nHitTest)
{
case HTTOP:
case HTBOTTOM:
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS)));
return TRUE;
case HTLEFT:
case HTRIGHT:
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
return TRUE;
case HTTOPLEFT:
case HTBOTTOMRIGHT:
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENWSE)));
return TRUE;
case HTTOPRIGHT:
case HTBOTTOMLEFT:
SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENESW)));
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
运行结果如图:
下一篇介绍如何来实现界面上6个按钮自绘,请继续关注......