yamakawa 发表于 2017-7-18 13:54:31

注册 WM_MOUSEWHEEL消息,触发的时候移动鼠标到combo上可以不?

chamlien 发表于 2017-7-18 15:12:31

回复 16# yamakawa


    顺序反了,先捕捉到下拉框,再捕捉滑轮事件,对下拉框进行滚动

chamlien 发表于 2017-7-18 15:14:16

回复 15# kk_lee69


    是的,WM_COMMAND 是鼠标点击事件,但是对下拉框进行不断滚动、选择、再滚动的操作之后,发现WM_COMMAND事件有时不响应,应该是被阻塞了。

chamlien 发表于 2017-7-18 18:49:20

回复 8# kk_lee69


    找到了获取下拉框状态的函数了,不需要注册WM_COMMAND消息,但上滑或下划还是不是很灵敏、存在阻塞,代码如下:


#include <GUIComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <WinAPIFiles.au3>;含RGB轉換BGR顏色UDF

Global $iColor = 0xffffff;0x114c93;選中顏色
Global $clrWindow = 0xffffff;底色
Global $hBrushNorm = _WinAPI_CreateSolidBrush($clrWindow)
Global $hBrushSel = _WinAPI_CreateSolidBrush(_WinAPI_SwitchColor($iColor))
Global $hPen = _WinAPI_CreatePen($PS_SOLID, 2, _WinAPI_SwitchColor($iColor))

GUIRegisterMsg($WM_MEASUREITEM, '_WM_MEASUREITEM')
GUIRegisterMsg($WM_DRAWITEM, '_WM_DRAWITEM')

$hGUI = GUICreate('Test', 220, 300)
$ComboBox = GUICtrlCreateCombo('', 10, 10, 200, 300, BitOR($WS_CHILD, $CBS_OWNERDRAWVARIABLE, $CBS_HASSTRINGS, $CBS_DROPDOWNLIST))
GUICtrlSetData($ComboBox, "實現這裡背景為白色|蘋果|香蕉|桔子|梨子|李子|西瓜|桔子|梨子|李子|西瓜|桔子|梨子|李子|西瓜", "實現這裡背景為白色")

;------------------------新增
Local $wProcNew2 = DllCallbackRegister("_comboScroll", "int", "hwnd;uint;wparam;lparam")
$wProcOld2 = _WinAPI_SetWindowLong(GUICtrlGetHandle($ComboBox), $GWL_WNDPROC, DllCallbackGetPtr($wProcNew2))
;------------------------新增

GUICtrlSetFont(-1, 10, 400, -1)
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
_WinAPI_DeleteObject($hPen)
_WinAPI_DeleteObject($hBrushSel)
_WinAPI_DeleteObject($hBrushNorm)
GUIDelete()

;------------------------新增代?
Func _comboScroll($hWnd, $uiMsg, $wParam, $lParam)
        If $uiMsg = $WM_MOUSEWHEEL Then
                If _GUICtrlComboBox_GetDroppedState($ComboBox) = True Then
                        If BitShift($wParam, 16) > 0 Then ;Wheel up
                                ControlSend($hGUI,"",$ComboBox,"{UP}")
                                ConsoleWrite("UP" & @CRLF)
                        Else ;-----------------------------Wheel down
                                ControlSend($hGUI,"",$ComboBox,"{DOWN}")
                                ConsoleWrite("DOWN" & @CRLF)
                        EndIf
                EndIf
        EndIf
        Return _WinAPI_CallWindowProc($wProcOld2, $hWnd, $uiMsg, $wParam, $lParam)
EndFunc   ;==>_comboScroll
;------------------------新增代?

Func _WM_MEASUREITEM($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tagMEASUREITEMSTRUCT = 'uint CtlType;uint CtlID;uint itemID;uint itemWidth;uint itemHeight;ulong_ptr itemData;'
        Local $tMIS = DllStructCreate($tagMEASUREITEMSTRUCT, $ilParam)
        Local $iCtlType, $iCtlID, $iItemID, $iItemWidth, $iItemHeight
        Local $hComboBox
        Local $tSize
        Local $sText

        $iCtlType = DllStructGetData($tMIS, 'CtlType')
        $iCtlID = DllStructGetData($tMIS, 'CtlID')
        $iItemID = DllStructGetData($tMIS, 'itemID')
        $iItemWidth = DllStructGetData($tMIS, 'itemWidth')
        $iItemHeight = DllStructGetData($tMIS, 'itemHeight')
        $hComboBox = GUICtrlGetHandle($iCtlID)

        If $iCtlType = 3 Then DllStructSetData($tMIS, 'itemHeight', 30)

        Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_MEASUREITEM

Func _WM_DRAWITEM($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tagDRAWITEMSTRUCT = 'uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;hwnd hwndItem;hwnd hDC;' & $tagRECT & ';ulong_ptr itemData;'
        Local $tDIS = DllStructCreate($tagDRAWITEMSTRUCT, $ilParam)
        Local $iCtlType, $iCtlID, $iItemID, $iItemAction, $iItemState
        Local $clrForeground, $clrBackground
        Local $hWndItem, $hDC, $hOldPen, $hOldBrush
        Local $tRect, $aRect
        Local $sText

        $iCtlType = DllStructGetData($tDIS, 'CtlType')
        $iCtlID = DllStructGetData($tDIS, 'CtlID')
        $iItemID = DllStructGetData($tDIS, 'itemID')
        $iItemAction = DllStructGetData($tDIS, 'itemAction')
        $iItemState = DllStructGetData($tDIS, 'itemState')
        $hWndItem = DllStructGetData($tDIS, 'hwndItem')
        $hDC = DllStructGetData($tDIS, 'hDC')
        $tRect = DllStructCreate($tagRECT)

        If $iCtlType = 3 Then
                Switch $iCtlID
                        Case $ComboBox
                                For $i = 1 To 4
                                        DllStructSetData($tRect, $i, DllStructGetData($tDIS, $i + 7))
                                        $aRect[$i - 1] = DllStructGetData($tRect, $i)
                                Next

                                _GUICtrlComboBox_GetLBText($hWndItem, $iItemID, $sText)

                                If GUICtrlRead($ComboBox) = "實現這裡背景為白色" Then
                                        Global $iColor = 0xffffff;選中顏色
                                        Global $clrWindow = 0xffffff;底色
                                        Global $hBrushNorm = _WinAPI_CreateSolidBrush($clrWindow)
                                        Global $hBrushSel = _WinAPI_CreateSolidBrush(_WinAPI_SwitchColor($iColor))
                                        Global $hPen = _WinAPI_CreatePen($PS_SOLID, 2, _WinAPI_SwitchColor($iColor))


                                Else
                                        Global $iColor = 0x114c93;選中顏色
                                        Global $clrWindow = 0xffffff;底色
                                        Global $hBrushNorm = _WinAPI_CreateSolidBrush($clrWindow)
                                        Global $hBrushSel = _WinAPI_CreateSolidBrush(_WinAPI_SwitchColor($iColor))
                                        Global $hPen = _WinAPI_CreatePen($PS_SOLID, 2, _WinAPI_SwitchColor($iColor))
                                EndIf


                                If BitAND($iItemState, 1) Then
                                        $hOldBrush = _WinAPI_SelectObject($hDC, $hBrushSel)
                                        $hOldPen = _WinAPI_SelectObject($hDC, $hPen)
                                        _WinAPI_Rectangle($hDC, $aRect + 1, $aRect + 1, $aRect, $aRect)
                                        _WinAPI_SelectObject($hDC, $hOldPen)
                                        _WinAPI_SelectObject($hDC, $hOldBrush)



                                        $clrBackground = _WinAPI_SetBkColor($hDC, _WinAPI_SwitchColor($iColor))
                                        $clrBackground = _WinAPI_SetTextColor($hDC, 0x000000)

                                Else

                                        $clrBackground = _WinAPI_SetBkColor($hDC, $clrWindow)
                                        _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrushNorm)
                                EndIf
                                DllStructSetData($tRect, "Left", $aRect + 4)
                                DllStructSetData($tRect, "Top", $aRect + 8)
                                DllStructSetData($tRect, "Bottom", $aRect - 2)

                                _WinAPI_DrawText($hDC, $sText, $tRect, BitOR($DT_LEFT, $DT_VCENTER))
                                _WinAPI_SetTextColor($hDC, $clrForeground)
                                _WinAPI_SetBkColor($hDC, $clrBackground)
                EndSwitch
        EndIf

        Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_DRAWITEM

Func _WinAPI_Rectangle($hDC, $iLeft, $iTop, $iRight, $iBottom)
        Local $aResult = DllCall("gdi32.dll", "int", "Rectangle", "hwnd", $hDC, "int", $iLeft, "int", $iTop, "int", $iRight, "int", $iBottom)

        If @error Then Return SetError(@error, @extended, 0)
        Return $aResult <> 0
EndFunc   ;==>_WinAPI_Rectangle

862228699 发表于 2017-7-18 18:50:42

有答案么???{:face (356):}

862228699 发表于 2017-7-18 18:52:09

回复 19# chamlien
你是啥版本?我一运行直接就卡死了。

chamlien 发表于 2017-7-18 19:33:16

最后摸索出来了,原来也很简单,使用_GUICtrlComboBox_GetDroppedState获取到下拉状态,再通过_GUICtrlComboBox_GetCurSel获取当前鼠标选中的索引,最后再用_GUICtrlComboBox_SetCurSel设置需要选中的索引,就达到了滚动的目的了。

   关于一次滚动多少个索引,这个可以自己计算,给出的例子只滚动了两屏。这次的滚动比较准确了,也没有出现阻塞的情况。


#include <GUIComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <WinAPIFiles.au3>;含RGB轉換BGR顏色UDF

Global $iColor = 0xffffff;0x114c93;選中顏色
Global $clrWindow = 0xffffff;底色
Global $hBrushNorm = _WinAPI_CreateSolidBrush($clrWindow)
Global $hBrushSel = _WinAPI_CreateSolidBrush(_WinAPI_SwitchColor($iColor))
Global $hPen = _WinAPI_CreatePen($PS_SOLID, 2, _WinAPI_SwitchColor($iColor))
Global $ComboBoxCounts = 0

GUIRegisterMsg($WM_MEASUREITEM, '_WM_MEASUREITEM')
GUIRegisterMsg($WM_DRAWITEM, '_WM_DRAWITEM')

$hGUI = GUICreate('Test', 220, 300)
$ComboBox = GUICtrlCreateCombo('', 10, 10, 200, 300, BitOR($WS_CHILD, $CBS_OWNERDRAWVARIABLE, $CBS_HASSTRINGS, $CBS_DROPDOWNLIST))
GUICtrlSetData($ComboBox, "實現這裡背景為白色|1|2|3|4|5|6|7|8|9|10|11|12|13|14", "實現這裡背景為白色")

;------------------------新增
Local $wProcNew2 = DllCallbackRegister("_comboScroll", "int", "hwnd;uint;wparam;lparam")
$wProcOld2 = _WinAPI_SetWindowLong(GUICtrlGetHandle($ComboBox), $GWL_WNDPROC, DllCallbackGetPtr($wProcNew2))
;------------------------新增
$ComboBoxCounts = _GUICtrlComboBox_GetCount($ComboBox)

GUICtrlSetFont(-1, 10, 400, -1)
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
_WinAPI_DeleteObject($hPen)
_WinAPI_DeleteObject($hBrushSel)
_WinAPI_DeleteObject($hBrushNorm)
GUIDelete()

;------------------------新增代?
Func _comboScroll($hWnd, $uiMsg, $wParam, $lParam)
        If $uiMsg = $WM_MOUSEWHEEL Then
                If _GUICtrlComboBox_GetDroppedState($ComboBox) = True Then
                        Local $index = _GUICtrlComboBox_GetCurSel($ComboBox)
                        If BitShift($wParam, 16) > 0 Then ;Wheel up
                                If $index > 6 Then
                                        _GUICtrlComboBox_SetCurSel($ComboBox, $index-7)
                                Else
                                        _GUICtrlComboBox_SetCurSel($ComboBox, 0)
                                EndIf
                        Else ;-----------------------------Wheel down
                                If $index > Int($ComboBoxCounts/2) And $index < $ComboBoxCounts Then
                                        _GUICtrlComboBox_SetCurSel($ComboBox, $ComboBoxCounts)
                                Else
                                        _GUICtrlComboBox_SetCurSel($ComboBox, $index+6)
                                EndIf
                        EndIf
                EndIf
        EndIf
        Return _WinAPI_CallWindowProc($wProcOld2, $hWnd, $uiMsg, $wParam, $lParam)
EndFunc   ;==>_comboScroll
;------------------------新增代?

Func _WM_MEASUREITEM($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tagMEASUREITEMSTRUCT = 'uint CtlType;uint CtlID;uint itemID;uint itemWidth;uint itemHeight;ulong_ptr itemData;'
        Local $tMIS = DllStructCreate($tagMEASUREITEMSTRUCT, $ilParam)
        Local $iCtlType, $iCtlID, $iItemID, $iItemWidth, $iItemHeight
        Local $hComboBox
        Local $tSize
        Local $sText

        $iCtlType = DllStructGetData($tMIS, 'CtlType')
        $iCtlID = DllStructGetData($tMIS, 'CtlID')
        $iItemID = DllStructGetData($tMIS, 'itemID')
        $iItemWidth = DllStructGetData($tMIS, 'itemWidth')
        $iItemHeight = DllStructGetData($tMIS, 'itemHeight')
        $hComboBox = GUICtrlGetHandle($iCtlID)

        If $iCtlType = 3 Then DllStructSetData($tMIS, 'itemHeight', 30)

        Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_MEASUREITEM

Func _WM_DRAWITEM($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tagDRAWITEMSTRUCT = 'uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;hwnd hwndItem;hwnd hDC;' & $tagRECT & ';ulong_ptr itemData;'
        Local $tDIS = DllStructCreate($tagDRAWITEMSTRUCT, $ilParam)
        Local $iCtlType, $iCtlID, $iItemID, $iItemAction, $iItemState
        Local $clrForeground, $clrBackground
        Local $hWndItem, $hDC, $hOldPen, $hOldBrush
        Local $tRect, $aRect
        Local $sText

        $iCtlType = DllStructGetData($tDIS, 'CtlType')
        $iCtlID = DllStructGetData($tDIS, 'CtlID')
        $iItemID = DllStructGetData($tDIS, 'itemID')
        $iItemAction = DllStructGetData($tDIS, 'itemAction')
        $iItemState = DllStructGetData($tDIS, 'itemState')
        $hWndItem = DllStructGetData($tDIS, 'hwndItem')
        $hDC = DllStructGetData($tDIS, 'hDC')
        $tRect = DllStructCreate($tagRECT)

        If $iCtlType = 3 Then
                Switch $iCtlID
                        Case $ComboBox
                                For $i = 1 To 4
                                        DllStructSetData($tRect, $i, DllStructGetData($tDIS, $i + 7))
                                        $aRect[$i - 1] = DllStructGetData($tRect, $i)
                                Next

                                _GUICtrlComboBox_GetLBText($hWndItem, $iItemID, $sText)

                                If GUICtrlRead($ComboBox) = "實現這裡背景為白色" Then
                                        Global $iColor = 0xffffff;選中顏色
                                        Global $clrWindow = 0xffffff;底色
                                        Global $hBrushNorm = _WinAPI_CreateSolidBrush($clrWindow)
                                        Global $hBrushSel = _WinAPI_CreateSolidBrush(_WinAPI_SwitchColor($iColor))
                                        Global $hPen = _WinAPI_CreatePen($PS_SOLID, 2, _WinAPI_SwitchColor($iColor))


                                Else
                                        Global $iColor = 0x114c93;選中顏色
                                        Global $clrWindow = 0xffffff;底色
                                        Global $hBrushNorm = _WinAPI_CreateSolidBrush($clrWindow)
                                        Global $hBrushSel = _WinAPI_CreateSolidBrush(_WinAPI_SwitchColor($iColor))
                                        Global $hPen = _WinAPI_CreatePen($PS_SOLID, 2, _WinAPI_SwitchColor($iColor))
                                EndIf


                                If BitAND($iItemState, 1) Then
                                        $hOldBrush = _WinAPI_SelectObject($hDC, $hBrushSel)
                                        $hOldPen = _WinAPI_SelectObject($hDC, $hPen)
                                        _WinAPI_Rectangle($hDC, $aRect + 1, $aRect + 1, $aRect, $aRect)
                                        _WinAPI_SelectObject($hDC, $hOldPen)
                                        _WinAPI_SelectObject($hDC, $hOldBrush)



                                        $clrBackground = _WinAPI_SetBkColor($hDC, _WinAPI_SwitchColor($iColor))
                                        $clrBackground = _WinAPI_SetTextColor($hDC, 0x000000)

                                Else

                                        $clrBackground = _WinAPI_SetBkColor($hDC, $clrWindow)
                                        _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $hBrushNorm)
                                EndIf
                                DllStructSetData($tRect, "Left", $aRect + 4)
                                DllStructSetData($tRect, "Top", $aRect + 8)
                                DllStructSetData($tRect, "Bottom", $aRect - 2)

                                _WinAPI_DrawText($hDC, $sText, $tRect, BitOR($DT_LEFT, $DT_VCENTER))
                                _WinAPI_SetTextColor($hDC, $clrForeground)
                                _WinAPI_SetBkColor($hDC, $clrBackground)
                EndSwitch
        EndIf

        Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_DRAWITEM

Func _WinAPI_Rectangle($hDC, $iLeft, $iTop, $iRight, $iBottom)
        Local $aResult = DllCall("gdi32.dll", "int", "Rectangle", "hwnd", $hDC, "int", $iLeft, "int", $iTop, "int", $iRight, "int", $iBottom)

        If @error Then Return SetError(@error, @extended, 0)
        Return $aResult <> 0
EndFunc   ;==>_WinAPI_Rectangle

chamlien 发表于 2017-7-18 19:35:03

回复 21# 862228699


    解决方法在22楼,选择32位运行就可以了

chamlien 发表于 2017-7-18 19:37:12

回复 15# kk_lee69


    其实想复杂了,一直卡在下拉状态这里,摸索出比较理想的解决方法,帖在了22楼

tingel 发表于 2017-7-19 17:22:46

概念不太一樣吧

WM_COMMAND是 下拉觸發一次關閉 觸發一次

WM_DRAWITEM應該是 一直在畫圖 上色吧   難道 你的那個檢核碼 要一直 切來切去的

tingel 发表于 2017-7-19 17:22:55

概念不太一樣吧

WM_COMMAND是 下拉觸發一次關閉 觸發一次

WM_DRAWITEM應該是 一直在畫圖 上色吧   難道 你的那個檢核碼 要一直 切來切去的
页: 1 [2]
查看完整版本: 【已解决】combo如何隐藏垂直滚动条且鼠标滚动有效