activebar在pb中动态生成outlook框架的应用
by …---… (qq:21417511)
一、activebar简介:
在vb、vc或者delphi程序员看来,activebar是一款设计用户界面必不可少的activex控件。使用它可以制作出像word一样的个性化菜单、“自定义”对话框;像outlook的快捷按钮栏;像coreldraw的入坞式窗口;像delphi的控件选择页面。并且activebar使用十分简单,保存设计图和加载设计图都十分简单,只用几个方法即可。
二、activebar在pb中的应用
很早就有大侠写了《activebar控件在powerbuilder中的应用》的文章,类似的介绍我就不多说了,没有看过该文章的可以用google找一下来看看。我着重介绍一下如何用activebar动态生成outlook框架。
1、 首先,我们要对activebar的对象及其关系有个大体的了解,如下图所示:
2、 接下来,我们来探讨一下如何用activebar做outlook框架。
先创建一个custom visual userobject,里面添置activebar ole控件ole_1,保存成:u_activebar。这样做的好处是将activebar控件封装成userobject,方便以后的调用。当然,我还喜欢在这个userobject上放一个statictext st_1,text是:activebar,这样我以后调用时就能一目了然啦:) userobject的construct代码如下:
st_1.hide( )
ole_1.x = 0
ole_1.y = 0
this.x = 0
this.y = 0
ole_1.width = this.width
ole_1.height = this.height
目的是让ole自动放置到调用窗口的左上方,并且隐藏掉st_1。
activebar提供了大量的属性和方法,我们把这些属性与方法转换到u_activebar中,以便以后直接调用。
下面,我们开始扩展u_activebar。先把activebar中常量定义到instance变量,这样就省得每次找帮助来看1、2、3…对应的含义啦,举例如下:
//captionpostion
int ddcpstandard = 0 , &
ddcpleft = 1 , &
ddcpright = 2 , &
ddcpabove = 3 , &
ddcpbelow = 4 , &
ddcpcenter = 5
//childbandfont3d
int dd3dnone = 0 , &
dd3draisedlight = 1 , &
dd3draisedheavy = 2 , &
dd3dinsetlight = 3 , &
dd3dinsetheavy = 4
在pb中,对于activebar的对象band及tool一律视为oleobject。例如我们要写一个函数,目的是让activebar可以动态增加一个band,我们可以在u_activebar中创建如下函数:
/*------------------------------------------------------------------------------
function: public u_activebar.uf_addband
returns: oleobject
parameters: value string name
value string caption
value integer dockingarea
value integer grabhandlestyle
description:
--------------------------------------------------------------------------------
2005-04-12 2.0.0 initial version by cuixuf (mail:[email protected])
------------------------------------------------------------------------------*/
oleobject lobj_band
lobj_band = create oleobject
lobj_band = ole_1.object.bands.add(name)
lobj_band.caption = caption
lobj_band.childbandstyle = ddcbsslidingtabs
lobj_band.dockingarea = dockingarea
lobj_band.grabhandlestyle = grabhandlestyle
return lobj_band
类似的,我们可以通过userobject的函数把activebar需要用到的方法和属性集成到一起,在这里我就不多说了。大家可以看一下我做的u_activebar,我集成了一些函数,但没有做全,如有人有兴趣的话,可以帮我补全,只是不要忘了发给我一份哦。
不过,不要开心得太早,我们用activebar时可能最头痛的地方就是在动态生成tool时调用setpicture方法。activebar中的帮助是这么写的:
[form!]tool.setpicture index as imagetypes, picture as picture, [ color as color ]
pb中是没有picture类型的,用blob取文件内容再赋值经过测试也不行,但是我们可以想到vb中有种数据类型就是picture,只好曲线救国,利用vb写个ocx返回picture类型让pb调用。vb中的ocx写法也很简单,如下:
public function getpict (byval strfilename as string) as object
dim x as picture
set x = loadpict (strfilename)
set getpicture = x
end function
生成ocx后,注册,并添加此ole到u_activebar中,名称为ole_2,设为invisible。u_activebar中uf_addtool函数示例如下:
/*------------------------------------------------------------------------------
function: public u_activebar.uf_addtool
returns: oleobject
parameters: value integer id
value string name
value string caption
value integer cposition
value string category
value integer controltype
value string picture
value integer toolstyle
value string tagvariant
description:
--------------------------------------------------------------------------------
2005-04-12 2.0.0 initial version by cuixuf (mail:[email protected])
------------------------------------------------------------------------------*/
oleobject lobj_tool
lobj_tool = create oleobject
lobj_tool = ole_1.object.tools.add(id, name)
lobj_tool.caption = caption
lobj_tool.captionposition = cposition
lobj_tool.category = category
lobj_tool.controltype = controltype
lobj_tool.style = toolstyle
lobj_tool.tagvariant = tagvariant
oleobject lobj_pic
lobj_pic = ole_2.object.getpict(picture)
lobj_tool.setpicture(dditnormal, lobj_pic )
return lobj_tool
ok,我们做完u_activebar后,现在开始来使用它了。我们做一个用activebar设计器做一个frame.tb2,只有一个status的band,其它的都不做,我们进行动态创建其它的对象。
在w_frame的open事件里写如下代码:
string ls_level1[]={"测试1","测试2","测试3"}, &
ls_level2_1[] = {"恭喜发财","万事如意","心想事成"}, &
ls_level2_2[] = {"hello","world","my god"}, &
ls_level2_3[] = {"嘻嘻","哈哈","关于"}
long i, &
j
oleobject lobj_band, &
lobj_childband, &
lobj_tool
ii_uniqueid = -1
//状态栏
uo_1.uf_load('',"frame.tb2",1 )
uo_1.uf_setstatuscaption( "status", "designer", "...---... qq:21417511" )
uo_1.uf_setstatuscaption( "status", "operater", "用户: cuixuf")
//outlook
lobj_band = uo_1.uf_addband( "outlook", "工具栏", dddaleft, ddgsnone)
uo_1.uf_setfont3d( lobj_band, dd3dinsetlight )
lobj_band.childbands.backcolor = rgb(58,110,165)
lobj_band.childbands.childbandbackgroundstyle = 0 //0:normal,1:gradient,2:picture
lobj_band.childbands.childbandcaptionalignment = 1 //0:left,1:center,2:right
lobj_band.childbands.forecolor = rgb(0,0,0)
lobj_band.childbands.toolforecolor = rgb(255,255,255)
uo_1.uf_removeflag( lobj_band, ddbfdocktop)
uo_1.uf_removeflag( lobj_band, ddbfdockbottom)
uo_1.uf_removeflag( lobj_band, ddbfdockright)
uo_1.uf_removeflag( lobj_band, ddbffloat)
uo_1.uf_removeflag( lobj_band, ddbfcustomize)
uo_1.uf_removeflag( lobj_band, ddbfhide)
//add tool
for i = 1 to upperbound(ls_level1)
lobj_childband = uo_1.uf_addchildband( lobj_band, ls_level1[i], ls_level1[i] )
choose case i
case 1
for j = 1 to upperbound(ls_level2_1)
// uo_1.uf_addtool( /*integer id*/, /*string name*/, /*string caption*/, /*integer cposition*/, /*string category*/, /*integer controltype*/, /*string picture*/, /*integer toolstyle*/, /*string tagvariant */)
lobj_tool = uo_1.uf_addtool( wf_getuniqueid(ii_uniqueid), ls_level2_1[j], ls_level2_1[j], ddcpbelow, ls_level1[i], ddttbutton, "find.ico", ddsicontext, ls_level2_1[j])
uo_1.uf_inserttool( lobj_childband, ii_uniqueid )
next
case 2
for j = 1 to upperbound(ls_level2_2)
lobj_tool = uo_1.uf_addtool( wf_getuniqueid(ii_uniqueid), ls_level2_2[j], ls_level2_2[j], ddcpbelow, ls_level1[j], ddttbutton, "find.ico", ddsicontext, ls_level2_2[j])
uo_1.uf_inserttool( lobj_childband, ii_uniqueid )
next
case 3
for j = 1 to upperbound(ls_level2_3)
lobj_tool = uo_1.uf_addtool( wf_getuniqueid(ii_uniqueid), ls_level2_3[j], ls_level2_3[j], ddcpbelow, ls_level1[j], ddttbutton, "find.ico", ddsicontext, ls_level2_3[j])
uo_1.uf_inserttool( lobj_childband, ii_uniqueid )
next
case else
end choose
next
//resize u_activebar
uo_1.uf_resize( this.workspacewidth( ) - 10 , this.workspaceheight( ) , mdi_1 )
uo_1.uf_resize( this.workspacewidth( ) , this.workspaceheight( ) , mdi_1 )
为了在w_frame变化窗口大小时activebar及mdi窗口能随之变化,w_frame的resize事件中写:uo_1.uf_resize( newwidth,newheight,mdi_1)
接下来,我们可以写一个函数f_menu,放在activebar的toolclick事件里,我封装在u_activebar的ue_toolclick上,根据activebar的tool tag来进行不同的工作。
这样,一个用activebar动态创建outlook的小例子就差不多完工了。我们在实际应用中,可以在数据库中建表存储menu对应的模块id号、模块名称、窗口名称、icon图标等等信息,结合动态生成menu的方法(关于动态生成menu,可以参照汽球的blog,嘻嘻),用户通过自己的权限将获得不同的模块,从而动态生成属于不同用户的outlook框架。
这是我第一次写东东,要特别感谢杨小宝做的取picture字段的ocx。另外,如果有说得不清楚的地方或者需要讨论的事宜,请与我联系:) mail:[email protected],qq:21417511。