Changing font within a string.

nobodySpecial
nobodySpecial used Ask the Experts™
on
I'm trying to change the font of part of a string before added to a list box but can't seem to figure out how, or even if its possible. I want to add a string item that is part bold and part regular. I know how to change the whole box, but I just want part of the string to change. Is there a technique to format a string in this special way, much like a mark-up? I would appreciate any help.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
I'm fairly certainyou can not do this with a standard listbox.  You can however do it with a RichTextBox, but then again, it wouldn't be a listbox now would it.  You could roll-yer-own listbox, but it would have to be user-drawn.  I'm fairly certain somebody has built a listbox that allows this:

Try looking at:
http://9rays.net/cgi-bin/components.cgi?act=2&cid=1



Alternatively, you can use the Listview.  You can then set each total list item as bold if you'd like, but not part of the string as you indicate desiring to do.:

    With ListView1
        .ListItems(1).Bold = True
    End With
Author of the Year 2009

Commented:
Hi nobodySpecial,
It appears that you have forgotten this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Refund points and save as a 0-pt PAQ.
    *** ownerdraw listbox could do it but I don't know if possible with VB

nobodySpecial, Please DO NOT accept THIS comment as an answer.
EXPERTS: Post a comment if you are certain that an expert deserves credit.  Explain why.
==========
DanRollins -- EE database cleanup volunteer
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Dan,
Yes, an Owner-drawn listbox is possible with VB but definitely not for the faint of heart.  I have personally created 4 owner drawn controls in use in the industrial world.  Haven't done a list box as is possibly required here, but the APIs are chock full of methods to do this and if pressed to do it, I could do so within a couple of days (but at 50 points would rather see this PAQ'd and refunded)

There's a lot of ownerdrawn/userdrawn VB6 projects on the net and even several combobox/listbox ones for examples.

 The VB help files have all kinds of information regarding User Drawn controls.  For instance a topic in the help file would be "User-Drawn Controls"  Here's the text from the help file For this topic:

When you're doing your own drawing, the only place you need to put drawing code is in the UserControl_Paint event procedure. When the container repaints the area your control is located on, the UserControl object will receive a Paint event.

If the built-in graphics methods of the UserControl object, such as Line and Circle, don't meet your drawing needs, you can use Windows API calls to draw your control. You can also "draw" text on your control using the Print method. Regardless of the drawing technique, the code goes in UserControl_Paint.

If your control has to change its appearance based on user actions, such as when the user clicks on the control, you can raise the Paint event by calling the UserControl's Refresh method.

Note   While you cannot draw on the transparent parts of a UserControl with BackStyle = Transparent, it is possible to create controls with transparent backgrounds that are mostly user-drawn. See "Giving Your Control a Transparent Background," earlier in this chapter.

Important   In Paint events, do not use DoEvents, or any other code that yields to other programs. Doing so will cause errors.

The following example demonstrates the basic principle of a three-state button, each of the three states being represented by a different bitmap. To work through the example, open a new Standard EXE project and use the Project menu to add a UserControl to the project. Place a PictureBox on the UserControl, and set object properties as follows:

Object Property Setting
UserControl Name TripleState
PictureBox AutoRedraw True
 Name picStates
 Picture (Any bitmap)
 Visible False


Note   The example works best if the bitmap chosen for the Picture property changes color dramatically from left to right.

Add the following code to the Declarations section of the UserControl's code window.

Option Explicit
' Private variable keeps track of the current state.
Private mintState As Integer

A simple mechanism is used to provide the three states: Clicking on the control rotates through the states by incrementing the value of a private state variable each time the control is clicked. If the value becomes too large, it is reset to zero. Add this code to the UserControl's Click event.

Private Sub UserControl_Click()
   mintState = mintState + 1
   If mintState > 2 Then mintState = 0
   ' The following line causes Paint event to occur.
   Refresh
End Sub

Add the following code to the UserControl's Paint event. When the Paint event occurs, the code copies one-third of the bitmap in the invisible PictureBox to the UserControl. Which third is copied depends on the current value of the private state variable mintState.

Private Sub UserControl_Paint()
   PaintPicture picStates.Picture, 0, 0, ScaleWidth, _
      ScaleHeight, mintState * picStates.Width / 3, _
      0, picStates.Width / 3
End Sub

Note   Another way to provide a different appearance for the each of your control's states is to use the Select…Case statement.

When mintState is zero, its initial value, the first third of the hidden bitmap will be copied onto the UserControl, as shown in Figure 9.12.

Figure 9.12   Copying the first third of the hidden bitmap to the UserControl



Click the Close box on the UserControl designer, to enable its icon in the Toolbox. Double-click the icon to place a copy of the control on a form, and press F5 to run the project. Click on the control to change the state.

You can hide the form behind another window, or minimize and restore the form, to verify that the control correctly retains its state, and repaints accordingly.

Tip   For better performance when drawing your own control, make sure the AutoRedraw property is set to False.

For More Information   See "Drawing the ShapeLabel Control," in "Creating an ActiveX Control."

Using Windows API calls is discussed in "Accessing the Microsoft Windows API," in the Component Tools Guide.The PaintPicture method is discussed in "Working with Text and Graphics," in the Visual Basic Programmer's Guide.

Working with Other Events
In similar fashion, you can simulate other event-driven appearance changes, such as button presses. To animate button presses, put state-changing code in the MouseUp and MouseDown events. Regardless of the events being used, the principle is the same: change the state, and call the Refresh method.

Showing That a User-Drawn Control Has the Focus
If your control can get the focus, you will need a second state variable to keep track of whether your control currently has the focus, so that each time your control redraws itself it will show (or not show ) an appropriate indication that it has the focus.

The Windows API DrawFocusRect can be used to draw the type of single-pixel dotted line used to show focus in the CommandButton control. There is no comparable API for non-rectangular shapes.

For More Information   See "How to Handle Focus in your Control," earlier in this chapter.

Showing a User-Drawn Control as Disabled
If you implement an Enabled property, you will need to keep track of whether your control is enabled, so you can provide a visual cue to the user when your control is disabled.

If you implement your control's Enabled property as discussed in "Allowing Your Control to be Enabled and Disabled," earlier in this chapter, you can simply test UserControl.Enabled to determine whether to draw your control as enabled or disabled.

The way you draw your control to indicate that it's disabled is entirely up to you.

User-Drawn Controls That Can Be Default Buttons
Setting the DefaultCancel property of your UserControl object to True tells the container your control can be a default or cancel button, so the Extender object can show Boolean Default and Cancel properties.

You can examine the value of the DisplayAsDefault property of the AmbientProperties object to determine whether your control should show the extra black border that tells the end user your control is the default button. Show the border only when the DisplayAsDefault property is True.

Important   Correct behavior for a button in Windows is to show the default border only if your control has been designated as the default button, and no other button has the focus. DisplayAsDefault is True only if both of these conditions are met. Other methods of determining when to display the border may result in incorrect behavior.

For More Information   See "Understanding the Container's Extender Object," and "Using the AmbientProperties Object to Stay Consistent with the Container," earlier in this chapter.

Handling the FontChanged Event
If you want to display text on your user-drawn control, you can do so using the Print method in the UserControl_Paint event. For example, the following code would display "Push Me" on the TripleState control from the previous example:

Private Sub UserControl_Paint()
   Cls      ' Clear any previous text
   Print Spc(3); "Push Me"
End Sub

There is just one problem with the above example — the text will always be displayed in the default font, even if you have exposed the Font property for your control. Your control has no idea that the font has changed, so the Paint event isn't fired.

To circumvent this problem, you need to add a Font object to your user control and call the User Control's Refresh method in the FontChanged event of the Font object. The Font object must be declared using the WithEvents keyword in order to expose this event:

Option Explicit
Private WithEvents mFont as stdFont

For a complete example of using a Font object and the FontChanged event, see "Adding a Font Object to Your User Control" in "ActiveX Control Features."


Author of the Year 2009

Commented:
Sorry twalgrave,
I didn't see that you had mentioned that very thing ("User drawn" didn't catch my eye when looking for "ownerdraw").  I'm changing my recommendation to:

   points to twalgrave

==========
DanRollins -- EE database cleanup volunteer    
Not a problem at all Dan.  Your cleanup work is very much appreciated.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial