CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  界面

怎样重画标题栏?

楼主snaill(com.chinaos.snaill)2003-08-01 18:37:57 在 VC/MFC / 界面 提问

如题  
  但关键是,  
  如何取道标题栏图标的rect,标题的rect?  
  如何得到关闭,极大化,极小化按钮的Rect及窗体句柄? 问题点数:100、回复次数:9Top

1 楼SoLike(思危)回复于 2003-08-01 18:51:28 得分 15

用不着得到,自己全画就可以了   WM_NCPAINTTop

2 楼hwndhwnd(何宗键)回复于 2003-08-01 18:59:34 得分 5

同意楼上Top

3 楼snaill(com.chinaos.snaill)回复于 2003-08-01 19:19:30 得分 0

我在WM_NCPAINT做了操作,在关闭按钮附近点击时,仍能看到关闭按钮被显示出来,不知是哪里的代码重画的  
   
  另外我想让我重画的关闭,极大化,极小化按钮能够使用缺省的window事件,不知如何实现?Top

4 楼snaill(com.chinaos.snaill)回复于 2003-08-01 19:52:22 得分 0

看来大家都去吃饭了Top

5 楼snaill(com.chinaos.snaill)回复于 2003-08-01 21:30:13 得分 0

还没有人吗?Top

6 楼hyamw(林锋)回复于 2003-08-02 09:34:44 得分 30

重载CMainFrame类的DefWindowProc()函数,并判断消息为:WM_NCPAINT,WM_NCACTIVATE,WM_NOTIFY的时候,调用自己的绘制窗口标题栏的函数.  
  用GetSystemMetrics(SM_CSFRAME);和GetSystemMetrics(SM_CYFRAME);可以取得标题栏的左上角的坐标。最大化,最小化的按钮自己画就可以了,如果不是在标准的位置,一定要记录下他们的位置,并且在WM_NCLBUTTONDOWN消息处理函数中判断是否是点击了按钮,以做出相应的处理。系统图标也可以自己重新画。  
  如果要是对话框的话,还有一个方法,就是不要标题栏,然后在顶部放置一个Static控件和几个Button控件,然后重绘这几个控件做成标题栏的样子。当然这要看你的绘图技术好不好了(这方法我还没用过,只是见别人用过)Top

7 楼zhouyong0371(小周周)回复于 2003-08-02 09:47:12 得分 50

本例以对话框应用程序为基础,自画非客户区,完成应用程序美化,代码运行效果图如下:  
   
   
     
   
  下面我们来探讨具体的实现过程  
   
    一、定义资源:  
    添加系统按钮的位图资源(本例中使用十个位图,分别显示帮助、最小化、最大化、恢复及关闭按钮的普通状态和焦点状态,当然可随程序的要求自定义添加)  
      
    二、定义全局变量及函数:  
   
       CRect   m_rtButtExit; //关闭按钮位置  
     CRect   m_rtButtMax; //最大化按钮位置  
     CRect   m_rtButtMin; //最小化按钮位置  
     CRect   m_rtButtHelp; //帮助按钮位置  
     CRect   m_rtIcon; //图标位置  
     void   DrawTitleBar(CDC   *pDC); //画非客户区主函数  
    三、函数实现:  
    本例需要对以下消息进行重载DefWindowProc、ON_WM_NCMOUSEMOVE、ON_WM_NCLBUTTONDOWN。  
    函数实现体如下:    
  //主函数,可根据实际情况进行自绘窗体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);  
            ……………………………..  
            //因代码过长,未贴,见源程序  
            ……………………………...  
            }  
            }  
     
  //将消息进行过滤,对可能影响界面初始及更新的消息,产生重画消息执行DrawTitleBar函数   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;  
            }  
   
  //实现标题栏按钮的鼠标移动效果   void   CTitleBarDlg::OnNcMouseMove(UINT   nHitTest,   CPoint   point)    
            {  
            CDC*   pDC   =   GetWindowDC();  
            if   (pDC)  
            {  
            ……………………………..  
            //因代码过长,未贴,见源程序  
            ……………………………...  
            }  
            ReleaseDC(pDC);  
            CDialog::OnNcMouseMove(nHitTest,   point);  
            }  
   
  //实现非客户区,用户鼠标点击操作   void   CTitleBarDlg::OnNcLButtonDown(UINT   nHitTest,   CPoint   point)    
            {  
            //检测各按钮是否按到  
            if   (m_rtIcon.PtInRect(point))  
            AfxMessageBox("欢迎访问FlySnowStdio主页");  
            else   if   (m_rtButtHelp.PtInRect(point))  
            SendMessage(WM_HELP);  
            else   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));  
            else  
            {  
            SendMessage(WM_SYSCOMMAND,   SC_MAXIMIZE,   MAKELPARAM(point.x,   point.y));  
            Invalidate();  
            }  
            }  
            else   if   (!IsZoomed())  
            Default();  
            }  
   
    四、总结  
  本例为对话框应用程序,单文档的基本原理也相似。对于包含菜单项的程序,可以采用自画菜单,将整个程序的界面融为一体,在此不做过多介绍,本人已经完成,请与我联系。如果你想使你的程序更漂亮,也可以尽情放至贴图到背景上,愿你的程序多姿多彩。本文是在百忙中匆匆完成,错误之处希望大家批评指正!    
  Top

8 楼zhouyong0371(小周周)回复于 2003-08-02 09:48:27 得分 0

void   CNetSendDlg::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);  
   
  CPoint   point;  
  //填充顶部框架  
  point.x   =   rtWnd.Width();  
  point.y   =   GetSystemMetrics(SM_CYSIZE)   +   GetSystemMetrics(SM_CYFRAME)+20;  
  pDC->PatBlt(0,   0,   point.x,   point.y,   PATCOPY);  
  //填充左侧框架  
  point.x   =   GetSystemMetrics(SM_CXFRAME)   +   1;  
  point.y   =   rtWnd.Height();  
  pDC->PatBlt(0,   0,   point.x,   point.y,   PATCOPY);  
  //填充底部框架  
  point.x   =   rtWnd.Width();    
  point.y   =   GetSystemMetrics(SM_CYFRAME)   +   1;  
  pDC->PatBlt(0,   rtWnd.Height()-point.y,   point.x,   point.y,   PATCOPY);  
  //填充右侧框架  
  point.x   =   GetSystemMetrics(SM_CXFRAME)   +   1;  
  point.y   =   rtWnd.Height();  
  pDC->PatBlt(rtWnd.Width()-point.x,   0,   point.x,   point.y,   PATCOPY);  
   
  //绘制美化线条  
  CBrush   BrushLine(RGB(255,   255,   255));  
  pDC->SelectObject(&BrushLine);  
  point.x   =   rtWnd.Width()   -   150;  
  point.y   =   GetSystemMetrics(SM_CYFRAME)   +   2;  
  pDC->PatBlt(GetSystemMetrics(SM_CXFRAME),   point.y,   point.x,   1,   PATCOPY);  
  point.y   +=   5;  
  pDC->PatBlt(GetSystemMetrics(SM_CXFRAME),   point.y,   point.x,   1,   PATCOPY);  
  point.y   +=   5;  
  pDC->PatBlt(GetSystemMetrics(SM_CXFRAME),   point.y,   point.x,   1,   PATCOPY);  
  point.x   +=   60;  
  point.y   +=   12;  
  pDC->PatBlt(point.x,   point.y,   85,   1,   PATCOPY);  
  point.y   +=   5;  
  pDC->PatBlt(point.x,   point.y,   85,   1,   PATCOPY);  
  point.x   -=   60   -   GetSystemMetrics(SM_CXFRAME);  
  point.y   +=   5;  
  pDC->PatBlt(point.x,   point.y,   145-GetSystemMetrics(SM_CXFRAME)   ,   1,   PATCOPY);  
  point.y   -=   32;  
  pDC->PatBlt(point.x,   point.y,   1   ,   32,   PATCOPY);  
   
  pDC->SelectObject(pOldBrush);  
   
  //重画图标  
  m_rtIcon.left   =   rtWnd.Width()   -   135;  
  m_rtIcon.top   =   GetSystemMetrics(SM_CYFRAME);  
  m_rtIcon.right   =   m_rtIcon.left   +   32;  
  m_rtIcon.bottom   =   m_rtIcon.top   +   32;  
  ::DrawIconEx(pDC->m_hDC,   m_rtIcon.left,   m_rtIcon.top,   m_hIcon,    
  m_rtIcon.Width(),   m_rtIcon.Height(),   0,   NULL,   DI_NORMAL);  
  m_rtIcon.OffsetRect(rtWnd.TopLeft());    
   
   
  //准备画XP风格按钮  
  CBitmap*   pBitmap   =   new   CBitmap;  
  CBitmap*   pOldBitmap;  
  CDC*   pDisplayMemDC=new   CDC;  
  pDisplayMemDC->CreateCompatibleDC(pDC);  
   
  //重画关闭button  
  rtButtons.left   =   rtTitle.right   -   19;  
  rtButtons.top   =   rtTitle.top;  
  rtButtons.right   =   rtButtons.left   +   19;  
  rtButtons.bottom   =   rtButtons.top   +   19;  
  pBitmap->LoadBitmap(IDB_EXIT_NORMAL);  
  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   -   19;  
  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   -   19;  
  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();  
   
  //重画帮助button  
  rtButtons.right   =   rtButtons.left   -   3;  
  rtButtons.left   =   rtButtons.right   -   19;  
  pBitmap->LoadBitmap(IDB_HELP_NORMAL);  
  pOldBitmap=(CBitmap*)pDisplayMemDC->SelectObject(pBitmap);  
  pDC->BitBlt(rtButtons.left,   rtButtons.top,   rtButtons.Width(),   rtButtons.Height(),   pDisplayMemDC,   0,   0,   SRCCOPY);  
  pDisplayMemDC->SelectObject(pOldBitmap);  
  m_rtButtHelp   =   rtButtons;  
  m_rtButtHelp.OffsetRect(rtWnd.TopLeft());  
  pBitmap->DeleteObject();  
   
  //重画caption  
  int   nOldMode   =   pDC->SetBkMode(TRANSPARENT);  
  COLORREF   clOldText=pDC->SetTextColor(RGB(255,   255,   255));  
  pDC->SelectStockObject(SYSTEM_FIXED_FONT);  
  rtTitle.left   +=   2;  
  rtTitle.top   +=   GetSystemMetrics(SM_CYSIZE);  
  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;  
  }  
  }Top

9 楼zhouyong0371(小周周)回复于 2003-08-02 09:49:43 得分 0

vckbase第13期上有例子  
  到www.vckbase.com去下载吧  
  Top

相关问题

  • 怎么重画标题栏?
  • 怎样改变标题栏?
  • 在C++Builder中如何实现重画标题栏?
  • 100分求一段关于标题栏重画的源码
  • 谁给我一段关于标题栏重画的源码?!(20分)
  • 怎样在标题栏上作画?
  • 怎样改IE标题栏的内容?
  • 怎样在标题栏上画线?
  • 怎样将form的标题栏去掉?
  • 怎样移动无标题栏窗口?

关键词

  • 函数
  • 消息
  • 框架
  • rtwnd
  • 标题栏
  • drawtitlebar
  • pwindc
  • 重画
  • 按钮
  • rttitle

得分解答快速导航

  • 帖主:snaill
  • SoLike
  • hwndhwnd
  • hyamw
  • zhouyong0371

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo