|
Frequently Asked
Questions
-
Question 4:
I'm writing an bilingual application (Arabic/English) and was wondering how I
can get an Arabic version of the common dialogs such as print, file open etc.
-
Answer
First of all, the
common dialogs are resources in the comdlg32.dll, and the version that ships
with Arabic localized Windows 2000 and Windows XP contains English and two
versions of Arabic (one is mirrored (right to left layout) and the other is
not) resources, of course Windows 2000 and Windows XP multilingual version
contains the same as the Arabic localized version.
This means the
common dialog that ships with the English Windows 2000 and Windows XP has the
English resources only, which means there is no way for you to display Arabic
common dialogs on such platforms.
With this have been
said, the only platforms that you can achieve the functionality you are looking
for are Windows 2000 and Windows XP Arabic localized edition and Multilingual.
Now, how it works on
these platforms?
Common dialog loads
the appropriate resource language for your application, what this means?
It means if your user
interface is English it loads the English common dialog for you, and if it is
Arabic user interface it loads one of the two Arabic resources for you.
How common dialog
knows that your Application is English or Arabic?
The common dialog examines
the owner window's extended styles as shown below,
|
Owner Window ExStyle
|
Common dialog used
|
|
WS_EX_LAYOUTRTL
|
Mirrored
|
|
WS_EX_RIGHT or/and WS_EX_RTLREADING
|
Enabled
|
|
None of the
above.
|
English
|
So you can control the
common dialogs language by setting the appropriate window style to your common
dialog's owner window prior to loading the common dialog.
-
Question 5:
Is there a way to convert from one codepage to another using Windows APIs?
-
Answer
Windows does not have a
single API that allows you to convert from CP (code page) to another CP but it
has one API that allows you to convert from a given CP to Unicode and it has
another one to convert from Unicode to given CP.
These two APIs are MultiByteToWideChar
and WideCharToMultiByte.
The very first
parameter for these two APIs is the coed page that you are converting from or
converting to.
So if you want to convert
a string from CP1 to CP2 all what you need to do is
//First convert the
CP1 string to Unicode string
MultiByteToWideChar(CP1,.);
//Now your string is
Unicode convert it to CP2 string
WideCharToMultiByte(CP2,.);
-
Question 6:I
am trying to set the RightToLeft property in design time to true but am
unable to do so. Do I need to design my software on a BI-DIRECTIONAL platform?
Or do I need to set something special in Windows 2000?
-
Answer
First, you need to install
the Arabic language pack for Windows XP or Windows 2000, to be able to use the RightToLeft
property.
On Windows
2000: "Regional Options" in the "General"
tab, add Arabic to the "Language setting for the system"
On Windows
XP: "Regional and Language Options" go to the "Advanced"
tab and change the "Language for non Unicode programs" to an
Arabic language.
PS. This
will not affect the user interface language.
-
Question 7: I opened my Visual Basic 6.0, and by
default the RightToLeft property is set to false. I
have tried to set it as true, but the program
doesn't accept it. It returns the property back to
false again.
-
Answer
You need to make sure you installed
Arabic properly.
From the "Control Panel\regional
settings" in the "Language" tab select
"Details." for the input languages. You
should find Arabic.
To test Arabic Input, run "notepad.exe",
switch the keyboard to Arabic (by
pressing ALT + Shift right) and type
Arabic text. Is the Arabic text properly
displayed? If not then you should make
sure you installed the Arabic language
pack properly.
-
Question
8:I am facing small problem
regarding the screen flipping in Visual Basic 6.0 for the Arabic conversion of
my application. Some of the controls are not laid out from right-to-left
properly, even when I specify RightToLeft = True. Example Treeview and
Toolbar. Is there any work around?
-
Answer
The RightToLeft property
has limited effect over some controls. Examples Form, Treeview, Listview,
Toolbar, Progressbar and Statusbar. In order to correctly achieve
the RightToLeft look we need to adopt the SetWindowLong technique.
The following is a code listing for its implementation.
Create a module and
declare the following APIs
|
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function InvalidateRect Lib "user32" (ByVal hwnd As Long, lpRect As Long, ByVal bErase As Long) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Const GW_CHILD = 5
Public Const WS_EX_LAYOUTRTL = &H400000
Public Const GWL_EXSTYLE = (-20)
|
| |
At the form load add
the mirroring effect as follows
Private Sub Form_Load() 'On Form Load you need to set the mirroring for the controls
Dim OldLong As Long
'For Form
OldLong = GetWindowLong(Me.hwnd, GWL_EXSTYLE)
SetWindowLong Me.hwnd, GWL_EXSTYLE, OldLong Or WS_EX_LAYOUTRTL
InvalidateRect hwnd, 0, False
'For List
OldLong = GetWindowLong(List1.hwnd, GWL_EXSTYLE)
SetWindowLong List1.hwnd, GWL_EXSTYLE, OldLong Or WS_EX_LAYOUTRTL
InvalidateRect hwnd, 0, False
'For The StatusBar
OldLong = GetWindowLong(StatusBar1.hwnd, GWL_EXSTYLE)
SetWindowLong StatusBar1.hwnd, GWL_EXSTYLE, OldLong Or WS_EX_LAYOUTRTL
InvalidateRect hwnd, 0, False
'For TreeView
Dim nodX As Node
Set nodX = TreeView1.Nodes.Add(, , "R", "Root")
Set nodX = TreeView1.Nodes.Add("R", tvwChild, "C1", "Child 1")
Set nodX = TreeView1.Nodes.Add("R", tvwChild, "C2", "Child 2")
Set nodX = TreeView1.Nodes.Add("R", tvwChild, "C3", "Child 3")
Set nodX = TreeView1.Nodes.Add("R", tvwChild, "C4", "Child 4")
nodX.EnsureVisible
OldLong = GetWindowLong(TreeView1.hwnd, GWL_EXSTYLE)
SetWindowLong TreeView1.hwnd, GWL_EXSTYLE, OldLong Or WS_EX_LAYOUTRTL
InvalidateRect hwnd, 0, False
'For ListView
OldLong = GetWindowLong(ListView1.hwnd, GWL_EXSTYLE)
SetWindowLong ListView1.hwnd, GWL_EXSTYLE, OldLong Or WS_EX_LAYOUTRTL
InvalidateRect hwnd, 0, False
'For ProgressBar
ProgressBar1.Value = 50
OldLong = GetWindowLong(ProgressBar1.hwnd, GWL_EXSTYLE)
SetWindowLong ProgressBar1.hwnd, GWL_EXSTYLE, OldLong Or WS_EX_LAYOUTRTL
InvalidateRect hwnd, 0, False
'For ToolBar
mhwnd = GetWindow(Toolbar1.hwnd, GW_CHILD)
oldlong = GetWindowLong(mhwnd, GWL_EXSTYLE)
SetWindowLong mhwnd, GWL_EXSTYLE, oldlong Or WS_EX_LAYOUTRTL
InvalidateRect hwnd, 0, False
End Sub
|
-
Question 9: How can I create Arabic Menus in a Visual Basic 6.0 application? I need my menus to be displayed from right-to-left
Answer
|
The Visual Basic Menu Editor does not supply this functionality, but it is fairly easy to implement this feature. All what you need to do is set the MFT_RIGHTORDER format using SetMenuItemInfo. You can follow these simple steps.
| 1. | Open a new standard EXE project. Form1 is created by default. |
| 2. | On the Tools menu, click Menu Editor. Create your Arabic menu. |
| 3. | Add the following code to the General Declarations section of Form1: |
|
|
Option Explicit
Private Type MENUITEMINFO
cbSize As Long
fMask As Long
fType As Long
fState As Long
wID As Long
hSubMenu As Long
hbmpChecked As Long
hbmpUnchecked As Long
dwItemData As Long
dwTypeData As String
cch As Long
End Type
Private Const MF_STRING = &H0
Private Const MFT_RIGHTORDER = &H2000
Private Const MFS_DEFAULT = &H1000
Private Const MIIM_ID = &H2
Private Const MIIM_SUBMENU = &H4
Private Const MIIM_TYPE = &H10
Private Const MIIM_DATA = &H20
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetMenuItemInfo Lib "user32" _
Alias "GetMenuItemInfoA" _
(ByVal hMenu As Long, ByVal un As Long, ByVal B As Boolean, _
lpMenuItemInfo As MENUITEMINFO) As Long
Private Declare Function SetMenuItemInfo Lib "user32" _
Alias "SetMenuItemInfoA" _
(ByVal hMenu As Long, ByVal un As Long, ByVal bool As Boolean, _
lpcMenuItemInfo As MENUITEMINFO) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As Long) _
As Long
Private Sub Form_Load()
Dim mnuItemInfo As MENUITEMINFO, hMenu As Long
Dim BuffStr As String * 80 ' Define as largest possible menu text.
hMenu = GetMenu(Me.hwnd) ' Retrieve the menu handle.
BuffStr = Space(80)
With mnuItemInfo ' Initialize UDT
.cbSize = Len(mnuItemInfo) ' 44
.dwTypeData = BuffStr & Chr(0)
.fType = MF_STRING
.cch = Len(mnuItemInfo.dwTypeData) ' 80
.fState = MFS_DEFAULT
.fMask = MIIM_ID Or MIIM_DATA Or MIIM_TYPE Or MIIM_SUBMENU
End With
If GetMenuItemInfo(hMenu, 0, True, mnuItemInfo) = 0 Then
MsgBox "GetMenuItemInfo failed. Error: " & Err.LastDllError, , _
"Error"
Else
mnuItemInfo.fType = mnuItemInfo.fType Or MFT_RIGHTORDER
If SetMenuItemInfo(hMenu, 0, True, mnuItemInfo) = 0 Then
MsgBox "SetMenuItemInfo failed. Error: " & Err.LastDllError, , _
"Error"
End If
End If
DrawMenuBar (Me.hwnd) ' Repaint top level Menu
End Sub
|
- Run the project. Notice that menu items are right-justified at the far right-side of the menu bar and is completely functional.
|

|