欢迎访问:常州市武进区嘉泽中心小学网站 !今天是:
栏目列表
您现在的位置是:首页>>教师>>计算机技术>>程序设计>>杂项>>文章内容
PRB: MFC 垂直工具栏不能在定制后显示的所有按纽(翻译)
发布时间:2008-11-20   点击:   来源:本站原创   录入者:佚名
 

 

适用于

              这一个文章先前在 Q298126 之下被出版

 

征兆

              当一个 MFC 工具栏垂直地被放置,工具栏的定制可能造成一个或更多个按纽不能显示。 定制可能使用CToolBarCtrlCustomize()函数 增加或除去按纽或相似的编程方法。

 

原因

              首先, MFC 提供 对象的所有细节 , 像是工具栏 , 但是自从4.0版本,MFC 开始MFC开始用公用控件来代替工具柆,状态栏等等的实现。这个导置了MFC控件类的兼容性。

 

解决

              无论工具栏是停靠或悬浮,在增加或删除按纽后,以下代码能够正确地调整大小,重画MFC垂直工具栏。  OnToolBarChange的句柄 响应 TBN_TOOLBARCHANGE 通知被执行。 代码分三个步骤执行。 首先, CalcDynamicLayout以适当的参数执行,工具栏的状态可能为停靠/ 悬浮/垂直/ 水平。 其次, DockControlBar( 或 FloatControlBar) 被执行, 主要地呼叫这些函数来执行 SetWindowPos 的呼叫。 最后, DrawBorders 被呼叫完成重画。

 

把下列的注册加入你 CMainFrame's 的信息映象中。 (AFX_IDW_TOOLBAR 是工具栏ID)

  

    ON_NOTIFY(TBN_TOOLBARCHANGE, AFX_IDW_TOOLBAR, OnToolBarChange)

                      

 

 

OnToolBarChange 成员函数加入 CMainFrame 类并且增加下列的代码:

 

void CMainFrame::OnToolBarChange(NMHDR *notify, LRESULT *result)

{  

    // Update the toolbar icons.  

    CFrameWnd* pFrame;

    if (m_wndToolBar.IsFloating())

          pFrame = m_wndToolBar.GetParentFrame();

    else       

          pFrame = m_wndToolBar.GetDockingFrame();  

 

    CRect rectActualSize;  

    CRect rectActualFrameSize;    

    CRect rect;

    CSize size;

 

        // Get the ToolBar's rectangle

    m_wndToolBar.GetWindowRect(&rect);  

        // Are we horizontal?

    BOOL bHorz = (m_wndToolBar.m_dwStyle & CBRS_ORIENT_HORZ) != 0;

    if ((m_wndToolBar.m_dwStyle & CBRS_FLOATING) && 

          (m_wndToolBar.m_dwStyle & CBRS_SIZE_DYNAMIC))

          size = m_wndToolBar.CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH |

                                            LM_COMMIT);

    else if (bHorz)   

          size = m_wndToolBar.CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK |

                                            LM_COMMIT);      

    else       

         size = m_wndToolBar.CalcDynamicLayout(0, LM_VERTDOCK | LM_COMMIT);   

 

        // Use the result to calculate a new size

    rectActualSize = CRect(rect.TopLeft(), size);   

    rectActualFrameSize = CRect(rect.TopLeft(), size);          

 

    // Calculate frame rectangle  

    CMiniFrameWnd::CalcBorders(rectActualFrameSize);

 

        // Leave room for the window's border. The values used here

        // for m_cxBorder and m_cyBorder are 2 and 2 as a result of

        // calling GetSystemMetrics for SM_CXBORDER and SM_CYBORDER

        // (these should return 1) and multiplying the result by 2

        // to accommodate the modern shell's wider borders.

    rectActualFrameSize.InflateRect(-m_cxBorder, -m_cyBorder); 

    if (m_wndToolBar.IsFloating())

    {

          pFrame->FloatControlBar(&m_wndToolBar,

                            rectActualFrameSize.TopLeft());

    }

    else       

          pFrame->DockControlBar(&m_wndToolBar);    

 

    // force the frame window to recalculate the size     

    m_wndToolBar.GetParentFrame()->RecalcLayout();  

 

    CDC* pDC = GetDC();     

    rectActualFrameSize.OffsetRect(-rectActualFrameSize.left,

                                       -rectActualFrameSize.top); 

    m_wndToolBar.DrawBorders(pDC, rectActualFrameSize);   

    ReleaseDC(pDC);

}

                      

                           

 

把下列的数据成员加入 CMainFrame 类中并且在 CMainFrame's OnCreate成员函数设定他们初值:

int m_cyBorder;

int m_cxBorder;

 

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

        m_cxBorder = GetSystemMetrics(SM_CXBORDER);

        m_cyBorder = GetSystemMetrics(SM_CYBORDER);

        .....

}

                      

 

                           

状态

这行为是藉着设计。

 

更多信息

为了要接受工具栏的定制特征 你一定将 CCS_ADJUSTABLE 风格设定为工具栏控制的特征,就象在这里显示:

    m_wndToolBar.GetToolBarCtrl.()ModifyStyle;(0,CCS_ADJUSTABLE)

                           

 

改变后,当定制对话框出现,最少有一个工具栏通知被处理。这个通知是TBN_QUERYINSERT,它能够在CMainFrame 类被处理,就象下面那样:

void CMainFrame::OnQueryInsert( NMHDR * pNotifyStruct, LRESULT * result )

{

       *result = TRUE;

}

                           

 

NMHDR 结构实际上是 NMTOOLBAR 通知结构。 应该被处理的另外一个通知是 TBN_GETBUTTONINFO 。 因为通知被送去,所以这很重要为那些可得被增加到工具栏的按纽发送请求按纽数据。 为了要适当地处理这一个通知, NMTOOLBAR 结构的 iItem 成员应该被比较到原先的 TBBUTTON 结构队列的索引 , 和处理的人应该将结构装满按纽数据而且设定result为TRUE。

叁考

对于关于该如何保持那定制会话框看得见的信息, 按文章在下面数看微软知识库的文章:

241850 PRB: Call to CToolBarCtrl::Customize() Does Not Keep the Customize Dialog Box Visible

MFC "Toolbar Topics" in the "Adding User Interface Features" section of the Visual C++ Programmer's Guide:

 

The Microsoft Platform SDK Documentation has extensive information on the ToolBar common control in its "User Interface Services" section under "Windows Common Controls":

 

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     


附件:
    关闭窗口
    打印文档
    账号登录
    保持登录 忘记密码?
    账号与武进教师培训平台同步