科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件MFC程序员的WTL指南之工具条与状态条

MFC程序员的WTL指南之工具条与状态条

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

自从作为Windows 95的通用控件出现以来,工具条和状态条就变成了很普遍的事物

作者:lithe 来源:csdnblog 2007年10月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
多窗格的状态条

  WTL另有一个状态条类实现多窗格的状态条,与MFC的默认的状态条一样有CAPS,LOCK和NUM LOCK指示器,这个类就是CMultiPaneStatusBarCtrl,在WTLClock3例子工程中演示了如何使用这个类。这个类支持有限的UI更新,当弹出式菜单被显示时有“Default”属性的窗格会延伸到整个状态条的宽度用于显示菜单的掠过式帮助。

  第一步就是在CMainFrame中声明一个CMultiPaneStatusBarCtrl类型的成员变量:

class CMainFrame : public ...
{
 //...
 protected:
  CMultiPaneStatusBarCtrl m_wndStatusBar;
};

  接着在OnCreate()中创建状态条并这只UI更新:

m_hWndStatusBar = m_wndStatusBar.Create ( *this );
UIAddStatusBar ( m_hWndStatusBar );

  就像CreateSimpleStatusBar()函数做得那样,我们也将状态条的句柄存放在m_hWndStatusBar中。

  下一步就是调用CMultiPaneStatusBarCtrl::SetPanes()函数建立窗格:

BOOL SetPanes(int* pPanes, int nPanes, bool bSetText = true);

  参数:

  ·pPanes

  存放窗格ID的数组

  ·nPanes

  窗格ID数组中元素的个数(译者加:就是窗格数)

  ·bSetText

  如果是true,所有的窗格被立即设置文字,这一点将在下面解释。

  窗格ID可以是ID_DEFAULT_PANE,此ID用于创建支持掠过式帮助的窗格,窗格ID也可以是字符串资源ID。对于非默认的窗格WTL装载这个ID对应的字符串并计算宽度,并将窗格设置为相应的宽度,这和MFC使用的逻辑是一样的。

  bSetText控制着窗格是否立即显示相关的字符串,如果是true,SetPanes()显示每个窗格的字符串,否则窗格就被置空。

  下面是我们对SetPanes()的调用:

// Create the status bar panes.
int anPanes[] = { ID_DEFAULT_PANE, IDPANE_STATUS,
IDPANE_CAPS_INDICATOR };

m_wndStatusBar.SetPanes ( anPanes, 3, false );

  IDPANE_STATUS对应的字符串是“@@@@”,这样应该有足够的宽度(希望是)显示两个时钟状态字符串“Running”和“Stopped”。和MFC一样,你需要自己估算窗格的宽度,IDPANE_CAPS_INDICATOR对应的字符串是“CAPS”。

  窗格的UI状态更新

  为了更新窗格上的文本,我们需要将相应的窗格添加到UI更新表:

BEGIN_UPDATE_UI_MAP(CMainFrame)
//...
UPDATE_ELEMENT(1, UPDUI_STATUSBAR) // clock status
UPDATE_ELEMENT(2, UPDUI_STATUSBAR) // CAPS indicator
END_UPDATE_UI_MAP()

  这个宏的第一个参数是窗格的索引而不是ID,这很不幸,因为如果你重新排列了窗格,你要记得更新UI更新表。

  由于我们在调用SetPanes()是第三个参数是false,所以窗格初始是空的。我们下一步要做得就是将时钟状态窗格的初始文本设为“Running”

// Set the initial text for the clock status pane.
UISetText ( 1, _T("Running") );

  和前面一样,第一个参数是窗格的索引。UISetText()是状态条唯一支持的UI更新函数。

  最后,在CMainFrame::OnIdle()中添加对UIUpdateStatusBar()函数的调用,使状态条的窗格能够在空闲时间被更新:

BOOL CMainFrame::OnIdle()
{
 UIUpdateToolBar();
 UIUpdateStatusBar();
 return FALSE;
}

  当你使用UIUpdateStatusBar()时CUpdateUI的一个问题就暴露出来了--菜单项的文本在调用UISetText()后没有改变!如果你在看WTLClock3工程的代码,时钟的开始/停止菜单项被移到了Clock菜单,在菜单项命令的响应处理函数中设置菜单项的文本。无论如何,如果当前调用的是UIUpdateStatusBar(),那么对UISetText()的调用就不会起作用。我没有研究这个问题是否可以被修复,所以如果你打算改变菜单的文本,你需要留意这个地方。

  最后,我们需要检查CAPS LOCK键的状态,更新相应的两个窗格。这些代码是通过OnIdle()被调用的,所以程序会在每次空闲时间检查它们的状态。

BOOL CMainFrame::OnIdle()
{
 // Check the current Caps Lock state, and if it is on, show the
 // CAPS indicator in pane 2 of the status bar.
 if ( GetKeyState(VK_CAPITAL) & 1 )
  UISetText ( 2, CString(LPCTSTR(IDPANE_CAPS_INDICATOR)) );
 else
  UISetText ( 2, _T("") );
  UIUpdateToolBar();
  UIUpdateStatusBar();
  return FALSE;
}

  第一次调用UISetText()时将从字符串资源中装载“CAPS”字符串,但是在CString的构造函数中使用了一个机灵的窍门(有充分的文档说明)。

  在完成所有的代码之后,状态条看起来是这个样子:


  承上启下:有关对话框的话题

  在第四章我将介绍对话框的用法(包括ATL的类和WTL的增强功能),控件的包装类和WTL有关对话框消息处理的改进。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章