happytc 发表于 2011-2-2 10:28:22

au3里怎么用$WM_LBUTTONDBLCLK消息?

本帖最后由 happytc 于 2011-2-2 11:39 编辑

创建个窗口,想捕获双击,在窗口样式里加上$CS_DBLCLKS(这个常量在那个#Include里?),找不到,只好直接加上它的值了:0x8,但双击(Case $WM_LBUTTONDBLCLK)没有效果,为什么?

#include <GuiConstants.au3>
#include <WindowsConstants.au3>

$hSelection_GUI = GUICreate("", 400, 300, -1, -1, _
                $WS_SIZEBOX+$WS_POPUP+0x8, $WS_EX_DLGMODALFRAME+$WS_EX_DLGMODALFRAME+$WS_EX_CLIENTEDGE+$WS_EX_TOPMOST+$WS_EX_TOOLWINDOW)
GUISetState()
While 1
        $nMsg = GUIGetMsg()
       Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
                Case $WM_LBUTTONDBLCLK
                        MsgBox(0,0,"0k")
                        ExitLoop
       EndSwitch
WEnd

happytc 发表于 2011-2-2 10:37:41

不是au3不register这个Window class吧,经常在C里用这个,然后照样写au3的,实在想不出来上面代码那里有问题了,只能怀疑这个原因了

netegg 发表于 2011-2-2 11:16:54

先看看消息是怎么定义的再来问

happytc 发表于 2011-2-2 11:22:39

本帖最后由 happytc 于 2011-2-2 11:24 编辑

回复 3# netegg
这个我当然知道了,若用GUIRegisterMsg($WM_COMMAND, "MY_WM_COMMAND")来做的
MY_WM_COMMAND函数没法加一个句柄变量呀。
若用全局变量来做的话,对我来说也难受。因为我程序里的函数基本都是独立文件,在别的函数里改了这个句柄变量值,没法传到MY_WM_COMMAND里去呀。怎么才可以ByRef传递过去呢?

有什么好办法没有?

看来难怪au3是没有这个window class($CS_DBLCLKS)了

netegg 发表于 2011-2-2 11:37:07

没明白你说的什么意思

netegg 发表于 2011-2-2 11:43:03

GUIRegisterMsg(0x8, "MY_WM_COMMAND")
如果你说的值没错的话

happytc 发表于 2011-2-2 11:47:09

本帖最后由 happytc 于 2011-2-2 11:51 编辑

就是实际程序中象上面例子中的句柄变量:$hSelection_GUI,在别的函数里也会改变它的值。如:
Func GUIDeleteSquare($hSquare_GUI)
        If IsHWnd($hSquare_GUI) Then
                GUIDelete($hSquare_GUI)
                $hSquare_GUI = -1
        EndIf
EndFunc

被改变后,在象下面中引用$hSelection_GUI就不行了,除非把全部相关函数写在一个文件里,然后在这个文件开头Global $hSelection_GUI

Func MY_WM_COMMAND($hWnd, $msg, $wParam, $lParam)
    Local $nNotifyCode = BitShift($wParam,16)
    Local $nID = BitAND($wParam, 0xFFFF)
    Local $hCtrl = $lParam

    Switch $nID
      Case $hSelection_GUI
            Switch $nNotifyCode
                Case 1
                   MsgBox(16,"警告","双击")
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc

也就是若是能定义象:Func MY_WM_COMMAND(Bydef $hSelection_GUI, $hWnd, $msg, $wParam, $lParam)就好了
本来若是能直接用WM_LBUTTONDBLCLK消息,就又简单又不会有上述问题了

_ddqs. 发表于 2011-2-2 15:21:47

#include <GuiConstants.au3>
#include <WindowsConstants.au3>

$hSelection_GUI = GUICreate("", 400, 300, -1, -1);, _
                ;$WS_SIZEBOX + $WS_POPUP + 0x8, $WS_EX_DLGMODALFRAME + $WS_EX_DLGMODALFRAME + $WS_EX_CLIENTEDGE + $WS_EX_TOPMOST + $WS_EX_TOOLWINDOW)
GUISetState()

Global $DBC = "", $mpos = , $npos =

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
                Case -8 To -7 ;$WM_LBUTTONDBLCLK
                        ;双击开始(不移动鼠标,点击2次)
                        If $mpos=0 And $mpos=0 Then
                                $mpos = MouseGetPos()
                        Else
                                $npos = MouseGetPos()
                                If $mpos<>$npos Or $mpos<>$npos Then
                                        $DBC = ""
                                        $mpos = 0
                                        $mpos = 0
                                        $npos = 1
                                        $npos = 1
                                EndIf
                        EndIf
                        $DBC &= $nMsg                       
                        If $DBC = "-7-8-7-8" Then
                                MsgBox(0, 0, "双击")
                                ExitLoop
                        EndIf
                        ;双击结束


        EndSwitch
WEnd

ceoguang 发表于 2011-2-3 14:29:12

MSDN:
Only windows that have the CS_DBLCLKS style can receive WM_LBUTTONDBLCLK messages, which the system generates whenever the user presses, releases, and again presses the left mouse button within the system's double-click time limit. Double-clicking the left mouse button actually generates a sequence of four messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, and WM_LBUTTONUP
确实autoit没有CS_DBLCLKS风格,不过可以实现的方法有很多.MSDN坑爹了?$hSelection_GUI = GUICreate("", 400, 300)
GUIRegisterMsg(0x0203, "WM_LBUTTONDBLCLK")
GUISetState()
While GUIGetMsg() <> -3
WEnd
GUIDelete()
Exit
Func WM_LBUTTONDBLCLK($hWnd, $msg, $wParam, $lParam)
        MsgBox(16, "警告", "双击", -1, $hWnd)
        Return "GUI_RUNDEFMSG"
EndFunc

happytc 发表于 2011-2-3 22:25:11


_ddqs. 发表于 2011-2-2 15:21 http://www.autoitx.com/images/common/back.gif

_ddqs.兄的思想很发散呀,赞一下,虽然健壮性不是很好!但也不失解决问题的一个方法
谢了!

happytc 发表于 2011-2-3 22:31:19

MSDN:

确实autoit没有CS_DBLCLKS风格,不过可以实现的方法有很多.MSDN坑爹了?
ceoguang 发表于 2011-2-3 14:29 http://www.autoitx.com/images/common/back.gif

为个就是常规方法了,但没动解决我在7楼提出的问题。
越是深入地用au3,就感觉au3还有很大的发展余地。把缺少的很多东西补上来。象COM的东西,象
   AutoItX的功能,都待加强。估计au4出来后,就有大的变化吧。
感觉autoit开发没有ahk那么“水深为热”呀,难道是因为autoit不开源的缘故?

ceoguang 发表于 2011-2-3 23:03:57

为个就是常规方法了,但没动解决我在7楼提出的问题。
越是深入地用au3,就感觉au3还有很大的发展余地。 ...
happytc 发表于 2011-2-3 22:31 http://www.autoitx.com/images/common/back.gif
你在7楼的问题不是问题.
GUI删除后对应注册的消息会自动删除.
而且没必要在消息函数中用到全局变量,因为那相当于一个回调函数,谁注册谁使用.
见http://www.autoitx.com/doc/html/functions/dllcallbackregister.htm

pusofalse 发表于 2011-2-3 23:30:47

消息函数的$hWnd参数就是父窗口$hSelection_GUI的句柄。如果不是,你可以用局部静态变量的方式(避免使用全局变量)维护一个网状型的数据结构,使各个窗口之间有一种映射关系,通过$hWnd就能获取$hSelection_GUI的值。

另外,7#的代码有问题。
调用GUIDelete($hSquare_GUI),这个窗口就被销毁了,之后不会产生任何有关于此窗口的消息,当然也不会产生WM_COMMAND消息,MY_WM_COMMAND函数如果只用作$hSquare_GUI窗口的消息处理函数,它的存活期跟$hSquare_GUI窗口的存活期是一样的。

另外,即便在销毁窗口之后,仍会产生有关于此窗口的WM_COMMAND消息,那么在MY_WM_COMMAND函数内部也有错误:
$nID = BitAND($wParam, 0xFFFF)
Switch $nID
Case $hSelection_GUI
         ...
EndSwitch

BitAnd($wParam, 0xFFFF)是取$wParam参数的低16位,这个数值是ID而不是句柄,而$hSelection_GUI是个32位的句柄数值,所以这个判断永远不会成立,ID和句柄是不一样的概念。

风行者 发表于 2011-2-4 01:19:05

汗,WM_LBUTTONDBLCLK = 0x0203
帮助里可以查到

happytc 发表于 2011-2-4 09:43:29

本帖最后由 happytc 于 2011-2-4 09:50 编辑

谢C/P版的热心回答,用P版的“局部静态变量”变通解决问题了。C/P说的关于7楼的代码,只是为了表答实际程序的问题,临时写的代码类似代码,没有多想,的确有点问题。

不过那个static的中文帮助的大红框让人心惊胆憻呀
页: [1]
查看完整版本: au3里怎么用$WM_LBUTTONDBLCLK消息?