How to create an enhanced label custom control?

Contributed by David Elfassy

1 - Introduction

This tutorial will teach you how to create your own user control. This user control will enhance the basic label control's capabilities.Actually, we will create from scratch a label control which will offer interesting new capabilities than the basic label control provided such like allows the developer to set properties BackColor, ForeColor, Font text and Text alignment. All these new enhancements will let you create a more attractive fully coloured interface for your programs.

2 - Setting the control's caption property

First of all, we start by creating a minimal project and add in a user control.

Click on the File menu, then choose the New command, the following dialog box appears:

New project dialog box

Choose Minimal Project, just as shown.

The following dialog box appears:

New project dialog box

You can leave all default values. Click the Next button. Do the same for step 2, just click the Next button. Finally to step 3 click the Finish button without changing anything. Now, we have a minimal project with a form. We have to add a UserControl. To do it, find the window called Project right click on UserControls and choose Add User Control into the contextual menu as shown below:

Contextual menu

UserControl1 is now added to your project. You can rename the user control by changing the property name UserControl1 for the following name: Enhanced_Label as shown below:

Renaming the UserControl

You can also change the frmMain caption property to Enhanced Label Demo.

At this point, the only thing we can expect from our enhanced custom control label is to display itself as a blank rectangle on a form.

To continue, double-click on the Enhanced_Label project item you have just added. This item is available in the project window:

Project window

Just add the following code for our control enhanced label:

Private Sub UserControl_Paint()
  'Draw the label border
  Rectangle 0, 0, Width-1, Height-1, hbRectBorderSolid+hbRectFillSolid
End Sub

Our new enhanced label control is now created! To test it, draw an occurrence of the enhanced label control onto your main form:

Open the main form and click on the tool box to choose the enhanced label control:

Toolbox

Once the Enhanced Label is selected, draw it on the form and launch the emulator. You can keep the default name which is Enhanced_Label1. You'll not see anything, except a blank rectangle:

A first try...

Our control is a little bit basic, isn't it? So what we are going to do now is to add the ability to set and display a text string into the control

Go back to the Enhanced Label project item (simply double click on it inside the Project Window, User Controls, Enhanced_Label).

At the top of the user control code, we declare a private variable called m_strCaption:

Private m_strCaption As String

m is for Member, str is for String. This convention is useful to know the type and scope of a variable simply from its name. This variable will contain our string shown into the label control.

We also add two properties procedures into the code:

Public Property Let Caption (ByRef Value as string)
End Property
Public Property Get Caption () as string
End Property

The Let Caption procedure property sets the content of our label's caption. The Get Caption procedure property allows us to get the current caption of the label. Now we are going to implement these properties. Add this code into each procedure property:

Public Property Let Caption (ByRef Value as string)
  m_strCaption = Value
  Repaint
End Property

Public Property Get Caption () As String
  Caption = m_strCaption
End Property

Also, we add this code into the two events control Load and Paint:

Private Sub UserControl_Load()
  m_strCaption = "Enhanced Label"
End Sub
Private Sub UserControl_Paint()
  'Draw the label border
  Rectangle 0, 0, Width-1, Height-1, hbRectBorderSolid+hbRectFillSolid
  'Show text in label centered horizontaly and vertically
  Textout Width/2, Height/2, m_strCaption, hbTextAlignCenter+hbTextAlignVCenter
End Sub

This is very important here to understand the role of the Load and the Paint events. Load is an event raised when the control is loaded in memory while the Paint event occurs when the control is painted on screen. We define the default value of the caption in the Load event. The default caption will be set to the word Enhanced Label, and will be showed on screen from the Paint event, using the TextOut function. One parameter of the TextOut function is the m_strCaption variable which contains our string.

Note that we raise automatically the Paint event by the reserved keyword Repaint called right after a change of the property in the Let Caption procedure.

Now we are going to show you how to modify the control's properties programmatically into our project. Add a button to your application in the main form and set its name property to Change_Caption and its Text property to Change Caption. Edit the code for the click event in the editor, and write in this code:

Enhanced_Label1.Caption = "Hello"

Now when you tap on the Change Caption button, the caption of the label changes to "Hello".

In the emulator, you will get this result:

Testing in the emulator

If you tap on the button, you should have this result:

The caption has changed

How does it works exactly ?

Actually, when you write this instruction:

Label_Enhanced1.Caption = "Hello!"

You change the Enhanced_Label Caption property. In the control code you actually make a call to Property Let Caption:

Public Property Let Caption (ByRef Value as string)
  m_strCaption = Value
  Repaint
End Property

The private variable m_strCaption is set to the Property Let parameter called Value. Value is passed to set the new caption for our control and is equal to "Hello!" in this case. Note that the member is updated directly, you should always first affect the new value to a private variable declared and visible only from the control code (m_strCaption, for instance). This allows you to perform checks on the new value before changingthe actual property value. Once m_strCaption is set, we raise immediately the Repaint event from our control.

This event refreshes the control by repainting it on the screen. Since the user control is repainted, the event UserControl_Paint() is raised, so the control caption will be redrawn with the new value of m_strCaption

Private Sub UserControl_Paint()
  'Show text in label centered horizontaly and vertically
  Textout Width/2, Height/2, m_strCaption, hbTextAlignCenter+hbTextAlignVCenter
End Sub

Additionnaly, suppose that you want to accept only 4 characters and no more for your caption, we could add into our Let Property a check before changing the value:

Public Property Let Caption (ByRef Value as string)
  If len(Value) > 4 then
    MsgBox "Please enter 4 characters only and no more"
    Exit Sub
  Else
    m_strCaption = Value
  End if
End Property

And, finally, you can get the actual caption property of the control simply by adding this statement into your Change_Caption Button event:

MsgBox Enhanced_ Label1.Caption

Actually, you call the Get Caption property of our Enhanced_Label:

Public Property Get Caption () As String
  Caption = m_strCaption
End Property

>Get Caption simply returns the current caption property of the control which is stored in the m_strCaption private variable.

That's all! Once you have assimilated the principle, it's pretty simple to continue our project. Now let's learn how to change the BackColor property of the Enhanced Label

3 - Changing the BackColor property

We will follow exactly the same approach.

Add a member variable called m_lngBackColor in our code control:

Private m_lngBackColor As Long

This variable will contain the Background Color of our enhanced label. Since a color is stored into a long integer, we had to declare our variable as a long variable, of course.

Also, add this code into the Load event:

Private Sub UserControl_Load()
  m_strCaption = "Label"
  m_lngBackcolor = hbColorWhite
End Sub

This line initializes the label background color to a default color, which is the "white" color in this example.

Now, add this code to the Paint event:

Private Sub UserControl_Paint()
  Backcolor = m_lngBackcolor
  'Draw the label border
   Rectangle 0, 0, Width-1, Height-1, hbRectBorderSolid+hbRectFillSolid
  'Show text in label centered horizontaly and verticaly
  Textout Width/2, Height/2, m_strCaption, hbTextAlignCenter+hbTextAlignVCenter
End Sub

This statement will paint the control with the color stored into the m_lngBackcolor variable (The white color, for instance) when your control appears on your form. Since the UserControl_Paint event is raised when you draw your control, the m_lngBackcolor member is initialized with the default background color.

But we also want to change programmatically the background color. So let's add two properties, just like we did before to set and get the caption control. However, we now want to set and get the background color of the control, so add those two properties:

Public Property Let BackColorLabel (Byval lngValue As Long)
  m_lngBackcolor = lngValue
  Repaint
End Property

Public Property Get BackColorLabel() As Long
  BackColorLabel = m_lngBackcolor
End Property

The Drawing color is defined when you call the BackColorLabel property. For example, draw a new button to your form and set its name to "Change_BackColor". Now open the code of its Click event and enter exactly the following statement to set the background color of the label to blue:

Enhanced_Label1.BackColorLabel = hbColorBlue

(Note that you can use any color constant to set the background color of the label easily)

Now, when you start the program and click on the button, the following code is executed:

Enhanced_Label1.BackColorLabel = hbColorBlue

Actually, you call the Let BackColorLabel property, inside the control code and pass the hbColorBlue value to this property. The blue color is, at first, assigned to our member variable m_lngBackcolor:

Public Property Let BackColorLabel (Byval lngValue As Long)
  m_lngBackcolor = lngValue
  Repaint
End Property

Now, m_lngBackcolor has the value hbColorBlue, the blue color.

Then, since the Repaint statement is called, the Paint event is raised, allowing us to immediately apply this change to our control by this statement:

Backcolor = m_lngBackcolor"

the control is repainted on the form with its new blue background color.

Note that the BackColor reserved word is a property inherited from the display class.

Here is the result:

Not blue yet

Click on the Change BackColor button, the background color of the label will become blue:

Blue is beautiful

To get the new background color of the control, you can use this statement whenever you want:

MsgBox Enhanced_Label1.BackColorLabel

4 - Adding the TextColor property

Now you know how to add properties to our Enhanced Label control and how to change them programmatically. What we are going to do now is to add a TextColor property allowing us to get/set the text color of our control.

Open the Enhanced_Label project item and add the following code:

Private m_lngTextcolor As Long

Public Property Let TextColorLabel (Byval lngValue As Long)
  m_lngTextcolor = lngValue
  Repaint
End Property

Public Property Get TextColorLabel () as long
  TextColorLabel = m_lngTextcolor
End Property

Also, add this line into the Private Sub UserControl_Paint() event handler:

Private Sub UserControl_Paint()
  'Change the background color
  Backcolor = m_lngBackcolor
  'Change the text color
  TextColor = m_lngTextcolor
  'Draw the label border
  Rectangle 0, 0, Width-1, Height-1, hbRectBorderSolid+hbRectFillSolid
  'Show text in label centered horizontaly and vertically
  Textout Width/2, Height/2, m_strCaption, hbTextAlignCenter+hbTextAlignVCenter
End Sub

Note that the TextColor reserved word is a property inherited from the Display class.

Now add this other line to the Private Sub UserControl_Load() event handler:

Private Sub UserControl_Load()
  m_strCaption = "Label"
  m_lngBackcolor = hbColorWhite
  m_lngTextcolor = hbColorBlack
End Sub

Now you can change the color of the label using a color constant .

Here is an example, you can copy it and paste it in the Click event handler of a button named Change Text Color to make the text color appear in red:

Enhanced_Label1.TextColorLabel = hbColorRed

When you launch the program you get this result:

Red is coming

Tap on the Change Text Color button, you will get this result:

Red is dead

Now let's see how to add a new feature allowing us to modify the font used in our Enhanced_Label control

5 - Adding the FontLabel property

We will add the "FontLabel" property allowing us to get/set the font used for the text inside our enhanced label control.

Select the Enhanced_Label item in the project explorer, and add the following code:

Private m_lngFontLabel As HbFont

Public Property Let FontLabel (Byval eFont As HbFont)
  m_lngFontLabel = eFont
  Repaint
End Property

Public Property Get FontLabel () as HbFont
  FontLabel = m_lngFontLabel
End Property

Then, add this statement into the Private Sub UserControl_Paint() event handler:

Private Sub UserControl_Paint()
  'Change the background color
  Backcolor = m_lngBackcolor
  'Change the text color
  TextColor = m_lngTextcolor
  'Change the font used for the label
  DrawFont = m_lngFontLabel
  'Draw the label border
  Rectangle 0, 0, Width-1, Height-1, hbRectBorderSolid+hbRectFillSolid
  'Show text in label centered horizontaly and vertically
  Textout Width/2, Height/2, m_strCaption, hbTextAlignCenter+hbTextAlignVCenter
End Sub

Note that the DrawFont reserved word is a property inherited from the Display class.

Now, add this line to the Private Sub UserControl_Load() event handler:

Private Sub UserControl_Load()
  m_strCaption = "Label"
  m_lngBackcolor = hbColorWhite
  m_lngTextcolor = hbColorBlack
  m_lngFontLabel = hbFontStandard
End Sub

Now you can change the font used in our Enhanced Label custom control by setting the FontLabel property using a font constant. Here is an example, you can copy it and paste it into the Click event handler of a button called Change_Font, to set the font of the label to a large font:

Enhanced_Label1. FontLabel = hbFontLarge

When you launch the program, you get this result:

Boo

Tap on the Change_Font button, the font is modified and is now larger.

Bigger, larger, stronger!

6 - List of the new properties added to the enhanced label control

Property Description
CaptionGet / Set the text displayed in the label
BackColorGet / Set the background color of the label
TextColorGet / Set the text color of the label
FontLabelGet / Set the font used to draw the label

7 - List of color constants

Constant Value Red Green Blue
hbColorBlack&H00000000000
hbColorBlue&H000000FF00255
hbColorCyan&H0000FFFF0255255
hbColorDarkGray&H00404040646464
hbColorGray&H00808080128128128
hbColorGreen&H0000FF0002550
hbColorLightGray&H00C0C0C0192192192
hbColorMagenta&H00FF00FF2550255
hbColorOrange&H00FFC080255192128
hbColorPink&H00FFB0B0255176176
hbColorRed&H00FF000025500
hbColorYellow&H00FFFF002552550
hbColorWhite&H00FFFFFF255255255

8 - List of font constants

hbFontStandard = 0
hbFontStandard

hbFontBold = 1
hbFontBold

hbFontLarge = 2
hbFontLarge

hbFontLargeBold = 7
hbFontLargeBold

hbFontSymbol = 3
hbFontSymbol

hbFontSymbol7 = 5
hbFontSymbol7

hbFontSymbol11 = 4
hbFontSymbol11

hbFontLED = 6
hbFontLED

9 - The complete source code for the Enhanced Label custom control

'============================================================
'User control declaration section
'============================================================
Private m_strCaption As String
Private m_lngBackcolor As Long
Private m_lngTextcolor As Long
Private m_lngFontLabel As HbFont

'============================================================
'Load event handler
'============================================================
Private Sub UserControl_Load()
  m_strCaption = "Enhanced Label"
  m_lngBackcolor = hbColorWhite
  m_lngTextcolor = hbColorBlack
  m_lngFontLabel = hbFontStandard
End Sub

'============================================================
'Paint event handler
'============================================================
Private Sub UserControl_Paint()
  'Change the background color
  Backcolor = m_lngBackcolor
  'Change the text color
  TextColor = m_lngTextcolor
  'Change the font used for the label
  DrawFont = m_lngFontLabel
  'Draw the label border
  Rectangle 0, 0, Width-1, Height-1, hbRectBorderSolid+hbRectFillSolid
  'Show text in label center horizontaly and verticaly
  Textout Width/2, Height/2, m_strCaption, hbTextAlignCenter+hbTextAlignVCenter
End Sub

'============================================================
'Caption property
'============================================================
Public Property Let Caption(ByRef Value as string)
  m_strCaption = Value
  Repaint
End Property
Public Property Get Caption() as String
  Caption = m_strCaption
End Property
'============================================================
'BackColorLabel property
'============================================================
Public Property Let BackColorLabel(Byval lngValue As Long)
  m_lngBackcolor = lngValue
  Repaint
End Property
Public Property Get BackColorLabel() as long
  BackColorLabel = m_lngBackcolor
End Property

'============================================================
'TextColorLabel property
'============================================================
Public Property Let TextColorLabel(Byval lngValue As Long)
  m_lngTextcolor = lngValue
  Repaint
End Property

Public Property Get TextColorLabel() as long
  TextColorLabel = m_lngTextcolor
End Property

'============================================================
'FontLabel property
'============================================================
Public Property Let FontLabel(ByVal eFont As HbFont)
  m_lngFontLabel = eFont
  Repaint
End Property

Public Property Get FontLabel()as HbFont
  FontLabel = m_lngFontLabel
End Property

You can downoad the whole project here

10 - Conclusion

The goal of this tutorial was to show you how easy it is to develop a custom user control.We have tried to explain in details how to add properties to a control. We hope that you have found this tutorial useful, as well as fun to read and to understand. Now you have all the knowledgeto create your own custom controls and extend your HB++ projects as far as you want with reusable and powerful controls.

We really hope that you will enjoy programming with HB++.

Contributed by David Elfassy