[RESOLVED] [Help]How to let WM_GETTEXT support unicode characters?
I'm using the code below to get text from controls, if the text only contains English letters, it works well. Once there are unicode characters involved, then the text becomes unreadable code.
Code:
Private Sub GetTextFromControls(oControl as Object)
Dim lRC As Long
Dim byt() As Byte
Dim lTextLen As Long
lTextLen = SendMessage(oControl.Hwnd, WM_GETTEXTLENGTH, 0, 0)
If lTextLen > 0 Then
ReDim byt(1 To lTextLen) As Byte
Call SendMessage(oControl.Hwnd, WM_GETTEXT, ByVal lTextLen + 1, byt(1))
oForm.txtControlText.Text = " " & Trim(StrConv(byt, vbUnicode))
Else
oForm.txtControlText.Text = ""
End If
End Sub
For example, the text is "立即", oForm.txtControlText.Text will become "¨¢¡é?¡ä".
Re: [Help]How to let WM_GETTEXT support unicode characters?
I'm not sure whether the problem is in the SendMessage call.
The standard VB Textbox is not capable of showing UNICODE texts, so maybe that's the problem
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by Arnoutdv
I'm not sure whether the problem is in the SendMessage call.
The standard VB Textbox is not capable of showing UNICODE texts, so maybe that's the problem
Sure, agree your point. SendMessage will put an byte array into my array "byt". I believe there is a way can let the textbox can display the unicode characters.
Re: [Help]How to let WM_GETTEXT support unicode characters?
Use the InkEdit control or the MSHFlexGrid, then you can test whether it's successful.
In the Code Library is a huge unicode component library developed by Krool
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by Arnoutdv
Use the InkEdit control or the MSHFlexGrid, then you can test whether it's successful.
In the Code Library is a huge unicode component library developed by Krool
Thank you for your suggestion. But I prefer the native method in VB6.0.
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by gyhu
Thank you for your suggestion. But I prefer the native method in VB6.0.
You can create an API textbox that supports unicode which can be complex depending on how you need to interact with it. You can jump to this forum's CodeBank section and look for unicode-aware controls.
Just a side note. Though you may not want to add dependencies, usually standard tools/components that are installed with Windows are considered exceptions. If it's already on the user's system, why not use it?
Edited: Here's an attempt to use VB's textbox for unicode. Partially successful, but requires manifesting for common controls. If interested, read through the entire thread. I am no longer pursuing that train of thought.
Last edited by LaVolpe; Apr 17th, 2018 at 05:38 AM.
Insomnia is just a byproduct of, "It can't be done"
Re: [Help]How to let WM_GETTEXT support unicode characters?
So the problem does in fact appear to be the get text call. Discovered the problem after seeing this thread and testing Unicode renaming in my shell control: It displays Unicode file names fine, when label edit starts the edit control displays the unicode characters fine, but then reading back the new (and old, checked) label contents, which relies on WM_GETTEXT, for rename fails with the question marks. (I'm checking with a MessageBoxW which shows the name correct when retrieved from the file record).
Dumped the raw data to confirm, text from record: 68 74 6D 2776 2777 2778 20 76
text from wm_gtx: 68 74 6D 3F 3F 3F 20 76 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Last edited by fafalone; Apr 17th, 2018 at 07:51 AM.
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by LaVolpe
You can create an API textbox that supports unicode which can be complex depending on how you need to interact with it. You can jump to this forum's CodeBank section and look for unicode-aware controls.
Just a side note. Though you may not want to add dependencies, usually standard tools/components that are installed with Windows are considered exceptions. If it's already on the user's system, why not use it?
Edited: Here's an attempt to use VB's textbox for unicode. Partially successful, but requires manifesting for common controls. If interested, read through the entire thread. I am no longer pursuing that train of thought.
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by fafalone
So the problem does in fact appear to be the get text call. Discovered the problem after seeing this thread and testing Unicode renaming in my shell control: It displays Unicode file names fine, when label edit starts the edit control displays the unicode characters fine, but then reading back the new (and old, checked) label contents, which relies on WM_GETTEXT, for rename fails with the question marks. (I'm checking with a MessageBoxW which shows the name correct when retrieved from the file record).
Dumped the raw data to confirm, text from record: 68 74 6D 2776 2777 2778 20 76
text from wm_gtx: 68 74 6D 3F 3F 3F 20 76 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Thank you for your reply. But Is there a way to solve this issue?
Re: [Help]How to let WM_GETTEXT support unicode characters?
Being just a naive American, is that Chinese text? Assuming that I can get:
Sadly none of it looks like what you are getting. What is your default codepage? I'm assuming you are requesting "ANSI" (probably in your case MBCS?) text and getting something other than what you are after. Are you using the MBCS (A-suffix) SendMessage entrypoint?
In any case you'll probably need more help from Chinese programmers, or at least programmers who deal with Far East localization a lot more than I ever have.
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by gyhu
Thank you for your reply. But Is there a way to solve this issue?
Edit: Yes, I got it. You need to use SendMessageW and pass by pointer:
Code:
Private Declare Function SendMessageW Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Dim sText As String
Dim lLen As Long
lLen = SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, ByVal 0&)
sText = String$(lLen, 0)
Call SendMessageW(hWnd, WM_GETTEXT, lLen + 1, ByVal StrPtr(sText))
Last edited by fafalone; Apr 17th, 2018 at 02:38 PM.
Re: [Help]How to let WM_GETTEXT support unicode characters?
Can also use DefWindowProcW.
Here is what I am using for Get/Let UnicodeText, including Unicode MsgBox.
Code:
Option Explicit
Private Const WM_SETTEXT As Long = &HC
Private Const WM_GETTEXT = &HD
Private Const WM_GETTEXTLENGTH = &HE
Private Type MsgBoxParams
cbSize As Long
hWndOwner As Long
hInstance As Long
lpszText As String
lpszCaption As String
dwStyle As Long
lpszIcon As Long
dwContextHelpID As Long
lpfnMsgBoxCallback As Long
dwLanguageId As Long
End Type
Private Declare Function MessageBoxIndirectW Lib "user32" (ByVal lpMsgBoxParams As Long) As Long
Private Declare Function DefWindowProcW Lib "USER32.DLL" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Property Get UnicodeText(ByVal hWnd As Long) As String
Dim lLen As Long
lLen = DefWindowProcW(hWnd, WM_GETTEXTLENGTH, 0, 0)
If lLen Then
UnicodeText = Space$(lLen)
DefWindowProcW hWnd, WM_GETTEXT, lLen + 1, StrPtr(UnicodeText)
End If
End Property
Public Property Let UnicodeText(ByVal hWnd As Long, ByVal RHS As String)
DefWindowProcW hWnd, WM_SETTEXT, 0, StrPtr(RHS)
End Property
Public Function MsgBox(ByVal Prompt As String, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal Title As String, Optional ByVal hWndOwner As Long) As VbMsgBoxResult
Dim udtMsgBox As MsgBoxParams
If hWndOwner = 0 Then If Not Screen.ActiveForm Is Nothing Then hWndOwner = Screen.ActiveForm.hWnd
With udtMsgBox
.cbSize = Len(udtMsgBox)
.hWndOwner = hWndOwner
.hInstance = App.hInstance
.lpszText = Prompt
If LenB(Title) = 0 Then Title = App.Title
.lpszCaption = Title
.dwStyle = Buttons
End With
MsgBox = MessageBoxIndirectW(VarPtr(udtMsgBox))
End Function
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by dilettante
Being just a naive American, is that Chinese text? Assuming that I can get:
Sadly none of it looks like what you are getting. What is your default codepage? I'm assuming you are requesting "ANSI" (probably in your case MBCS?) text and getting something other than what you are after. Are you using the MBCS (A-suffix) SendMessage entrypoint?
In any case you'll probably need more help from Chinese programmers, or at least programmers who deal with Far East localization a lot more than I ever have.
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by DrUnicode
Can also use DefWindowProcW.
Here is what I am using for Get/Let UnicodeText, including Unicode MsgBox.
Code:
Option Explicit
Private Const WM_SETTEXT As Long = &HC
Private Const WM_GETTEXT = &HD
Private Const WM_GETTEXTLENGTH = &HE
Private Type MsgBoxParams
cbSize As Long
hWndOwner As Long
hInstance As Long
lpszText As String
lpszCaption As String
dwStyle As Long
lpszIcon As Long
dwContextHelpID As Long
lpfnMsgBoxCallback As Long
dwLanguageId As Long
End Type
Private Declare Function MessageBoxIndirectW Lib "user32" (ByVal lpMsgBoxParams As Long) As Long
Private Declare Function DefWindowProcW Lib "USER32.DLL" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Property Get UnicodeText(ByVal hWnd As Long) As String
Dim lLen As Long
lLen = DefWindowProcW(hWnd, WM_GETTEXTLENGTH, 0, 0)
If lLen Then
UnicodeText = Space$(lLen)
DefWindowProcW hWnd, WM_GETTEXT, lLen + 1, StrPtr(UnicodeText)
End If
End Property
Public Property Let UnicodeText(ByVal hWnd As Long, ByVal RHS As String)
DefWindowProcW hWnd, WM_SETTEXT, 0, StrPtr(RHS)
End Property
Public Function MsgBox(ByVal Prompt As String, Optional ByVal Buttons As VbMsgBoxStyle = vbOKOnly, Optional ByVal Title As String, Optional ByVal hWndOwner As Long) As VbMsgBoxResult
Dim udtMsgBox As MsgBoxParams
If hWndOwner = 0 Then If Not Screen.ActiveForm Is Nothing Then hWndOwner = Screen.ActiveForm.hWnd
With udtMsgBox
.cbSize = Len(udtMsgBox)
.hWndOwner = hWndOwner
.hInstance = App.hInstance
.lpszText = Prompt
If LenB(Title) = 0 Then Title = App.Title
.lpszCaption = Title
.dwStyle = Buttons
End With
MsgBox = MessageBoxIndirectW(VarPtr(udtMsgBox))
End Function
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by fafalone
Edit: Yes, I got it. You need to use SendMessageW and pass by pointer:
Code:
Private Declare Function SendMessageW Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Dim sText As String
Dim lLen As Long
lLen = SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, ByVal 0&)
sText = String$(lLen, 0)
Call SendMessageW(hWnd, WM_GETTEXT, lLen + 1, ByVal StrPtr(sText))
Thank you very much for the tip. I'll take a shot then reply to you.
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by fafalone
Edit: Yes, I got it. You need to use SendMessageW and pass by pointer:
Code:
Private Declare Function SendMessageW Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Dim sText As String
Dim lLen As Long
lLen = SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, ByVal 0&)
sText = String$(lLen, 0)
Call SendMessageW(hWnd, WM_GETTEXT, lLen + 1, ByVal StrPtr(sText))
Hi fafalone,
Your solution is perfect. Not only Chinese, Japanese, Russian or something else can also display properly. Thank you very much.
Re: [Help]How to let WM_GETTEXT support unicode characters?
Originally Posted by fafalone
Edit: Yes, I got it. You need to use SendMessageW and pass by pointer:
Code:
Private Declare Function SendMessageW Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Dim sText As String
Dim lLen As Long
lLen = SendMessageW(hWnd, WM_GETTEXTLENGTH, 0, ByVal 0&)
sText = String$(lLen, 0)
Call SendMessageW(hWnd, WM_GETTEXT, lLen + 1, ByVal StrPtr(sText))
Awsome!
I register this account to thank your code.
Thanks again!
Re: [RESOLVED] [Help]How to let WM_GETTEXT support unicode characters?
keli, You'll find the StrPtr(YourString) method quite useful for virtually all the ...W API calls. The basic rules are, change the "As String" argument in the API call to "As Long", and then pass your strings by wrapping them in StrPtr(YourString). Not much more to it.
This completely circumvents all the to-Ansi and back-to-Unicode stuff. The ...W basically means that the API call is expecting a Unicode string, so no need to translate anything, which passing the string pointer accomplishes.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.