Results 1 to 12 of 12

Thread: [RESOLVED] Trigger Listbox Click Event in Out of Process LIstbox

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jul 2001
    Location
    Tucson, AZ
    Posts
    2,166

    Resolved [RESOLVED] Trigger Listbox Click Event in Out of Process LIstbox

    Using the following I can get the caret (colored line) to move to the correct index.
    However, that movement does NOT appear to trigger the listbox-Click event.

    Code:
    Public Sub LB_SetItemIndex(ByVal hWnd As Long, ByVal Index As Long)
       Dim retval As Long  ' return value
     
       'Change selection to index number
       retval = SendMessage(hWnd, LB_SETCURSEL, Index,  &H0)
       
    End Sub
    I'm guessing I need to followup with WM Mouse messages but wondering if I'm missing some LB control message that will accomplish what I need?

  2. #2
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    did you try lb_setsel?
    i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
    Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next

    dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part

    come back and mark your original post as resolved if your problem is fixed
    pete

  3. #3
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,653

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    There's LBN_DBLCLICK (a WM_NOTIFY code) but otherwise it's just the standards. https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Jul 2001
    Location
    Tucson, AZ
    Posts
    2,166

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    westconn1:

    LB_SETSEL is only for a multiple selection listbox. will try it but have my doubts.

    Tried it. Does NOT work for single selection listbox.

    fafalone:
    Good idea had forgotten about WM_NOTIFY. Will try today.
    Last edited by dw85745; Jun 30th, 2016 at 09:12 AM.

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Jul 2001
    Location
    Tucson, AZ
    Posts
    2,166

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    Turns out may be more difficult than initial thoughts.

    Want I want to do is allow user to have two associated Apps running.
    Instead of having to leave the primary app and click on the listbox in the other App,
    Send a message to the listbox in the other App with the listbox choice so it updates all other control information for that choice.

    LB_SETCURSEL identifies and highlights the listbox item of interest. However it does not appear to trigger the listbox click event
    to allow all other controls to update.

    Using FINDSTRING or FINDEXACTSTRING does not appear to work XProcess. Whether it would in fact trigger the click event if it did work is unknown.

    Questions -- in my mind -- and if someone has the answers:
    1) Does the listbox need to have focus for this to occur
    2) Whats the best way to ID the point (x,y) location of the item of interest in order to send WM mouse messages.
    (e.g. ClientToScreen)
    3) Does the parent need to be involved even though I have the handle to the listbox.

  6. #6
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    Manually sending the LBN_SELCHANGE notification code after having sent the LB_SETCURSEL message appears to work:

    Code:
    Option Explicit
    
    Private WithEvents LB As VB.ListBox
    
    Private Sub Form_Load()
        Dim i%, shWnd$, PB As VB.PictureBox
    
        Set PB = Controls.Add("VB.PictureBox", "PB")
        PB.BorderStyle = 0
        PB.Visible = True
    
        Set LB = Controls.Add("VB.ListBox", "LB", PB)
        LB.Visible = True
    
        For i = 0 To 99
            LB.AddItem i
        Next
    
        shWnd = "&H" & Hex$(LB.hWnd)
        Caption = "LB.hWnd = " & shWnd
        Clipboard.Clear
        Clipboard.SetText shWnd
    End Sub
    
    Private Sub Form_Resize()
        With Me!PB
            .Move ScaleLeft, ScaleTop, ScaleWidth, ScaleHeight
            LB.Move .ScaleLeft, .ScaleTop, .ScaleWidth, .ScaleHeight
        End With
    End Sub
    
    Private Sub LB_Click()
        Caption = LB
    End Sub
    Code:
    Option Explicit
    
    Private Declare Function GetDlgCtrlID Lib "user32.dll" (ByVal hWndCtl As Long) As Long
    Private Declare Function GetParent Lib "user32.dll" (ByVal hWnd As Long) As Long
    Private Declare Function SendMessageW Lib "user32.dll" (ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    
    Private WithEvents CB As VB.CommandButton
    
    Private Sub CB_Click()
        Const LBN_SELCHANGE = 1&, LB_ERR = -1&, LB_SETCURSEL = &H186&, WM_COMMAND = &H111&
        Dim Index&, hWndLB&, hWndParent&, HiWord&, LoWord&, RV1&, RV2&
    
        On Error GoTo 1
        hWndLB = CLng(Me!TB.Text)
        On Error GoTo 0
    
        Index = Int(100! * Rnd)
        RV1 = SendMessageW(hWndLB, LB_SETCURSEL, Index, 0&)
    
        If RV1 <> LB_ERR Then
            hWndParent = GetParent(hWndLB)
    
            If hWndParent Then
                HiWord = LBN_SELCHANGE * &H10000
                LoWord = GetDlgCtrlID(hWndLB) And &HFFFF&
                RV2 = SendMessageW(hWndParent, WM_COMMAND, HiWord Or LoWord, hWndLB)
    
                Caption = ("Index=" & Index) & ("  RV1=" & RV1) & ("  RV2=" & RV2)
            End If
    1   End If
    End Sub
    
    Private Sub Form_Load()
        Rnd -Timer * Now
        Randomize
        ScaleMode = vbPixels
    
        With Controls.Add("VB.TextBox", "TB")
            .Visible = True
    
            If Clipboard.GetFormat(vbCFText) Then
                .Text = Clipboard.GetText
            Else
                .Text = "Enter the ListBox's hWnd here"
            End If
        End With
    
        Set CB = Controls.Add("VB.CommandButton", "CB")
        CB.Caption = "&Click Random ListBox Item"
        CB.Visible = True
    End Sub
    
    Private Sub Form_Resize()
        Const GAP = 10!
    
        If WindowState <> vbMinimized Then
            With Me!TB
                .Move GAP, GAP, ScaleWidth - GAP - GAP, 22!
                CB.Move GAP, .Top + .Height + GAP, .Width
            End With
        End If
    End Sub
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  7. #7

    Thread Starter
    PowerPoster
    Join Date
    Jul 2001
    Location
    Tucson, AZ
    Posts
    2,166

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    Ms West:

    THANK YOU __ THANK YOU __ THANK YOU.
    Had spent the last couple of hours looking for IDC_LIST.
    Wasn't aware I could have easily obtained it with "GetDlgCtrlID"

    QUESTION:
    Why is SendMessageW needed?
    Just using MS Common Controls from VB5.
    Note: Code did NOT trigger click event with just SendMessage.

    Did find this about difference XP and Win7, but based on my read going the other way (dropping the W)
    https://social.msdn.microsoft.com/Fo...elopmentissues
    Last edited by dw85745; Jun 30th, 2016 at 04:36 PM.

  8. #8
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,653

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    It's just good practice these days to always just use the W variants of APIs. Unicode is just too common to ignore anymore, and there's really no benefit to not using it unless you're really lazy with string handling.

    Also last time I actually did cross-process stuff:
    Call SendMessage(hList, LB_SETCURSEL, index, 0&)
    Call PostMessage(hList, WM_LBUTTONDBLCLK, 0&, 0&)

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Jul 2001
    Location
    Tucson, AZ
    Posts
    2,166

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    fafalone:
    Thanks for your input.

    Re:
    It's just good practice these days to always just use the W variants of APIs. Unicode is just too common to ignore anymore
    "W" supprised me since I'm using VB5.

    Call SendMessage(hList, LB_SETCURSEL, index, 0&)
    Call PostMessage(hList, WM_LBUTTONDBLCLK, 0&, 0&)
    Didn't try this -- will give it a go -- but was of the opinion I would need to be sending a WM_ mouse to the same line as LB_SETCURSEL.

  10. #10
    Default Member Bonnie West's Avatar
    Join Date
    Jun 2012
    Location
    InIDE
    Posts
    4,060

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    Quote Originally Posted by dw85745 View Post
    Had spent the last couple of hours looking for IDC_LIST.
    Wasn't aware I could have easily obtained it with "GetDlgCtrlID"
    There is no constant value for a control's ID. The control ID is dynamically assigned (by the programmer or the compiler, in VB6's case) during the creation of the child window and I suspect (but haven't verified) that it may even be possible to change it afterwards. EDIT It appears it can be done via SetWindowLong(..., GWL_ID, ...).

    Quote Originally Posted by dw85745 View Post
    Why is SendMessageW needed?
    I tend to call Unicode APIs whenever possible for 2 reasons: (1) Microsoft recommends that practice for all new programs and (2) on NT-based OSs, Unicode APIs are faster than their ANSI counterparts (especially when strings are involved). In the code above, there are no strings being passed to the SendMessage API, so if you prefer calling the traditional ANSI declaration of SendMessage, there's nothing stopping you from simply changing W to A.

    Quote Originally Posted by dw85745 View Post
    Just using MS Common Controls from VB5.
    Note: Code did NOT trigger click event with just SendMessage.
    I'm confused. I thought you were using the intrinsic ListBox control? Are you, in fact, using the ListView control instead?

    Quote Originally Posted by dw85745 View Post
    "W" supprised me since I'm using VB5.
    It should be possible to call "Wide" APIs in VB5 as well. It can be done either by using StrPtr/VarPtr or via Unicode declarations in a TLB.
    Last edited by Bonnie West; Aug 16th, 2016 at 11:46 AM.
    On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
    Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Jul 2001
    Location
    Tucson, AZ
    Posts
    2,166

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    fafalone

    Tried your suggestion. Could not get it to work.

    ///////////////////////////////////////////////////////////////////

    Ms. West.
    Thanks for clearing several things up for me.

    Re:
    I'm confused. I thought you were using the intrinsic ListBox control?
    I am. My error. Will chalk it up to a senior moment.

    It should be possible to call "Wide" APIs in VB5 as well.
    Had no problem using SendMessageW in VB5.
    However, when I substituted SendMessageA -- when I "tested" your code for further understanding -- it failed, hence the question on why "W" was needed. Will check my declare again and retest based on your comments.

    ---------------------------------------------------------------
    As a aside, don't know if this may be of interest to you.
    PBS discussed a new book yesterday titled: "Rise of the Rocket Girls".
    Turns out before computers, a group of NASA women had the job title "computer"
    and did ALL the space calculations using the old manual calculators (remember them well) and by hand.
    Unfortuantely, no or little credit for their efforts.
    May be an interesting read.
    Last edited by dw85745; Jul 1st, 2016 at 08:44 AM.

  12. #12
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,653

    Re: Trigger Listbox Click Event in Out of Process LIstbox

    Just goes to show not all listboxes respond to all messages when there's a bunch of different ways to do it that wouldn't be different to a normal user. The code was from a production app, and absolutely worked on the particular list it was designed for. C/C++ sometimes don't have high level "events".. all the processing comes from manually responding to WM_ messages. So if the only handled message was WM_NOTIFY codes, for example, they wouldn't be triggered by WM_[buttonclicks], but the end user would never notice.
    Good old fashioned trial and error will tell you which messages it responds to.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width