回调函数如何调用?
本帖最后由 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
问题如标题,像上面回调函数该如何调用? 哪位大大指点下啊,感激!
showshow 发表于 2011-12-29 11:17 http://www.autoitx.com/images/common/back.gif
正好回复前面一个帖子用到了回调函数,我就简单地说明一下
链接: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程序直接崩掉 哪位大大指点下啊,感激! 是电源管理消息吗? 我是这样理解的,不知道对不对,测试了下,好像没效果。。。
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 参见 缘鸟AUTOIT-API教程
其中,第五章(最后一章)就是讲回调函数的。 进来学习一下了,谢谢 回复 7# happytc
回调函数很是神秘,还需细细体会! 是懂非懂{:face (356):}
页:
[1]