PB中用Windows API制作位图菜单
许多优秀的软件在窗口菜单的左边显示一个小图片,例如Word,这种菜单图文并茂,使操作者感到非常直观。而对于PowerBuilder来说,它为应用开发了几百个简单实用地函数,对于一般的开发应用已经足够,并不需要扩展[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]。然而,我们经常希望为最终用户提供一些[url=http://www.bc-cn.net/Article/sjk/pb/Index.html]PowerBuilder[/url]并不能提供的功能,例如这种位图菜单,这时我们就需要外部[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]。外部函数是用其他语言编写的并且存储在动态链接库(DLL)中的函数。一个DLL就是一个包含可以执行的Windows代码的文件。DLL在运行时被动 态地装入和链接,并且可被多个应用程序共享。DLL在内存中可以被移动或者固定,可预装入或者命令装入,也可以删除或者永久装入。开发者在使用外部函数之前,必须先对其进行定义,外部函数根据作用域的不同而分为两种类型:全局外部函数与局部外部[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]。在[url=http://www.bc-cn.net/Article/sjk/pb/Index.html]PowerBuilder[/url]中定义外部函数的语法相当简单,定义函数时根据有无返回值分别使用两种关键字:FUNCTION([url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url])和SUBROUTINE(子程序)。
在PowerBuilder中,我们也可以通过Windows API函数来实现此项功能,利用Windows API[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]能够实现许多[url=http://www.bc-cn.net/Article/sjk/pb/Index.html]PowerBuilder[/url]不能实现的功能。
下面通过一个实例来叙述如何通过Windows API[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]实 现位图菜单。在本实例中,假设在创建一个应用对象Application之后,再分别创建一个菜单对象m_main和窗口对象w_main。在菜单对象 m_main中有如下菜单项:File/New、File/Open、File/Save、File/Exit、Edit/Copy、Edit/Cut、 Edit/Paste和Edit/Delete。在窗口对象w_main中,将其"Title"[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%CA%F4%D0%D4]属性[/url]设置为"位图菜单",并且将菜单"w_main"关连到窗口"w_main"上。
1)首先为窗口w_main声明局部外部[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]
FUNCTION ulong LoadImageA(ulong hintance, string filename,uint utype, int x,int y,uint fload) & LIBRARY "USER32.DLL"
//该[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]实现装入图象数据的功能
FUNCTION boolean SetMenuItemBitmaps(ulong hmenu,uint upos,uint flags,&
ulong handle_bm1,ulong handle_bm2) LIBRARY "USER32.DLL"
//该[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]设置菜单位图
FUNCTION int GetSystemMetrics( int nIndex ) LIBRARY "USER32.DLL"
//该[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]获取菜单的位图尺寸
FUNCTION ulong GetMenuItemID(ulong hMenu,uint uItem) LIBRARY "USER32.DLL"
//该[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]获取菜单项目的ID号
FUNCTION int GetSubMenu (ulong hMenu,int pos) LIBRARY "USER32.DLL"
//该[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]获取子菜单项的句柄
FUNCTION ulong GetMenu(ulong hWindow) LIBRARY "USER32.DLL"
//该[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]获取应用的菜单项
FUNCTION boolean ModifyMenu(ulong hMnu, ulong uPosition, ulong uFlags, &
ulong uIDNewItem, long lpNewI) alias for ModifyMenuA LIBRARY "USER32.DLL"
//该[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%BA%AF%CA%FD]函数[/url]用来更新菜单项
2)其次为窗口w_main声明实例变量
//Win32常量
CONSTANT Integer IMAGE_BITMAP = 0
CONSTANT Integer LR_LOADFROMFILE = 16
CONSTANT Integer SM_CXMENUCHECK = 71
CONSTANT Integer SM_CYMENUCHECK = 72
CONSTANT Integer MF_BITMAP = 4
CONSTANT Integer MF_BYPOSITION = 1024
3)最后给窗口w_main的Open[url=http://www.bc-cn.net/Article/Search.asp?Field=Title&ClassID=&keyword=%CA%C2%BC%FE]事件[/url]添加脚本
long ll_MainHandle
long ll_SubMenuHandle
integer li_MenuItemID
long ll_X
long ll_Y
long ll_BitmapNew
long ll_BitmapOpen
long ll_BitmapSave
long ll_BitmapExit
long ll_BitmapCopy
long ll_BitmapCut
long ll_BitmapPaste
long ll_BitmapDelete
//取得菜单句柄
ll_MainHandle = GetMenu(Handle(this))
//取得第一个菜单项的句柄
ll_SubMenuHandle = GetSubMenu(ll_MainHandle,0)
//装入图像数据
ll_BitmapNew = LoadImageA(0,'new.bmp',IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
ll_BitmapOpen = LoadImageA(0,'open.bmp',IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
//取得第一个子菜单项的ID并修改菜单
li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,0)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapNew)
//取得第二个子菜单项的ID并修改菜单
li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,1)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapOpen)
//取得菜单缺省check-mark位图的尺寸
ll_x = GetSystemMetrics(SM_CXMENUCHECK)
ll_y = GetSystemMetrics(SM_CYMENUCHECK)
//按系统尺寸装入图像
ll_BitmapSave = LoadImageA(0,'save.bmp', IMAGE_BITMAP ,ll_x,ll_y,LR_LOADFROMFILE)
ll_BitmapExit= LoadImageA(0,'exit.bmp', IMAGE_BITMAP ,ll_x,ll_y,LR_LOADFROMFILE)
//设置菜单位图
SetMenuItemBitmaps(ll_SubMenuHandle,2,MF_BYPOSITION,ll_BitmapSave,ll_BitmapSave)
SetMenuItemBitmaps(ll_SubMenuHandle,3,MF_BYPOSITION,ll_BitmapExit,ll_BitmapExit)
//取得第二个菜单项的句柄
Ll_SubMenuHandle = GetSubMenu(ll_MainHandle,1)
//装入图像数据
ll_BitmapCopy = LoadImageA(0,'copy.bmp',IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
ll_BitmapCut = LoadImageA(0,'cut.bmp',IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
//取得第一个子菜单项的ID并修改菜单
li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,0)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapCopy)
//取得第二个子菜单项的ID并修改菜单
li_MenuItemID = GetMenuItemID(ll_SubMenuHandle,1)
ModifyMenu(ll_SubMenuHandle,li_MenuItemID,MF_BITMAP,li_MenuItemId,ll_BitmapCut)
//取得菜单缺省check-mark位图的尺寸
ll_x = GetSystemMetrics(SM_CXMENUCHECK)
ll_y = GetSystemMetrics(SM_CYMENUCHECK)
//按系统尺寸装入图像
ll_BitmapPaste=LoadImageA(0,'paste.bmp', IMAGE_BITMAP ,ll_x,ll_y,LR_LOADFROMFILE)
ll_BitmapDelete=LoadImageA(0,'delete.bmp', IMAGE_BITMAP ,ll_x,ll_y,LR_LOADFROMFILE)
//设置菜单位图
SetMenuItemBitmaps(ll_SubMenuHandle,2,MF_BYPOSITION,ll_BitmapPaste,ll_BitmapPaste)
SetMenuItemBitmaps(ll_SubMenuHandle,3,MF_BYPOSITION,ll_BitmapDelete,ll_BitmapDelete)
上面的代码知识如何设置File与Edit子菜单项的脚本。至此整个应用程序制作完毕,用户在运行该程序时便可以得到带位图的菜单项,本例在[url=http://www.bc-cn.net/Article/sjk/pb/Index.html]PowerBuilder[/url]7.0中运行通过。如下图显示。
[attach]56193[/attach]
从上面设置菜单位图的脚本中我们可以看到,菜单可以带有两种不同类型的图标:完全位图菜单和文字与位图共存菜单。用户在实际开发中可以根据自己的喜好选择相应的类型。值得注意的是,用户在制作应用程序时,必须提供相应的位图,否则将会出错。 学习
页:
[1]