Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Saving unicode data
Message
De
28/12/2011 10:41:44
 
 
Information générale
Forum:
Visual FoxPro
Catégorie:
Contrôles ActiveX en VFP
Versions des environnements
Visual FoxPro:
VFP 9 SP2
OS:
Windows 7
Network:
Windows 2003 Server
Database:
MS SQL Server
Divers
Thread ID:
01531693
Message ID:
01531792
Vues:
109
This message has been marked as the solution to the initial question of the thread.
J'aime (1)
>>>>>>So, it's very simple
>>>>>>
>>>>>>
>>>>>>(1) the msforms accepts UTF-16
>>>>>
>>>>>If I get the value from SQL Server, I don't get the string above. I get a 4 bytes per character string. You missed the step of retrieving the value from SQL Server.
>>>>
>>>>Look, I just copied your code to fill the cursor - and it's 2 bytes/char
>>>>
>>>>
>>>>>>(2) And gives its value back in the 'current' code page - which is a bad conversion
>>>>>>(3) swith to the code page of the language you're displaying with sys(3101)
>>>>>
>>>>>!!!!!!!!!!!!! But I don't know which language I am displaying - that's the whole point!
>>>>
>>>>Well, you'll need to know the language - how else can you know the codepage ?
>>>>
>>>>
>>>>>
>>>>>>(4) retrieve the value
>>>>>>(5) set the original value of sys(3101) back
>>>>>>(6) convert the value to utf-16
>>>>>
>>>>>Ok, I'll try.
>>>>>
>>>>>Although two extra steps are missing in your tests:
>>>>>
>>>>>1. Retrieve data from nvarchar(100) field
>>>>
>>>>That is the cursor
>>>>
>>>>>
>>>>>5. Save data back to nvarchar(100) field
>>>>
>>>>Well, I have the data in a string - you can add an undate or a replace ?
>>>>
>>>>
>>>>>6. Try with different languages (don't know in advance which) and all different languages need to show correctly on the same form.
>>>>
>>>>
>>>>I have shown an example in Cyrillic - surely you can try a few others
>>>
>>>Gregory,
>>>
>>>The form I am developing is for specifying languages we're going to use in the interface. I can not know in advance which languages the user is going to pick. So, I want to develop a universal form where the user can specify any language and type in that language. Which particular language they pick I don't know in advance.
>>>
>>>Also, the SQL Server does add an extra complexity, so I ask you to please try the whole thing (from retrival to saving) if possible, of course. And assume you don't know the CodePage in advance.
>>
>>
>>Give me the russian data you have retrieved from sqlserver (create cursor and insert). I cannot and willl not go any further than that -
>
>Not sure if my last reply was helpful (with the exact value I got from SQL Server), but attached is the picture of what I see. The messagebox displays the text value of the first textbox (I set the comprop UTF8 to 1).


Yes, it was - I have found another way with comprop() toi avoid the codepage

First - The length of the data is 14, the number of chars is 7 - which makes it two bytes / char (and not 4)

By setting comprop(utf8, 1), you get utf8 back from the text

I then added a function to convert utf8 to utf16

(1) Form
PUBLIC oform1

oform1=NEWOBJECT("form1")
oform1.Show
RETURN


	**************************************************
*-- Form:         form1 (d:\project9\coreframe\core\yy.scx)
*-- ParentClass:  form
*-- BaseClass:    form
*-- Time Stamp:   12/28/11 04:35:02 PM
*
DEFINE CLASS form1 AS form


	Top = 0
	Left = 0
	Height = 390
	Width = 551
	DoCreate = .T.
	Caption = "Form1"
	Name = "Form1"


	ADD OBJECT text1 AS olecontrol WITH ;
		Top = 72, ;
		Left = 12, ;
		Height = 93, ;
		Width = 372, ;
		Name = "text1"


	ADD OBJECT command1 AS commandbutton WITH ;
		Top = 12, ;
		Left = 48, ;
		Height = 25, ;
		Width = 97, ;
		Caption = "Assign value", ;
		Name = "Command1"


	ADD OBJECT command2 AS commandbutton WITH ;
		Top = 12, ;
		Left = 192, ;
		Height = 25, ;
		Width = 97, ;
		Caption = "Get value back", ;
		Name = "Command2"


	PROCEDURE Load
		CREATE CURSOR csrTest (cVal blob, nVal blob)

		INSERT INTO  csrTest ;
		    VALUES;
		   (STRCONV( "Russian",5),;
		     STRCONV('20044304410441043A0438043904',16)  )
	ENDPROC


	PROCEDURE command1.Click

		=comprop(this.Parent.Text1, 'utf8', 1)

		this.Parent.Text1.Text = csrTest.nVal 
	ENDPROC


	PROCEDURE command2.Click
		local utf8, utf16Out
		utf8 =m.this.Parent.text1.Text


		= StringUtf8ToUTF16(@m.utf16Out, m.utf8)

		acti screen
		?strconv(csrTest.nval, 15)
		?strconv(utf16Out, 15)

		?'Same value ', csrTest.nval == utf16Out
		assert .f.
	ENDPROC


ENDDEFINE
*
*-- EndDefine: form1
**************************************************
(2) with StringUtf8ToUTF16()
#include "Foxpro.h"
#define true .t.
#define false .f.

*_______________________________________________________________________________
function StringToUTF8(utf8Out, stringIn, codepageIn)
	
	local success
	success = true
	
	do case
	case !m.success
	
	case !StringToUTF16(@m.utf8Out, m.stringIn, m.codepageIn)
		assert false
		success = false
	
	case !StringUTF16ToUTF8(@m.utf8Out, m.utf8Out)
		assert false
		success = false
	
	endcase
	
	return m.success
	
endfunc
*_______________________________________________________________________________


*_______________________________________________________________________________
*_______________________________________________________________________________
#define CP_ACP					0
#define CP_MACCP				2
#define CP_OEMCP				1
#define CP_SYMBOL				42
#define CP_THREAD_ACP			3
#define CP_UTF7					65000
#define CP_UTF8					65001
#define MB_PRECOMPOSED			0x1
#define MB_COMPOSITE			0x2
#define MB_USEGLYPHCHARS		0x4
#define MB_ERR_INVALID_CHARS	0x8

#define WC_DEFAULTCHAR			0x00000040 
#define WC_ERR_INVALID_CHARS	0x00000080 
#define WC_NO_BEST_FIT_CHARS 	0x00000400 
*_______________________________________________________________________________
function StringToUTF16(utf16Out, stringIn, codepageIn)

	local success
	success = true
	
	do case
	case !m.success
	
	case empty(len(m.stringIn))
		utf16Out = ''
		
	otherwise
		local lpWideCharStr, result
		lpWideCharStr = space(len(m.stringIn)*2)
	
		result = MultiByteToWideChar( ;
					evl(m.codepageIn, cpcurrent()), ;
					MB_ERR_INVALID_CHARS, ;
					@m.stringIn, ;
					len(m.stringIn), ;
					@m.lpWideCharStr, ;
					len(m.lpWideCharStr) ;
				)
			
		do case
		case !m.success
		
		case empty(m.result)
			assert false
			success = false
		
		otherwise
			utf16Out = left(m.lpWideCharStr, m.result * 2) 
		
		endcase
		
	endcase
	
	return m.success
	
	
endfunc
*_______________________________________________________________________________
function StringUTF16ToUTF8(utf8Out, utf16In)

	local success
	success = true
	
	do case
	case !m.success
	
	case empty(len(m.utf16In))
		utf8Out = ''
		
	otherwise
	
		local lpMultiByteStr, lpUsedDefaultChar, result
		lpMultiByteStr = space(len(m.utf16In) * 2)
		lpUsedDefaultChar = 0
		
		result = WideCharToMultiByte( ;
					CP_UTF8, ;
					WC_ERR_INVALID_CHARS, ;
					@m.utf16In, ;
					len(m.utf16In)/2, ;
					@m.lpMultiByteStr, ;
					len(m.lpMultiByteStr), ;
					null, ;
					@m.lpUsedDefaultChar ;
				)
		
		do case
		case !m.success
		
		case empty(m.result)			
			assert false
			success = false
			
			
		otherwise
			utf8Out = left(m.lpMultiByteStr, m.result)
		
		endcase
	endcase
	
	return m.success
	
	
	
endfunc
*_______________________________________________________________________________
function StringUTF8ToUTF16(utf16Out, uft8In)

	return StringToUTF16(@m.utf16Out, uft8In, CP_UTF8)
	
endfunc
*_______________________________________________________________________________

function MultiByteToWideChar
	lparameters codepage, ;
				dwFlags, ;
				lpMultiByteStr, ;
				cbMultiByte, ;
				lpWideCharStr, ;
				cchWideChar

	local success
	success = true

	local result
	
	do case
	case !m.success
	
	otherwise
		try
			declare integer MultiByteToWideChar in Kernel32.dll ;
				long	codepage, ;
				long	dwFlags, ;
				string@	lpMultiByteStr, ;
				integer	cbMultiByte, ;
				string@	lpWideCharStr, ;
				integer	cchWideChar
		
			result = MultiByteToWideChar( ;
					m.codepage, ;
					m.dwFlags, ;
					@m.lpMultiByteStr, ;
					m.cbMultiByte, ;
					@m.lpWideCharStr, ;
					m.cchWideChar ;
				)
		catch
			assert false
			success = false
			
		endtry
	endcase
	
	return iif(m.success, m.result, 0)
	
endfunc
*_______________________________________________________________________________
function WideCharToMultiByte
	lparameters codepage, ;
				dwFlags, ;
				lpWideCharStr, ;
				cchWideChar, ;
				lpMultiByteStr, ;
				cbMultiByte, ;
				lpDefaultChar, ;
				lpUsedDefaultChar

	local success
	success = true

	local result
	
	do case
	case !m.success
	
	otherwise
		try
			declare integer WideCharToMultiByte in Kernel32.dll ;
				long	codepage, ;
				long	dwFlags, ;
				string@	lpWideCharStr, ;
				integer	cchWideChar, ;
				string@	lpMultiByteStr, ;
				integer	cbMultiByte, ;
				string	lpDefaultChar, ;
				integer	@lpUsedDefaultChar
		
			result = WideCharToMultiByte ( ;
					m.codepage, ;
					m.dwFlags, ;
					@m.lpWideCharStr, ;
					m.cchWideChar, ;
					@m.lpMultiByteStr, ;
					m.cbMultiByte, ;
					m.lpDefaultChar, ;
					@m.lpUsedDefaultChar;
				)
		catch
			assert false
			success = false
			
		endtry
	endcase
	
	return iif(m.success, m.result, 0)
	
endfunc
*_______________________________________________________________________________
Gregory
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform