找回密码
 加入
搜索
查看: 6472|回复: 10

[GUI管理] 如何在combo中捕获回车键

  [复制链接]
发表于 2010-3-23 20:51:22 | 显示全部楼层 |阅读模式
如题,打算在combo中获取回车事件,但不知如何实现,请赐教,谢谢!
发表于 2010-3-23 21:00:43 | 显示全部楼层
新手期待中!!顶一个
发表于 2010-3-23 21:02:00 | 显示全部楼层
#Include <Misc.au3>
#include <ComboConstants.au3>
#include <WindowsConstants.au3>

GUICreate("Form1", 280, 100)
$Combo1 = GUICtrlCreateCombo("Combo1", 20, 20, 200, 30)
GUICtrlSetData(-1, "Combo2|Combo3|Combo4|Combo5")
GUISetState(@SW_SHOW)
$dll = DllOpen("user32.dll")

While 1
        If _IsPressed("0D", $dll) Then MsgBox(0,'回车键被按下', GUICtrlRead($Combo1))
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case -3
                        Exit

        EndSwitch
WEnd

评分

参与人数 1金钱 +20 收起 理由
afan + 20

查看全部评分

发表于 2010-3-23 21:47:59 | 显示全部楼层
谢谢分享!!
 楼主| 发表于 2010-3-23 22:32:11 | 显示全部楼层
存在一个问题,当焦点不在该控件仍触发了该事件,如何获知焦点在combo上呢?
发表于 2010-3-23 23:01:07 | 显示全部楼层
本帖最后由 水木子 于 2010-3-23 23:04 编辑

回复 5# caodongchun
#include <Misc.au3>
#include <ComboConstants.au3>
#include <WindowsConstants.au3>

$hGui = GUICreate("Form1", 250, 150)
$Combo1 = GUICtrlCreateCombo("Combo1", 20, 20, 200, 30)
GUICtrlSetData(-1, "Combo2|Combo3|Combo4|Combo5")
$Input1 = GUICtrlCreateInput("", 20, 80, 200, 21)
GUISetState(@SW_SHOW)
$dll = DllOpen("user32.dll")

While 1
        If ControlGetFocus($hGui) = 'Edit1' Then
                If _IsPressed("0D", $dll) Then MsgBox(0, '回车键被按下', GUICtrlRead($Combo1))
        EndIf

        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case - 3
                        DllClose($dll)
                        Exit
        EndSwitch
WEnd

评分

参与人数 1金钱 +30 贡献 +5 收起 理由
caodongchun + 30 + 5 感谢!

查看全部评分

发表于 2010-3-23 23:28:49 | 显示全部楼层
本帖最后由 pusofalse 于 2010-3-23 23:30 编辑

回复 6# 水木子
            If ControlGetFocus($hGui) = 'Edit1' Then
                If _IsPressed("0D", $dll) Then MsgBox(0, '回车键被按下', GUICtrlRead($Combo1))
        EndIf
这里似乎出了点问题。两句条件判断,第一句ControlGetFocus($hGui) = 'Edit1',这个条件大多数情况下是成立的,COMBO控件不只是在按下回车时才会拥有焦点,在其他情况下也会拥有,比如输入字符时、鼠标点击时,第一句判断一旦成立便接着执行第二句判断,因为用户不可能一直按回车,_IsPressed只有在指定的按键被确确实实地按下时才会返回TRUE,用户没有在按回车键的时候,第一句判断就白费了。为确保程序的效率,在多重条件中,应该首先判断 成立几率相比较而言较小的。

或者,楼主应该看下GUISetAccelerators函数。

评分

参与人数 2金钱 +70 贡献 +5 收起 理由
caodongchun + 30 + 5 感谢!!
gapkiller + 40 同意

查看全部评分

发表于 2010-3-23 23:36:57 | 显示全部楼层
本帖最后由 水木子 于 2010-3-23 23:46 编辑

回复 7# pusofalse

谢谢老师指教!这些细节上的问题还真没注意到,还是老师细心啊!
如果改成这样呢?会不会好一点?先判断是否有回车键按下,再判断光标位置。
刚刚发现我这方法存在个问题?实在不好意思想,献丑啦!
 楼主| 发表于 2010-3-23 23:51:58 | 显示全部楼层
十分感谢!这个问题解决了!
#region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=autorun.ico
#AutoIt3Wrapper_outfile=文件搜索列表.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Comment=Winter.Cao@Live.cn
#AutoIt3Wrapper_Res_Description=Flie Search List Prog
#AutoIt3Wrapper_Res_Fileversion=0.0.1.0
#AutoIt3Wrapper_Res_LegalCopyright=Copyright (C) 1998-2009 Caodongchun
#endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseAnsi=y
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
Opt("GUIOnEventMode", 1)
Opt("TrayOnEventMode", 1)
Opt("TrayMenuMode", 1)
TraySetClick(16)
$Filelist = _FileListToArray(@ScriptDir, '*', 1)
$JForm = GUICreate('文件搜索', 800, 600)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked1");退出OnEvent
GUICtrlCreateLabel('请填写关键字', 10, 13, 75, 20)
$JInput = GUICtrlCreateCombo('', 85, 10, 655, 20)
GUICtrlSetOnEvent(-1, '_Click');OnEvent
$JSearchButton = GUICtrlCreateButton('搜索', 750, 10, 40, 20)
GUICtrlSetOnEvent(-1, '_Click');OnEvent
$JList = GUICtrlCreateListView('                              文件名                              |文件类型', 10, 40, 780, 550)
_GUICtrlListView_SetExtendedListViewStyle($JList, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_DOUBLEBUFFER))
_GUICtrlListView_SetColumnWidth($JList, 0, 700)
_GUICtrlListView_SetColumnWidth($JList, 1, 70)
$EXIT = TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, '_Exit')

TraySetOnEvent(-8, '_show')
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW, $JForm)
AdlibRegister('_Enter', 150)

Func _Enter()
        If ControlGetFocus($JForm) = 'Edit1' And _IsPressed("0D") Then
                _GetFileName(GUICtrlRead($JInput))
        EndIf
EndFunc   ;==>_Enter

Func _Exit()
        Exit
EndFunc   ;==>_Exit

Func _Click()
        If @GUI_CtrlId = $JSearchButton Then _GetFileName(GUICtrlRead($JInput))
EndFunc   ;==>_Click

Func _GetFileName($sString = '')
        _GUICtrlListView_DeleteAllItems($JList)
        $WArray = StringSplit(GUICtrlRead($JInput), ' ')

        For $x = 1 To $Filelist[0]
                $Flag = 0
                For $y = 1 To $WArray[0]
                        If StringInStr($Filelist[$x], $WArray[$y]) <> 0 Then $Flag += 1;
                Next
                If $Flag = $WArray[0] Then
                        $Filename = StringRegExp($Filelist[$x], '(.*)\.[^\.]*', 1)
                        If IsArray($Filename) Then
                                $Filename = $Filename[0]
                        Else
                                $Filename = $Filelist[$x]
                        EndIf
                        $Filetype = StringRegExp($Filelist[$x], '.*(\.[^\.]*)', 1)
                        If IsArray($Filetype) Then
                                $Filetype = $Filetype[0]
                        Else
                                $Filetype = ''
                        EndIf


                        GUICtrlCreateListViewItem($Filename & '|' & $Filetype, $JList)
                EndIf
        Next

EndFunc   ;==>_GetFileName


Func CLOSEClicked1()
        GUISetState(@SW_HIDE)
EndFunc   ;==>CLOSEClicked1

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam
        Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $tInfo, $hWndListView = $JList
        If Not IsHWnd($JList) Then $hWndListView = GUICtrlGetHandle($JList)

        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
        $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
        $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
        $iCode = DllStructGetData($tNMHDR, "Code")
        Switch $hWndFrom
                Case $hWndListView
                        Switch $iCode
                                Case $NM_DBLCLK; Sent by a list-view control when the user double-clicks an item with the left mouse button
                                        $SelFileN = _GUICtrlListView_GetItemText($JList, Int(_GUICtrlListView_GetSelectedIndices($JList)))
                                        $SelFileT = _GUICtrlListView_GetItemText($JList, Int(_GUICtrlListView_GetSelectedIndices($JList)), 1)
                                        ShellExecute(@ScriptDir & '\' & $SelFileN & $SelFileT)
                                Case $NM_RCLICK
                                        ShellExecute(@ScriptDir & '\')
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _show()
        GUISetState(@SW_SHOW)
EndFunc   ;==>_show

Func _FileListToArray($sPath, $sFilter = "*", $iFlag = 0)
        Local $hSearch, $sFile, $sFileList, $sDelim = "|"
        $sPath = StringRegExpReplace($sPath, "[\\/]+\z", "") & "" ; ensure single trailing backslash
        If Not FileExists($sPath) Then Return SetError(1, 1, "")
        If StringRegExp($sFilter, "[\\/:><\|]|(?s)\A\s*\z") Then Return SetError(2, 2, "")
        If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, "")
        $hSearch = FileFindFirstFile($sPath & $sFilter)
        If @error Then Return SetError(4, 4, "")
        While 1
                $sFile = FileFindNextFile($hSearch)
                If @error Then ExitLoop
                If ($iFlag + @extended = 2) Then ContinueLoop
                $sFileList &= $sDelim & $sFile
        WEnd
        FileClose($hSearch)
        If Not $sFileList Then Return SetError(4, 4, "")
        Return StringSplit(StringTrimLeft($sFileList, 1), "|")
EndFunc   ;==>_FileListToArray

Func _IsPressed($sHexKey, $vDLL = 'user32.dll')
        ; $hexKey must be the value of one of the keys.
        ; _Is_Key_Pressed will return 0 if the key is not pressed, 1 if it is.
        Local $a_R = DllCall($vDLL, "short", "GetAsyncKeyState", "int", '0x' & $sHexKey)
        If @error Then Return SetError(@error, @extended, False)
        Return BitAND($a_R[0], 0x8000) <> 0
EndFunc   ;==>_IsPressed

While 1
        Sleep(100)
WEnd
发表于 2010-3-23 23:57:58 | 显示全部楼层
回复 8# 水木子


    是这样的,我想表达的意思就是这样,_IsPressed应该写在ControlGetFocus前面。
用户输入回车的几率 小于 COMBO拥有焦点的几率

刚才测试了一下,GUISetAccelerators函数竟不适用于COMBO控件~(?)

PS:不要再叫老师了,真的不要再这样叫了~
发表于 2010-3-24 00:02:15 | 显示全部楼层
回复 10# pusofalse
是啊!GUISetAccelerators 函数不适用于COMBO控件。
根据刚才发现的情况和P版 超级版主(没有叫老师哈!)的指点 我改成了这样。
#include <Misc.au3>
#include <ComboConstants.au3>
#include <WindowsConstants.au3>

$hGui = GUICreate("Form1", 250, 150)
$Combo1 = GUICtrlCreateCombo("Combo1", 20, 20, 200, 30)
GUICtrlSetData(-1, "Combo2|Combo3|Combo4|Combo5")
$Input1 = GUICtrlCreateInput("", 20, 80, 200, 21)
$But1 = GUICtrlCreateButton("Read", 200, 200, 60, 30)
GUISetState(@SW_SHOW)
$dll = DllOpen("user32.dll")
Dim $AccelKeys[1][2] = [["{Enter}", $But1]]
GUISetAccelerators($AccelKeys)

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case - 3
                        DllClose($dll)
                        Exit
                Case $But1
                        If ControlGetFocus($hGui) = 'Edit1' Then MsgBox(0, '回车键被按下', GUICtrlRead($Combo1))
        EndSwitch
WEnd

评分

参与人数 1金钱 +20 收起 理由
pusofalse + 20

查看全部评分

您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-11-22 18:22 , Processed in 0.096447 second(s), 30 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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