一:工具栏的创建
CToolBar m_tbar;
m_tbar.Create(this,WS_CHILD | WS_VISIBLE | CBRS_TOP,123);
在资源视图中创建一个工具栏资源,ID为:IDR_TOOLBAR1
m_tbar.LoadToolBar(IDR_TOOLBAR1);
注意:工具栏创建的过程中使用了两个ID(分别为123,IDR_TOOLBAR1)。
而RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0,reposQuery,rcClientNew)函数前两个参数就是要直到一个控制栏ID范围,它使用的是m_tbar.Create(this,WS_CHILD | WS_VISIBLE | CBRS_TOP,123)中的ID:123。
所以对工具栏的可以这样理解:m_tbar.Create(this,WS_CHILD | WS_VISIBLE | CBRS_TOP,123);该代码才是真正的创建了一个工具栏,而m_tbar.LoadToolBar(IDR_TOOLBAR1);只是在工具栏上设置了一张图像,图像ID为:IDR_TOOLBAR1。
CToolBar类有一个构造函数:
BOOL Create(CWnd* pParentWnd,DWORD dwStyle=WS_CHILD|WS_VISIBLE|CBRS_TOP,UINT nID=AFX_IDW_TOOLBAR);
所以我们常用的m_tbar.Create(this)函数创建的工具栏ID为:AFX_IDW_TOOLBAR,
该值大小界于AFX_IDW_CONTROLBAR_FIRST与AFX_IDW_CONTROLBAR_LAST之间。
实验:
一、创建MFC对话框应用程序。
二、在对话框类添加成员变量:CToolBar m_tbar;
三、在资源视图中创建工具栏资源:
四、在OnInitDialog函数中添加源码:
<span style="font-family:Courier New;font-size:14px;">if(m_tbar.Create(this) && m_tbar.LoadToolBar(IDR_TOOLBAR1))
{
CRect rcClientOld;
CRect rcClientNew;
GetClientRect(rcClientOld);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0,reposQuery,rcClientNew);
CPoint ptOffset(rcClientNew.left-rcClientOld.left,rcClientNew.top-rcClientOld.top);
CRect rcWindow;
GetWindowRect(rcWindow);
rcWindow.right += rcClientOld.Width() - rcClientNew.Width();
rcWindow.bottom += rcClientOld.Height() - rcClientNew.Height();
MoveWindow(rcWindow,FALSE);
CRect rcChild;
CWnd* pwndChild = GetWindow(GW_CHILD);
while(pwndChild)
{
pwndChild->GetWindowRect(rcChild);
ScreenToClient(rcChild);
rcChild.OffsetRect(ptOffset);
pwndChild->MoveWindow(rcChild,FALSE);
pwndChild = pwndChild->GetNextWindow();
}
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
}</span>
代码RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0,reposQuery,rcClientNew)的作用是去掉客户区中ID在区间[AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST]中控件占用的区域,并将剩余的区域大小填充到矩形结构rcClientNew中。
代码RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0)的作用是显示ID值界于[AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST]的所有Bar类(控制条类)。
实验结果:
现在如果将上述代码中
m_tbar.Create(this)改为
m_tbar.Create(this,WS_CHILD | WS_VISIBLE | CBRS_TOP,123)则不能显示工具栏,运行结果为:
原因是123不介于[AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST]中,
如果将
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0,reposQuery,rcClientNew);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
修改为:
RepositionBars(0,124,0,reposQuery,rcClientNew);
RepositionBars(0,124,0);
则又能正常显示了。因此不难得出结论:m_tbar.Create(this,WS_CHILD | WS_VISIBLE | CBRS_TOP,123)中第三个参数才是真正的工具条ID.
CWnd::RepositionBars
void RepositionBars(
UINT nIDFirst,
UINT nIDLast,
UINT nIDLeftOver,
UINTnFlag = CWnd::reposDefault,
LPRECT lpRectParam = NULL,
LPCRECTlpRectClient = NULL,
BOOL bStretch = TRUE
);
参数:
nIDFirst 要重新定位并改变大小的控制条范围中的第一个控制条的ID。
nIDLast 要重新定位并改变大小的控制条范围中的最后一个控制条的ID。
nIDLeftOver 指定了填充客户区其余部分的方格的ID。
nFlag 可以具有下列值:
· CWnd::reposDefault实现控制条的布局。lpRectParam没有被使用,可以是NULL。
· CWnd::reposQuery没有执行控制条的布局,相反用客户区的大小初始化了lpRectParam,就像已经完成了布局一样。
· CWnd::reposExtra将lpRectParam的值加到nIDLast的客户区上,并执行布局。
lpRectParam 指向一个RECT结构;其用法依赖于nFlag的值。
lpRectClient 指向一个RECT结构,其中包含了可用的客户区。如果为NULL,则窗口的客户区将被使用。
bStretch 指明控制条是否要被缩放到框架的大小。