-
Jun 29th, 2016, 10:02 PM
#1
Thread Starter
PowerPoster
[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?
-
Jun 30th, 2016, 03:54 AM
#2
Re: Trigger Listbox Click Event in Out of Process LIstbox
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
-
Jun 30th, 2016, 04:47 AM
#3
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
-
Jun 30th, 2016, 07:22 AM
#4
Thread Starter
PowerPoster
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.
-
Jun 30th, 2016, 09:25 AM
#5
Thread Starter
PowerPoster
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.
-
Jun 30th, 2016, 12:52 PM
#6
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)
-
Jun 30th, 2016, 04:26 PM
#7
Thread Starter
PowerPoster
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.
-
Jun 30th, 2016, 07:07 PM
#8
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&)
-
Jun 30th, 2016, 09:33 PM
#9
Thread Starter
PowerPoster
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.
-
Jun 30th, 2016, 11:29 PM
#10
Re: Trigger Listbox Click Event in Out of Process LIstbox
Originally Posted by dw85745
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, ...).
Originally Posted by dw85745
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.
Originally Posted by dw85745
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?
Originally Posted by dw85745
"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)
-
Jul 1st, 2016, 08:25 AM
#11
Thread Starter
PowerPoster
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.
-
Jul 1st, 2016, 01:38 PM
#12
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|