前几天在做一个功能时增加了一个停靠栏,恰好停靠栏中使用到了CMFCToolBar ,于是模仿多文档demo例子的CFileView里写了CCheckView,运行后发现第一次工具栏排列是好的,第二次运行时工具栏会排列到框架的左侧,然后每次打开都会放到左侧,此bug,百思不得其解,初期以为是注册表的问题,后来看了注册表,发现注册表里面根本就没有存储工具栏的停靠位置。如图:
然后调试了mfcdocmanager.cpp的系统代码,仍然没发现什么问题,后来对比CFileView 发现我创建的Toolbar有一个细节跟Demo里的不一样。
int CFileView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDockablePane::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rectDummy;
rectDummy.SetRectEmpty();
// 创建视图:
const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS;
if (!m_wndFileView.Create(dwViewStyle, rectDummy, this, 4))
{
TRACE0("未能创建文件视图\n");
return -1; // 未能创建
}
// 加载视图图像:
m_FileViewImages.Create(IDB_FILE_VIEW, 16, 0, RGB(255, 0, 255));
m_wndFileView.SetImageList(&m_FileViewImages, TVSIL_NORMAL);
m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE, IDR_EXPLORER);
m_wndToolBar.LoadToolBar(IDR_EXPLORER, 0, 0, TRUE /* 已锁定*/);
OnChangeVisualStyle();
m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() | CBRS_TOOLTIPS | CBRS_FLYBY);
m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() & ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
m_wndToolBar.SetOwner(this);
// 所有命令将通过此控件路由,而不是通过主框架路由:
m_wndToolBar.SetRouteCommandsViaFrame(FALSE);
// 填入一些静态树视图数据(此处只需填入虚拟代码,而不是复杂的数据)
FillFileView();
AdjustLayout();
return 0;
}
int CControlPointsCheckWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDockablePane::OnCreate(lpCreateStruct) == -1)
return -1;
//方案一 //
/*m_wndToolBar.CreateEx(this//,0 ,WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_TOOLTIPS,
);
m_wndToolBar.LoadToolBar(IDR_TOOLBAR2);
m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY);
m_wndToolBar.SetPaneStyle(
m_wndToolBar.GetPaneStyle() &
~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP |
CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
m_wndToolBar.SetOwner(this);
*/
//方案2 //
m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE, IDR_TOOLBAR2);
m_wndToolBar.LoadToolBar(IDR_TOOLBAR2, 0, 0, TRUE);
m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() | CBRS_TOOLTIPS | CBRS_FLYBY);
m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() & ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
m_wndToolBar.SetOwner(this);
//listctrl
CRect rectDummy;
rectDummy.SetRectEmpty();
const DWORD dwListStyle = WS_CHILD | WS_VISIBLE | TVS_HASLINES | LVS_SINGLESEL|LVS_SORTASCENDING;
m_List.Create(dwListStyle, rectDummy, this, IDC_LIST_CTRL);
m_List.SetOwner(this);
m_List.SetParent(this);
LONG lStyle;
lStyle = GetWindowLong(m_List.m_hWnd, GWL_STYLE);//获取当前窗口style
lStyle &= ~LVS_TYPEMASK; //清除显示方式位
lStyle |= LVS_REPORT; //设置style
SetWindowLong(m_List.m_hWnd, GWL_STYLE, lStyle);//设置style
DWORD dwStyle = m_List.GetExtendedStyle();
dwStyle |= LVS_EX_FULLROWSELECT;//选中某行使整行高亮(只适用与report风格的listctrl)
dwStyle |= LVS_EX_GRIDLINES;//网格线(只适用与report风格的listctrl)
dwStyle |= LVS_SHOWSELALWAYS;
m_List.SetExtendedStyle(dwStyle); //设置扩展风格
m_List.InsertColumn(0,L"1", LVCFMT_LEFT, 60);//插入列
m_List.InsertColumn(1,L"2", LVCFMT_LEFT, 230);
m_List.InsertColumn(2,L"3", LVCFMT_LEFT, 100);
m_List.InsertColumn(3,L"4", LVCFMT_LEFT, 100);
m_List.EnableMultipleSort(TRUE);
//调整大小
AdjustLayout();
return 0;
}
1:正常,不会停靠到左侧边栏。
m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE, IDR_EXPLORER);
m_wndToolBar.LoadToolBar(IDR_EXPLORER, 0, 0, TRUE /* 已锁定*/);
2:会停靠到左侧边栏。
m_wndToolBar.CreateEx(this//,0 ,WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_TOOLTIPS,
);
m_wndToolBar.LoadToolBar(IDR_TOOLBAR2);
区别就在这两行代码上。如果用CreateEx
会停靠到左侧边栏。用Create则正常。
目前为止没发现为啥会出现这样。原因待后面发现后补充。