BaoFu
驱动小牛
驱动小牛
  • 注册日期2002-10-07
  • 最后登录2010-11-25
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望9点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
阅读:1267回复:7

为什么WIN2KAPI中引用回调函数,只用函数名,之后可以没有括号和参数?

楼主#
更多 发布于:2002-11-19 06:04
我最近看win2000API方面的书籍,其中很多例子程序,发现其中的回调函数很特别:该(回调)函数定义的时候明明参数,但在调用这个回调函数的时候,只用了该函数的名字,函数名之后连括号也没有,更不用说带参数了。这和通常的函数调用很不一样。尽管如此,经过试验,这些程序确实能够顺利编译运行。请行家指教。

最新喜欢:

ytoneboyytoneb...
hfyhl
驱动小牛
驱动小牛
  • 注册日期2002-11-08
  • 最后登录2005-10-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-11-19 08:55
回调函数是让系统调用的函数,
一般是有事件发生时,系统来调用,
系统有可能通过其他方式得到参数.
不过,你能不能贴一段例子程序出来
让大家分析分析.
ydyuse
驱动老牛
驱动老牛
  • 注册日期2002-07-25
  • 最后登录2005-03-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-11-19 09:10
引用回调函数只需传函数地址,也就是函数名。
生命驱动,活力无限!
BaoFu
驱动小牛
驱动小牛
  • 注册日期2002-10-07
  • 最后登录2010-11-25
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望9点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-11-19 11:39
这个程序的的作用是设置窗口的大小,其中有个About函数是我要问的问题

以下是头文件,也就是下面的\"Adjwndex.h\"

#define IDM_EXIT           100
#define IDM_TEST           200
#define IDM_ABOUT          301

LRESULT CALLBACK WndProc  (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About    (HWND, UINT, WPARAM, LPARAM);

#include <windows.h>  
#include \"Adjwndex.h\"


HINSTANCE hInst = NULL;   // current instance

LPCTSTR lpszAppName   = \"MyApp\";
LPCTSTR lpszTitle     = \"My Application\";
LPCTSTR lpszClassName = \"My Class\";


BOOL InitAppInstance( HANDLE hInstance )
{
   WNDCLASSEX wc;

   // Register the main application window class.
   //............................................
   wc.style         = CS_HREDRAW | CS_VREDRAW;
   wc.lpfnWndProc   = (WNDPROC)WndProc;      
   wc.cbClsExtra    = 0;                      
   wc.cbWndExtra    = 0;                      
   wc.hInstance     = hInstance;              
   wc.hIcon         = LoadIcon( hInstance, lpszAppName );
   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
   wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
   wc.lpszMenuName  = lpszAppName;              
   wc.lpszClassName = lpszClassName;              
   wc.cbSize        = sizeof(WNDCLASSEX);
   wc.hIconSm       = LoadImage( hInstance, lpszAppName,
                                 IMAGE_ICON, 16, 16,
                                 LR_DEFAULTCOLOR );

   if ( !RegisterClassEx( &wc ) )
      return( FALSE );

   return( TRUE );
}


int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPTSTR lpCmdLine, int nCmdShow)
{
   MSG        msg;
   HWND       hWnd;
   RECT       rect;


   //Register the application class.
   //.................................
   if (  !InitAppInstance( hInstance ) )
      return FALSE;


   hInst = hInstance;

   // Initialize a RECT with the size and position of
   // the client area we want.
   //...................................
   rect.left   = 100; // 100 pixels from the left of the screen.
   rect.top    = 150; // 150 pixels from the top of the screen.
   rect.right  = 200; // The width will be 100 pixels.
   rect.bottom = 200; // The height will be 50 pixels.

   AdjustWindowRectEx( &rect, WS_OVERLAPPEDWINDOW, TRUE, WS_EX_TOOLWINDOW );    

   // Create the main application window.
   //....................................
   hWnd = CreateWindow( lpszClassName,       // Class name registered.
                        \"My Application\",    // Title bar text.
                        WS_OVERLAPPEDWINDOW, // Window style.
                        rect.left,           // Use the rect calculated
                        rect.top,            //   with AdjustWindowRect()
                        rect.right,          //   for the size and
                        rect.bottom,         //   position.
                        NULL,                // No parent.
                        NULL,                // Use class menu.
                        hInstance,          
                        NULL);              

   if ( !hWnd )
      return( FALSE );

   ShowWindow( hWnd, nCmdShow );
   UpdateWindow( hWnd );        

   while( GetMessage( &msg, NULL, 0, 0) )  
   {
      TranslateMessage( &msg );
      DispatchMessage( &msg );  
   }

   return( msg.wParam );
}


LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
   switch( uMsg )  
   {  
      case WM_COMMAND :
              switch( LOWORD( wParam ) )
              {
                 case IDM_ABOUT :
                        DialogBox( hInst, \"AboutBox\", hWnd, (DLGPROC)About );/*注意,这里只有函数About的名字,其定义在下面*/
                        break;

                 case IDM_EXIT :
                        DestroyWindow( hWnd );
                        break;
              }
              break;
      
      case WM_DESTROY :
              PostQuitMessage(0);
              break;

      default :
            return( DefWindowProc( hWnd, uMsg, wParam, lParam ) );
   }

   return( 0L );
}

//但这里在定义的时候,却是有参数的函数。
LRESULT CALLBACK About( HWND hDlg,          
                        UINT message,        
                        WPARAM wParam,      
                        LPARAM lParam)
{
   switch (message)
   {
       case WM_INITDIALOG:
               return (TRUE);

       case WM_COMMAND:                              
               if (   LOWORD(wParam) == IDOK        
                   || LOWORD(wParam) == IDCANCEL)    
               {
                       EndDialog(hDlg, TRUE);        
                       return (TRUE);
               }
               break;
   }

   return (FALSE);
}


系统回调函数可以不用参数也不加括号,其原理是什么呢。能否将这种简便方法用到自己定义的回调函数中?,若可以,如何实现?难道只加上CALLBACK就万事大吉了吗?



[编辑 -  11/19/02 by  BaoFu]
SWLEO
驱动牛犊
驱动牛犊
  • 注册日期2002-10-12
  • 最后登录2003-07-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-11-19 12:59
 关注
多谢指点
hfyhl
驱动小牛
驱动小牛
  • 注册日期2002-11-08
  • 最后登录2005-10-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-11-19 14:22
这里并非调用about函数,
而是注册窗口的消息处理函数,
实际上这个函数是由操作系统来调用的,
他的参数也就是消息,由系统自动传递,
这就是所谓的消息驱动,这些后台工作
你是看不到的拉.
BaoFu
驱动小牛
驱动小牛
  • 注册日期2002-10-07
  • 最后登录2010-11-25
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望9点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-11-19 18:56
楼上所说很有启发,即认为消息就是该函数的参数。由于消息能被整个系统的所有部分利用,所以无须传递---这当然是我的猜测。
   但即使如此,还有个问题没有解决:依据规定,引用函数都要在函数名之后带上括号,这里连括号都不用又是为什么呢?
hfyhl
驱动小牛
驱动小牛
  • 注册日期2002-11-08
  • 最后登录2005-10-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-11-20 04:25
这里仅仅是注册这个回调函数,
不是调用,实际上系统在调用
这个函数的时候会给他参数的.
游客

返回顶部