用户名: 密码: 验证码: gdcode 注册

Powerbuilder中利用API实现动画特效

时间:2007-06-15 来源: 作者: 【字体: 减小 增大点击: 收藏 | 投稿
  

  一、问题的提出

  Powerbuilder是一个面向对象的开发大型数据库的图形化的前端开发工具,其优异的性能越来越受到广大开发人员的欢迎。然而,在绘图方面却显不足。其图片的显示是主要靠picture控件来完成的,由于不象cbuilder等工具那样具有画布功能,要实现动画特效,单靠Picture控件本身的属性与方法来实现,只能完成基本的、简单的动画,且效果不理想,容易产生闪烁现象。我们在开发中为了较好的实现动画特效,调用了WindowsAPI函数,结果不仅克服了闪烁现象,而且还能实现较复杂的动画功能。

  二、设计思想

  我们知道windows图形设备接口为windows应用程序提供了屏幕及打印机的设备无关接口,而windows为应用程序提供设备无关性所使用的基本工具是设备描述表〔DC〕。为了显示位图,要将位图加到显示器设备描述表上。程序通常不能直接在设备描述表上绘图,用CreateCompatibleDC函数创建与指定设备兼容的内存设备描述表,每当程序使用位图时,程序首先把位图放在内存设备描述表中,然后再拷贝到指定的设备描述表中。 财软联盟.fs119.net

  那幺我们如何应用上述原理来实现powerbuilder中的动画特效呢﹖由于在Powerbuilder中位图图片是由picture控件来显示的,只要用获取设备描述表的函数GetDC来取得picture控件的设备描述表,再将与其兼容的内存设备描述表中的位图通过Bitblt、StretchBlt函数将图象按一定的增加量从小到大分多步拷贝到picture设备描述表中,在加以时间延迟,便形成动画特效。

  三、所涉及的WindowsAPI函数

  API函数在Powerbuilder下的声明如下:

  1〕functionuintGetDC(uinthwnd)library"c:\windows\system\user32.dll"//取得一个显示器设备描述表。参数hwnd标识将绘图的窗口的句柄。若成功,则返回指定窗口的设备描述表,若失败,则返回为NULL。

  2〕functionlongBitBlt(uinthdcdest,intxdest,intydest,intwdest,inthdest,uinthdcsrc,intxsrc,intysrc,ulongdwrop)library"c:\windows\system\gdi32.dll"//将源设备描述表中的图片转移到目的设备描述表中。参数hdcdest标识图象转移的目的DC,xdest和ydest标识目的DC的位置,wdest和hdest标识图象的宽度与高度,hwndsrc标识图象转移的来源DC,xsrc和ysrc标识来源DC的位置,dwrop标识图象转移方式。若成功返回值为0,若失败返回值为非零。 财.管家园.fs119.net

  3〕functionlongStretchBlt(uinthddest,intxdest,intydest,intwdest,inthdest,uinthdsrc,intxsrc,intysrc,intwsrc,inthsrc,ulongdwrop)library"c:\windows\system\gdi32.dll"//将源设备描述表中的图片放大、缩小、翻转、转移到目的设备描述表中。参数意义同BitBlt中的参数意义相同,多出的wsrc和hsrc为来源图象的宽度与高度。

  4〕functionulongReleaseDC(ulonghwnd,ulonghdc)library"c:\windows\system\user32.dll"//将由GetDC取得的设备描述表释放掉。参数hwnd标识窗口,hdc标识ReleaseDC将释放的设备描述表,若释放成功则返回1,若释放失败则返回0。

  5〕functionulongCreateCompatibleDC(ulonghdc)library"c:\windows\system\gdi32.dll"//创建一个与hdc兼容的内存设备描述表。参数hdc标识设备描述表。若创建成功,则返回内存设备描述表,若创建失败,则返回为NULL。

  6〕functionulongDeleteDC(ulonghdc)library"c:\windows\system\gdi32.dll"//将由CreateCompatibleDC建立的DC释放掉。参数hdc为设备描述表的句柄。若成功则返回值为非零,若失败则返回值为0。 财软联.盟.fs119.net

  7〕functionulongSelectObject(ulonghdc,ulonghobject)library"c:\windows\system\gdi32.dll"//将一个已建立好的对象选入到指定的设备描述表中。参数hdc标识DC的句柄,hobject为对象的句柄。返回值为DC之中前一个同类型对象的句柄。

  8〕functionulongDeleteObject(ulonghobject)library"c:\windows\system\gdi32.dll"//删除一个位图、花色对象。参数hobject为对象的句柄。若成功则返回值为非零,若失败则返回值为0。

  9〕functionulongLoadImageA(ulonghintance,refstringfilename,uintutype,intwidth,intheight,uintfload)library"c:\windows\system\user32.dll"//装入一个位图、图标、光标。参数hintance为装有图象的实例的句柄,若装入一OEM图象,此参数置为0,filename为图象的名字或定义,utype为装入图象的类型,width和height为装入时希望的图象的宽度与高度,fload为装入时的标志。若成功,返回值为最近装入图象的句柄,若失败,返回值为NULL。 财 软联盟 fs119.net

财管家园 fs119.net

财管家园.fs119.net


财.管家园.fs119.net

财软联 盟 fs119.net

  四、设计举例

  笔者设计的动画特效包括图片的逐渐放大和图片的翻转两大功能。

  我们在窗口上放一个tab控件,在tab控件上分图象放大与图象翻转两个tab标签页。

  在图象放大tab标签页,有一单行编辑器〔显示选择图片的路径与名称〕、一个picture控件、一个选择图片按钮〔用于选择显示的图片〕,另外就是从左上向右下、从左下向右上、从右上向左下、从右下向左上、从左向右、从右向左、从上向下、从下向上、从中央向四周九个功能按钮。

  在图片翻转tab标签页上,有三个单行编辑器〔显示选择的背景图片、正面图片、背面图片的路径与名称〕、一个选择背景图片按钮、一个选择正面图片按钮、一个选择背面图片按钮、一个picture控件、一个翻转按钮。

  在这里假定窗口上picture控件的宽为width,高为height。

财管家.园.fs119.net



  1.图片逐渐放大

  将要显示的图片从小到大依次延迟复制到picture控件中,直到占据整个控件为止。

  以从左上角向右下角放大为例:先将要显示的图片放入内存DC(设备环境)中,再依次延时将尺寸为1/8width*1/8height,2/8width*2/8height,3/8width*3/8height,4/8width*4/8height,5/8width*5/8height,6/8width*6/8height,7/8width*7/8height,整个控件大小的8幅图片复制到picture控件DC中即可。代码如下:

财管,家园,fs119.net

inti,i1,dx,dy,pixelwidth,pixelheight,xz,yz,div,mode
uinthdc,hpicture
ulongscrcopy,hmdc
stringpicname
div=8//图片描绘的次数
mode=16//代表从指定的文件装入图片
p_2.picturename=""
picname=trim(sle_1.text)//sle_1.text中为要显示的图片的文件名
scrcopy=13369376//代表图片转移时的操作方式为覆盖
pixelwidth=UnitsToPixels(p_2.width,XUnitsToPixels!)//将picture控件在pb下的宽度转换为以象素为单位的宽度
pixelheight=UnitsToPixels(p_2.height,yUnitsToPixels!)//将picture控件在pb下的高度转换为以象素为单位的高度
dx=pixelwidth/div
dy=pixelheight/div
hdc=GetDC(handle(p_2))//取得p_2控件的DC
hpicture=LoadImageA(0,picname,0,pixelwidth,pixelheight,mode)//将图片以宽度pixelwidth高度pixelheight的尺寸装入内存
hmdc=CreateCompatibleDC(hdc)//创建与hdc兼容的内存设备描述表hmdc

财软联盟 fs119.net

SelectObject(hmdc,hpicture)//将位图对象选入hmdc
fori=1todiv
xz=0
yz=0
StretchBlt(hdc,xz,yz,dx*i,dy*i,hmdc,0,0,pixelwidth,pixelheight,scrcopy)//将左上角坐标为〔0,0〕,宽度为pixelwidth,高度为pixelheight的hmdc的图象转移到左上角坐标为〔xz,yz〕宽度为dx*I,高度为dy*I的hdc中
fori1=1to20000//用于延迟时间
next
next
ReleaseDC(0,hdc)
DeleteDC(hmdc)
DeleteObject(hpicture)

p_2.picturename=picname//注意此句可防止点击图片时,图象从picture控件中消失 财软联盟,fs119.net


  其它几种放大方式与此类似,只要注意改变源设备描述表中图象的左上角的坐标、高度、宽度即可。限于篇幅,在此省略。

  2.图片翻转特效

  1)将背景图片放入内存DC(hmdc)中,正面图片放入内存DC(hmdc1)中,依次将正面图片以大小为整个控件、7/8width*7/8height,6/8width*6/8height,5/8width*5/8height,4/8width*4/8height,3/8width*3/8height,2/8width*2/8height,1/8width*1/8height、零尺寸覆盖到存放背景图片的hmdc中,再从hmdc中复制到picture控件DC中。

  2)将背景图片放入内存DC(hmdc)中,背面图片放入内存DC(hmdc1)中,依次将背面图片以大小为零、1/8width*1/8height,2/8width*2/8height,3/8width*3/8height,4/8width*4/8height,5/8width*5/8height,6/8width*6/8height,7/8width*7/8height,整个控件的尺寸覆盖到存放背景图片的hmdc中,再从hmdc中复制到picture控件DC中。

财软联盟.fs119.net

财管家,园,fs119.net

财 软联盟 fs119.net


财软,联盟,fs119.net

财管家,园,fs119.net

  代码如下:

财软联.盟.fs119.net

inti,i1,dx,dy,pixelwidth,pixelheight,xz,yz,div,mode,diff
uinthdc,hpicture,hback
ulongscrcopy,hmdc,hmdc1
stringpicname,picname1,back
div=8
mode=16
p_1.picturename=""
picname=trim(sle_3.text)//sle_3.text中为正面图片的文件名
picname1=trim(sle_4.text)//sle_4.text中为背面图片的文件名
back=trim(sle_2.text)//sle_2.text中为背景图片的文件名
scrcopy=13369376
pixelwidth=UnitsToPixels(p_1.width,XUnitsToPixels!)
pixelheight=UnitsToPixels(p_1.height,yUnitsToPixels!)
dx=pixelwidth/div
dy=pixelheight/div
hdc=GetDC(handle(p_1))
hpicture=LoadImageA(0,picname,0,pixelwidth,pixelheight,mode)//装入正面图片
hmdc=CreateCompatibleDC(hdc)
SelectObject(hmdc,hpicture)
diff=dx/2
fori=0todiv
hback=LoadImageA(0,back,0,pixelwidth,pixelheight,mode)//装入背景图片hmdc1=CreateCompatibleDC(hdc) 财软,联盟,fs119.net
SelectObject(hmdc1,hback)
StretchBlt(hmdc1,diff*i,0,pixelwidth,diff*i*2,pixelheight,hmdc,0,0,pixelwidth,pixelheight,scrcopy)//将正面图片与背景图片在背景图片DC中进行"复制"操作
BitBlt(hdc,0,0,pixelwidth,pixelheight,hmdc1,0,0,scrcopy)//将hmdc1中的合成图片转移到picture控件的hdc中
DeleteDC(hmdc1)
DeleteObject(hback)
fori1=1to15000
next
next
DeleteDC(hmdc)
DeleteObject(hpicture)
hpicture=LoadImageA(0,picname1,0,pixelwidth,pixelheight,mode)//装入背面图片
hmdc=CreateCompatibleDC(hdc)
SelectObject(hmdc,hpicture)
fori=divto0step-1
hback=LoadImageA(0,back,0,pixelwidth,pixelheight,mode)
hmdc1=CreateCompatibleDC(hdc)
SelectObject(hmdc1,hback)
StretchBlt(hmdc1,diff*i,0,pixelwidth,diff*i*2,pixelheight,hmdc,0,0,pixelwidth,pixelheight,scrcopy)//将背面图片与背景图片在背景图片Dc中进行"与复制"操作
BitBlt(hdc,0,0,pixelwidth,pixelheight,hmdc1,0,0,scrcopy)//将hmdc1中的合成图片转移到picture控件的hdc中 财 软联盟 fs119.net
DeleteDC(hmdc1)
DeleteObject(hback)
fori1=1to15000
next
next
DeleteDC(hmdc)
DeleteObject(hpicture)
ReleaseDC(0,hdc)
p_1.picturename=picname1 财软联盟.fs119.net


  五、结束语

  通过上述方法,我们实现了图片变换时的动画特效,为程序增色不少。

  以上代码在powerbuilder6.0forwindows98下调试通过。

财软 联盟 fs119.net

财软联盟,fs119.net

财 管家园 fs119.net


文章摘自网络,如有侵权,请与我们联系.
数据统计中!!
上一篇:用PowerBuilder6.0建立B/S结构的应用程序
下一篇:用PowerBuilder开发多媒体播放器

精品课程推荐



用户名: 密码: 匿名? 注册