MFC标题栏及边框的自绘

阅读: 评论:0

SDI 和 MDI 程序中对非客户区(标题栏、左右下边界)的美化
   
    基本思路是重载 CMainFrame 类的 DefWindowProc()函数,并判断消息为:
WM_NCPAINT,WM_NCACTIVATE,WM_NOTIFY的时候,调用自己的绘制窗口标题栏的函
音箱布数。用 GetSystemMetrics(SM_CSFRAME)和 GetSystemMetrics(SM_CYFRAME)可以取得标
题栏的左上角的坐标。最大化,最小化的按钮自己画,如果不是在标准的位置,一定要记录
下他们的位置,并且在 WM_NCLBUTTONDOWN消息处理函数中判断是否是点击了按钮,
以做出相应的处理。系统图标也可以自己重新画。
    主要任务有贴图(包括标题栏、左边界、右边界、下边界、系统图标、最大化、最小化、
关闭按钮)、处理消息(屏蔽系统自带按钮、双击状态栏改变大小、鼠标停放在三个自绘按
微型轴钮上时改变按钮图标、单击自绘按钮时作出相应反应)。
一、响应的消息及重载的函数
    响应的消息及重载的函数都在 CMainFrame 类中。响应 DefWindowProc 函数,在其中
判断消息是不是 WM_NCPAINT、WM_MOVE、WM_NCACTIVATE、WM_NOTIFY,若是则厌氧胶能用于木材吗
重画标题栏、左框架、右框架、下框架、最大化、最小化、关闭按钮(放在一个函数里)。
    响应消息 WM_NCHITTEST,使鼠标位于自绘按钮时返回相应 hittest 值,同时屏蔽自带
按钮的鼠标事件。简言之,当鼠标位于自绘按钮时,让      系统误以为鼠标位于相应按钮,
而当鼠标位于系统自带按钮时,让系统误以为鼠标只是位于标题栏。自绘图标与之类似,不
再赘述。
    响应消息 WM_NCMOUSEMOVE,判断光标是不是位于自绘最大化、最小化、关闭按钮
区域,如是则重画相应的按钮。
  响应消息 WM_NCLBUTTONDOWN,判断单击左键时鼠标是否位于自绘制的最大化、
最小化、关闭按钮或图标区域,如是则执行相应的按钮操作。
    响应消息 WM_NCLBUTTONDBCLK,使双击标题栏时窗口能最大化或还原。
二、主要函数
    LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM
lParam),在此函数内判断 WM_NCPAINT、WM_MOVE、WM_NCACTIVATE、WM_NOTIFY
消息,自绘框架。
自定义函数  void DrawFrame(CDC *pDC),用于绘制标题栏、左框架、右框架、下框架、
最大化、最小化、关闭按钮。
三、位图资源
      标题栏位图  IDB_TITLEBAR
      左右框架位图 IDB_LEFTANDRIGHT 
      下框架位图  IDB_BOTTOM
      最小化按钮  IDB_MIN_NORMAL
                  IDB_MIN_FOCUS
再生油
      最大化/恢复按钮 IDB_MAX_NORMAL
干衣柜
                    IDB_MAX_FOCUS
                    IDB_RESTORE_NORMAL
                    IDB_RESTORE_FOCUS
      关闭按钮    IDB_EXIT_NORMAL
                  IDB_EXIT_FOCUS
四、主要变量
      CRect m_rtButtExit; //关闭按钮位置
      CRect m_rtButtMax;  //最大化按钮位置
      CRect m_rtButtMin;  //最小化按钮位置
      CRect m_rtIcon;    //图标位置
五、具体实现细节
    1、填充各框架:设置 CRect 变量 rtWnd, rtTitle, rtButtons,rtFrames分别保存窗口位置、
标题栏位置、关闭最大最小化按钮位置及左右下框架位置坐标。用函数木盒制作
GetWindowRect(&rtWnd)获得窗口位置;用函数 GetSystemMetrics(SM_CXFRAME)获得
框架水平边缘厚度,GetSystemMetrics(SM_CYFRAME)获得框架竖直边缘的厚度,
GetSystemMetrics ( SM_CXSIZE )获得标题栏上按钮的水平宽度,                 
GetSystemMetrics(SM_CYSIZE)获得标题栏上按钮的竖直高度。用 CWnd 类的 IsZoomed()
函数判断是否为最大化还是恢复状态。双缓冲贴图用 CDC* pDisplayMemDC=new
CDC;pDisplayMemDC->CreateCompatibleDC(pDC);BitBlt()函数。
    2、处理鼠标位于自绘按钮和自带按钮以及图标上的HitTest:在1中给m_rtButtExit;CRect
m_rtButtMax;CRect m_rtButtMin 和 m_rtIcon 赋值,记录相应按钮位置,在 OnNcHitTest()
函数中用m_rtButtExit.PtInRect(point)判断鼠标是否位于自绘按钮区域,是则返回相应HitTest
值,同时判断鼠标是否位于系统自带的按钮上,是则当做鼠标位于标题栏,返回
HTCAPTION,屏蔽鼠标消息。
    3、处理非客户区鼠标移动消息:在 OnNcMouseMove()函数中判断 nHitTest 值,得
到鼠标位于哪个按钮上,进行重绘鼠标指向时的自绘按钮。
    4、  处理非客户区鼠标左击消息:在 OnNcLButtonDown()函数中判断 nHitTest 值,
得到鼠标位于哪个按钮上时按下,用 SendMessage(WM_CLOSE);
SendMessage(WM_SYSCOMMAND, SC_RESTORE, MAKELPARAM(point.x, point.y));等发
送相应消息。
    5、处理非客户区双击消息:在 OnNcLButtonDblClk()函数中判断 nHitTest 值为
HTCAPTION 时,用 IsZoomed ()函数判断窗口是否为最大化,如果是则
SendMessage(WM_SYSCOMMAND, SC_RESTORE, MAKELPARAM(point.x, point.y));否则
SendMessage(WM_SYSCOMMAND,SC_MAXIMIZE,MAKELPARAM(point.x, point.y));
六、说明
    1、如何去掉默认的主菜单:在 App 类中注释掉 BEGIN_MESSAGE_MAP 映射中的三
行,注释掉 class CAboutDlg : public CDialog 后面所有内容。同时在 CMainFrm 中的
precreatewindow()中加上 cs.hMenu=NULL;语句即可。注意一定不要完全删除资源中原有
的菜单。
    2、修改标题:法一:在 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
函数里修改 cs.lpszName 值;法二:在 App 类的初始化函数里在显示并更新窗口前加上
AfxGetMainWnd()->SetWindowText(_T(“”));相应地如果设置其他标题用
//Set title for View’s MDI child frame window .
GetParentFrame ( ) —> SetWindowText ("_T ("MDI Child Frame new title"))
//Set title for dialog’s push button control.
GetDlgitem (IDC_BUTTON) —> SetWindowText (_T ("Button new title ") )
3、居中显示窗口:
法一:在 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) 函数里
cs.x=GetSystemMetrics(SM_CXSCREEN)//2;cs.y=GetSystemMetrics(SM_CYSCREEN)/
/2;
法二:(此法不好,会导致程序启动时闪动)在 App 类初始化函数中执行
AfxGetMainWnd()->CenterWindow();类似 CenterWindow()的实现代码可如下 
//****居中显示   
RECT  rcDlg;   
int  cxDlg,cyDlg;   
::GetWindowRect(hWnd,&rcDlg);   
cxDlg=rcDlg.right-rcDlg.left;   
::cyDlg=p;   
SetWindowPos(hWnd,HWND_TOP,GetSystemMetrics(SM_CXSCREEN)/2-cxDlg/2,GetSystem
Metrics(SM_CYSCREEN)/2-cyDlg/2,0,0,SWP_NOSIZE);
    4、程序运行顺序:从 App 类的App::InitInstance()函数开始运行到其中的
  “//  调度在命令行中指定的命令。如果
//  用 /RegServer、/Register、/Unregserver  或 /Unregister  启动应用程序,则返回 FALSE。
if (!ProcessShellCommand(cmdInfo))

本文发布于:2023-06-22 22:53:00,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/3/149008.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:按钮   鼠标   位于   框架
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图