VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "ArmColumn"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Private Const SEP = "ой"                  'standard armstrong separator
Private Const DT_CENTER = &H1
Private Const DT_LEFT = &H0
Private Const DT_RIGHT = &H2

Private Declare Function GetSystemDefaultLCID Lib "Kernel32" () As Long

Private Declare Function lstrlenW Lib "Kernel32" (lpString As Any) As Long
Private Declare Function WideCharToMultiByte Lib "Kernel32" (ByVal Codepage As Long, ByVal dwFlags As Long, lpWideCharStr As Any, ByVal cchWideChar As Long, lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpDefaultChar As String, ByRef lpUsedDefaultChar As Long) As Long

'armsyscom field type enumeration
Public Enum ArmSysType
  DBTYPE_EMPTY = 0
  DBTYPE_I4 = 3
  DBTYPE_R4 = 4
  DBTYPE_R8 = 5
  DBTYPE_DATE = 7
  DBTYPE_BSTR = 8 '- UNICODE string
  DBTYPE_BOOL = 11
  DBTYPE_STR = 129
  DBTYPE_BMP = 999
End Enum

Public Enum ArmMeasure
  MEASURE_NONE = 0
  MEASURE_SUM = 1
  MEASURE_AVG = 2
  MEASURE_COUNT = 3
  MEASURE_UNKNOWN = -1
End Enum

'column sorting directions flag
Public Enum ArmColSort
  csNone
  csAscending
  csDescending
End Enum

'name of column, column can be referenced by name or index
Public Name As String
'name of database field from which data will be populated
Public FieldName As String
'type of field
Public FieldType As ArmSysType
'format of column which is compatible with function Format
Public FormatString As String
'Alignment of column
Public Alignment As AlignmentSettings
'this column has system sort column (for date columns)
Public SortSystemColumn As ArmColumn
'position in sort list
Public SortOrder As Long
'this column is system sort column
Public IsSortSystemColumn As Boolean
'index of column in FlexGrid
Public ColumnIndex As Integer
'this column is measure for total functions
Public Measure As ArmMeasure
'this column is group column for measure function
Public Group As Boolean
'this column show subtotal for measure function
Public Subtotal As Boolean
'width of the column in printer units
Public PrintWidth As Long
'left coordinate of the column in printer units
Public PrintLeft As Long
'horizontal page number on which column is printed
Public PrintPage As Long
'grif reference
Public FlexGrid As MSFlexGrid
Public Grid As ArmGrid

Public mo_Trace As Object

Private mu_Sort As ArmColSort
'this column is key or not
Private mb_Key As Boolean

Public Property Let Key(ByVal ab_Value As Boolean)

  mb_Key = ab_Value
  Call Grid.UpdateKeyCount
End Property

Public Property Get Key() As Boolean

  Key = mb_Key
End Property

'get data in variant format from FlexGrid
Public Function GetData(al_Row As Long) As Variant
Dim lv_Value As Variant
  
On Error GoTo ErrorHandler
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:GetData")
#End If
  
  'skip first row with column titles
  If SortSystemColumn Is Nothing Then
    lv_Value = FlexGrid.TextMatrix(al_Row + 1, ColumnIndex)
  Else
    lv_Value = SortSystemColumn.GetData(al_Row)
  End If
  Select Case FieldType
  Case DBTYPE_I4
    GetData = CLng(Val(lv_Value))
  Case DBTYPE_R4, DBTYPE_R8
    GetData = CDbl(lv_Value)
  Case DBTYPE_DATE
    GetData = DateSerial(CInt(Mid(lv_Value, 1, 4)), CInt(Mid(lv_Value, 5, 2)), CInt(Mid(lv_Value, 7, 2))) + _
              TimeSerial(CInt(Mid(lv_Value, 10, 2)), CInt(Mid(lv_Value, 13, 2)), CInt(Mid(lv_Value, 16, 2)))
  Case DBTYPE_BOOL
    GetData = IIf((StrComp(lv_Value, "0") = 0) Or _
                  (StrComp(lv_Value, "N", vbTextCompare) = 0) Or _
                  (StrComp(lv_Value, "False", vbTextCompare) = 0), False, True)
  Case DBTYPE_BMP
    GetData = Trim(lv_Value)
  Case Else
    GetData = lv_Value
  End Select
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:GetData")
#End If
  Exit Function
ErrorHandler:
  GetData = Empty
#If CompDebug Then
  Call mo_Trace.WriteTraceError("ArmColumn:GetData", "al_Row=" & al_Row, _
  "ColumnIndex=" & ColumnIndex, "Name=" & Name)
#End If
End Function

'set data as variant into FlexGrid
Public Function SetData(al_Row As Long, av_Value As Variant) As Boolean
Dim ls_Value As String, lv_StrArray As Variant
Dim ll_SaveRow As Long, ll_SaveCol As Long
  
On Error GoTo ErrorHandler
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:SetData")
#End If
  
  Select Case FieldType
  Case DBTYPE_DATE
    If FormatString = "" Then
      If IsNull(av_Value) Then av_Value = 0
      If av_Value = 0 Then
        ls_Value = ""
      Else
        ls_Value = Format(av_Value, "dd\/mm\/yyyy")
        'ls_Value = Format(av_Value, "dd/mm/yyyy")
      End If
    ElseIf StrComp(FormatString, "CUSTOM", vbTextCompare) = 0 Then
      ls_Value = Grid.GetCustomFormat(av_Value, Me)
    Else
      ls_Value = Format(av_Value, FormatString)
    End If
  Case DBTYPE_R4, DBTYPE_R8
    If FormatString = "" Then
      ls_Value = CDbl(av_Value)
    ElseIf StrComp(FormatString, "CUSTOM", vbTextCompare) = 0 Then
      ls_Value = Grid.GetCustomFormat(av_Value, Me)
    Else
      ls_Value = Format(av_Value, FormatString)
    End If
  Case DBTYPE_BOOL
    If FormatString = "" Then
      ls_Value = IIf(av_Value, "Y", "N")
    Else
      ls_Value = Format(av_Value, FormatString)
    End If
  Case DBTYPE_BMP

    ll_SaveRow = FlexGrid.Row
    ll_SaveCol = FlexGrid.Col
  
    FlexGrid.Row = al_Row + 1
    FlexGrid.Col = ColumnIndex
    FlexGrid.CellPictureAlignment = flexAlignCenterCenter
    If Trim(av_Value = "") Then
      Set FlexGrid.CellPicture = Nothing
      ls_Value = ""
    Else
      lv_StrArray = Split(CStr(av_Value), SEP)
      Set FlexGrid.CellPicture = LoadResPicture(lv_StrArray(0), vbResBitmap)
      'this makes sure that user won't see text when he expand column
      FlexGrid.CellFontName = "Arial"
      FlexGrid.CellFontSize = 40
      ls_Value = Space(100) & av_Value
    End If
    If (ll_SaveRow <> 0) And (ll_SaveCol <> 0) Then
      FlexGrid.Row = ll_SaveRow
      FlexGrid.Col = ll_SaveCol
    End If
  Case DBTYPE_BSTR
  'unicode data
    av_Value = ConvertCodePageFromUnicode(av_Value, Grid.Codepage)
    If FormatString = "" Then
      ls_Value = CStr(av_Value)
    ElseIf StrComp(FormatString, "CUSTOM", vbTextCompare) = 0 Then
      ls_Value = Grid.GetCustomFormat(av_Value, Me)
    Else
      ls_Value = Format(av_Value, FormatString)
    End If
  Case Else
    If FormatString = "" Then
      ls_Value = CStr(av_Value)
    ElseIf StrComp(FormatString, "CUSTOM", vbTextCompare) = 0 Then
      ls_Value = Grid.GetCustomFormat(av_Value, Me)
    Else
      ls_Value = Format(av_Value, FormatString)
    End If
  End Select
  If Not (SortSystemColumn Is Nothing) Then
    Call SortSystemColumn.SetData(al_Row, av_Value)
  End If
  'skip first row with column titles
  FlexGrid.TextMatrix(al_Row + 1, ColumnIndex) = ls_Value
  SetData = True
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:SetData")
#End If
  Exit Function
ErrorHandler:
  SetData = False
#If CompDebug Then
  Call mo_Trace.WriteTraceError("ArmColumn:SetData", "al_Row=" & al_Row, _
  "ColumnIndex=" & ColumnIndex, "Name=" & Name, "av_Value=" & av_Value)
#End If
End Function

'sort column in FlexGrid
Public Function Sort() As Boolean

On Error GoTo ErrorHandler
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:Sort")
#End If
  
  Sort = False
  If SortDirection <> csNone Then
    If SortSystemColumn Is Nothing Then
      FlexGrid.Col = ColumnIndex
    Else
      FlexGrid.Col = SortSystemColumn.ColumnIndex
    End If
    FlexGrid.ColSel = FlexGrid.Col
    FlexGrid.RowSel = FlexGrid.Row
    
    Select Case mu_Sort
    Case csAscending
      Select Case FieldType
      Case DBTYPE_I4, DBTYPE_R4, DBTYPE_R8
        FlexGrid.Sort = flexSortNumericAscending
      Case DBTYPE_EMPTY
        FlexGrid.Sort = flexSortGenericAscending
      Case Else
        FlexGrid.Sort = flexSortStringNoCaseAscending
      End Select
    Case csDescending
      Select Case FieldType
      Case DBTYPE_I4, DBTYPE_R4, DBTYPE_R8
        FlexGrid.Sort = flexSortNumericDescending
      Case DBTYPE_EMPTY
        FlexGrid.Sort = flexSortGenericDescending
      Case Else
        FlexGrid.Sort = flexSortStringNoCaseDescending
      End Select
    End Select
    Sort = True
  End If

#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:Sort")
#End If
  Exit Function
ErrorHandler:
  Sort = False
#If CompDebug Then
  Call mo_Trace.WriteTraceError("ArmColumn:Sort", "FieldType=" & FieldType, _
  "ColumnIndex=" & ColumnIndex, "Name=" & Name, "mu_Sort=" & mu_Sort)
#End If
End Function

'set and get column width
Property Let Width(al_Value As Long)
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:Width_Let")
#End If
  
  FlexGrid.ColWidth(ColumnIndex) = al_Value

#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:Width_Let")
#End If
End Property

Property Get Width() As Long
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:Width_Get")
#End If
  
  Width = FlexGrid.ColWidth(ColumnIndex)

#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:Width_Get")
#End If
End Property

'set and get FlexGrid title
Property Let Title(as_Value As String)
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:Title_Let")
#End If
  
  FlexGrid.TextMatrix(0, ColumnIndex) = as_Value

#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:Title_Let")
#End If
End Property

Property Get Title() As String
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:Title_Get")
#End If
  
  Title = FlexGrid.TextMatrix(0, ColumnIndex)

#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:Title_Get")
#End If
End Property

'set sort direction, update column icon and sort column according data and direction
Property Let SortDirection(au_Value As ArmColSort)
Dim ll_SaveRow As Long, ll_SaveCol As Long

On Error GoTo ErrorHandler
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:SortDirection_Let")
#End If
  
  mu_Sort = au_Value
  ll_SaveRow = FlexGrid.Row
  ll_SaveCol = FlexGrid.Col
  
  FlexGrid.Row = 0
  FlexGrid.Col = ColumnIndex
  FlexGrid.CellPictureAlignment = flexAlignRightCenter
  'show or hide picture
  Select Case mu_Sort
  Case csNone
    Set FlexGrid.CellPicture = Nothing
  Case csAscending
    Set FlexGrid.CellPicture = LoadResPicture("ASC", vbResBitmap)
  Case csDescending
    Set FlexGrid.CellPicture = LoadResPicture("DESC", vbResBitmap)
  End Select
  'sort this column in FlexGrid
  'Call Sort
  FlexGrid.Row = ll_SaveRow
  FlexGrid.Col = ll_SaveCol
  
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:SortDirection_Let")
#End If
  Exit Property
ErrorHandler:
  FlexGrid.Row = ll_SaveRow
  FlexGrid.Col = ll_SaveCol
#If CompDebug Then
  Call mo_Trace.WriteTraceError("ArmColumn:SortDirection_Let", "FieldType=" & FieldType, _
  "ColumnIndex=" & ColumnIndex, "Name=" & Name, "mu_Sort=" & mu_Sort)
#End If
End Property

Property Get SortDirection() As ArmColSort
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:SortDirection_Get")
#End If
  
  SortDirection = mu_Sort

#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:SortDirection_Get")
#End If
End Property

Public Function GetMax(ByRef al_RowIndex As Long) As Variant
Dim ll_Row As Long
Dim lv_Max As Variant

On Error GoTo ErrorHandler
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:GetMax")
#End If
  
  lv_Max = Empty
  If FlexGrid.Rows > 1 Then
    lv_Max = GetData(0)
    al_RowIndex = 0
    For ll_Row = 1 To FlexGrid.Rows - 2
      If lv_Max < GetData(ll_Row) Then
        lv_Max = GetData(ll_Row)
        al_RowIndex = ll_Row
      End If
    Next
  End If
  GetMax = lv_Max

#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:GetMax")
#End If
  Exit Function
ErrorHandler:
#If CompDebug Then
  Call mo_Trace.WriteTraceError("ArmColumn:GetMax", "FieldType=" & FieldType, _
  "ColumnIndex=" & ColumnIndex, "Name=" & Name, "ll_Row=" & ll_Row)
#End If
End Function

Public Function GetMin(ByRef al_RowIndex As Long) As Variant
Dim ll_Row As Long
Dim lv_Min As Variant

On Error GoTo ErrorHandler
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:GetMin")
#End If
  lv_Min = Empty
  If FlexGrid.Rows > 1 Then
    lv_Min = GetData(0)
    al_RowIndex = 0
    For ll_Row = 1 To FlexGrid.Rows - 2
      If lv_Min > GetData(ll_Row) Then
        lv_Min = GetData(ll_Row)
        al_RowIndex = ll_Row
      End If
    Next
  End If
  GetMin = lv_Min

#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:GetMin")
#End If
  Exit Function
ErrorHandler:
#If CompDebug Then
  Call mo_Trace.WriteTraceError("ArmColumn:GetMin", "FieldType=" & FieldType, _
  "ColumnIndex=" & ColumnIndex, "Name=" & Name, "ll_Row=" & ll_Row)
#End If
End Function

Public Function GetSum() As Variant
Dim ll_Row As Long
Dim lv_Sum As Variant

On Error GoTo ErrorHandler
#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(True, "ArmColumn:GetSum")
#End If
  
  lv_Sum = 0
  If (FieldType = DBTYPE_I4) Or (FieldType = DBTYPE_R4) Then
    For ll_Row = 0 To FlexGrid.Rows - 2
      lv_Sum = lv_Sum + GetData(ll_Row)
    Next
  End If
  GetSum = lv_Sum

#If CompDebugGR Then
  Call mo_Trace.WriteTraceProc(False, "ArmColumn:GetSum")
#End If
  Exit Function
ErrorHandler:
#If CompDebug Then
  Call mo_Trace.WriteTraceError("ArmColumn:GetSum", "FieldType=" & FieldType, _
  "ColumnIndex=" & ColumnIndex, "Name=" & Name, "ll_Row=" & ll_Row)
#End If
End Function

Public Function Merge() As Boolean
  FlexGrid.MergeCells = flexMergeRestrictColumns
  FlexGrid.MergeCol(ColumnIndex) = True
End Function

Public Function DeleteRow(al_Row) As Boolean
  Call FlexGrid.RemoveItem(al_Row + 1)
End Function

Public Function CalculateMeasure(av_Sum As Variant, av_Count As Variant) As Variant

On Error GoTo ErrorHandler:
  CalculateMeasure = "N/A"
  Select Case Measure
  Case MEASURE_SUM
    CalculateMeasure = av_Sum
  Case MEASURE_AVG
    If av_Count > 0 Then
      CalculateMeasure = av_Sum / av_Count
    Else
      CalculateMeasure = "ERR"
    End If
  Case MEASURE_COUNT
    CalculateMeasure = av_Count
  End Select
  Exit Function
ErrorHandler:
  CalculateMeasure = "ERR"
End Function

' Returns the string up to the first Null Char
Private Function GetStrFromANSIBuffer(sBuf As Variant) As Variant
    If InStr(sBuf, Chr(&H0)) > 0 Then
        GetStrFromANSIBuffer = Left(sBuf, InStr(sBuf, Chr(&H0)) - 1)
    Else
        GetStrFromANSIBuffer = sBuf ' no null, so don't worry about it
    End If
End Function

' Return ANSI string from a pointer to a Unicode string.
Private Function GetStrFromPtrW(ByVal lpszW As Long, ByVal al_CodePage As Long, ByRef lpUsedDefaultChar) As Variant
    Dim sRV As String
    Dim llReturn As Long
    
    sRV = String$(lstrlenW(ByVal lpszW), Chr(&H0))  ' 2 bytes/char
     
    ' copy from Unicode string into new buffer
    WideCharToMultiByte al_CodePage, 1024, ByVal lpszW, -1, ByVal sRV, Len(sRV), Chr(&H0), lpUsedDefaultChar
    GetStrFromPtrW = GetStrFromANSIBuffer(sRV)
End Function

' Return ANSI string from a pointer to a Unicode string.
Private Function GetBoolFromPtrW(lpszW As Long, ByVal al_CodePage As Long) As Boolean
Dim ll_UsedDefaultChar
         
    GetBoolFromPtrW = False
    
    GetStrFromPtrW lpszW, al_CodePage, ll_UsedDefaultChar
    If ll_UsedDefaultChar = 0 Then
        GetBoolFromPtrW = True
    End If

End Function

'convert code page into charset integer
Public Function GetCharSetFromCodePage(ByVal al_CodePage As Long) As Long

    On Error GoTo Trace_Err

    Select Case CStr(al_CodePage)
        Case 932 ' Japanese
            GetCharSetFromCodePage = 128
        Case 936 ' Simplified Chinese
            GetCharSetFromCodePage = 134
        Case 949 ' Korean
            GetCharSetFromCodePage = 129
        Case 950 ' Traditional Chinese
            GetCharSetFromCodePage = 136
        Case 1250 ' Eastern Europe
            GetCharSetFromCodePage = 238
        Case 1251 ' Russian
            GetCharSetFromCodePage = 204
        Case 1252 ' Western European Languages
            GetCharSetFromCodePage = 0
        Case 1253 ' Greek
            GetCharSetFromCodePage = 161
        Case 1254 ' Turkish
            GetCharSetFromCodePage = 162
        Case 1255 ' Hebrew
            GetCharSetFromCodePage = 177
        Case 1256 ' Arabic
            GetCharSetFromCodePage = 178
        Case 1257 ' Baltic
            GetCharSetFromCodePage = 186
        Case Else
            GetCharSetFromCodePage = 0
    End Select
    
    Exit Function
    
Trace_Err:
End Function

Public Function GetCodePageFromLCID(ByVal al_LCID As Long) As Long

    On Error GoTo Trace_Err

    Select Case al_LCID
        Case 1041 ' Japanese
            GetCodePageFromLCID = 932
        Case 2052 ' Simplified Chinese
            GetCodePageFromLCID = 936
        Case 1042 ' Korean
            GetCodePageFromLCID = 949
        Case 1028 ' Traditional Chinese
            GetCodePageFromLCID = 950
        Case 1045 ' Eastern Europe
            GetCodePageFromLCID = 1250
        Case 1049 ' Russian
            GetCodePageFromLCID = 1251
        Case 1033 ' Western European Languages
            GetCodePageFromLCID = 1252
        Case 1032 ' Greek
            GetCodePageFromLCID = 1253
        Case 1055 ' Turkish
            GetCodePageFromLCID = 1254
        Case 1037 ' Hebrew
            GetCodePageFromLCID = 1255
        Case 1025 ' Arabic
            GetCodePageFromLCID = 1256
        Case 1061 ' Baltic
            GetCodePageFromLCID = 1257
        Case Else
            GetCodePageFromLCID = 1252
    End Select
    
    Exit Function
    
Trace_Err:
End Function

Public Function GetLCIDFromCodePage(ByVal al_CodePage As Long) As Long

    On Error GoTo Trace_Err

    Select Case al_CodePage
        Case 932 ' Japanese
            GetLCIDFromCodePage = 1041
        Case 936 ' Simplified Chinese
            GetLCIDFromCodePage = 2052
        Case 949 ' Korean
            GetLCIDFromCodePage = 1042
        Case 950 ' Traditional Chinese
            GetLCIDFromCodePage = 1028
        Case 1250 ' Eastern Europe
            GetLCIDFromCodePage = 1045
        Case 1251  ' Russian
            GetLCIDFromCodePage = 1049
        Case 1252  ' Western European Languages
            GetLCIDFromCodePage = 1033
        Case 1253 ' Greek
            GetLCIDFromCodePage = 1032
        Case 1254 ' Turkish
            GetLCIDFromCodePage = 1055
        Case 1255 ' Hebrew
            GetLCIDFromCodePage = 1037
        Case 1256 ' Arabic
            GetLCIDFromCodePage = 1025
        Case 1257 ' Baltic
            GetLCIDFromCodePage = 1061
        Case Else
            GetLCIDFromCodePage = 1033
    End Select
    
    Exit Function
    
Trace_Err:
End Function

Public Function DetectCodePageFromUnicode(ByVal av_String As Variant) As Long

    If GetBoolFromPtrW(StrPtr(av_String), 1252) Then
        DetectCodePageFromUnicode = 1252
        Exit Function
    End If
    If GetBoolFromPtrW(StrPtr(av_String), 1250) Then
        DetectCodePageFromUnicode = 1250
        Exit Function
    End If
    If GetBoolFromPtrW(StrPtr(av_String), 1251) Then
        DetectCodePageFromUnicode = 1251
        Exit Function
    End If
    If GetBoolFromPtrW(StrPtr(av_String), 1253) Then
        DetectCodePageFromUnicode = 1253
        Exit Function
    End If
    If GetBoolFromPtrW(StrPtr(av_String), 1254) Then
        DetectCodePageFromUnicode = 1254
        Exit Function
    End If
    If GetBoolFromPtrW(StrPtr(av_String), 1255) Then
        DetectCodePageFromUnicode = 1255
        Exit Function
    End If
    If GetBoolFromPtrW(StrPtr(av_String), 1256) Then
        DetectCodePageFromUnicode = 1256
        Exit Function
    End If
    If GetBoolFromPtrW(StrPtr(av_String), 1257) Then
        DetectCodePageFromUnicode = 1257
        Exit Function
    End If
    
    DetectCodePageFromUnicode = 1252
    
End Function

Public Property Get PrintAlignment() As Long
Dim ll_Align As Long

    ll_Align = 0
    Select Case Alignment
    Case AlignmentSettings.flexAlignRightCenter
        ll_Align = DT_RIGHT
    Case AlignmentSettings.flexAlignCenterCenter
        ll_Align = DT_CENTER
    Case AlignmentSettings.flexAlignLeftCenter
        ll_Align = DT_LEFT
    Case Else
        Select Case FieldType
        Case ArmSysType.DBTYPE_I4
            ll_Align = DT_RIGHT
        Case ArmSysType.DBTYPE_R4, ArmSysType.DBTYPE_R8
            ll_Align = DT_RIGHT
        Case ArmSysType.DBTYPE_DATE
            ll_Align = DT_RIGHT
        Case Else
            ll_Align = DT_LEFT
        End Select
    End Select
    PrintAlignment = ll_Align
End Property

Public Function ConvertCodePageFromUnicode(ByVal av_String As Variant, al_CodePage As Long) As Variant
Dim ll_UsedCodePage As Long

    ConvertCodePageFromUnicode = GetStrFromPtrW(StrPtr(av_String), al_CodePage, ll_UsedCodePage)
    
End Function

Public Function ConvertCodePageFromAnsi(ByVal av_String As Variant, al_CodePage As Long) As Variant
Dim ll_UsedCodePage As Long

    ConvertCodePageFromAnsi = StrConv(StrConv(av_String, vbFromUnicode, 1033), vbUnicode, GetLCIDFromCodePage(al_CodePage))
    
End Function

Public Function UCaseInternational(ByVal av_Text As Variant, ByVal al_CodePage As Long) As Variant

    UCaseInternational = ConvertCodePageFromUnicode(UCase(ConvertCodePageFromAnsi(av_Text, al_CodePage)), al_CodePage)

End Function

Public Function LCaseInternational(ByVal av_Text As Variant, ByVal al_CodePage As Long) As Variant

    LCaseInternational = ConvertCodePageFromUnicode(LCase(ConvertCodePageFromAnsi(av_Text, al_CodePage)), al_CodePage)

End Function



