LISTBOX: LBN_SELCHANGE

Started by Eddy Van Esch, October 07, 2013, 05:29:44 PM

Previous topic - Next topic

Eddy Van Esch

Hi,

I was a bit confused today.
I have a form with a listbox, single selection.
I want the listbox to respond to a mousewheel scrolling: When the mousewheel is scrolled, I want the listbox selection to move up or down.
That works fine like this:

Function TBMAIN_LISTBOXOUTPUT_CUSTOM ( _
                                     ControlIndex  As Long,  _  ' index in Control Array
                                     hWndForm      As Dword, _  ' handle of Form
                                     hWndControl   As Dword, _  ' handle of Control
                                     wMsg          As Long,  _  ' type of message
                                     wParam        As Dword, _  ' first message parameter
                                     lParam        As Long   _  ' second message parameter
                                     ) As Long

    Local i As Long
   
    Select Case wMsg
        Case %WM_MouseWheel
                    'Mousewheel interaction: Move listbox selection up or down if mouse weel is scrolled.
                Select Case Hi(Integer,wParam)    'note the use of Integer
                    Case > 0
                            'Move listbox selection up
                        i = FF_ListBox_GetCurSel( HWND_TBMAIN_LISTBOXOUTPUT )
                        If i <> %LB_ERR Then    'An item was selected
                            If i > 0 Then
                                FF_ListBox_SetCurSel( HWND_TBMAIN_LISTBOXOUTPUT, i - 1 )
                            End If
                        End If
                       
                    Case < 0
                            'Move listbox selection down
                        i = FF_ListBox_GetCurSel( HWND_TBMAIN_LISTBOXOUTPUT )
                        If i <> %LB_ERR Then    'An item was selected
                            If i < (FF_ListBox_GetCount( HWND_TBMAIN_LISTBOXOUTPUT ) - 1 ) Then
                                FF_ListBox_SetCurSel( HWND_TBMAIN_LISTBOXOUTPUT, i + 1 )
                            End If
                        End If                   
                                   
                End Select
    End Select
   
End Function

But .. As the listbox selection changes, I need 'something' to be done.
This 'something' I have stored in the listbox LBN_SELCHANGE message handler:
TBMAIN_LISTBOXOUTPUT_LBN_SELCHANGE

But to my surprise, LBN_SELCHANGE is not triggered by  FF_ListBox_SetCurSel().
LBN_SELCHANGE is only triggered if I explicitely click a listbox item with my mouse.

I could of course call my payload code directly from the mousewheel detection code (as shown above) but I think it would be more elegant if I could trap the event with a single message.
Is there a message that is fired when both FF_ListBox_SetCurSel() is used and when a listbox item is clicked with the mouse?

Kind regards


Eddy

Paul Squires

Hi Eddy,

As you have found out, the LB_SETCURSEL api message does not generate a notification to the parent. This is clearly specified in the LBN_SELCHANGE api docs:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb775161(v=vs.85).aspx
Quote
This notification code is not sent if the LB_SETSEL, LB_SETCURSEL, LB_SELECTSTRING, LB_SELITEMRANGE or LB_SELITEMRANGEEX message changes the selection.

If you don't want to separate your payload from the lbn_selchange code then you could manually add a notification call in the FF_ListBox_SetCurSel code (Functions Library):

Function FF_ListBox_SetCurSel( ByVal hWndControl As Dword, ByVal nIndex As Long) As Long
   
    ' Do a check to ensure that this is actually a window handle
    If IsWindow(hWndControl) Then 
       ' Set the text and return the position where the text was added.
       Function = SendMessage( hWndControl, %LB_SETCURSEL, nIndex, 0)
       PostMessage GetParent(hWndControl), %WM_COMMAND, Mak(Long, GetDlgCtrlID(hWndControl), %LBN_SELCHANGE), hWndControl
    Else
       Function = %LB_ERR
    End If 
   
End Function             


A bit of a hack, but it should work.

Paul Squires
PlanetSquires Software

Eddy Van Esch

Paul,
thanks for the guidance! I keep getting lost in the windows messages every once in a while... Didn't think to go look at MSDM ..  :-[

In order to keep FF_ListBox_SetCurSel function 'unspoiled' I will fire the %LBN_SELCHANGE notification message in my mousewheel code. That seems pretty clean.

Thanks!

Kind regards
Eddy