ATL GUI (四)

ATL GUI 4
WTL可以完成工具栏和状态栏

RESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/,
                             LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
    CreateSimpleToolBar();
    CreateSimpleStatusBar();

    m_hWndClient = m_view.Create(...);

// ...

    // register object for message filtering and idle updates
    CMessageLoop* pLoop = _Module.GetMessageLoop();
    ATLASSERT(pLoop != NULL);
    pLoop->AddMessageFilter(this);
    pLoop->AddIdleHandler(this);

    return 0;
}

CFrameWindowImpl::CreateSimpleToolBar()函数使用资源 IDR_MAINFRAME创建工具条并将其句柄赋值给m_hWndToolBar,
下面是CreateSimpleToolBar()函数的代码:

BOOL CFrameWindowImpl::CreateSimpleToolBar(
    UINT nResourceID = 0,
    DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE,
    UINT nID = ATL_IDW_TOOLBAR)
{
    ATLASSERT(!::IsWindow(m_hWndToolBar));
 
    if(nResourceID == 0)
        nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
 
    m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE,
                                               dwStyle, nID);
    return (m_hWndToolBar != NULL);
}

这是新添加的代码的开始部分,
CFrameWindowImpl::CreateSimpleToolBar()函数使用资源 IDR_MAINFRAME创建工具条并将其句柄赋值给m_hWndToolBar,
下面是CreateSimpleToolBar()函数的代码:

BOOL CFrameWindowImpl::CreateSimpleToolBar(
    UINT nResourceID = 0,
    DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE,
    UINT nID = ATL_IDW_TOOLBAR)
{
    ATLASSERT(!::IsWindow(m_hWndToolBar));
 
    if(nResourceID == 0)
        nResourceID = T::GetWndClassInfo().m_uCommonResourceID;
 
    m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, TRUE,
                                               dwStyle, nID);
    return (m_hWndToolBar != NULL);
}

显示和隐藏工具条和状态条
LRESULT CMainFrame::OnViewToolBar(WORD /*wNotifyCode*/, WORD /*wID*/,
                                  HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    BOOL bVisible = !::IsWindowVisible(m_hWndToolBar);
    ::ShowWindow(m_hWndToolBar, bVisible ? SW_SHOWNOACTIVATE : SW_HIDE);
    UISetCheck(ID_VIEW_TOOLBAR, bVisible);
    UpdateLayout();
    return 0;
}

这些代码翻转控制条的显示状态,相应的翻转View|Toolbar菜单上的检查标记,
然后调用UpdateLayout()重新定位控制条并改变视图窗口的大小。

工具条按钮的UI状态更新

向导生成的代码已经为CMainFrame添加了对View|Toolbar和View|Status Bar两个菜单项的Check和Uncheck的UI更新处理。
对CMainFrame类的两个命令使用UI更新的宏:
BEGIN_UPDATE_UI_MAP(CMainFrame)
    UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP)
    UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP)
END_UPDATE_UI_MAP()

我们的时钟程序的工具条按钮与对应的菜单项有相同的ID,所以第一步就是为每个宏添加UPDUI_TOOLBAR标志:
BEGIN_UPDATE_UI_MAP(CMainFrame)
    UPDATE_ELEMENT(ID_VIEW_TOOLBAR, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
    UPDATE_ELEMENT(ID_VIEW_STATUS_BAR, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)
END_UPDATE_UI_MAP()

使用Rebar代替简单的工具条

LRESULT CMainFrame::OnCreate(...)
{
    HWND hWndToolBar = CreateSimpleToolBarCtrl ( m_hWnd,
                           IDR_MAINFRAME, FALSE,
                           ATL_SIMPLE_TOOLBAR_PANE_STYLE );
 
    CreateSimpleReBar(ATL_SIMPLE_REBAR_NOBORDER_STYLE);
    AddSimpleReBarBand(hWndToolBar);
// ...
}
代码从创建工具条开始,只是使用了不同的风格,也就是ATL_SIMPLE_TOOLBAR_PANE_STYLE,
它定义在 atlframe.h文件中,与ATL_SIMPLE_TOOLBAR_STYLE风格相似,只是附加了一些诸如CCS_NOPARENTALIGN之类的风格,
这是使工具条作为Rebar的子窗口能够正常工作所必需的风格。

CMainFrame::OnViewToolBar()函数也有些不同,它只隐藏Rebar上工具条所在的条位而不是隐藏m_hWndToolBar(如果隐藏m_hWndToolBar将隐藏整个Rebar而不仅仅是工具条)。

如果你使用多个工具条,只需像向导为我们生成的关于第一个工具条的代码那在OnCreate()创建它们并调用 AddSimpleReBarBand()添加到Rebar就行了。
CFrameWindowImpl使用标准的Rebar控件,不像MFC那样支持可停靠的工具条,你所能作得就是排列这些工具条在Rebar中的位置。

窗格的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()

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

最后,在CMainFrame::OnIdle()中添加对UIUpdateStatusBar()函数的调用,使状态条的窗格能够在空闲时间被更新:
BOOL CMainFrame::OnIdle()
{
    UIUpdateToolBar();
    UIUpdateStatusBar();
    return FALSE;
}
当你使用UIUpdateStatusBar()时CUpdateUI的一个问题就暴露出来了--菜单项的文本在调用UISetText()后没有改变!
如果你在看WTLClock3工程的代码,时钟的开始/停止菜单项被移到了Clock菜单,在菜单项命令的响应处理函数中设置菜单项的文本。
无论如何,如果当前调用的是UIUpdateStatusBar(),那么对UISetText()的调用就不会起作用。
我没有研究这个问题是否可以被修复,所以如果你打算改变菜单的文本,你需要留意这个地方。

文章转至http://www.imyaker.com/wtl/,加入了自己的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值