LB_ADDSTRING with SendMessage

Ok, This is where I'm at. I have an owner drawn listbox with a horizontal scrollbar. When a string item is added through the normal AddItem method of my control, The HorizontalExtent for the scrollbar is usually determined by the size of the string passed to the method. What I can't figure out is how to determine the width of the string item added, if a user populates my listbox via SendMessage API without using the AddItem method. I must find a way to determine what the added string item was so I can set my scrollbar.

I'm pretty sure I can hook the LB_ADDSTRING and LB_INSERTSTRING messages, but how do I get a reference to the actual string added, or even what the new index is, If these messages are hooked before the listbox is updated.
MCHomesAsked:
Who is Participating?
 
Richie_SimonettiConnect With a Mentor IT OperationsCommented:
Generally speaking:
If programer who uses your custom control use api to manage it, it is up to him how to solve the problem.
You already provided a method to add item to your custom control, so if programaer want to use API, good luck to him.
It is the same as for a common listbox contro from VB. If you want to use API to manage it, be clever enought how to solve the instric problem.
0
 
Richie_SimonettiIT OperationsCommented:
you need to use sendmessage with
Private Const LB_GETHORIZONTALEXTENT = &H193
0
 
Richie_SimonettiIT OperationsCommented:
0
Cloud Class® Course: Microsoft Office 2010

This course will introduce you to the interfaces and features of Microsoft Office 2010 Word, Excel, PowerPoint, Outlook, and Access. You will learn about the features that are shared between all products in the Office suite, as well as the new features that are product specific.

 
Richie_SimonettiIT OperationsCommented:
forget about my first comment, constant was:
Private Const LB_SETHORIZONTALEXTENT = &H194
0
 
MCHomesAuthor Commented:
Richie,
I don't mean to sound rude, but please read the question again. I'm not asking how to set the horizontal scrollbar. or even how to convert the string length to pixels. I already know that much. The example below is what I use from the AddItem method to set the scrollbar...

''''''''''
Sub SetHorizontalExtent(ByVal NewItem As String)

Dim lTextWidth As Long
Static m_LargestItemWidth As Long

        On Error Resume Next

        lTextWidth = (UserControl.TextWidth(NewItem) * Screen.TwipsPerPixelX)

        If m_LargestItemWidth < lTextWidth Then
                m_LargestItemWidth = lTextWidth
        Else
                Exit Sub
        End If

        If m_LargestItemWidth <> 0 Then
            SendMessage hLB, LB_SETHORIZONTALEXTENT,(m_LargestItemWidth / Screen.TwipsPerPixelX), 0
        End If
       
End Sub
''''''''''''

If the item is added through api instead of through the AddItem method in my control, how can I get the string width for the new item?
Example...
SendMessage hLB, LB_ADDSTRING, 0&, ByVal sItemText


When the new item is added through SendMessage, My WinProc function for the subclassed listbox passes the LB_ADDSTRING or LB_INSERTSTRING window messages.

example...
Friend Function WindowProcLB(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

    Select Case uMsg    
        Case LB_ADDSTRING, LB_INSERTSTRING
         ' ????????????????????????
        Case Else:
    End Select

    WindowProcLB = CallWindowProc(m_hWndLBProc, hWnd, uMsg, wParam, ByVal lParam)

End Function

Is there a way to retreive the current string item after the LB_ADDSTRING message has been sent to the subclassed listbox?
0
 
Z_BeeblebroxCommented:
This is cheap, but couldn't you detect the message, forward it on to the listbox, then use the new index property to determine which item was added, get the width of that item, then update the scroll bar appropriately?

Zaphod.
0
 
Richie_SimonettiIT OperationsCommented:
Good luck then!
Cheers
0
 
Richie_SimonettiIT OperationsCommented:
0
 
MCHomesAuthor Commented:
Z_Beeblebrox,

That's my problem. Even if I can hook and then consume the LB_ADDSTRING message, I would still need to retrieve the string for the new item being added so I can pass it to the listbox's AddItem method. But of course, Since the string for the added item is all I need anyway, hooking and forwarding the message would be unnecessary.
''''''''''''
'''''''''''''
'''''''''''''


Richie,

First, Thanks for the link. Unfortunately, after reading through some of the examples from the site, I couldn't really find anything helpful outside of a slightly different approach for creating a horizontal scrollbar.

I don't know if you downloaded the sample project or not, but the mAddScrollBar method calculates incorrect values for the text width.
0
 
MCHomesAuthor Commented:
Z_Beeblebrox,

continued...My listbox is owner-drawn and created using CreateWindowEx so there is no NewIndex property.
0
 
MCHomesAuthor Commented:
Richie,

Point well taken. Although in my opinion, VB's inability to display a horizontal scrollbar in a Listbox has nothing to do with a user's preference or instric problems. After all I can't see what programming dilemmas there would be in displaying a horizontal scrollbar when a vertical scrollbar has no problem. Oh well, that's probably something I should take up with Microsoft.
0
 
MCHomesAuthor Commented:
On second thought, I do agree with your general statement that programmers using activex controls will do what is necessary to allow full functionality of their apps. I just wanted to make that easier. Anyway, thanks for the help. I appreciate it.
0
 
Z_BeeblebroxCommented:
I'm sorry, I misunderstood.

The second parameter of the message is a pointer to the string being added. Unfortunately there is no way in VB that I am aware of to cast that pointer to a string. What you can do is use the copy memory API, passing in the pointer and returning the value pointed to by that pointer. The trick with this is that you don't know the size of the string. Maybe CopyMemory is smart enough to check this for you but I doubt it. Instead what you will have to do is get the string into a byte array. The first thing you do is extract the first 4 bytes into a long. This will tell you how long the string is. Then extract that many bytes * 2 (since it is UNICODE) into a byte array of the correct size. Then iterate through the byte array combined the two bytes of the unicode characters and appending them to a string. Definitately not pretty but it ought to work.

Zaphod.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.