CWnd直接派生的窗口下使用CToolBar笔记
来源:互联网 发布:怎么找手机淘宝小二 编辑:程序博客网 时间:2024/06/16 22:15
问题
按msdn上的教程在CWnd派生的窗口的OnCreate下创建CToolBar,工具栏不显示。
- Create a toolbar resource.
- Construct the CToolBar object.
- Call the Create (or CreateEx) function to create the Windows toolbar 4. and attach it to the CToolBar object.
- Call LoadToolBar to load the toolbar resource
由CFrameWnd派生的窗口的OnCreate按上文提到的方法在OnCreate丰创建CToolBar, 工具栏显示了,但显示的图片都是位图的第一张
探究
问题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
原因在于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后,我想最快的解决办法就是从CFrameWnd派生,这样就让CFrameWnd去操心这些Bars吧
- 问题2的话就很简单了,不多说了,看MSDN
总结
在MFC下,如果不想使用单文档/多文档的结构,但又想使用工具栏、状态栏等一些Bars的话,就从CFrameWnd下派生窗口类,这样就能轻松拥有这些Bars了。
- CWnd直接派生的窗口下使用CToolBar笔记
- InitInstance中创建CWnd派生的窗口对象,内存泄漏
- CToolBar的使用总结
- CToolBar的使用介绍
- CToolBar的使用总结
- CToolBar的使用介绍
- CToolBar的使用介绍
- CToolBar的使用介绍
- CToolBar的使用总结
- CToolBar的使用介绍
- CWnd派生类添加双表双击消息 需要注册窗口属性里面的 CS_DBLCLKS
- CWnd 直接创建窗口之教训
- CToolBar的使用总结(转)
- CToolBar的使用总结(2)
- CToolBar的使用总结1
- 拥塞窗口cwnd的理解
- CToolBar使用
- CToolBar使用
- Django_TemplateNotExist
- [代码片]同步锁内外判断
- CountDownLatch和CyclicBarrier使用示例
- 湖大C语言程序设计7
- mysql 常见分表方案
- CWnd直接派生的窗口下使用CToolBar笔记
- Redis之—— Spring4.0 注解Cache+Redis缓存
- linux内核笔记之时间管理(二) : 低精度timer
- linux 内核笔记之时间管理(三) : 高精度timer
- excel 数据处理
- POJ
- linux 内核笔记之watchdog
- sdcc 存储类型关键字
- (每天进步)hibernate的获取