能否徒劳地尝试一下,调用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
**************************************************
...全文
187 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
myfav 2020-06-13
  • 打赏
  • 举报
回复
说实话,VB6我不太在行,连蒙带猜地“翻译”为VFP代码。 VB6大致思路,好像是用SendMessageW()发送一条消息,参数分别为: (oTree.hWnd, 4415, 0, 【具体显示内容的Type结构】) 其中,VB代码中的lNode参数,我不太确定是指Node的内存地址指针,还是Node.index。不过两者我都试过,都不行。 而10个Long型构成的Type...EndType结构,因VFP没有对应的结构,只能用40字节的字符串来模拟。就是这个结构体,我一直弄不好。 热切期待都市夜猫、wwwwb、十豆三……等API高手指点!

2,727

社区成员

发帖
与我相关
我的任务
社区描述
VFP,是Microsoft公司推出的数据库开发软件,用它来开发数据库,既简单又方便。
社区管理员
  • VFP社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧