利用C++ Builder开发动画DLL
热门问答:
推荐阅读
| · 充分利用3300的64m空间存放mp3 |
| 摘要:诺基亚3300买来时只有64m,而一首mp3一般也在3-5m。就算dietmp3软件来压缩,...... |
| · 因宽广所以美丽-宽屏笔记本导购pc导购中心 |
| 摘要: 去年的宽屏幕笔记本电脑的当红,所反馈出的信息笔记本电脑已经逐渐从商务走向娱乐,宽屏的走红究起原因一是16:10的比例比以往传统的在画面上有了不少优势 去年的宽屏幕电脑的当红,所反馈出的信息笔记本电脑已经逐渐从商务走向娱乐,宽屏的走红究起原因一是16:10的比例比以往传统的在画面上有了不少优势,另一个原因就是屏幕笔记本电脑的兴起和上游面板供应有关,比如由于去年液晶面板供应吃紧,15.4寸面板切割较经济,因此不少笔记...... |
正文
p> 我们在windows98环境下执行拷贝文件、查找文件或计算机等耗时比较长的操作时,windows会显示一个小小的动画,指示正在进行的操作,与死板的静止图像相比增色不少。那么我们自己开发软件时,能否也显示一个这样的动画提示呢?我在开发一个外贸应用软件系统时,遇到的数据量很大,当通过复合条件查找时,因为不是数据库表的每个项目都有索引,所以很费时,系统也会表现出长时间停顿,用户感觉极为不爽。我经过一段时间的探索,开发了一个能够在采用的开发环境powerbuilder下调用的动画dll,由于采用多线程编程,pb调用的dll函数能够及时将控制权交还为pb,不影响应用系统的运转。用户能够看到一个东西在动,也就不会想到系统是不是停止响应了,感觉时间也似乎没那么久了。
代码与编译选项
(1).在c++builder的file菜单下选择new,在new item对话框的new属性中选择dll,c++builder就会创建一个空白的dll项目。
(2).在file菜单下选择new form,c++builder创建一个空白的form,修改它的属性为:
borderstyle=bsdialog
bordericons的子属性均为false
formstyle=fsstayontop
position= poscreencenter
name=statusform
(3).在form上添加一个win32下的animate控件animate1,修改它的属性为:
align=altop
(4).在form上添加一个standard下的button控件button_cancel,再添加system下的timer控件timer1,设置定时interval时间位250,以较快的响应用户的取消请求。
因为pb应用系统与动画窗体代码分别属于两个线程,不能采用pb线程直接关闭动画窗体线程的窗口,否则会引起系统运行不正常,因此采用pb线程设置关闭标志,而动画线程采用timer控件定时检查标志,一旦检测到关闭标志,就关闭窗口,清除线程标志,结束动画线程。
下面给出编码及编码原理:
1.dll dll主体代码:
/**********************************
* dll主体代码
* 定义dll公用变量
* g_commonavi
对animate控件动画类型索引
* gi_canceled
button_cancel按钮是否被选择过
* gi_avitype _declspec(dllexport)
int pascal dllentrypoint(hinstance hinst,
unsigned long reason, void*);
extern "c" __declspec(dllexport) int
pascal showstatuswindow(int avitype,
lpstr wintitle,long hwnd);
extern "c" __declspec(dllexport) int
pascal getstatus(int ai_closewin);
extern "c" __declspec(dllexport) int
pascal closestatuswindow();
/*定义线程tformthread:*/
class tformthread : public tthread{
public:// user declarations
__fastcall tformthread(bool createsuspended);
void __fastcall execute(void);
};
__fastcall tformthread::
tformthread(bool createsuspended):
tthread(createsuspended){
}
/* 动画线程执行代码,
动画窗体的定时器控件会关闭它,
清除窗体存在标志后结束线程的运行
*/
void __fastcall tformthread::execute(void){
gi_windowactive=1;
statusform=new tstatusform(null);
statusform- $#@62;caption=lpswintitle;
statusform- $#@62;showmodal();
gi_windowactive=0;
delete statusform;
gi_requestclose=0;
}
/* 定义一个线程实例指针 */
tformthread *formthread;
/**********************************************
* 输出函数代码实现部分
* dllentrypoint 32位dll入口
* showstatuswindow 显示动画窗口,
它通过创建一个线程来创建窗口,避免由于窗口
的modal属性而使控制权不能及时的返还给调用者
* getstatus
取得“取消”状态,即用户有没有选择“取消”按钮
* closestatuswindow 关闭动画窗口,
*/
__declspec(dllexport) int winapi dllentrypoint
(hinstance hinst, unsigned long reason, void*)
{
return 1;
}
__declspec(dllexport) int pascal
showstatuswindow(int avitype,lpstr
wintitle,long hwnd){
hwndparent=(hwnd)hwnd;
memset(lpswintitle,0,sizeof(lpswintitle));
strncpy(lpswintitle,wintitle,sizeof(lpswintitle)-1);
if (avitype $#@62;0 && avitype$#@60; =8)
gi_avitype=avitype;
formthread=new tformthread(true);
formthread- $#@62;priority = tpnormal;
formthread- $#@62;resume();
}
__declspec(dllexport) int pascal
getstatus(int ai_closewin){
if (gi_canceled)
if (gi_windowactive){
gi_requestclose=1;
while(gi_requestclose);
}
return gi_canceled;
}
__declspec(dllexport) int pascal
closestatuswindow(){
if (gi_windowactive){
gi_requestclose=1;
while(gi_requestclose);
}
return gi_canceled;
}
2.窗体statusform的代码:
tstatusform *statusform;
//-----------------------------------
extern int gi_canceled;
extern int gi_avitype;
extern tcommonavi g_commonavi[];
__fastcall tstatusform::
tstatusform(hwnd parentwindow)
: tform(parentwindow)
{
gi_canceled=0;
}
//-----------------------------------
//取消按钮并不直接关闭窗体,
而指示设置取消标志,供调用者查看
void __fastcall tstatusform::
button_cancelclick(tobject *sender)
{
gi_canceled=1;
// modalresult=mrcancel;
}
//-----------------------------------
// 激活动画,在formcreate事件中
void __fastcall tstatusform::
formcreate(tobject *sender)
{
animate1- $#@62;commonavi=g_commonavi[gi_avitype];
animate1- $#@62;active = true;
}
//-----------------------------------
extern int gi_requestclose;
// 定时器事件检测到结束标志关闭窗体
void __fastcall tstatusform::
timer1timer(tobject *sender)
{
if (gi_requestclose){
modalresult=mrok;
}
}
//-----------------------------------
(5) 设置编译选项:project-$#@62;options打开project options对话框,清除linker属性页中的use dynamic rtl标志,清除packages属性页中的build with runtime packages。这样只要单个dll就可以运行了,而不必安装一些动态连接运行时间库。使用动画dll
上面编译出dll可以由其它任何开发语言调用,下面给出在pb中的使用方法。
(1) 定义:
//declare - $#@62; global external functions
function long showstatuswindow(long
avitype,string wintitle,long hwnd) &
library "statwin.dll" alias for "showstatuswindow"
function long getcancelstatus(long closewindow) &
library "statwin.dll" alias for "getstatus"
function long closestatuswindow() &
library "statwin.dll" alias for "closestatuswindow"
(2) 调用:
long ll_endtime
//显示查找文件夹动画
showstatuswindow(2)
setpointer(hourglass!)
ll_endtime = cpu() + 10 * 1000
do
if getcancelstatus(0)=1 then
exit
end if
// 做想做的事情
loop until cpu() $#@62; ll_endtime
closestatuswindow()


讨论区