一、漂亮界面实现的原理
用图象元素自绘窗口标题样栏,边框,系统按钮(最大化、最小化、关闭按钮)还有按窗口中的控件。图象元素可以是位图,也可用绘图函数实现。如果用位图实现,那需要美工的支持。如果绘图函数实现需要你超强审美观和对VC绘图函数熟练掌握!。
二、VC绘图技术介绍
CDC* pDisplayMemDC=new CDC; //建立MemDC
pDisplayMemDC->CreateCompatibleDC(pDC); //MemDC关联到窗口pDC
CBitmap* pBitmap = new CBitmap;
BITMAP BmpInfo;
CBitmap* pOldBitmap;
// **********************************************
pBitmap->LoadBitmap(IDB_TITLE_LEFT); //用位图ID装入位图
pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);
pBitmap->GetBitmap(&BmpInfo);
// x,y为绘图位置 ,必要时此语句要有For(..;..;..)控制
pDC->BitBlt(x,y, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY);
pDisplayMemDC->SelectObject(pOldBitmap);
pBitmap->DeleteObject();
//***********************************************
ReleaseDC(pDisplayMemDC);//记得执行以下的语句
delete pDisplayMemDC;
delete pBitmap;
二、实现方法及代码
①、重载对话框的消息函数:
//单击标题栏时是响应
void OnNcLButtonDown(UINT nHitTest, CPoint point);
//Mous 在标题移动时响应
void OnNcMouseMove(UINT nHitTest, CPoint point);
//窗口消息前预处理函数
LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
②、添加关键成员函数为:BOOL DrawTitleBar(CDC *pDC)
③、实现函数代码:
void CTitleBarDlg::OnNcMouseMove(UINT nHitTest, CPoint point) { CDC* pDC = GetWindowDC(); CDC* pDisplayMemDC=new CDC; pDisplayMemDC->CreateCompatibleDC(pDC); CBitmap* pBitmap = new CBitmap; CBitmap* pOldBitmap; CRect rtWnd, rtButton; if (pDC) { CString StrTemp = ""; GetWindowRect(&rtWnd); //mouse坐标转化为本窗口坐标 重要 point.x = point.x - rtWnd.left; point.y = point.y - rtWnd.top; //判断mouse是否移到系统按钮上 if (m_rtButtExit.PtInRect(point)) { pBitmap->LoadBitmap(IDB_EXIT_FOCUS); StrTemp = _T("关闭"); } else { if(m_rtButtMin.PtInRect(point)) { pBitmap->LoadBitmap(IDB_MIN_FOCUS); StrTemp = _T("最小化窗口"); } else { if(m_rtButtMax.PtInRect(point)) { pBitmap->LoadBitmap(IDB_MAX_FOCUS); if(IsZoomed()) { StrTemp = _T("还原窗口"); } else { StrTemp = _T("最化大窗口"); } } else { pBitmap->LoadBitmap(IDB_NORMAL); } } } rtButton = m_rtButtMin; BITMAP BmpInfo; pBitmap->GetBitmap(&BmpInfo); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButton.left-6, rtButton.top-2, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); CRect ShowTipRec; ShowTipRec = m_rtButtMin; if(!StrTemp.IsEmpty()) { // ScreenToClient(&ShowTipRec); // m_ToolTip.AddToolTip(IDD_TITLEBAR_DIALOG,&ShowTipRec,StrTemp); // m_ToolTip.SetDelayTime(200); } } ReleaseDC(pDisplayMemDC); ReleaseDC(pDC); delete pDisplayMemDC; delete pBitmap; CDialog::OnNcMouseMove(nHitTest, point);}
//**************************************************//此为关键函数void CTitleBarDlg::DrawTitleBar(CDC *pDC){ if (m_hWnd) { CBrush Brush(RGB(0,100,255)); CBrush* pOldBrush = pDC->SelectObject(&Brush); CRect rtWnd, rtTitle, rtButtons; GetWindowRect(&rtWnd); //取得标题栏的位置 rtTitle.left = GetSystemMetrics(SM_CXFRAME); rtTitle.top = GetSystemMetrics(SM_CYFRAME); rtTitle.right = rtWnd.right - rtWnd.left - GetSystemMetrics(SM_CXFRAME); rtTitle.bottom = rtTitle.top + GetSystemMetrics(SM_CYSIZE); //计算最小化按钮的位置,位图大小为15X15 rtButtons.left = rtTitle.right-60; rtButtons.top= rtTitle.top+2; rtButtons.right = rtTitle.right-42; rtButtons.bottom = rtTitle.top+20; m_rtButtMin = rtButtons; //计算最大化按钮的位置,位图大小为15X15 m_rtButtMax.left = m_rtButtMin.left + 18; m_rtButtMax.top = m_rtButtMin.top; m_rtButtMax.right = m_rtButtMin.right + 16; m_rtButtMax.bottom = m_rtButtMin.bottom; m_rtButtExit.left = m_rtButtMax.left + 18; m_rtButtExit.top = m_rtButtMax.top; m_rtButtExit.right = m_rtButtMax.right + 16; m_rtButtExit.bottom = m_rtButtMax.bottom; //准备 CBitmap* pBitmap = new CBitmap; BITMAP BmpInfo; CBitmap* pOldBitmap; CDC* pDisplayMemDC=new CDC; pDisplayMemDC->CreateCompatibleDC(pDC); //重画最Caption POINT DrawPonit; DrawPonit.x = rtTitle.left-4; DrawPonit.y = rtTitle.top-4; pBitmap->LoadBitmap(IDB_TITLE_LEFT); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pBitmap->GetBitmap(&BmpInfo); pDC->BitBlt(rtTitle.left-4, rtTitle.top-4, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY); DrawPonit.x = DrawPonit.x + BmpInfo.bmWidth; pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); pBitmap->LoadBitmap(IDB_TOP); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pBitmap->GetBitmap(&BmpInfo); while(DrawPonit.x<= m_rtButtMin.left-66) { pDC->BitBlt(DrawPonit.x, DrawPonit.y, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY); DrawPonit.x = DrawPonit.x + BmpInfo.bmWidth; } pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); pBitmap->LoadBitmap(IDB_TITLE_RIGHT); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pBitmap->GetBitmap(&BmpInfo); pDC->BitBlt(DrawPonit.x, DrawPonit.y, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); //重画最小化button rtButtons = m_rtButtMin; pBitmap->LoadBitmap(IDB_NORMAL); pBitmap->GetBitmap(&BmpInfo); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); pDC->BitBlt(rtButtons.left-6, rtButtons.top-2, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY); pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); int nOldMode = pDC->SetBkMode(TRANSPARENT); COLORREF clOldText=pDC->GetTextColor(); CFont titleFont; titleFont.CreateFont( 12, // nHeight 8, // nWidth 0, // nEscapement文本行逆时针旋转角度 0, // nOrientation字体角度 FW_BOLD, // nWeight字体粗细程度 FALSE, // bItalic FALSE, // bUnderline 0, // cStrikeOut 删除线 ANSI_CHARSET, // nCharSet OUT_DEFAULT_PRECIS, // nOutPrecision CLIP_DEFAULT_PRECIS, // nClipPrecision DEFAULT_QUALITY, // nQuality DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily _T("隶书"));// lpszFac pDC->SelectStockObject(SYSTEM_FIXED_FONT); CFont *OldFont; OldFont = pDC->SelectObject(&titleFont); CString m_StrTitle; GetWindowText(m_StrTitle); pDC->SetTextColor(RGB(80,255,25)); if(m_ShowTitle) { pDC->TextOut(65,10,m_StrTitle); } else { m_StrTitle = m_StrTitle.Left(6); m_StrTitle += "..."; pDC->TextOut(30,10,m_StrTitle); } pDC->SetBkMode(nOldMode); pDC->SetTextColor(clOldText); pDC->SelectObject(OldFont); //pDC->TextOut(60,60,m_StrTitle); //重画左边框 pBitmap->LoadBitmap(IDB_LEFTDOWN); pBitmap->GetBitmap(&BmpInfo); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); int i ; for (i= 20;i<=rtWnd.bottom;i=i+BmpInfo.bmHeight-3) { pDC->BitBlt(0, rtButtons.top+i, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY); } pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); //重画右边框 pBitmap->LoadBitmap(IDB_RIGHTDOWN); pBitmap->GetBitmap(&BmpInfo); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); GetClientRect(&rtWnd); for (i= 25;i<=rtWnd.bottom+27;i=i+BmpInfo.bmHeight-3) { pDC->BitBlt(rtWnd.right, i, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY); } pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); //重画底边框 pBitmap->LoadBitmap(IDB_DOWN); pBitmap->GetBitmap(&BmpInfo); pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap); GetClientRect(&rtWnd); for (i= 9; i<=rtWnd.right; i=i+2) { GetClientRect(&rtWnd); pDC->BitBlt(i,rtWnd.bottom+26, BmpInfo.bmWidth, BmpInfo.bmHeight, pDisplayMemDC, 0, 0, SRCCOPY); } pDisplayMemDC->SelectObject(pOldBitmap); pBitmap->DeleteObject(); ReleaseDC(pDisplayMemDC); delete pDisplayMemDC; delete pBitmap; }}void CTitleBarDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) { CRect rtWnd; GetWindowRect(&rtWnd); //mouse坐标转化为本窗口坐标 重要 point.x = point.x - rtWnd.left; point.y = point.y - rtWnd.top; //检测各按钮是否按到 if (m_rtIcon.PtInRect(point)) AfxMessageBox("界面软件设计者:朱一松 EMail:[email protected]"); else { if (m_rtButtHelp.PtInRect(point)) { SendMessage(WM_HELP); } else { if (m_rtButtExit.PtInRect(point)) { SendMessage(WM_CLOSE); } else { if (m_rtButtMin.PtInRect(point)) { m_ShowTitle = FALSE; SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, MAKELPARAM(point.x, point.y)); } else { if (m_rtButtMax.PtInRect(point)) { m_ShowTitle = TRUE; if (IsZoomed()) SendMessage(WM_SYSCOMMAND, SC_RESTORE, MAKELPARAM(point.x, point.y)); else { SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, MAKELPARAM(point.x, point.y)); Invalidate(); } } else { if (!IsZoomed()) { Default(); } } } } } }}//******************************************************LRESULT CTitleBarDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { LRESULT lrst=CDialog::DefWindowProc(message, wParam, lParam); if (!::IsWindow(m_hWnd)) return lrst; if (message==WM_MOVE|| message==WM_PAINT|| message==WM_NCPAINT|| message==WM_NCACTIVATE|| message == WM_NOTIFY) { CDC* pWinDC = GetWindowDC(); if (pWinDC) DrawTitleBar(pWinDC); ReleaseDC(pWinDC); } return lrst;}