增加带区 翻译:tellmenow
REBARBANDINFO结构用来描述控件中的每个带区,通过给CommamndBands_AddBands函数传递一个REBARBANDINFO结构数组,可以给应用程序添加带区。CommandBands_AddBands函数原型如下:
BOOL CommandBands_AddBands (HWND hWndCmdBands, HINSTANCE hinst, UINT cBands, LPREBARBANDINFO prbbi);
再调用该函数之前,您必须先把准备加到控件里的每个带区的信息填写到REBARBANDINFO结构中。该结构定义如下:
typedef struct tagREBARBANDINFO{
UINT cbSize;
UINT fMask;
UINT fStyle;
COLORREF clrFore;
COLORREF clrBack;
LPTSTR lpText;
UINT cch;
int iImage;
HWND hwndChild;
UINT cxMinChild;
UINT cyMinChild;
UINT cyMinChild;
UINT cx;
HBITMAP hbmBack;
UINT wID;
UINT cyChild;
UINT cyMaxChild;
UINT cyIntegral;
UINT cxIdeal;
LPARAM lParam;
} REBARBANDINFO;
幸运地是,虽然该结构看上去很宏伟壮观,但其中的许多域可以被忽略掉,因为对未初始化的域有默认值。和通常的Windows结构一样,做为一种容错安全措施,cbSize需要填充为结构的尺寸。fMask域则填充了许多标志,用来指出结构中其它域中哪些域填写的是有效信息。在讨论到每个域的时候,我会描述这些标志的。
如果fMask域中指定了RBBIM_STYLE标志,那fStyle域就必须使用带区的风格标志来填充。适用的标志如下:
RBBS_BREAK 带区从新的一行开始
RBBS_FIXEDSIZE 带区不能被调整大小。当指定了该标志,带区的“小把手”将不显示。
RBBS_HIDDEN 当命令带被创建后,带区不可视。
RBBS_GRIPPERALWAYS 带区有可调尺寸的小把手,即使命令带只有一个带区。
RBBS_NOGRIPPER 带区没有可调尺寸的小把手,因此用户不能移动带区
RBBS_NOVERT 如果使用CCS_VERT风格,命令带控件垂直显示的话,带区不会显示出来。
RBBS_CHILDEDGE 在带区的顶部和底部绘制边线
RBBS_FIXEDBMP 当带区改变大小的时候,带区的背景位图不移动。
基本上这些标志是自解释型的。虽然命令带通常显示在窗口顶部,但是他们可以创建成垂直命令带并显示在窗口左边。在这种情况下,RBBS_NOVERT风格允许程序员来指定当命令带在垂直方向时,带区不显示。包含菜单或略宽一些控件的带区是很适合这种标志的,因为它们在垂直带区上不能被正确显示。
clrFore和clrBack域中填写的是颜色信息,在应用程序绘制带区的时候,会用这些颜色绘制前景色和背景色。需要注意的是,只有在掩码域中设置了RBBIM_COLORS标志时这两个域才有用。对这两个域以及用来为带区指定背景位图的hbmBack域来说,只有在带区包含透明命令条的时候才有用。否则命令条会占据带区的大部分空间,并遮盖任何背景位图或者颜色。在“配置单独带区”一节中,我将解释如何使命令条透明。
lpText域指定了用来标记单个带区的可选文本。这些文字将直接显示在带区条的左边。iImage域用于指定一个显示在带区条左边的位图,使用包含在图像列表控件中的图象列表的索引来填充iImage域。当和命令带控件的RBS_SMARTLABELS风格配套使用的时候,文字和位图显地更加重要。指定了RBS_SMARTLABELS风格以后,如果带区被还原或者最大化,文字就会显示出来;如果带区被最小化,位图就显示出来。该技术被H/PC Explorer用在它的命令带控件上。
wID域中填充的是带区的ID值。带区ID是很重要的,如果您计划在创建带区后配置它们或者想查询它们的状态的话。即使您不打算在程序里使用带区ID,保持每个带区ID唯一也是很重要的,因为控件自身使用该ID来管理带区。只有在fMask域中设置了RBBIM_ID标志时才会检查wID域。
如果带区中默认的命令条控件需要被另一个控件替代的话,hwndChild域就是很有用的了。为了替换命令条控件,必须首先创建新控件,再把该控件的窗口句柄放到hwndChild域中。只有在fMask域中设置了RBBIM_CHILD标志时才会检查hwndChild域。
cxMinChild和cyMinChild域中定义了带区可以缩小到的最小尺寸。当使用默认命令条以外的控件时,这两个域对定义带区的高度和最小宽度很有用。只有在fMask域中设置了RBBIM_CHILDSIZE标志时才会检查这两个域。
当带区被用户最大化的时候,会使用cxIdeal 域。如果这个域没有初始化,命令带最大化时会伸展到整个控件宽度。通过设置cxIdeal,应用程序可以限制带区最大化的宽度,这对于带区上的控件只占整个带区宽度一部分的情况来说是很方便的。只有在fMask域中设置了RBBIM_IDEALSIZE标志时才会检查这个域。
lParam域提供了一个空间来存储由应用程序定义的关于带区信息的值。只有在fMask域中设置了RBBIM_LPARAM标志时才会检查这个域。
REBARBANDINFO中的其它域多用于更灵活的rebar控件,而不仅仅是命令带控件。下面的代码创建了一个命令带控件,初始化了一个带三个REBARBANINFO结构的数组并把带区加到控件里。
// Create a command bands control.
hwndCB = CommandBands_Create (hInst, hWnd, IDC_CMDBAND, RBS_SMARTLABELS | RBS_VARHEIGHT, himl);
// Initialize common REBARBANDINFO structure fields.
for (i = 0; i < dim(rbi); i++) {
rbi[i].cbSize = sizeof (REBARBANDINFO);
rbi[i].fMask = RBBIM_ID | RBBIM_IMAGE | RBBIM_SIZE | RBBIM_STYLE;
rbi[i].fStyle = RBBS_FIXEDBMP;
rbi[i].wID = IDB_CMDBAND+i;
}
// Initialize REBARBANDINFO structure for each band.
// 1. Menu band.
rbi[0].fStyle |= RBBS_NOGRIPPER;
rbi[0].cx = 130;
rbi[0].iImage = 0;
// 2. Standard button band.
rbi[1].fMask |= RBBIM_TEXT;
rbi[1].cx = 200;
rbi[1].iImage = 1;
rbi[1].lpText = TEXT ("Std Btns");
// 3. Edit control band.
hwndChild = CreateWindow (TEXT ("edit"), TEXT ("edit ctl"),
WS_VISIBLE | WS_CHILD | WS_BORDER,
0, 0, 10, 5, hWnd, (HMENU)IDC_EDITCTL,
hInst, NULL);
rbi[2].fMask |= RBBIM_TEXT | RBBIM_STYLE | RBBIM_CHILDSIZE | RBBIM_CHILD;
rbi[2].fStyle |= RBBS_CHILDEDGE;
rbi[2].hwndChild = hwndChild;
rbi[2].cxMinChild = 0;
rbi[2].cyMinChild = 25;
rbi[2].cyChild = 55;
rbi[2].cx = 130;
rbi[2].iImage = 2;
rbi[2].lpText = TEXT ("Edit field");
// Add bands.
CommandBands_AddBands (hwndCB, hInst, 3, rbi);
上面的代码中创建的命令带控件有三个带区,一个包含一个菜单,一个包含一组按钮,一个则使用编辑控件代替了命令条。使用RBS_SMARTLABELS 和 RBS_VARHEIGHT 风格创建了控件。当命令条最小化的时候,智能标签显示一个图标;当不在最小化状态时,显示文字图标。RBS_VARHEIGHT风格则允许控件上的每行有不同的高度。
在一个循环里初始化了REBARBANINFO结构中共用的域。接下来,结构中剩余的域根就据控件中的每个带区进行定制。包含编辑控件的第三个带区初始化是最复杂的。该带区需要更多的初始化,因为编辑控件需要适当的调整尺寸来匹配其它带区中命令条控件的标准高度。
使用图像列表索引来初始化每个带区中的iImage域。该图像列表创建并传递进了CommandBands_Create函数。用在第二和第三个带区中的文本域被标记所填充。包含菜单的第一个带区中并不包含文本标记,因为菜单不需要标记。可以对第一个带区使用RBBS_NOGRIPPER风格,这样它就不能在控件上移动了。这可以使菜单带区固定显示在控件中适当的位置上。
既然我们已经创建了带区,那是时候来看看如何初始化它们了。(待续)