Jump to content

ListBox events


RAMzor
 Share

Recommended Posts

Hello all,
I am trying to get scrolling events for ListBox (mouse wheel and up/down arrows) but without success. The event not occured on row change but if I click on it - yes
The ComboBox works fine even if not in focus (with mouse wheel) but I prefer visual look of ListBox. In addition to all, I can't change the height of control. Unfortunately it depends only on font size and same fonts has different heights between InputBox and ComboBox

Is there a way to get over the issue?

Any other ideas for unit selection realization are welcome B)

#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListBoxConstants.au3>

Global $idCombo, $idComboUnit, $idList, $idListUnit
Global $sComboInitUnit = "pJ", $fComboVal = 7.5
Global $sListInitUnit = "nF", $fListVal = 0.15

Units_Conversion_Example()

Func Units_Conversion_Example()
    ; Create GUI
    GUICreate("Units Conversion", 400, 296)

    $idCombo = GUICtrlCreateInput($fComboVal, 22, 20, 91, 26)
    GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")
    $idComboUnit = GUICtrlCreateCombo("", 112, 20, 50, 30)
    GUICtrlSetData(-1, "uJ|nJ|pJ", $sComboInitUnit)
    GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")

    $idList = GUICtrlCreateInput($fListVal, 22, 80, 91, 26)
    GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")
    $idListUnit = GUICtrlCreateList("", 112, 80, 57, 26, BitOR($LBS_NOTIFY,$LBS_NOSEL,$WS_VSCROLL))
    GUICtrlSetData(-1, "uF|nF|pF", $sListInitUnit)
    GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")

    GUISetState(@SW_SHOW)

    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

    Do
        Sleep(5)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>Example





Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo, $hWndListBox
    If Not IsHWnd($idComboUnit) Then $hWndCombo = GUICtrlGetHandle($idComboUnit)
    If Not IsHWnd($idListUnit) Then $hWndListBox = GUICtrlGetHandle($idListUnit)
    $hWndFrom = $lParam
    $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
    $iCode = BitShift($wParam, 16) ; Hi Word


    Switch $hWndFrom
        Case $hWndCombo
            Switch $iCode
                Case $LBN_SELCHANGE
                    ConsoleWrite(GUICtrlRead($idComboUnit) & @CRLF)
        EndSwitch

        Case $hWndListBox
            Switch $iCode
                Case $CBN_SELCHANGE
                    ConsoleWrite(GUICtrlRead($idListUnit) & @CRLF)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

 

 

Edited by RAMzor
Link to comment
Share on other sites

Just idea/concept, not working ...

#include <GuiListBox.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListBoxConstants.au3>

Global Const $WM_MOUSEWHEEL = 0x020A ; needed only for older AutoIt's versions

Global $idCombo, $idComboUnit, $idList, $idListUnit
Global $sComboInitUnit = "pJ", $fComboVal = 7.5
Global $sListInitUnit = "nF", $fListVal = 0.15
Global $hWndCombo, $hWndListBox

Units_Conversion_Example()

Func Units_Conversion_Example()
    ; Create GUI
    GUICreate("Units Conversion", 400, 296)

    $idCombo = GUICtrlCreateInput($fComboVal, 22, 20, 91, 26)
    GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")
    $idComboUnit = GUICtrlCreateCombo("", 112, 20, 50, 30)
    $hWndCombo = GUICtrlGetHandle($idComboUnit)
    GUICtrlSetData(-1, "uJ|nJ|pJ", $sComboInitUnit)
    GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")

    $idList = GUICtrlCreateInput($fListVal, 22, 80, 91, 26)
    GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")
    $idListUnit = GUICtrlCreateList("", 112, 80, 57, 26, BitOR($LBS_NOTIFY,$LBS_NOSEL,$WS_VSCROLL))
    $hWndListBox = GUICtrlGetHandle($idListUnit)
    GUICtrlSetData(-1, "uF|nF|pF", $sListInitUnit)
    GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")

    GUISetState(@SW_SHOW)

    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
    GUIRegisterMsg($WM_MOUSEWHEEL, "WM_MOUSEWHEEL")

    Do
        Sleep(5)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>Example

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg
    Local $hWndFrom, $iIDFrom, $iCode
    $hWndFrom = $lParam
    $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
    $iCode = BitShift($wParam, 16) ; Hi Word


    Switch $hWndFrom
        Case $hWndCombo
            Switch $iCode
                Case $LBN_SELCHANGE
                    ConsoleWrite('LBN_SELCHANGE1 ' & GUICtrlRead($idComboUnit) & @CRLF)
        EndSwitch

        Case $hWndListBox
            Switch $iCode
                Case $LBN_SELCHANGE
                    ConsoleWrite('LBN_SELCHANGE2 ' & GUICtrlRead($idListUnit) & @CRLF)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func WM_MOUSEWHEEL($hWnd, $iMsg, $wParam, $lParam)
    If $hWnd <> $hWndListBox Then Return
    $i = _GUICtrlListBox_GetTopIndex($idListUnit) ; first visible item
    _GUICtrlListBox_SetSel($idListUnit, $i)
EndFunc

 

Edited by Zedna
Link to comment
Share on other sites

That seems to work quite well :

#include <GuiListBox.au3>
#include <WinAPI.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListBoxConstants.au3>

Global $idCombo, $idComboUnit, $idList, $idListUnit
Global $sComboInitUnit = "pJ", $fComboVal = 7.5
Global $sListInitUnit = "nF", $fListVal = 0.15

Units_Conversion_Example()

Func Units_Conversion_Example()
  ; Create GUI
  Global $hGUI = GUICreate("Units Conversion", 400, 296)

  $idCombo = GUICtrlCreateInput($fComboVal, 22, 20, 91, 26)
  GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")
  $idComboUnit = GUICtrlCreateCombo("", 112, 20, 50, 30)
  GUICtrlSetData(-1, "uJ|nJ|pJ", $sComboInitUnit)
  GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")

  $idList = GUICtrlCreateInput($fListVal, 22, 80, 91, 26)
  GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")
  $idListUnit = GUICtrlCreateList("", 112, 80, 57, 26, BitOR($LBS_NOTIFY, $LBS_NOSEL, $WS_VSCROLL))
  GUICtrlSetData(-1, "uF|nF|pF", $sListInitUnit)
  GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")

  Global $hCtrl = GUICtrlGetHandle($idListUnit)

  Global $iDummy = GUICtrlCreateDummy()

  GUISetState(@SW_SHOW)

  GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

  Local $hProc = DllCallbackRegister(WM_LIST_BOX, "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr")
  Local $hProcPtr = DllCallbackGetPtr($hProc)
  DllCall("comctl32.dll", "bool", "SetWindowSubclass", "hwnd", $hCtrl, "ptr", $hProcPtr, "uint_ptr", 0xBEEF, "dword_ptr", 0)

  While True
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
      Case $iDummy
        ;ControlFocus ($hGUI, "", $hCtrl)
        ControlClick($hGUI, "", $idListUnit)
    EndSwitch
  WEnd

  GUIDelete()
  DllCall("comctl32.dll", "bool", "RemoveWindowSubclass", "hwnd", $hCtrl, "ptr", $hProcPtr, "uint_ptr", $WM_VSCROLL)
  DllCallbackFree($hProc)
EndFunc   ;==>Units_Conversion_Example

Func WM_LIST_BOX($hWnd, $iMsg, $wParam, $lParam, $uIdSubClass, $IRefData)
  #forceref $hWnd, $iMsg, $wParam, $lParam, $uIdSubClass, $IRefData
  Local $iDirection
  Switch $iMsg
    Case $WM_VSCROLL
      $iDirection = _WinAPI_LoWord ($wParam)
      If $iDirection = 0 Or $iDirection = 1 Then GUICtrlSendToDummy ($iDummy)
    Case $WM_MOUSEWHEEL
      $iDirection = _WinAPI_HiWord ($wParam)
      GUICtrlSendToDummy ($iDummy)
  EndSwitch

  Return DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)[0]
EndFunc

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
  #forceref $hWnd, $iMsg
  Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo, $hWndListBox
  If Not IsHWnd($idComboUnit) Then $hWndCombo = GUICtrlGetHandle($idComboUnit)
  If Not IsHWnd($idListUnit) Then $hWndListBox = GUICtrlGetHandle($idListUnit)
  $hWndFrom = $lParam
  $iIDFrom = BitAND($wParam, 0xFFFF)   ; Low Word
  $iCode = BitShift($wParam, 16)   ; Hi Word

  Switch $hWndFrom
    Case $hWndCombo
      Switch $iCode
        Case $CBN_SELCHANGE
          ConsoleWrite(GUICtrlRead($idComboUnit) & @CRLF)
      EndSwitch

    Case $hWndListBox
      Switch $iCode
        Case $LBN_SELCHANGE
          ConsoleWrite(GUICtrlRead($idListUnit) & @CRLF)
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

 

Link to comment
Share on other sites

2 hours ago, argumentum said:

..not that I can code it but, to what purpose is the scrolling position needed ?

The issue that the value in ListBox can be changed without control is focused - only mouse pointer hovers over a ListBox and mouse wheel will change the value. Even arrows up and down not really change a value (only move it). 
This is very useful option but very "danger" because the value visually changed without really be accepted.

Hope I made my self clear because my English is lame 🤪

 

@Zedna

Thanks a lot but it still not worked as you said...

Link to comment
Share on other sites

1 hour ago, Nine said:

That seems to work quite well :

#include <GuiListBox.au3>
#include <WinAPI.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ListBoxConstants.au3>

Global $idCombo, $idComboUnit, $idList, $idListUnit
Global $sComboInitUnit = "pJ", $fComboVal = 7.5
Global $sListInitUnit = "nF", $fListVal = 0.15

Units_Conversion_Example()

Func Units_Conversion_Example()
  ; Create GUI
  Global $hGUI = GUICreate("Units Conversion", 400, 296)

  $idCombo = GUICtrlCreateInput($fComboVal, 22, 20, 91, 26)
  GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")
  $idComboUnit = GUICtrlCreateCombo("", 112, 20, 50, 30)
  GUICtrlSetData(-1, "uJ|nJ|pJ", $sComboInitUnit)
  GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")

  $idList = GUICtrlCreateInput($fListVal, 22, 80, 91, 26)
  GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")
  $idListUnit = GUICtrlCreateList("", 112, 80, 57, 26, BitOR($LBS_NOTIFY, $LBS_NOSEL, $WS_VSCROLL))
  GUICtrlSetData(-1, "uF|nF|pF", $sListInitUnit)
  GUICtrlSetFont(-1, 13, 400, 0, "MS Reference Sans Serif")

  Global $hCtrl = GUICtrlGetHandle($idListUnit)

  Global $iDummy = GUICtrlCreateDummy()

  GUISetState(@SW_SHOW)

  GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

  Local $hProc = DllCallbackRegister(WM_LIST_BOX, "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr")
  Local $hProcPtr = DllCallbackGetPtr($hProc)
  DllCall("comctl32.dll", "bool", "SetWindowSubclass", "hwnd", $hCtrl, "ptr", $hProcPtr, "uint_ptr", 0xBEEF, "dword_ptr", 0)

  While True
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        ExitLoop
      Case $iDummy
        ;ControlFocus ($hGUI, "", $hCtrl)
        ControlClick($hGUI, "", $idListUnit)
    EndSwitch
  WEnd

  GUIDelete()
  DllCall("comctl32.dll", "bool", "RemoveWindowSubclass", "hwnd", $hCtrl, "ptr", $hProcPtr, "uint_ptr", $WM_VSCROLL)
  DllCallbackFree($hProc)
EndFunc   ;==>Units_Conversion_Example

Func WM_LIST_BOX($hWnd, $iMsg, $wParam, $lParam, $uIdSubClass, $IRefData)
  #forceref $hWnd, $iMsg, $wParam, $lParam, $uIdSubClass, $IRefData
  Local $iDirection
  Switch $iMsg
    Case $WM_VSCROLL
      $iDirection = _WinAPI_LoWord ($wParam)
      If $iDirection = 0 Or $iDirection = 1 Then GUICtrlSendToDummy ($iDummy)
    Case $WM_MOUSEWHEEL
      $iDirection = _WinAPI_HiWord ($wParam)
      GUICtrlSendToDummy ($iDummy)
  EndSwitch

  Return DllCall("comctl32.dll", "lresult", "DefSubclassProc", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)[0]
EndFunc

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
  #forceref $hWnd, $iMsg
  Local $hWndFrom, $iIDFrom, $iCode, $hWndCombo, $hWndListBox
  If Not IsHWnd($idComboUnit) Then $hWndCombo = GUICtrlGetHandle($idComboUnit)
  If Not IsHWnd($idListUnit) Then $hWndListBox = GUICtrlGetHandle($idListUnit)
  $hWndFrom = $lParam
  $iIDFrom = BitAND($wParam, 0xFFFF)   ; Low Word
  $iCode = BitShift($wParam, 16)   ; Hi Word

  Switch $hWndFrom
    Case $hWndCombo
      Switch $iCode
        Case $CBN_SELCHANGE
          ConsoleWrite(GUICtrlRead($idComboUnit) & @CRLF)
      EndSwitch

    Case $hWndListBox
      Switch $iCode
        Case $LBN_SELCHANGE
          ConsoleWrite(GUICtrlRead($idListUnit) & @CRLF)
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

 

Wow! Thanks a lot, it really works! 

Is this normal behavior? So many code for so simple thing 😬

Edited by RAMzor
Link to comment
Share on other sites

It is not such a big deal, it is, after all,  only a few additional lines of code to get the functionality you wanted.  The hard part is to find the right API to perform the task properly.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...