Home > Programmer's Guide > More About Programming > Adding Program Functionality

Dynamic Input Area

Most recent devices come with a collapsible graffiti area that the user can close when they do not need to enter characters. On these devices, the application area is not fixed: it is the usual square size while the input area is opened, and it is a rectangular size when the input area is closed, giving more space to the application. In this documentation, this feature is refered as DIA, which stands for Dynamic Input Area.

HB++ provides both a high-level and a low-level support for the DIA. In most applications, you won't have to write a single line of code to benefit the enlarged screen size; but you can also override the default processing if it does not suit your needs. This section describes how to support the DIA in your application.

Enabling DIA support

The dynamic input area is handled on a form-by-form basis. In a single application, some forms can support the enlarged screen size and of some others not. This behavior is determined by each form's DIA property, which can take one of the following values:

ValueDescription
DisabledThe form does not support the DIA. When this kind of form is entered, the input area is always opened and locked up, so that the form is displayed in the traditionnal square area. If your application is not intended to support DIA, you should select this value for all the forms in your project.
Enabled (Fixed)The form supports the DIA. When this kind of form is entered, the input area state is neither modified, nor locked; the user can open or close it as needed. However, the form is displayed "as is", using the position and dimensions specified at design time, and is never resized. This setting is typically used for dialog boxes or message boxes.
Enabled (Resize)Same as above, but the form is enlarged or shrinked as needed so that its right and bottom borders always reach the screen borders (the left and top borders are always fixed). This setting should be used for modeless full screen forms, such as your main application form.

Note that this property only specifies the way a form reacts to screen changes. It does not specify the input area state. If you wish to open, close or lock the DIA for a particular form, you should affect the relevant value to the InputArea global property at the time it is activated. However, this is strongly discouraged, as it is probably better to let the user decide whether the input area is opened or closed. Automatically changing the DIA state in too many instances can also result in a jumpy user interface that produces bad user experience.

If your application is not intended to support the DIA, you should set the DIA property to 'Disabled' for all forms. This will result in a smaller code, since the compiler will not link the DIA support routines in your executable file.

Dialog boxes

By default, dialog and message boxes are still displayed so that they are aligned with the bottom of a square, 160x160 pixels screen. This is consistent with most Palm OS® applications. However, you may want to ensure that dialog boxes are always aligned with the bottom of the screen, even if the dynamic input area is collapsed.

For dialog boxes, you can achieve this simply by specifying the hbFormAlignBottom flag when calling the Show method. For message boxes, the same can be obtained by specifying the hbMsgBoxAlignBottom flag when calling the MsgBox function.

Note that you should not bottom align a dialog box that contains a text field, since the user will have to open the input area to enter characters.

Moving controls, the easy way

When the user opens or closes the DIA and the currently active form has its DIA property set to 'Enabled (Resize)', this form is resized. It is typically time to change the layout of the form, so that the controls it is made of occupy the whole space. HB++ provides a very simple way to achieve this, using anchors.

Every control has an Anchors property, that allows to tie its borders to the form borders. When a form is resized, its controls are automatically moved and/or resized accordingly to these anchors. The following shows a simple form with a few controls and their anchors, and the way it looks like on the various available screen sizes:

Note that when defining anchors, you should keep in mind that a form can be resized both horizontally and vertically, due to the portrait and landscape modes available on some devices. For more information about anchors, please refer to the documentation for the Anchors property.

Moving controls, the hard way

In some circumstances, anchors do not provide enough flexibility. For example, you could have a form with two buttons, and wish that these buttons are always the same height or width; when the user closes the DIA, the extra space should be dispatched equally between the two controls. You can achieve this by handling the Resize event, and manually move your controls. The following example illustrate this:

Private Sub Form_Resize(ByVal iWidth As Integer, ByVal iHeight As Integer)
  Dim h as Integer
  
  h=(iHeight-30)/2
  Button1.Move 1,20,iWidth-2,h-1
  Button2.Move 1,h+30,iWidth-2,h-1
End Sub

You can mix automated anchors processing and manual processing. Since the Resize event is always sent after the new layout is computed, you can override any default processing in your code. However, you should not repaint your form from this event handler, as it can result in flickering; the user interface will automatically be redrawn when the resize process terminates.

You should keep in mind that receiving a Resize event does not mean that the DIA state changed; it means the form dimensions changed. Therefore, you won't receive this event if the user simply rotates the screen while the input area is opened, or if your form has its DIA property set to 'Enabled (fixed)'. Although this is not permitted yet, in a future release you may also receive this event as a result of resizing a form by calling its Move method.

Special cases

Some controls perform special processing when resized, as described below:

ControlDescription
ListThe height of a list always adapts so that an integral number of items are displayed. Due to this, the spacing between the bottom of a list and the controls below can vary.
FieldThe height of a field always adapts so that an integral number of lines are displayed. Due to this, the spacing between the bottom of a field and the controls below can vary, and the height of an attached scrollbar may not always match the height of the field.
SpinButtonThis control cannot be resized.
LabelThis control cannot be resized, as its size depends on the text it displays.
PictureThis control cannot be resized, as its size depends on the bitmap it displays.
GraffitiThis control cannot be resized.
GridThis control cannot be resized. You should use a GridEx control instead.
UserControlWhen this control is resized, either automatically due to anchors or manually when calling its Move method, it receives an Resize event, and then a Paint event. It is up to your code to handle those events appropriately, as explained in the next section.

User controls and double buffering

Most user controls (and some forms) rely on double buffering, using a bitmap allocated at the time the component is loaded. This won't work anymore for components that can be resized; offscreen bitmaps should now be created and possibly resized in the Resize event handler. The following shows the preferred way of implementing double buffering in a user control:

Private bm As New Bitmap

Private Sub UserControl_Load()
  ' You can initialize some member variables here.
End Sub

Private Sub UserControl_Resize(ByVal iWidth As Integer, ByVal iHeight As Integer)
  ' Create or resize the offscreen bitmap, and
  ' update its content.
  bm.Create iWidth, iHeight
  UpdateControl
End Sub

Private Sub UserControl_Paint()
  ' Copy the bitmap to the screen
  CopyArea 0,0,Width,Height,bm,0,0
End Sub

Private Sub UpdateControl()
  ' Update the offscreen bitmap content. For example:
  bm.BackColor=hbColorBlue
  bm.ForeColor=hbColorBlack
  bm.Rectangle 0,0,Width-1,Height-1,hbRectBorderSolid+hbRectFillSolid
End Sub

For more information on this sample, you should read the Form introductory page which describes the various events forms and controls receive during their lifetime.