Solved

LB_ADDSTRING with SendMessage

Posted on 2002-04-17
13
1,952 Views
Last Modified: 2007-12-19
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.
0
Comment
Question by:MCHomes
  • 6
  • 5
  • 2
13 Comments
 
LVL 16

Expert Comment

by:Richie_Simonetti
Comment Utility
you need to use sendmessage with
Private Const LB_GETHORIZONTALEXTENT = &H193
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
Comment Utility
0
 
LVL 16

Expert Comment

by:Richie_Simonetti
Comment Utility
forget about my first comment, constant was:
Private Const LB_SETHORIZONTALEXTENT = &H194
0
 

Author Comment

by:MCHomes
Comment Utility
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
 
LVL 7

Expert Comment

by:Z_Beeblebrox
Comment Utility
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
 
LVL 16

Expert Comment

by:Richie_Simonetti
Comment Utility
Good luck then!
Cheers
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 16

Expert Comment

by:Richie_Simonetti
Comment Utility
0
 

Author Comment

by:MCHomes
Comment Utility
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
 

Author Comment

by:MCHomes
Comment Utility
Z_Beeblebrox,

continued...My listbox is owner-drawn and created using CreateWindowEx so there is no NewIndex property.
0
 
LVL 16

Accepted Solution

by:
Richie_Simonetti earned 300 total points
Comment Utility
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
 

Author Comment

by:MCHomes
Comment Utility
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
 

Author Comment

by:MCHomes
Comment Utility
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
 
LVL 7

Expert Comment

by:Z_Beeblebrox
Comment Utility
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

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now