修改状态栏“就绪”

在MFC程序中如果使用默认的状态栏的话,其第一栏在空闲时显示的是“就绪”,如果用户点击菜单,还会用于显示菜单栏的提示文本,如“建立新文档”等。有时候我们不希望程序在状态栏中显示这些东西,那该怎么办呢?

在MFC中,是用主框架类中的CStatusBar对象m_wndStatusBar来管理状态栏的。CStatusBar中有一个SetPaneText的函数可用于设置状态栏中的文字。我们在CMainFrame类中的OnCreate函数中添加

m_wndStatusBar.SetPaneText(0, "Hello");

则程序启动后,状态栏上显示的文字为“Hello”。但是当我们点击菜单后,会发现这段文字会消失,被替换成菜单的提示文本;若菜单操作结束,则又显示成“就绪”了。那该如何禁止MFC自动修改状态栏文本呢?

我们再看看主框架类的源程序。当中有这么一段

static UINT indicators[] =
{
ID_SEPARATOR,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};

而在OnCreate中有这么一段

m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)))

这一句的作用是设置状态栏各部分的ID,默认的ID由indicators数组指定。由于MFC中把状态栏的第一栏设置为ID_SEPARATOR 了,这是一个MFC默认的ID,所以它有一系列默认的操作,如显示“就绪”二字。我们想禁止MFC自动操作状态栏就必须修改indicators数组。

我们打开Resource View,修改String Table,找到那堆ID_INDICATOR开头的,在后面新加一个ID_INDICATOR_1。然后修改CMainFrame中indicators的声明

static UINT indicators[] =
{
ID_INDICATOR_1,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};

然后编译运行程序。我们会发现,MFC不会再自动修改状态栏的文本了,可是前面添加的一句
m_wndStatusBar.SetPaneText(0, "Hello");
也不起作用了。这是为什么呢?

附录中对此进行了介绍:

Note   The SetText approach is recommended. It is possible to perform this task at a slightly lower level by calling the CStatusBar member function SetPaneText. Even so, you still need an update handler. Without such a handler for the pane, MFC automatically disables the pane, erasing its content.

意思大概是如果我们不为状态栏添加UPDATE的处理函数,MFC会自动禁止状态栏的该栏(pane)。按照MSDN的说法,我们需要增加UPDATE的处理函数。在MainFrm.h中添加

afx_msg void OnUpdate1(CCmdUI *pCmdUI);

在MainFrm.cpp中添加

ON_UPDATE_COMMAND_UI(ID_INDICATOR_1, OnUpdate1)

void CMainFrame::OnUpdate1(CCmdUI *pCmdUI)
{
 pCmdUI->Enable();
}

这样我们就可以往状态栏的第一栏写文字,而避开MFC对其的自动修改了。


附录:

CAUSE
Setting any but the first pane of the status bar is relatively simple. You just need to set the pane using SetPaneText() and make sure you have added in an ON_UPDATE_COMMAND_UI handler for the ID of that pane (set in your MAINFRAME.CPP as an element of an indicators[] array). This handler should call Enable() in the following manner to make sure that the pane is not erased:  


  void CMainFrame::OnUpdateMystat(CCmdUI* pCmdUI)
  {
  pCmdUI->Enable();
  }


However, setting the FIRST pane of a status bar using SetPaneText() or calling SetWindowText() on the status bar is a bit more difficult.  
The problem is that the framework itself is changing the first pane using some special techniques. Basically, the framework is passing a WM_SETTEXT command directly to the status bar, from a number of places within its own code.  

Adding ON_UPDATE_COMMAND_UI handlers or calling SetPaneText() for the first pane of the status bar does not permanently set it. The framework eventually sends a WM_SETTEXT message directly to the status bar, changing the text from what was set.
RESOLUTION
One way of setting the first pane yourself and keeping it set to what you want is to derive your own class from CStatusBar (for example CMyStat) and to give it a WM_SETTEXT handler. (Adding the WM_SETTEXT handler cannot be done using ClassWizard, so the handler must be added by hand.)  

LRESULT CMyStat::OnSetText(WPARAM wParam, LPARAM lParam)
  {
  if ( !bIgnoreSetText )
  return CStatusBar::OnSetText( wParam, lParam );
  return 0; // Same as CStatusBar::OnSetText success
  }

  whenever bIgnoreSetText is true only if you have set your own text in the
  status bar with a SetPaneText() call.
Whenever bIgnoreSetText is true, the first pane of the status bar will be updated only when you update it with SetPaneText(). The frameworks WM_SETTEXT messages will be blocked when you have this flag set to a non- zero value. Note that this blocking effects only the first pane of the status bar.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值