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
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,
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