前往Shuct.Net首页

Shudepb PB反编译专家长时间以来,为业内同类软件事实上的唯一选择.细节,彰显专业.态度,决定品质.

关于PowerBuilder的搜索

中华网--科技频道--网络教室 聊天室 | 搜索引擎 | 个人主页 | 中华论坛 | 电子杂志 | 电子商务 | 电子邮件 --特色服务-- 缘分的天空 网上医院 在线炒股 网上求职 积分大奖 游戏归谷 清风围棋 手机上网 下载基地 桌面壁纸 电子贺卡 ·精彩论坛 ·E网情深 ·聊天无限 主页 新闻 体育 游戏 文化 教育 健康 财经 科技 旅游 军事 娱乐 商贸 科技动态 硬件广场 下载基地 网络教室 网络冲浪 科学博览 移动时代 手机上网 桌面壁纸 科技商情 PowerBuilder中利用Window API实现图片的动画特效 2000-08-31 11:32:15 摘要:本文通过在PowerBuilder中调用Windows API函数,实现任意图片的放大及任意图片从正面逐渐翻转到背面的功能关键字:内存设备描述表 显示器设备描述表 API一、问题的提出PowerBuilder是一个面向对象的开发大型数据库的图形化的前端开发工具,其优异的性能越来越受到广大开发人员的欢迎。然而,在绘图方面却显不足。其图片的显示是主要靠picture控件来完成的,由于不象c++builder等工具那样具有画布功能,要实现动画特效,单靠Picture 控件本身的属性与方法来实现,只能完成基本的、简单的动画,且效果不理想,容易产生闪烁现象。我们在开发中为了较好的实现动画特效,调用了Windows API函数,结果不仅克服了闪烁现象,而且还能实现较复杂的动画功能。二、设计思想我们知道windows图形设备接口为windows应用程序提供了屏幕及打印机的设备无关接口,而windows为应用程序提供设备无关性所使用的基本工具是设备描述表(DC)。为了显示位图,要将位图加到显示器设备描述表上。程序通常不能直接在设备描述表上绘图,用CreateCompatibleDC函数创建与指定设备兼容的内存设备描述表,每当程序使用位图时,程序首先把位图放在内存设备描述表中,然后再拷贝到指定的设备描述表中。那么我们如何应用上述原理来实现PowerBuilder中的动画特效呢?由于在PowerBuilder中位图图片是由picture控件来显示的,只要用获取设备描述表的函数GetDC来取得picture控件的设备描述表,再将与其兼容的内存设备描述表中的位图通过Bitblt、StretchBlt函数将图象按一定的增加量从小到大分多步拷贝到picture设备描述表中,在加以时间延迟,便形成动画特效。三、所涉及的Windows API函数API函数在PowerBuilder下的声明如下:1) function uint GetDC(uint hwnd) library "c:\windows\system\user32.dll"//取得一个显示器设备描述表。参数hwnd标识将绘图的窗口的句柄。若成功,则返回指定窗口的设备描述表,若失败,则返回为NULL。2) function long BitBlt(uint hdcdest,int xdest,int ydest,int wdest,int hdest,uint hdcsrc,int xsrc,int ysrc,ulong dwrop) library "c:\windows\system\gdi32.dll"//将源设备描述表中的图片转移到目的设备描述表中。参数hdcdest标识图象转移的目的DC,xdest和ydest标识目的DC的位置,wdest和hdest标识图象的宽度与高度,hwndsrc标识图象转移的来源DC,xsrc和ysrc标识来源DC的位置,dwrop标识图象转移方式。若成功返回值为0,若失败返回值为非零。3) function long StretchBlt(uint hddest,int xdest,int ydest,int wdest,int hdest,uint hdsrc,int xsrc,int ysrc,int wsrc,int hsrc,ulong dwrop) library "c:\windows\system\gdi32.dll"//将源设备描述表中的图片放大、缩小、翻转、转移到目的设备描述表中。参数意义同BitBlt中的参数意义相同,多出的wsrc和hsrc为来源图象的宽度与高度。4) function ulong ReleaseDC(ulong hwnd,ulong hdc) library "c:\windows\system\user32.dll" //将由GetDC取得的设备描述表释放掉。参数hwnd标识窗口,hdc标识ReleaseDC将释放的设备描述表,若释放成功则返回1,若释放失败则返回0。5) function ulong CreateCompatibleDC(ulong hdc) library "c:\windows\system\gdi32.dll"//创建一个与hdc兼容的内存设备描述表。参数hdc标识设备描述表。若创建成功,则返回内存设备描述表,若创建失败,则返回为NULL。6) function ulong DeleteDC(ulong hdc) library "c:\windows\system\gdi32.dll"//将由CreateCompatibleDC建立的DC释放掉。参数hdc为设备描述表的句柄。若成功则返回值为非零,若失败则返回值为0。7) function ulong SelectObject(ulong hdc ,ulong hobject) library "c:\windows\system\gdi32.dll"//将一个已建立好的对象选入到指定的设备描述表中。参数hdc标识DC的句柄,hobject为对象的句柄。返回值为DC之中前一个同类型对象的句柄。8) function ulong DeleteObject(ulong hobject) library "c:\windows\system\gdi32.dll"//删除一个位图、花色对象。参数 hobject为对象的句柄。若成功则返回值为非零,若失败则返回值为0。9) function ulong LoadImageA(ulong hintance, ref string filename,uint utype,int width,int height,uint fload) library "c:\windows\system\user32.dll"//装入一个位图、图标、光标。参数hintance为装有图象的实例的句柄,若装入一OEM图象,此参数置为0,filename为图象的名字或定义,utype为装入图象的类型,width和height为装入时希望的图象的宽度与高度,fload为装入时的标志。若成功,返回值为最近装入图象的句柄,若失败,返回值为NULL。四、设计举例笔者设计的动画特效包括图片的逐渐放大和图片的翻转两大功能。我们在窗口上放一个tab控件,在tab控件上分图象放大与图象翻转两个tab标签页。在图象放大tab标签页,有一单行编辑器(显示选择图片的路径与名称)、一个picture控件、一个选择图片按钮(用于选择显示的图片),另外就是从左上向右下、从左下向右上、从右上向左下、从右下向左上、从左向右、从右向左、从上向下、从下向上、从中央向四周九个功能按钮。在图片翻转tab标签页上,有三个单行编辑器(显示选择的背景图片、正面图片、背面图片的路径与名称)、一个选择背景图片按钮、一个选择正面图片按钮、一个选择背面图片按钮、一个picture控件、一个翻转按钮。在这里假定窗口上picture控件的宽为width,高为height。1. 图片逐渐放大将要显示的图片从小到大依次延迟复制到picture控件中,直到占据整个控件为止。以从左上角向右下角放大为例:先将要显示的图片放入内存DC(设备环境)中,再依次延时将尺寸为1/8 width *1/8 height,2/8 width *2/8 height,3/8 width *3/8 height,4/8 width *4/8 height,5/8 width *5/8 height,6/8 width *6/8 height,7/8 width *7/8 height,整个控件大小的8幅图片复制到picture控件DC中即可。代码如下: int i,i1,dx,dy,pixelwidth,pixelheight,xz,yz,div,modeuint hdc,hpictureulong scrcopy,hmdcstring picnamediv=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/divdy=pixelheight/divhdc=GetDC(handle(p_2))//取得p_2控件的DChpicture=LoadImageA(0,picname,0,pixelwidth,pixelheight,mode)//将图片以宽度pixelwidth高度pixelheight的尺寸装入内存hmdc=CreateCompatibleDC(hdc)//创建与hdc兼容的内存设备描述表hmdcSelectObject(hmdc,hpicture)//将位图对象选入hmdcfor i=1 to divxz=0yz=0StretchBlt(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中for i1=1 to 20000//用于延迟时间nextnextReleaseDC(0,hdc)DeleteDC(hmdc)DeleteObject(hpicture)p_2.picturename=picname//注意此句可防止点击图片时,图象从picture控件中消失其它几种放大方式与此类似,只要注意改变源设备描述表中图象的左上角的坐标、高度、宽度即可。限于篇幅,在此省略。2. 图片翻转特效1)将背景图片放入内存DC(hmdc)中,正面图片放入内存DC(hmdc1)中,依次将正面图片以大小为整个控件、7/8 width *7/8 height,6/8 width *6/8 height,5/8 width *5/8 height,4/8 width*4/8 height,3/8 width *3/8 height,2/8 width *2/8 height,1/8 width *1/8 height、零尺寸覆盖到存放背景图片的hmdc中,再从hmdc中复制到picture控件DC中。2) 将背景图片放入内存DC(hmdc)中,背面图片放入内存DC(hmdc1)中,依次将背面图片以大小为零、1/8 width *1/8 height,2/8 width *2/8 height,3/8 width *3/8 height,4/8 width *4/8 height,5/8 width *5/8 height,6/8 width *6/8 height,7/8 width *7/8 height,整个控件的尺寸覆盖到存放背景图片的hmdc中,再从hmdc中复制到picture控件DC中。代码如下:int i,i1,dx,dy,pixelwidth,pixelheight,xz,yz,div,mode,diffuint hdc,hpicture,hbackulong scrcopy,hmdc,hmdc1string picname,picname1,backdiv=8mode=16p_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=13369376pixelwidth=UnitsToPixels(p_1.width,XUnitsToPixels!)pixelheight=UnitsToPixels(p_1.height,yUnitsToPixels!)dx=pixelwidth/divdy=pixelheight/divhdc=GetDC(handle(p_1))hpicture=LoadImageA(0,picname,0,pixelwidth,pixelheight,mode)// 装入正面图片hmdc=CreateCompatibleDC(hdc)SelectObject(hmdc,hpicture)diff=dx/2for i=0 to divhback=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中DeleteDC(hmdc1)DeleteObject(hback)for i1=1 to 15000nextnextDeleteDC(hmdc)DeleteObject(hpicture)hpicture=LoadImageA(0,picname1,0,pixelwidth,pixelheight,mode)// 装入背面图片hmdc=CreateCompatibleDC(hdc)SelectObject(hmdc,hpicture)for i=div to 0 step -1hback=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中DeleteDC(hmdc1)DeleteObject(hback)for i1=1 to 15000nextnextDeleteDC(hmdc)DeleteObject(hpicture)ReleaseDC(0,hdc)p_1.picturename=picname1五、结束语通过上述方法,我们实现了图片变换时的动画特效,为程序增色不少。以上代码在PowerBuilder6.0 for windows98下调试通过。主要参考文献:1)美Kris Jamsa,Lars Klander著 张春晖 刘大庆等译 中国水利水电出版社出版发行的《c/c++程序员实用大全》2)MSDN Library Visual studio 6.0版联机帮助3)何军 刘红岩 主编 电子工业出版社出版发行的《PowerBuilder5.0原理与应用开发指南》   摘自《软件世界》 李淑华 李建东/文 错误提示页 —— china.com 很抱歉,您访问页面时出错 5秒钟之后将会带您进入首页! 科技检索 与 或 标题 全文 关键字 以上全部 中华网推荐 中东战争一触即发 中国军队世纪大演兵 2000亚洲杯专题 前朝字纸博览 网上医院医生超过500名 精选股票天地 闪光的flash教程 产业国际竞争力峰会 中国酒店查询 网络教室编辑信箱 版权声明 | 本站检索 | 联系方法 | 刊登广告 | 使用说明 | 关于中华网 | 豁免条款 版权所有 中华网