Unicode Controls & Classes for VB6 - Version 4

ctlUniMenu Control

Transforms a standard VB6 menu into an Unicode Icon menu;
as the VB6 menu is ANSI, the idea is to put Unicode data in ANSI format into menu item texts.
This is possible by encoding Unicode data to UTF8 or Hex. The menu will translate this encoded
data into Unicode at runtime (see [StringMode] property)
Check common properties here

Enums
Name Description
eUniMenuStringMode Menu string mode
Events
Name Description
OnOwnerDraw Raised when a menu item is about to be drawn. Change properties of this event for translating items
at runtime or assign icons to menu items. This event is called the first time for measuring the item
then every time the item needs to be refreshed
Properties
Name Type Description
CustomFontFace (String) Permits you to customize the font used for the menu without changing the one used by Windows.
You can for example set the font to "Arial Unicode MS" for displaying Vietnamese and Chinese words in the menu.
If this property is blank the control will use the one used by the system.
ExtSepBackColor (OLE_COLOR) Gets or sets a custom background color for extended separators
ExtSepForeColor (OLE_COLOR) Gets or sets a custom text color for an extended separator
FadeBackground (Boolean) Gets or sets the ability to fade the background of menu popups
FadeExtSep (Boolean) Gets or sets the ability to fade the extended separator
FadeLeftBand (Boolean) Gets or sets the ability to fade the left band background color
FullSelector (Boolean)
IconDim (Integer) Gets or sets the default size of item images
ImageArray (Collection) Permits you to specify a Collection of StdPictures to display automatically in menu items
when you configure them at design time. See remarks...
LeftBand (Boolean) Gets or sets the ability to show a left band in an alternate color
LeftBandBackColor (OLE_COLOR) Gets or sets a custom background color for the left band
LeftBandSeparators (Boolean) Gets or sets the ability to show a vertical line between the left band (contains icons) and the text
MenuBackColor (OLE_COLOR) Gets or sets the background color for menu popups
MenubarBackColor (OLE_COLOR) Gets or sets the menubar background color
MenubarForeColorDisabled (OLE_COLOR) Gets or sets the text color of menubar disabled items
MenubarForeColorNormal (OLE_COLOR) Gets or sets the text color of menubar "normal" items (not selected and not disabled)
MenuForeColorDisabled (OLE_COLOR) Gets or sets the text color for disabled menu items
MenuForeColorNormal (OLE_COLOR) Gets or sets the text color for menu "normal" menu items (not selected and not disabled)
OwnerDrawState (eOwnerDrawState) Gets the OwnerDraw status, by checking this flag you can load items (icons or images) only when needed
RightToLeft (Boolean) Gets or sets the ability to show bidirectional text on the control
RoundSelector (Boolean) Gets or sets the ability to use rounded borders for the item selector
SelectorBackColor (OLE_COLOR) Gets or sets the background color of menu selectors
SelectorForeColor (OLE_COLOR) Gets or sets the text color for selected items
SelectorStyle (eCtlButtonStyle) Gets or sets the style of the selector
Separators3D (Boolean) Gets or sets the ability to show 3D separators lines or not
StringMode (eUniMenuStringMode) Specify the type of encoding used by menu items
Methods
Name Type Description
Attach Starts the custom menu management by the control, you can optionally refresh the menubar if you specify a custom color for it in the control properties
Detach Terminates the custom menu management by tyhe control
Refresh Refreshes the entire menu; use this function when you need to translate main menu items (items on the menubar)
because the control cannot refresh them automatically when you change them
Remarks
How to use the control:
Place this control in every form with a menu; it permits you to turn a VB6 menu into an Unicode menu, use the [Attach] method to start the menu management in that form.
The Hexadecimal encoding permits you to use an ANSI string to specify an UNICODE string; in the [clsCommonWrapper] class you'll find conversion functions between UTF8, Hex and UNICODE strings.
The first pixel (0,0) of image items will be used as transparent color if you specify that the image should be treated as transparent ([OnOwnerDraw])

Choose the menu type using the [StringMode] property (available only at design time), 'Hex' is the default as the menu is able to check if strings are encoded in Hex or not.
If a menu item is not in Hex format, the menu will use it as it is.

StringMode = Hex
When using the Hex mode you can load every menu items using Hex encoded strings

mnuFile.Caption = clsCommonWrapper.StrToHex(myUnicodeString)


you can also design your menu at design time placing Hex strings into Captions (quite difficult to maintain).
You can also translate your strings to UNICODE at run-time changing strings in the OnOwnerDraw event.

StringMode=UTF8 (Available only for backward compatibility)
When using the UTF8 mode you can load every menu items using UTF8 strings

mnuFile.Caption = clsCommonWrapper.StrToUTF8(myUnicodeString)


you can also create your menu at design time placing UTF8/HEX strings into Captions.
You can also translate your strings to UNICODE at run-time changing strings in the OnOwnerDraw event.

StringMode=AsIs (no encoding)
The only way to use UNICODE strings is to translate/set them at run-time using the OnOwnerDraw event.
This option is very useful when you need only an advanced menu control without translation (for example you use only the English alphabet).

When using a MDI child form which replaces a parent MDI form menu remember that the child menu (OnOwnerDraw event) is managed by the parent.
In order to place extended separators, prefix a menu caption with [SEP]; the control will translate this item to an extended separator.
it 's possible to assign icons to items at design time by adding to the Caption the "|" character followed by the Index of the image in the ImageArray property (see above).



Working on multiple languages on the same application:
When working with many languages in the same application you probably need to translate the entire menu and the title of your form when a user choose to change the actual language.
Unfortunately there is no way for the ctlUniMenu to receive a notification from Windows that a Top level menu item (items on the menu toolbars) has been changed and need to be refreshed.
Sub-level menu items are automatically refreshed when they change.


You can avoid this problem by acting in this way:

ctlMenu.Detach

'<...Do your translations to the menu and to the Title of your Form...>

ctlMenu.Attach


Menu Sample:

- Put menu images into a ctlImageBag control (use bitmaps or icons)
- Draw a ctlUNiMenu control into your form
- Set StringMode=Hex (you must use Hex strings for menu captions); you can use the UTF8Conv program to translate Unicode strings to Hex strings. You can also use the [clsCommonWrapper] class for doing conversions.
- Write Hex strings into the menu designer (if you want) or setup them later using conversion functions:

mnuItem1.Caption=oCommonWrapper.StrToHex(UTF16String)


- In the Form_Load event of your form call the [Attach] method to start the menu management

Item Images:
I suggest you to use a private enum in order to store image indexes ;-)

Method 1:

- Use a | after the caption to setup images at design time (ex. Item2|2 uses the second image in the ctlUniMenu.ImageArray collection) or manage the [OnOwnerDraw] event
- Create a collection, add images clones ([ctlImageBag.GetPictureClone]) to the collection
- Set the new collection to the ctlUniMenu

Method 2:

Manage the [OnOwnerDraw] event of ctlUniMenu and set the oItemPic variable using the ctlImageBag control:

Private Sub ctlUTF8Menu1_OnOwnerDraw( _
sItemText As String, _
oItemPic As stdole.StdPicture, _
iItemPicWidth As Integer, _
iItemPicHeight As Integer, _
bItemPicTransp As Boolean, _
ByVal bItemSelected As Boolean)

Select Case sItemText
Case Item1.Caption
Set oItemPic = ctlImageBag1.GetPictureClone(epics_first)
Case Item2.Caption
Set oItemPic = ctlImageBag1.GetPictureClone(epics_second)
End Select
End Sub


If you change a Top Level menu item caption after having called the [Attach] method of the usercontrol, you need to use the [Refresh] method to refresh menu items.
This because there isn't a way to do such as thing automatically.
If you change all other menu items you don't need to do anything.