回调函数:轻松使用自己的回调函数

     回调个很有用也很重要概念当发生某种事件时系统或其他将会自动你定义回调在windows编程使用场合很多比如Hook回调:MouseProc,GetMsgProc以及EnumWindows,DrawState回调等等还有很多系统级回调过程本文不准备介绍这些和过程而是谈谈实现自己回调些经验



     的所以产生使用回调这个想法现在使用VC和Delphi混合编程用VC写个DLL进行些时间比较长异步工作工作完成的后需要通知使用DLL应用:某些事件已经完成,请处理事件后续部分开始想过使用同步对象文件影射消息等实现DLL到应用通知后来突然想到可不可以在应用端先写等需要处理后续事宜时候在DLL里直接这个即可

   

      于是就动手写了个回调原形在VC和 Delphi里都进行了测试



:声明回调类型

       vc版

              typedef (WINAPI *PFCALLBACK)( Param1, Param2) ;



       Delph版

              PFCALLBACK = function(Param1:eger;Param2:eger):eger;stdcall;



       实际上是声明了个返回值为,传入参数为两个指向指针

       由于C和PASCAL编译器对参数入栈和返回处理有可能不类型用WINAPI(WINAPI宏展开就是__stdcall)或stdcall统修饰



2:声明回调原形



       声明原形

      vc版

                WINAPI CBFunc( Param1, Param2);

  

      Delphi版

          function CBFunc(Param1,Param2:eger):eger;stdcall;

           

        

      以上为全局如果要使用个类里作为回调原形把该类声明为静态即可





3: 回调



         回调我把它放到了DLL里这是个很简单VC生成WIN32 DLL.并使用DEF文件输出其名 TestCallBack实现如下:



              PFCALLBACK  gCallBack=0;



            void WINAPI TestCallBack(PFCALLBACK Func)

           {

                  (FuncNULL);

                  gCallBack=Func;

                  DWORD ThreadID=0;



                  HANDLE hThread = CreateThread(

                                                                    NULL,

                                                                         NULL,

                                Thread1,

                             LPVOID(0),

                                                                         &ThreadID

                                                                          );

                   ;

             }

      此工作把传入 PFCALLBACK Func参数保存起来等待使用并且启动个线程声明了指针PFCALLBACK gCallBack保存传入地址





4: 回调如何被使用:

            

         TestCallBack启动了个线程作为演示线程人为进行了延时处理并且把线程运行过程打印在屏幕上.

本段线程代码也在DLL工程里实现



      ULONG  WINAPI Thread1(LPVOID Param)

     {



             TCHAR Buffer[256];

             HDC hDC = GetDC(HWND_DESKTOP);

              Step=1;

             MSG Msg;

              DWORD StartTick;

        //个延时循环

             for(;Step<200;Step)

             {

                        StartTick = GetTickCount;

                  /*这段为线程交出部分运行时间以让系统处理其他事务*/

                       for(;GetTickCount-StartTick<10;)

                         {

                                 (PeekMessage(&Msg,NULL,0,0,PM_NOREMOVE) )

                                 {

                                   TranslateMessage(&Msg);

                                   DispatchMessage(&Msg);

                                   }

                           }                                

                      /*把运行情况打印到桌面这是vcbear调试时最喜欢干事情*/

           sprf(Buffer,"Running %04d",Step);

                         (hDC!=NULL)

                                  TextOut(hDC,30,50,Buffer,strlen(Buffer));

                   }



                /*延时段时间后回调*/  

                (*gCallback)(Step,1);



                 /*结束*/

                   ::ReleaseDC (HWND_DESKTOP,hDC);

                   0;

      }



   

5:万事具备

        使用vc和Delphi各建立了个工程编写回调实现部分

       VC版

      WINAPI CBFunc( Param1, Param2)

       {

                res= Param1+Param2;

             TCHAR Buffer[256]="";

            sprf(Buffer,"callback result = %d",res);

            MessageBox(NULL,Buffer,"Testing",MB_OK);  //演示回调

              res;            

       }   



         Delphi版

          function CBFunc(Param1,Param2:eger):eger;

          begin

                  result:= Param1+Param2;

                  TForm1.Edit1.Text:=tostr(result);    / /演示回调

           end;

        

       使用静态连接思路方法连接DLL里出口 TestCallBack,在工程里添加 Button( 对于Delphi工程还需要在Form1上放个EditControl控件默认名为Edit1)

        响应ButtonClick事件 TestCallBack



              TestCallBack(CBFunc) //参数CBFunc为回调地址



        创建线程后立刻返回应用可以同时干别事情去了现在可以看到屏幕上不停显示表示dll里创建线程运行正常会的后线程延时部分结束结束vc应用弹出MessageBox,表示回调并显示根据Param1Param2运算结果DelphieditControl控件里文本则被改写成Param1Param2 运算结果

     

      可见使用回调编程模式可以根据区别需求传递区别回调地址或者定义各种回调原形(同时也需要改变使用回调参数和返回值约定)实现多种回调事件处理可以使控制灵活多变也是种高效率清晰模块的间耦合方式些异步或复杂系统里尤其有用 -- 你可以在个模块(如DLL)里专心实现模块核心业务流程和技术功能外围扩展功能只给出个回调接口通过其他模块传递过来回调地址方式将后续处理无缝地交给另个模块随它按自定义方式处理

 

      本文例子使用了在DLL里多线程延时后回调方式只是为了突出下回调效果其实只要是在本进程的内都可以随你高兴可以把地址传递来传递去当成回调使用

 

       这样编程模式原理非常简单单:就是把也看成个指针个地址来没有什么别复杂东西仅仅是编程里个小窍门技巧至于回调模式究竟能为你带来多少好处就看你是否使用如何使用这种编程模式了
Tags:  vc回调函数 windows回调函数 什么是回调函数 回调函数

延伸阅读

最新评论

发表评论