以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 C/C++编程思想 』  (http://bbs.xml.org.cn/list.asp?boardid=61)
----  如何用VC++实现用户登录界面?  (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=88556)


--  作者:葛靖青001
--  发布时间:12/7/2010 3:07:00 PM

--  如何用VC++实现用户登录界面?
【转自互联网】

VC开发程序单调的界面相信大家都是深有感触,提到界面美化编程,人们都会说做界面不要用VC写,太难了。

  一句俗语:难者不会,会者不难。VC的美化界面编程并没有人们想像的那么难。这篇文章是我写的一个用户登录界面,但界面被我美化了,我将一步一步的来讲解它的美化界面的实现步骤。相信有了这篇文章,你的VC界面从此也能绚丽多彩。

  实现步骤:

  第一步:美化界面的非客户区(重绘标题栏和界面边框)。

  关键代码如下:

  代码

  // 函 数 名:DrawTitleBar// 功能描述:绘制标题栏、边框颜色,绘制标题内容、图标和按钮// 输入参数:pDC:设备指针// 输出参数:void// 创建日期:2006-2-20// 修改日期:2006-2-20// 作 者:joinclear// 附加说明:无void CTitleBarColorDlg::DrawTitleBar(CDC *pDC){    if (m_hWnd)    {        CBrush Brush(RGB(187,200,143));        CBrush* pOldBrush = pDC->SelectObject(&Brush);        CRect rtWnd, rtTitle, rtButtons;        GetWindowRect(&rtWnd);                //取得标题栏的位置         //SM_CXFRAME 窗口边框的边缘宽度         //SM_CYFRAME 窗口边框的边缘高度         //SM_CXSIZE 窗口标题栏宽度          //SM_CYSIZE 窗口标题栏高度        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);        CPoint point;        //填充顶部框架        point.x = rtWnd.Width();                                point.y = GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYFRAME) + 0;        pDC->PatBlt(0, 0, point.x, point.y, PATCOPY);        //填充左侧框架        point.x = GetSystemMetrics(SM_CXFRAME) -1;        point.y = rtWnd.Height()- 1;        pDC->PatBlt(0, 0, point.x, point.y, PATCOPY);        //填充底部框架        point.x = rtWnd.Width();         point.y = GetSystemMetrics(SM_CYFRAME);        pDC->PatBlt(0, rtWnd.Height()-point.y, point.x, point.y, PATCOPY);        //填充右侧框架        point.x = GetSystemMetrics(SM_CXFRAME);        point.y = rtWnd.Height();        pDC->PatBlt(rtWnd.Width()-point.x, 0, point.x, point.y, PATCOPY);                        //重画标题栏图标        m_rtIcon.left = rtTitle.left ;        m_rtIcon.top = rtTitle.top;        m_rtIcon.right = m_rtIcon.left + 16;        m_rtIcon.bottom = m_rtIcon.top + 15;        ::DrawIconEx(pDC->m_hDC, m_rtIcon.left, m_rtIcon.top, AfxGetApp()->LoadIcon(IDR_MAINFRAME),             m_rtIcon.Width(), m_rtIcon.Height(), 0, NULL, DI_NORMAL);        m_rtIcon.OffsetRect(rtWnd.TopLeft());            CBitmap* pBitmap = new CBitmap;        CBitmap* pOldBitmap;        CDC* pDisplayMemDC=new CDC;        pDisplayMemDC->CreateCompatibleDC(pDC);                //重画关闭button        rtButtons.left = rtTitle.right - 16;        rtButtons.top = rtTitle.top - 1;        rtButtons.right = rtButtons.left + 16;        rtButtons.bottom = rtButtons.top + 15;        pBitmap->LoadBitmap(IDB_EXIT_FOCUS);        pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);        pDC->BitBlt(rtButtons.left, rtButtons.top, rtButtons.Width(), rtButtons.Height(), pDisplayMemDC, 0, 0, SRCCOPY);        pDisplayMemDC->SelectObject(pOldBitmap);        m_rtButtExit = rtButtons;        m_rtButtExit.OffsetRect(rtWnd.TopLeft());         pBitmap->DeleteObject();                //重画最大化/恢复button        rtButtons.right = rtButtons.left - 3;        rtButtons.left = rtButtons.right - 16;        if (IsZoomed())            pBitmap->LoadBitmap(IDB_RESTORE_NORMAL);        else            pBitmap->LoadBitmap(IDB_MAX_NORMAL);        pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);        pDC->BitBlt(rtButtons.left, rtButtons.top, rtButtons.Width(), rtButtons.Height(), pDisplayMemDC, 0, 0, SRCCOPY);        pDisplayMemDC->SelectObject(pOldBitmap);        m_rtButtMax = rtButtons;        m_rtButtMax.OffsetRect(rtWnd.TopLeft());        pBitmap->DeleteObject();                //重画最小化button        rtButtons.right = rtButtons.left - 3;        rtButtons.left = rtButtons.right - 16;        pBitmap->LoadBitmap(IDB_MIN_NORMAL);        pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);        pDC->BitBlt(rtButtons.left, rtButtons.top, rtButtons.Width(), rtButtons.Height(), pDisplayMemDC, 0, 0, SRCCOPY);        pDisplayMemDC->SelectObject(pOldBitmap);        m_rtButtMin = rtButtons;        m_rtButtMin.OffsetRect(rtWnd.TopLeft());        pBitmap->DeleteObject();        //重画caption        int nOldMode = pDC->SetBkMode(TRANSPARENT);        COLORREF clOldText=pDC->SetTextColor(RGB(255, 255, 255));                CFont m_captionFont;        m_captionFont.CreateFont(            18, // 字体的高度                        0, // 字体的宽度            0, // 字体显示的角度            0, // 字体的角度            FW_BOLD, // 字体的磅数            FALSE, // 斜体字体            FALSE, // 带下划线的字体            0, // 带删除线的字体            ANSI_CHARSET, // 所需的字符集            OUT_DEFAULT_PRECIS, // 输出的精度            CLIP_DEFAULT_PRECIS, // 裁减的精度            DEFAULT_QUALITY, // 逻辑字体与输出设备的实际字体之间的精度            DEFAULT_PITCH | FF_SWISS, // 字体间距和字体集            _T("Arial")); // 字体名称                    CFont* pOldFont = NULL;                    pOldFont = pDC->SelectObject(&m_captionFont);                rtTitle.left += m_rtIcon.Width ()+3;        rtTitle.top = rtTitle.top;        rtTitle.bottom = rtTitle.top + 30;        CString m_strTitle;        GetWindowText(m_strTitle);        pDC->DrawText(m_strTitle, &rtTitle, DT_LEFT);        pDC->SetBkMode(nOldMode);        pDC->SetTextColor(clOldText);                ReleaseDC(pDisplayMemDC);        delete pDisplayMemDC;        delete pBitmap;    }}

  还有在非客户区 绘制鼠标的消息。分别为:

  代码

  void CTitleBarColorDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) {    if (m_rtButtExit.PtInRect(point)) //关闭        SendMessage(WM_CLOSE);    else if (m_rtButtMin.PtInRect(point)) //最小化        SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, MAKELPARAM(point.x, point.y));    else if (m_rtButtMax.PtInRect(point))    {        if (IsZoomed()) //最大化        {            SendMessage(WM_SYSCOMMAND, SC_RESTORE, MAKELPARAM(point.x, point.y));            CRect rtWnd;            GetWindowRect(&rtWnd);            CRgn rgn;            rgn.CreateRoundRectRgn(0,0,rtWnd.Width(),rtWnd.Height(),5,5);            SetWindowRgn((HRGN)rgn,true);             Invalidate();        }        else        {            SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, MAKELPARAM(point.x, point.y));                        CRect rtWnd;            GetWindowRect(&rtWnd);            CRgn rgn;            rgn.CreateRoundRectRgn(0,0,rtWnd.Width(),rtWnd.Height(),5,5);            SetWindowRgn((HRGN)rgn,true);             Invalidate();        }    }    else if (!IsZoomed())        Default();}void CTitleBarColorDlg::OnNcMouseMove(UINT nHitTest, CPoint point) {    CWindowDC dc(this);    CWindowDC* pDC = &dc;    CDC* pDisplayMemDC=new CDC;    pDisplayMemDC->CreateCompatibleDC(pDC);    CBitmap* pBitmap = new CBitmap;    CBitmap* pOldBitmap;    CRect rtWnd, rtButton;        if (pDC)    {        GetWindowRect(&rtWnd);                //关闭button        if (m_rtButtExit.PtInRect(point))            pBitmap->LoadBitmap(IDB_EXIT_NORMAL);        else            pBitmap->LoadBitmap(IDB_EXIT_FOCUS);        rtButton = m_rtButtExit;        rtButton.OffsetRect(-rtWnd.left, -rtWnd.top);        pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);        pDC->BitBlt(rtButton.left, rtButton.top, rtButton.Width(), rtButton.Height(), pDisplayMemDC, 0, 0, SRCCOPY);        pDisplayMemDC->SelectObject(pOldBitmap);        pBitmap->DeleteObject();                //最大化/恢复button        if (m_rtButtMax.PtInRect(point))        {            if (IsZoomed())                pBitmap->LoadBitmap(IDB_RESTORE_FOCUS);            else                pBitmap->LoadBitmap(IDB_MAX_FOCUS);        }        else        {            if (IsZoomed())                pBitmap->LoadBitmap(IDB_RESTORE_NORMAL);            else                pBitmap->LoadBitmap(IDB_MAX_NORMAL);        }        rtButton = m_rtButtMax;        rtButton.OffsetRect(-rtWnd.left, -rtWnd.top);        pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);        pDC->BitBlt(rtButton.left, rtButton.top, rtButton.Width(), rtButton.Height(), pDisplayMemDC, 0, 0, SRCCOPY);        pDisplayMemDC->SelectObject(pOldBitmap);        pBitmap->DeleteObject();                //最小化button        if (m_rtButtMin.PtInRect(point))            pBitmap->LoadBitmap(IDB_MIN_FOCUS);        else            pBitmap->LoadBitmap(IDB_MIN_NORMAL);        rtButton = m_rtButtMin;        rtButton.OffsetRect(-rtWnd.left, -rtWnd.top);        pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);        pDC->BitBlt(rtButton.left, rtButton.top, rtButton.Width(), rtButton.Height(), pDisplayMemDC, 0, 0, SRCCOPY);        pDisplayMemDC->SelectObject(pOldBitmap);        pBitmap->DeleteObject();            }        pDisplayMemDC->DeleteDC();        delete pDisplayMemDC;    delete pBitmap;    CDialog::OnNcMouseMove(nHitTest, point);}

  大部分实现如上代码所示具体实现请参照程序附带的源代码。

  第二步:改变窗口边框为圆角。

  关键代码如下:

  代码

  int CTitleBarColorDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) {    if (CDialog::OnCreate(lpCreateStruct) == -1)        return -1;    CRect rtWnd;    GetWindowRect(&rtWnd);        CRgn rgn;    rgn.CreateRoundRectRgn(0,0,rtWnd.Width(),rtWnd.Height(),5,5);    SetWindowRgn((HRGN)rgn,true);     return 0;}

  第三步:填充背景。

  关键代码如下:

  代码

  BOOL CTitleBarColorDlg::OnEraseBkgnd(CDC* pDC) {    BOOL retValue= CDialog::OnEraseBkgnd(pDC);    CRect rc;    GetClientRect(&rc);    pDC->FillSolidRect(&rc,RGB(236,233,216));        return retValue;}

  第四步:绘制按钮。

  具体请参考源代码中类CXPButton.h、CXPButton.cpp

  第五步:绘制编辑框。

  具体请参考源代码中类COwnerEdit.h、COwnerEdit.cpp

  第六步:绘制静态字体和颜色。

  这一步本来也写了一个类的,但想想用OnCtlColor()还是能很好的实现的,就没写。具体实现请看OnCtlColor()中的实现。

  以上代码具体实现的细节问题,你可以下载例子代码,仔细查看其源码实现(内有详细注释)。


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
9,085.938ms