当前位置:首页 > 多媒体相关

利用C++ Builder开发动画DLL



热门问答:
  • 请问,谁用过IdPOP3控件?请进来说明一下怎么使用好吗? [详细内容]
  • 还是数据库的问题 [详细内容]
  • 伙计们,推荐几本.net的经典好书? [详细内容]
  • 请教在职程序员!!! [详细内容]
  • 哪里能找得到异常处理工具? [详细内容]

  • 推荐阅读
      · 充分利用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()

    讨论区

    Login