能否徒劳地尝试一下,调用Windows API,让标准Treeview控件,正确显示Unicode字符,而不是????
myfav 2020-06-13 08:35:19 之所以说“徒劳”,实因十多年来,从未有人成功在简体中文版Windows本地代码页的系统环境下,让mscomctl.ocx中的Treeview控件正确显示阿拉伯文或韩文等等Unicode字符。
这意味着:此控件的Unicode支持,理论上,至少有99.9%的概率无法实现;甚至可能连“一线希望”也不存在。
究其本质原因,可能由于MSComctl.ocx中的Treeview控件窗口,初始化时以CreateWindowExA()来创建,比较方便支持ANSI;若打算完美支持Unicode,最好以CreateWindowExW()来创建。此外,控件在封装时,可能自动忽略了“4415”号消息,无论怎么SendMessage过去,也是白搭!当然,我无源代码,仅仅是无端猜测。呵呵。
这是抽取的VB代码:
***********************************
Private Type TVITEMW
Mask As Long
hItem As Long
State As Long
stateMask As Long
pszText As Long
cchTextMax As Long
iImage As Long
iSelectedImage As Long
cChildren As Long
lParam As Long
End Type
Private Const TVIF_TEXT As Long = &H1
Private Const TV_FIRST As Long = &H1100
Private Const TVM_SETITEMW As Long = (TV_FIRST + 63)
Private Sub SetNodeText(ByVal lNode As Long, ByVal sText As String)
Dim uTVW As TVITEMW
sText = sText & Chr$(0)
With uTVW
.hItem = lNode
.Mask = TVIF_TEXT
.pszText = StrPtr(sText)
.cchTextMax = LenB(sText)
End With
SendMessageW m_lTVHwnd, TVM_SETITEMW, 0&, uTVW
End Sub
***********************************
*以下相应的VFP代码,其实修改自张洪举老师《专家门诊——Visual FoxPro开发答疑160问》 之“第56问”的Treeview示例代码。
* 可惜最后一步SendMessageW()永远提示出错:“数据类型不匹配”。
* 不知狐友们有无办法让这一行正确运行?
***********************************
PUBLIC oform1
oform1=NEWOBJECT("form1")
oform1.Show
RETURN
**************************************************
*-- Form: form1 (e:\treeview\form1.scx)
*-- ParentClass: form
*-- BaseClass: form
*-- 时间戳: 06/13/20 08:18:04 PM
*
DEFINE CLASS form1 AS form
Top = 0
Left = 0
Height = 253
Width = 367
DoCreate = .T.
Caption = "简单的TreeView控件示例"
Name = "Form1"
ADD OBJECT olecontrol1 AS olecontrol WITH ;
Top = 18, ;
Left = 18, ;
Height = 199, ;
Width = 252, ;
Name = "Olecontrol1"
ADD OBJECT label1 AS label WITH ;
Caption = "Label1", ;
Height = 19, ;
Left = 12, ;
Top = 222, ;
Width = 312, ;
Name = "Label1"
ADD OBJECT command1 AS commandbutton WITH ;
Top = 18, ;
Left = 276, ;
Height = 24, ;
Width = 84, ;
Caption = "移除节点", ;
Name = "Command1"
PROCEDURE unitext
* UniText方法:调用API显示Unicode字符
lpara lNode, UniStr
TVIF_TEXT = 0x1
TV_FIRST = 0x1100
TVM_SETITEMW = TV_FIRST + 63
cUnicodeStr = UniStr + Chr(0) + Chr(0)
* 这里传送的相当于 vb 中 StrPtr( cUnicodeStr )
pBStr = SysAllocString( cUnicodeStr )
cchTextMax = len(cUnicodeStr)
pNode = SYS(3095, lNode)
* 构造显示文本的结构TVITEMW,共4*10=40字节
uTVW1 = BinToC(TVIF_TEXT, 'rs')
uTVW2 = BinToC(pNode, 'rs')
uTVW3 = Replicate(Chr(0), 8)
uTVW4 = BinToC(pBStr, 'rs')
uTVW5 = BinToC(cchTextMax, 'rs')
uTVW6 = Replicate(Chr(0), 16)
uTVW = uTVW1 + uTVW2 + uTVW3 + uTVW4 + uTVW5 + uTVW6
= SendMessageW( This.Olecontrol1.hWnd, TVM_SETITEMW, 0, @ uTVW )
SysFreeString( pBStr) && 释放这个 BSTR
ENDPROC
PROCEDURE Load
DECLARE Long SendMessageW IN WIN32API AS SendMessageW Long nHandle, Long nMessage, Long nParameter, Long uParameter
Declare Long SysAllocString In Oleaut32 String sz
Declare Long SysFreeString In Oleaut32 String bstr
ENDPROC
PROCEDURE olecontrol1.Collapse
*** ActiveX Control Event ***
LPARAMETERS node
Thisform.Label1.Caption="您对"+Node.Text+"进行了折叠操作"
ENDPROC
PROCEDURE olecontrol1.Expand
*** ActiveX Control Event ***
LPARAMETERS node
Thisform.Label1.Caption="您对"+Node.Text+"进行了展开操作"
ENDPROC
PROCEDURE olecontrol1.NodeClick
*** ActiveX Control Event ***
LPARAMETERS node
Thisform.Label1.Caption="您单击了"+Node.Text+"节点"
ENDPROC
PROCEDURE olecontrol1.Init
=COMPROP(this,'UTF8',1)
This.Font.Name = "Microsoft YaHei"
This.Font.Size = 12
loNode = Null
This.LineStyle= 1 && tvwRootLines
This.Style= 7 && tvwTreelinesPlusMinusPictureText
This.Nodes.Add(,,"Sport","体育")
This.Nodes.Add("Sport",4,"Ball","球类")
This.Nodes.Add("Ball",4,,"足球")
This.Nodes.Add("Ball",4,,"篮球")
This.Nodes.Add("Ball",4,,"排球")
This.Nodes.Add("Sport",4,"Swim","游泳")
This.Nodes.Add("Swim",4,,"蛙泳")
This.Nodes.Add("Swim",4,,"自由泳")
This.Nodes.Add(,,"Army","军事")
This.Nodes.Add("Army",4,"Kinds","军种")
This.Nodes.Add("Kinds",4,,"海军")
This.Nodes.Add("Kinds",4,,"陆军")
This.Nodes.Add("Kinds",4,,"空军")
This.Nodes.Add("Army",4,"Weapon","武器")
This.Nodes.Add("Weapon",4,,"枪")
loNode = This.Nodes.Add("Weapon",4,,"大炮")
* 试图将最后1个Node.Text修改为VFP不支持的Unicode字符:B14D B24D B34D B44D
lcUnicode = CHR(0xB1)+ CHR(0x4D)+ CHR(0xB2)+ CHR(0x4D)+ CHR(0xB3)+ CHR(0x4D)+ CHR(0xB4)+ CHR(0x4D)
thisForm.uniText(loNode, lcUnicode)
ENDPROC
PROCEDURE command1.Click
IF Thisform.Olecontrol1.Nodes.Count#0
Thisform.Label1.Caption="您移除了"+Thisform.Olecontrol1.SelectedItem.Text+"节点"
Thisform.Olecontrol1.Nodes.Remove(Thisform.Olecontrol1.SelectedItem.Index)
ENDIF
ENDPROC
ENDDEFINE
*
*-- EndDefine: form1
**************************************************