状态栏

1、相关类

  CStatusBar  -父类CControlBar,封装了关于状态栏的操作,也包括状态栏的创建

2、状态栏的使用

  2.1创建状态栏 CStatusBar::CreateEx / CStatusBar::Create

    BOOL CreateEx(

      CWnd* pParentWnd,  //指定状态栏的父窗口指针,通常都是指向程序的框架类窗口对象

      DWORD dwCtrlStyle = 0 ,  //设置内嵌在状态栏上的CStatusBarCtrl对象创建时的扩展风格

      DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM,  //状态栏的风格

      UINT nID = AFX_IDW_STATUS_BAR   //指定状态栏这个子窗口的ID,默认为AFX_IDW_STATUS_BAR

    );

    BOOL Create(

      CWnd* pParentWnd,  //指定状态栏的父窗口指针,通常都是指向程序的框架类窗口对象

      DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_BOTTOM,  //状态栏的风格

      UINT nID = AFX_IDW_STATUS_BAR  //指定状态栏这个子窗口的ID,默认为AFX_IDW_STATUS_BAR

    );

    在程序的CMainFrame类的OnCreate函数中可见MFC自动创建状态栏的方法:      

if (!m_wndStatusBar.Create(this) || !m_wndStatusBar.SetIndicators(
	indicators,sizeof(indicators)/sizeof(UINT)))
{
    TRACE0("Failed to create status bar\n");
    return -1;      // fail to create
}

      SetIndicators函数的第一个参数indicators为一个静态数组,其定义在CMainFrame类的源文件中:

        static UINT indicators[] =

        {

          ID_SEPARATOR,       //提示行

           ID_INDICATOR_CAPS,  //Caps Lock键的状态指示器

          ID_INDICATOR_NUM,   //Num Lock键的状态指示器

          ID_INDICATOR_SCRL,  //Scroll Lock键的状态指示器

        };

        该数组中的后3个ID都是MFC预先定义好的字符串资源ID,在工程的资源窗口中的String Table的字串表中可见:

          

      若要修改状态栏的外观,如添加或减少状态栏上的窗格,只需要在indicators数组中添加或减少相应的字符串资源ID即可;

  2.2设置状态栏指示器(窗格)

    CStatusBar::SetIndicators

  2.3设置指示器(窗格)的宽度和风格

    CStatusBar::SetPaneInfo

    void SetPaneInfo(

      int nIndex,  //指定要设置其样式的窗格的位置索引

      UINT nID,    //为指定窗格重新设置的新ID

      UINT nStyle, //窗格的样式:SBPS_NORMAL/SBPS_STRETCH/SBPS_DISABLED/SBPS_POPOUT/SBPS_NOBORDERS

      int cxWidth  //指定窗格的宽度

    );

  2.4设置指示器(窗格)的文本内容

    CStatusBar::SetPaneText

    BOOL SetPaneText(

      int nIndex,  //当前窗格在指示器数组(indicators)中的位置索引

      LPCTSTR lpszNewText,  //要在当前窗格中显示的文本

      BOOL bUpdate = TRUE

    );

    若不知道当前窗格在指示器数组(indicators)中的位置索引,可利用CStatusBar::CommandToIndex

    int CommandToIndex( UINT nIDFind );  //根据指定的资源ID获得相应的位置索引

本例将在状态栏上显示当前系统的时间和一个进度条控件:

  1、显示系统时间

  在程序资源窗口中的字串表中增加两个新的字符串资源:

  

  将这两个新的字符串资源ID添加到CMainFrame类的源文件中的indicators数组中:  

static UINT indicators[] =
{
    ID_SEPARATOR,           

    IDS_TIMER,
    IDS_PROGRESS,

    ID_INDICATOR_CAPS,
    ID_INDICATOR_NUM,
    ID_INDICATOR_SCRL,
};

  利用CTime类的静态成员函数GetCurrentTime获取系统当前的时间对象;再调用CTime类的另一个成员函数Format对得到的时间对象进行格式化,得到一个包含格式化时间的字符串;调用SetPaneInfo函数修改窗格的显示宽度以装下将要显示的字符串文本;调用SetPaneText函数将该字符串显示到状态栏的窗格中;  

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    ......

    CTime t=CTime::GetCurrentTime();
    CString str=t.Format("%Y-%m-%d %H:%M:%S");
    CClientDC dc(this);
    CSize sz=dc.GetTextExtent(str);
    m_wndStatusBar.SetPaneInfo(1,IDS_TIMER,SBPS_NORMAL,sz.cx);
    m_wndStatusBar.SetPaneText(1,str);
    
    return 0;
}

  此时在状态栏窗格中显示的时间是静止的,利用定时器每隔一秒就发送WM_TIMER消息,在消息响应函数OnTimer中重新获取一次系统当前时间并显示到状态栏窗格中,已达到显示动态时间的效果;

  在CMainFrame类的OnCreate函数中埋下定时器: 

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    ......
    
    SetTimer(1,1000,NULL);
    
    return 0;
}

  为CMainFrame类添加WM_TIMER消息,生成消息响应函数OnTimer,在该函数中重新执行一次系统时间的获取并显示到状态栏窗格中: 

void CMainFrame::OnTimer(UINT nIDEvent) 
{
    // TODO: Add your message handler code here and/or call default

    CTime t=CTime::GetCurrentTime();
    CString str=t.Format("%Y-%m-%d %H:%M:%S");
    CClientDC dc(this);
    CSize sz=dc.GetTextExtent(str);
    m_wndStatusBar.SetPaneInfo(1,IDS_TIMER,SBPS_NORMAL,sz.cx);
    m_wndStatusBar.SetPaneText(1,str);
    
    CFrameWnd::OnTimer(nIDEvent);
}

  2、进度条控件

  要在程序中使用进度栏,首先需要构造一个CProgressCtrl对象,然后调用CProgressCtrl类的Create函数创建进度栏控件;

    BOOL Create(

      DWORD dwStyle,  //进度栏控件的类型,窗口所有的类型+PBS_VERTICAL(进度栏垂直)/PBS_SMOOTH(进度栏连续)

      const RECT& rect,  //进度栏控件的大小、位置

      CWnd* pParentWnd,  //进度栏的父窗口

      UINT nID   //指定进度栏控件的ID

    );

  在程序的CMainFrame类中添加成员变量:CProgressCtrl m_progress

    

  要在状态栏的窗格中显示进度栏,首先利用GetItemRect函数获得该窗格的区域大小:

    void GetItemRect(int nIndex, LPRECT lpRect ) const;

    nIndex:指定窗格的位置索引

    lpRect:窗格的矩形区域

  

  当程序窗口第一次显示时就会发送WM_PAINT消息,而且当程序的窗口尺寸发生变化需要重绘时也会发送WM_PAINT消息,故可在WM_PAINT消息的响应函数中判断,若程序还未创建进度栏则创建它,若已创建则将进度栏移动至目标窗格的矩形区域中;

  为CMainFrame类添加WM_PAINT消息的响应函数:

    

void CMainFrame::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    
    // TODO: Add your message handler code here
    CRect rect;
    m_wndStatusBar.GetItemRect(2,&rect);  //获得状态栏中窗格的矩形区域
    if(!m_progress.m_hWnd){   //判断当m_progress对象的句柄为NULL时,说明该对象还未创建,则创建进度栏
        m_progress.Create(WS_CHILD|WS_VISIBLE,rect,&m_wndStatusBar,123);  //创建进度栏
    }else{
        m_progress.MoveWindow(rect);  //将进度栏移至目标矩形中
    }
    
    m_progress.SetPos(50);  //设置进度栏的当前进度
    
    // Do not call CFrameWnd::OnPaint() for painting messages
}

  若要实现进度栏进度的动态增加,需要利用定时器,在WM_TIMER消息的响应函数OnTimer函数中实现:  

void CMainFrame::OnTimer(UINT nIDEvent) 
{
    ......

    m_progress.StepIt();
    
    CFrameWnd::OnTimer(nIDEvent);
}

    CProgressCtrl::StepIt:使进度栏控件的进度按照一定的步长增加

    CProgressCtrl::SetStep:设置进度栏每次增加的步长

    CProgressCtrl::SetRange:设置进度栏的范围,默认为0~100

  3、在状态栏上显示鼠标当前的位置

    当在程序的客户区窗口移动鼠标时,将鼠标当前的坐标位置显示在状态栏的提示行上;

    首先需要在程序的CStyleView类中添加WM_MOUSEMOVE消息的响应函数:

      

    因为GetParent函数返回的为CWnd类型的指针,需要强制转换为CMainFrame类型的指针,故须在视图类的源文件中包含框架类的头文件:

      #include "MainFrm.h"

    在WM_MOUSEMOVE消息的响应函数中,实现状态栏对象的获取及在其窗格中的文本显示:      

void CStyleView::OnMouseMove(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    CString str;
    str.Format("x=%d,y=%d",point.x,point.y);  //格式化鼠标坐标位置的信息
    //通过调用GetParent函数获取视图类的父窗口即框架类窗口,将返回值强制转换后,调用框架窗口对象中的状态栏成员变量
    ((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);
    
    CView::OnMouseMove(nFlags, point);
}

    将鼠标当前位置信息显示到状态栏对象的提示行中的方法:

      方法一:SetWindowText

        框架类CMainFrame类的状态栏成员变量m_wndStatusBar默认在CMainFrame类的头文件中被定义为protected类型,须手动将其修改为public类型才能被调用;

      方法二:CFrameWnd类的成员函数:SetMessageText

        该函数的作用即为在ID为0的状态栏窗格(即提示行)设置一个字符串;因程序框架类CMainFrame类派生于CFrameWnd类,故这里可以直接用框架类对象调用该成员函数来设置状态栏文本;        

void CStyleView::OnMouseMove(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    CString str;
    str.Format("x=%d,y=%d",point.x,point.y);
    //((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);
    ((CMainFrame*)GetParent())->SetMessageText(str);
    
    CView::OnMouseMove(nFlags, point);
}

      方法三:CFrameWnd类的成员函数:GetMessageBar

        该函数返回状态栏对象的指针,故无须像方法一那样修改并调用CMainFrame类的保护成员变量m_wndStatusBar了,可直接调用SetWindowText函数设置状态栏的第一个窗格(提示行)的文本;       

void CStyleView::OnMouseMove(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    CString str;
    str.Format("x=%d,y=%d",point.x,point.y);
    //((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);
    //((CMainFrame*)GetParent())->SetMessageText(str);
    ((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);
    
    CView::OnMouseMove(nFlags, point);
}

      方法四:CWnd类的成员函数:GetDescendantWindow

        该函数可通过指定的ID来获得当前窗口的所有子孙窗口,因状态栏属于框架类窗口,故先要得到框架类窗口的指针,然后根据状态栏的窗口ID调用该函数获得状态栏对象的指针       

void CStyleView::OnMouseMove(UINT nFlags, CPoint point) 
{
    // TODO: Add your message handler code here and/or call default
    CString str;
    str.Format("x=%d,y=%d",point.x,point.y);
    //((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);
    //((CMainFrame*)GetParent())->SetMessageText(str);
    //((CMainFrame*)GetParent())->GetMessageBar()->SetWindowText(str);
    GetParent()->GetDescendantWindow(AFX_IDW_STATUS_BAR)->SetWindowText(str);
    
    CView::OnMouseMove(nFlags, point);
}
时间: 2024-10-15 17:04:13

状态栏的相关文章

android手机安全卫士、Kotlin漫画、支付宝动画、沉浸状态栏等源码

Android精选源码 轻量级底部导航栏 android手机卫士源码 android实现高仿今日头条源码 一个用Kotlin写的简单漫画App源码 android吐槽项目完整源码 实现可以滑动文字逐渐变色的TabLayout android实现将app隐藏加密功能的源码 android实现横向滚动的卡片堆叠布局 android仿支付宝的咻咻动画源码 android状态栏和沉浸式导航栏管理源码 Android优质博客 从BaseActivity与BaseFragment的封装谈起 这篇博客主要是从

statusBar状态栏_02

苹果终于发布了iOS 7正式版,大批的用户都已经纷纷进行了升级.如果App是由Xcode 4.6或者更早版本生成,iOS 7系统会使用兼容模式运行该App,以便尽可能保持原有外观.但是,当使用Xcode 5重新编译App源代码时,此时会使用iOS 7 SDK来进行编译链接.(注意在使用Xcode 5打开旧项目之前备份项目源代码,因为Xcode 5会升级项目中的资源文件,且无法再使用旧版本的Xcode打开.)由于iOS 7 SDK较早期版本的SDK改动较大,因此App的界面也会出现种种问题,其中最

Android 透明状态栏

if(VERSION.SDK_INT >= VERSION_CODES.KITKAT) {    //4.4以上                                 //透明状态栏                                 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);                                 //透明导航栏        

Winform控件之菜单控件,工具栏控件和状态栏控件

菜单是用户获取应用程序中主要功能和实用程序的主要途径,如新建文件,打开文件等,这就需要用到菜单控件(MenuStrip).工具栏另一种获取应用程序主要功能的常用方法,比起菜单要直观,这就需要用到工具栏控件(ToolStrip).状态栏用于显示用户状态的简短信息,这就需要用到状态栏控件(StatusStrip). 一,MenuStrip控件和ContenxMenuStrip控件 MenuStrip控件是由System.Windows.Forms.MenuStrip类提供的,取代了以前的MainMe

IOS7的状态栏和导航栏

iOS 7中默认的导航栏 在开始定制之前,我们先来看看iOS 7中默认导航栏的外观.通过Xcode用Single View Controller模板创建一个工程.然后将view controller嵌入到一个navigation controller中.如果你不想从头开始,那么也可以在这里下载到这个示例工程. Xcode 5包含有iOS 6和iOS 7模拟器,我们可以在这两个不同的模拟器版本中运行示例程序,进行对比,如下图所示: vcC4tcSxs76w0dXJqzwvaDM+CjxwPtTaa

IOS总结_IOS7.0以后改变状态栏字体颜的问题

首先info.plist文件中,加入View controller-based status bar appearance项 如果设为YES,则View controller对status bar的设置优先级高于application的设置:设置为NO则以application的设置为准. 虽然7.0SDK后在UIViewController中也加入加入了 - (UIStatusBarStyle)preferredStatusBarStyle NS_AVAILABLE_IOS(7_0); //

【Fiddler的基本界面操作之工具栏、状态栏】

一.工具栏 备注:工具栏气泡点击可添加备注,添加成功的备注可以在comment栏中展示: 2.[replay]回放操作:选中一条记录后,点击[replay]可以再次请求一次该操作,也可以按键盘上的字母[R],利用快捷键回放. 3.[〤]清空监控面板:下拉选项有多个,可以选中[remove all]清空所有,也可以选中[images]只清空图片,非200的状态的[non-200s],或者非浏览器请求的[non-browserr]等 4.[go]调试debug:选中一条记录后,点击底部的[All P

张高兴的 UWP 开发笔记:手机状态栏 StatusBar

UWP 有关应用标题栏 TitleBar 的文章比较多,但介绍 StatusBar 的却没几篇,在这里随便写写.状态栏 StatusBar 用法比较简单,花点心思稍微设计一下,对应用会是个很好的点缀. 说明一下,当应用运行在 PC 上时我们叫 TitleBar ,运行在 Mobile 上时我们叫 StatusBar ,这是两个不同的玩意儿. 在使用 StatusBar 之前,你需要在项目的引用里添加 Windows Mobile Extensions for the UWP ,并且引用 Wind

沉浸式状态栏

知识来源:https://zhidao.baidu.com/question/1989575143165411427.html (1)内容应用到状态栏(360流量允许拖动到状态栏的效果) Window window = getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); window

Android中隐藏顶部状态栏的那些坑

Android中隐藏顶部状态栏的那些坑 先看看常规的隐藏状态栏的方法: 方法一: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //去除title requestWindowFeature(Window.FEATURE_NO_TITLE); //去掉Activity上面的状态栏 getWindow().setFlags(WindowManager