# Re: 唔该...答下我呀..

Posted by 老怪 on March 01, 1999 at 08:54:23:

In Reply to: Re: 唔该...答下我呀.. posted by jutso on February 25, 1999 at 10:00:31:

: : 请问如何使它们可以在Listbox 或其他工具做到对称显示...(好似 Getright 中间那个显示Local File , Resume , Progress.... 可以自由控制它的长度, 又可做到对称显示)
: : 不知何故中文显示总是不能对称.
: : 我以将它们定为一提定字长..

: : Private Type Rec
: : Name as String * 50
: : Itme as string * 100
: : Total as Long
: : End type

: : Dim Data as Rec
: : ....
: : ....
: : ....
: : ....

: : List1.Additem Data.Name + Data.Item + Str(Data.Total)

: :
: : 结果 :

: : 公司 名称 货品 数量
: : -------------------------------------------------------------------------------------
: : Company A Item 1 10
: : Com B TEST ABC 5
: : TEST C ABCDEFGH 10
: : 某某店 AAAAA 150

: 你可以试着用 msflexgrid 来代替 listbox，当然两者还是不太
: 一样，能不能代替看你是用来做什么用的了！

分散对齐输出：
'Windows 字型在列印时，常为栏位对齐而苦，因为就算字串字数完全一样，
'也可能因个别字元宽窄不同，而造成字串输出宽窄不同(最明显的例子是空白字元)。
'就因为此种特性，使得以往在 Dos 时代，用空白字元补齐字串长度，以求输出
'栏位对齐的方式变的不可行，因此详细计算输出物件的座标，移动输出的目前位置再
'加以输出，虽然是一件苦差，但为求输出的准确，似乎是免不了的事。
'本范例就在展示如何利用 VB 输出物件的 CurrentX,CurrentY 属性，达成所有输出
'字串画面长度一样，并有 Word 常用 "分散对齐" 格式的效果。

'测试本范例，请于 Form 上布置 Command1、Picture1

Option Explicit
Private Sub Command1_Click()
Dim SendArray(2) As String
Dim I As Byte

SendArray(0) = "1234567890"
SendArray(1) = "VB 6.0 问世"
SendArray(2) = "长度相同的字串输出"

For I = 0 To 2
'逐一把字串阵列送往字串输出自订函数显示，
'取字长度是 10 个中文字
FixWidthString 10, SendArray(I)
Next
End Sub
'分散对齐输出自订函数
'StringLength 取字长度
'AcceptString 对齐字串
Private Sub FixWidthString(ByVal StringLength As Integer _
, ByVal AcceptString As String)
'计算取字有多宽的字串变数
Dim CalcString As String
'两字间隔的宽度
Dim SepWidth As Single
Dim I As Integer
'储存上次输出的结尾位置
Dim oldY As Single, oldX As Single

'接收字串比取字长度长则截断
If Len(AcceptString) > StringLength Then
AcceptString = Left(AcceptString, StringLength)
End If

'将取字变数填满中文字
CalcString = String(StringLength, "国")
'计算两字间隔的宽度，原理是取字变数比传入字串多出的长度，
'要平均插入两字间隔中
SepWidth = (Picture1.TextWidth(CalcString) - _
Picture1.TextWidth(AcceptString)) / _
(Len(AcceptString) - 1)

'记住输出前的 Y 座标
oldY = Picture1.CurrentY
'输出第一字
Picture1.Print "[" & Mid(AcceptString, 1, 1)
'换算接续输出的 X 座标是多少
oldX = oldX + Picture1.TextWidth("[" & Mid(AcceptString, 1, 1))

For I = 2 To Len(AcceptString)
'回到输出前的 Y 座标
Picture1.CurrentY = oldY
'输出位置向右移一空白间隔
oldX = oldX + SepWidth
'输出座标移到 oldX
Picture1.CurrentX = oldX
Picture1.Print Mid(AcceptString, I, 1)
'换算接续输出的 X 座标是多少
oldX = oldX + Picture1.TextWidth(Mid(AcceptString, I, 1))
Next
Picture1.CurrentY = oldY
Picture1.CurrentX = oldX
'"[" 和 "]" 主要是为了标示输出宽度，正式使用时请拿掉。
Picture1.Print "]"
End Sub
向右对齐输出：
'测试本范例请于 Form 上布置 Picture1,Command1
'欲使用于列印，将输出物件由 Picture 转至 Printer
Option Explicit
Private Sub Command1_Click()
'以下两行是把数字在左边补齐五个字，但最后你会发觉这在输出
'对齐上一点用都没有，因为 Windows 字型宽窄不一，同样字数字串
'宽度就是不一样。
Picture1.Print Right(Space(5) & Format(123, "###"), 5)
Picture1.Print Right(Space(5) & Format(12, "###"), 5)

'下面是呼叫右齐输出自订函数，此函数完全放弃了以往 Dos 补字数对齐字串
'的方法，以图形座标换算的方式，把不等长字串放在不同位置输出，达成右齐
'输出的目的。
FixRightPrint CStr(123), 5
FixRightPrint CStr(12), 5
'用 "W" 字元的目的是告诉你，同样是英文字元，字宽差别有多大。
FixRightPrint "WWWWW", 5
End Sub
'右齐输出自订函数
'PrintString 是欲右齐输出之字串
'PrintLength 是设定输出之最大字数
'StartPos 是设定输出时向右偏移字数，省略为不右移。
'以字数换算宽度的概念来说，本涵数以大写 "W" 宽度为单位。
Private Sub FixRightPrint(ByVal PrintString As String, _
ByVal PrintLength As Integer, _
Optional ByVal StartPos As Integer)
'纵合最大字数及偏移字数之计算宽度字串
Dim CalcWidthString As String
'计算宽度字串等于最大字数加偏移字数
CalcWidthString = String(PrintLength + StartPos, "W")
'以单 Byte 字元为计算基准
PrintString = StrConv(PrintString, vbFromUnicode)

'只取 PrintLength 字数输出
If LenB(PrintString) > PrintLength Then
PrintString = LeftB(PrintString, PrintLength)
End If

'还原为双位元字
PrintString = StrConv(PrintString, vbUnicode)

With Picture1
'移动输出之 X 轴
.CurrentX = .TextWidth(CalcWidthString) - _
.TextWidth(PrintString)
End With

Picture1.Print PrintString
End Sub

Follow Ups: