CWnd直接派生的窗口下使用CToolBar笔记

来源:互联网 发布:怎么找手机淘宝小二 编辑:程序博客网 时间:2024/06/16 22:15

问题

  1. 按msdn上的教程在CWnd派生的窗口的OnCreate下创建CToolBar,工具栏不显示。

    1. Create a toolbar resource.
    2. Construct the CToolBar object.
    3. Call the Create (or CreateEx) function to create the Windows toolbar 4. and attach it to the CToolBar object.
    4. Call LoadToolBar to load the toolbar resource
  2. 由CFrameWnd派生的窗口的OnCreate按上文提到的方法在OnCreate丰创建CToolBar, 工具栏显示了,但显示的图片都是位图的第一张

探究

  1. 问题1
    由CWnd直接派生的窗口下创建不显示,第一个我想到的就是CToolBar的窗口大小没设置,导致不显示,在代码中印证了下,果然如此,

    m_ToolBar.CreateEx( this );m_ToolBar.LoadToolBar( IDR_TOOLBAR1 );m_ToolBar.SetButtons( NULL, 3 );m_ToolBar.SetButtonText( 0, _T("button1") );m_ToolBar.SetButtonText( 0, _T("button2") );m_ToolBar.SetButtonText( 0, _T("button3") );m_ToolBar.MoveWindow( 20, 20, 200, 50 );

    显示如下
    手动设置工具栏大小

    上面手动设置,工具栏是显示出来,但是位置、大小都要自己手动去管理,非常麻烦。由CFrameWnd直接派生的窗口下创建就可以显示,而且是自动管理位置、大小的。基于以上事实,那么很容易想到是不是CFrameWnd对工具栏做过什么特别的管理呢。通过网上查找相关资料(特别是这往篇博文http://blog.csdn.net/qiuchengw/article/details/6255459),查看MFC对CFrameWnd的实现源码,印证了我的推断,代码如下:

    void CFrameWnd::RecalcLayout(BOOL bNotify){    if (m_bInRecalcLayout)        return;    m_bInRecalcLayout = TRUE;    // clear idle flags for recalc layout if called elsewhere    if (m_nIdleFlags & idleNotify)        bNotify = TRUE;    m_nIdleFlags &= ~(idleLayout|idleNotify);#ifndef _AFX_NO_OLE_SUPPORT    // call the layout hook -- OLE support uses this hook    if (bNotify && m_pNotifyHook != NULL)        m_pNotifyHook->OnRecalcLayout();#endif    // reposition all the child windows (regardless of ID)    if (GetStyle() & FWS_SNAPTOBARS)    {        CRect rect(0, 0, 32767, 32767);        RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery,            &rect, &rect, FALSE);        RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra,            &m_rectBorder, &rect, TRUE);        CalcWindowRect(&rect);        SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(),            SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);    }    else        RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposExtra, &m_rectBorder);    m_bInRecalcLayout = FALSE;}

    从以上代码中可以看出,CFrameWnd在调整窗口布局时,调用了CWnd::RepositionBars去调整Bars的位置,此函数内部会依次遍历子窗口,并向子窗口发送WM_SIZEPARENT消息。就此打住,就不继续深入进去了。

  2. 问题2
    原因在于m_ToolBar.SetButtons( NULL, 3 )的第一个参数 传递的是NULL,即没有对各个按钮进行位图的初始化,由MFC源码得知,MSDN上也有提到:
    If lpIDArray is NULL, this function allocates space for the number of items specified by nIDCount. Use SetButtonInfo to set each item’s attributes.

解决

  1. 探究了问题1后,我想最快的解决办法就是从CFrameWnd派生,这样就让CFrameWnd去操心这些Bars吧
  2. 问题2的话就很简单了,不多说了,看MSDN

总结

在MFC下,如果不想使用单文档/多文档的结构,但又想使用工具栏、状态栏等一些Bars的话,就从CFrameWnd下派生窗口类,这样就能轻松拥有这些Bars了。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 6s储存空间虚满怎么办 大胸下垂穿婚纱怎么办 美团签约成功后怎么办 拍婚纱照笑不出来怎么办 长得丑拍婚纱照怎么办 失恋了怎么办才能最快走出来 眼镜大了往下掉怎么办 眼镜带着往下掉怎么办 眼镜腿松了怎么办妙招 眼镜框大了总掉怎么办 吃不下饭恶心想吐怎么办 买到苹果翻新机怎么办 欠装修款不给怎么办 老板欠工资跑了怎么办 挖机老板欠工资怎么办 欠工程款耍赖不给怎么办 辞工后不给工资怎么办 工伤仲裁后不给怎么办 离职后不给工资怎么办 离职了不发工资怎么办 饭店欠工资不给怎么办 单位欠工资不给怎么办 离职后工资不发怎么办 暑假工不给工资怎么办 暑假工工资不发怎么办 个人欠钱2万不还怎么办 快递发错地址了怎么办 香烟被快递扣了怎么办 买st股票退市了怎么办 av淘宝看不了了,怎么办 厨房通水道堵了怎么办 皮鞋大了不跟脚怎么办 敞口皮鞋穿大了怎么办 穿皮鞋老掉跟怎么办 皮鞋鞋垫不粘了怎么办 上海拍好车牌后怎么办 补好的牙齿碎了怎么办 狗死了埋浅了怎么办 公租房租满5年后怎么办 买的股票停盘了怎么办 央企重组后员工怎么办