21.1 Caption过渡色实现
// 方法一
void CCaptionDlg::DrawColorTitle(CRect rect, COLORREF col1, COLORREF col2,CDC* pDC)
{int cx = rect.Width();int red = GetRValue(col2) - GetRValue(col1);int green = GetGValue(col2) - GetGValue(col1);int blue = GetBValue(col2) - GetBValue(col1);int i = 0;CPen* pOldPen = pDC->GetCurrentPen();;while (i < cx){int r = GetRValue(col1) + i*red / cx;int g = GetGValue(col1) + i*green / cx;int b = GetBValue(col1) + i*blue / cx;/* int j = 0;while (j < rect.bottom){pDC->SetPixel(i, j, RGB(r, g, b));++j;}*/CPen pen(PS_SOLID, 1, RGB(r, g, b));pDC->SelectObject(&pen);pDC->MoveTo(i, 0);pDC->LineTo(i, rect.bottom);++i;}if(pOldPen)pDC->SelectObject(pOldPen);
}
void CCaptionDlg::OnNcPaint()
{CWindowDC dc(this);CRect rect,rt;GetWindowRect(rect);rect.OffsetRect(-rect.left, -rect.top);rt = rect;rt.bottom = 30;DrawColorTitle(rect, RGB(255, 0, 0), RGB(0, 255, 255),&dc);//dc.Rectangle(rt);dc.SetTextColor(RGB(128, 255, 0));dc.SetBkMode(TRANSPARENT);dc.DrawText(_T("欢迎使用本软件!"), rt, DT_CENTER|DT_VCENTER|DT_SINGLELINE);rt.right -= 5;rt.top += 5;rt.bottom -= 5;rt.left = rt.right - rt.Height();rt.OffsetRect(-5, 4);//CBrush br(RGB(255, 255, 0));//dc.SelectObject(br);//dc.Rectangle(rt);//dc.MoveTo(rt.TopLeft());//dc.LineTo(rt.BottomRight());//dc.MoveTo(rt.right, rt.top);//dc.LineTo(rt.left, rt.bottom);dc.DrawFrameControl(rt, DFC_CAPTION, DFCS_CAPTIONCLOSE);::DrawIconEx(dc.m_hDC, 7, 8, m_hIcon, 20, 20, 0, NULL, DI_NORMAL| DI_MASK); //标题栏画图标
// int cx = GetSystemMetrics(SM_CXFRAME);
}
21.2 形状填充
dc.Rectangle(110, 10, 200, 100);
dc.Ellipse(150, 50, 300, 150);
CBrush br(RGB(0, 255, 0));
dc.SelectObject(br);
dc.ExtFloodFill(115, 15, dc.GetPixel(115, 15), FLOODFILLSURFACE);
21.3 假按钮
//CRect rect(5, 5, 100, 35);//dc.DrawIcon(200, 200, m_hIcon);//dc.SelectObject(GetFont());//rect.DeflateRect(2, 2);//dc.DrawFocusRect(rect);//rect.OffsetRect(-1, -1);//dc.DrawText(_T("假按钮"), rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);//dc.DrawEdge(CRect (5, 5, 100, 35) , m_bSelected? BDR_SUNKENINNER :BDR_RAISEDINNER, BF_RECT);
//CRect rect(5, 5, 100, 35);
//dc.SelectObject(GetFont());
//
//dc.DrawFrameControl(rect, DFC_BUTTON, DFCS_BUTTONPUSH);
//dc.DrawText(_T("假按钮"), rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
21.4 GDI对象之四——位图
一、位图输出
a)加载位图:CBitmap::LoadBitmap
b)创建内存DC:CDC::CreateCompatible
c)内存DC选择位图:CDC::SelectObject
d)从内存DC输出到界面:CDC::Bitblt
CPaintDC dc(this); // 用于绘制的设备上下文int nCount;if (!m_bmp.GetSafeHandle()){m_bmp.LoadBitmap(IDB_BITMAP1);}CDC mdc;//mdc.CreateCompatibleDC(&dc);mdc.SelectObject(&m_bmp);BITMAP bm;m_bmp.GetBitmap(&bm);
dc.BitBlt(0, 0, bm.bmWidth,bm.bmHeight, &mdc, 0, 0, SRCCOPY);
二、辅助位图输出:
a)获取图像高宽等信息:CBitmap::GetBitmap
b)压缩或拉伸:CDC:StretchBlt
dc.BitBlt(0, 0, bm.bmWidth,bm.bmHeight, &mdc, 0, 0, SRCCOPY);dc.StretchBlt(bm.bmWidth + 2, 0, bm.bmWidth * 2, bm.bmHeight * 2,&mdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);dc.StretchBlt(0, bm.bmHeight+2, bm.bmWidth /2, bm.bmHeight /2,&mdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
c)设置压缩算法:SetStretchBltMode
dc.SetStretchBltMode(STRETCH_HALFTONE);
d)图像翻转
dc.StretchBlt(bm.bmWidth,0, -bm.bmWidth , bm.bmHeight ,&mdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);dc.StretchBlt(0,bm.bmHeight*2, bm.bmWidth,-bm.bmHeight,&mdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
e)WIN32位图输出
void OnPaint(HWND hwndDlg)
{PAINTSTRUCT ps;HDC hdc = BeginPaint(hwndDlg, &ps);if(!g_bmp)g_bmp = LoadBitmap(g_hInst, (LPCTSTR)IDB_BITMAP1);BITMAP bm;GetObject(g_bmp, sizeof(BITMAP), &bm);HDC mdc = ::CreateCompatibleDC(hdc);::SelectObject(mdc, g_bmp);::SetStretchBltMode(hdc, HALFTONE);::BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, mdc, 0, 0, SRCCOPY);::StretchBlt(hdc, bm.bmWidth * 2, 0, -bm.bmWidth, bm.bmHeight, mdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);EndPaint(hwndDlg, &ps);OutputDebugString(_T("WM_PAINT-OnPaint\n"));
}
f)图像数据
if (!m_bmp.GetSafeHandle())
{m_bmp.LoadBitmap(IDB_BITMAP1);nCount = m_bmp.GetBitmapBits(0, NULL);char* p = new char[nCount];m_bmp.GetBitmapBits(nCount, p);delete []p;
}
21.5 GDI对象之五——区域
一、区域输出
CPaintDC dc(this); // 用于绘制的设备上下文int nCount;if (!m_bmp.GetSafeHandle())m_bmp.LoadBitmap(IDB_BITMAP1);CDC mdc;//mdc.CreateCompatibleDC(&dc);mdc.SelectObject(&m_bmp);BITMAP bm;m_bmp.GetBitmap(&bm);dc.SetStretchBltMode(STRETCH_HALFTONE);CRgn r;r.CreateEllipticRgn(0, 0, bm.bmWidth, bm.bmHeight);
//另一种方法//CRect rect(0, 0, bm.bmWidth, bm.bmHeight);//r.CreateEllipticRgnIndirect(rect);dc.SelectObject(r);dc.StretchBlt(0,0, bm.bmWidth *2, bm.bmHeight *2,&mdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
二、手动绘制区域输出
CRgn r1,r2;
r1.CreateEllipticRgn(0, 0, bm.bmWidth*2, bm.bmHeight*2);
POINT ps[] = { {172,249} ,{5,420},{320,420} };
r2.CreatePolygonRgn(ps, _countof(ps), ALTERNATE);
CRgn r;
r.CreateRectRgn(0,0,0,0);
r.CombineRgn(&r1, &r2, RGN_XOR);
this->SetWindowRgn(r,TRUE);
//dc.SelectObject(r);
dc.StretchBlt(0,0, bm.bmWidth *2, bm.bmHeight *2,&mdc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
拖动客户区——假标题栏
LRESULT CBmDlg::OnNcHitTest(CPoint point)
{return HTCAPTION;
}