找回密码
 加入
搜索
查看: 4365|回复: 8

[AU3基础] 回调函数如何调用?

  [复制链接]
发表于 2011-12-29 10:35:31 | 显示全部楼层 |阅读模式
本帖最后由 showshow 于 2011-12-29 10:37 编辑
LRESULT CALLBACK WindowProc(
  HWND   hwnd,    // handle to window
  UINT   uMsg,    // WM_POWERBROADCAST
  WPARAM wParam,  // power-management event
  LPARAM lParam   // function-specific data
);
http://msdn.microsoft.com/en-us/library/windows/desktop/aa373247(v=vs.85).aspx

问题如标题,像上面回调函数该如何调用?
发表于 2012-1-1 09:57:39 | 显示全部楼层
哪位大大指点下啊,感激!
showshow 发表于 2011-12-29 11:17


正好回复前面一个帖子用到了回调函数,我就简单地说明一下
链接:http://www.autoitx.com/thread-28936-2-1.html (上面帖子的24楼)
回调函数是一个非常重要的概念,首先你要能清楚地区分开回调函数和普通函数本质的区别是什么?
简单容易理解来讲,你在你的程序里写了一个回调函数,但这个回调函数却不是你的程序调用的,而是系统(或别的应用程序)来调用它,但系统又如何知道调用你写的回调函数呢,于是就得先‘注册’,也就是先把你写的回调函数地址入口(也就是指针,后面就光说地址了)告诉系统,Au3里由于没有指针的概念,于是比C/C++里多了用DllCallbackRegister()函数来指定那个函数是回调函数(因为在au3里,普通函数/变量/数组等等都无法象C/C++里那样能直接获得地址),然后由DllCallbackGetPtr()函数得到回调函数地址,其参数就是DllCallbackRegister()函数返回值。现在回调函数的地址有了,我们就得把它传递给系统,当系统产生了你在回调函数里用到的事件时,系调就调用你定义的回调函数了

Au3简单的回调函数过程:定义→注册→传递→回调(这里之所以叫‘回’,是相对于前面的‘传递’地址给系统)

具体上面的例子:例子里我首先定义了一个回调函数WindowProc(回调函数的参数格式基本是固定的):
Func WindowProc($hWnd, $iMsg, $wParam, $lParam)
        ....
EndFunc
然后用下面语句来指定(或叫‘注册’)上面的WindowProc函数是个回调函数,而不是普通函数
$hProcA = DllCallbackRegister("WindowProc", "ptr", "hwnd;uint;long;ptr")
下面就是要传递的过程了,例子里用到了下面的语句来做
$hProcB = _WinAPI_SetWindowLong(GUICtrlGetHandle($cInput), $GWL_WNDPROC, DllCallbackGetPtr($hProcA))
其中,$GWL_WNDPROC是重新设置窗口/控件的地址为回调函数的地址,例子里是Input控件,而能重新设置地址的行为是系统,而不是程序本身了,这样就完成了‘注册’的动作。例子里的回调函数定义中还用到了钩子函数_WinAPI_CallWindowProc,它的作用是就截获系统产生的消息,例子里就是三大消息:$WM_RBUTTONDOWN, $WM_CONTEXTMENU, $WM_LBUTTONDOWN,也就是系统在控件Input上当有这三个消息产生时,别按默认方式处理了,而是按回调函数里的自定义方式处理(如:$WM_RBUTTONDOWN消息对Input控件来说有默认的右键菜单)

于是就告诉了系统,当控件Input有相应事件发生时,别按默认方式了,而是把地‘回调’自定义的回调函数来处理

写了这么多,希望你能明白什么是回调函数了。

若你真的明白了,你可以自己写个,试试题目:
一个100元素的数组,其所有的元素都是数字,现在你用回调函数的方法找出第一个元素值大于10的
一般最容易想的方法就是for循环遍历这个数组,然后针对每一个元素进行操作,但这样的最容易想的方法有时就不灵了,如有异步进程修改了这个数组(在内存里修改),就会可能导致你的au3程序直接崩掉

评分

参与人数 3金钱 +80 贡献 +2 收起 理由
Xxkwwz + 20 很给力!
showshow + 10 感谢,乐于助人,很有心!
afan + 50 + 2

查看全部评分

 楼主| 发表于 2011-12-29 11:17:06 | 显示全部楼层
哪位大大指点下啊,感激!
发表于 2011-12-29 11:26:42 | 显示全部楼层
是电源管理消息吗?
发表于 2011-12-29 11:37:50 | 显示全部楼层
我是这样理解的,不知道对不对,测试了下,好像没效果。。。
Global Const $WM_POWERBROADCAST = 0x218

Global Const $PBT_APMPOWERSTATUSCHANGE = 0xA
Global Const $PBT_APMRESUMEAUTOMATIC = 0x12
Global Const $PBT_APMRESUMESUSPEND = 0x7
Global Const $PBT_APMSUSPEND = 0x4
Global Const $PBT_POWERSETTINGCHANGE = 0x8013

GUICreate('My Test', 400, 300)
GUISetState()
GUIRegisterMsg($WM_POWERBROADCAST, 'My_Message_Test')

Do
Until GUIGetMsg() = -3

Func My_Message_Test($hWnd, $Msg, $wParam, $lParam)
        Switch $wParam
                Case $PBT_APMPOWERSTATUSCHANGE ;电源状态发生了变化。
                        MsgBox(0, $wParam, '电源状态发生了变化')
                Case $PBT_APMRESUMEAUTOMATIC
                        
                Case $PBT_APMRESUMESUSPEND
                        
                Case $PBT_APMSUSPEND
                
                Case $PBT_POWERSETTINGCHANGE
        EndSwitch
EndFunc   ;==>My_Message_Test

评分

参与人数 1金钱 +10 收起 理由
showshow + 10 对我来说,还是有用的!多谢!

查看全部评分

发表于 2011-12-29 12:35:08 | 显示全部楼层
参见 缘鸟AUTOIT-API教程
其中,第五章(最后一章)就是讲回调函数的。
发表于 2011-12-29 15:43:33 | 显示全部楼层
进来学习一下了,谢谢
 楼主| 发表于 2012-1-1 20:27:08 | 显示全部楼层
回复 7# happytc


   回调函数很是神秘,还需细细体会!
发表于 2013-6-14 19:33:29 | 显示全部楼层
是懂非懂
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-17 17:35 , Processed in 0.091006 second(s), 29 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表