Welcome, Guest
Username: Password: Remember me
Visual Objects

Please use this forum to post questions about Visual Objects and Vulcan.NET
  • Page:
  • 1
  • 2

TOPIC:

German Umlaute üöä ÜÖÄ 03 Sep 2022 17:56 #23614

  • Kai
  • Kai's Avatar
  • Topic Author


  • Posts: 37
  • Hello everyone!

    I'm still testing various things in XSharp and XIDE before attempting to migrate my applications from VO to XSharp.

    Now I have some Problems with german "Umlaute" (äöü ÄÜÖ ß). I have a .dbf database with items like "Hähnchenschnitzel" and so on.

    In VO I have no Problems with code like this:

    oTB := TextBox{, "Test", oDBServer:Fieldget("Bez")}
    oTB:Show()

    The Textbox shows "Hähnchenschnitzel" with the correct "ä".

    In XSharp the Textbox shows some kind of special character instead of the "ä"

    I've tried using SetAnsi(FALSE), SetAnsi(true), Ansi2OEM(), OEM2Ansi() but nothing works. With Ansi2OEM() the small "äöü" are displayed correctly, but the large "ÄÖÜ" are still displayed as special charcters.

    How can I get XSharp to work properly with these characters?

    I have included an example .dbf in the attachments. For example please look at the record numbers 10 / 11 / 12 / 25 / 85.

    Regards
    Kai
    Attachments:

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 03 Sep 2022 20:25 #23615

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3185
  • Hi Kai,
    do you have any samples of code how do you access your DBF tables?
    Wolfgang
    P.S. I'm using several X# applications that access the same DBFs as VO applications - in different formats: VOOGUI, WPF, Windows Forms, Windows services
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 03 Sep 2022 20:26 #23616

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3185
  • Hi Kai,
    I forgot: what are the language settings of your VO application?
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 04 Sep 2022 15:06 #23620

    • Kai
    • Kai's Avatar
    • Topic Author


  • Posts: 37
  • Hi Wolfgang!

    Here the xSharp-code. It uses the artikel.dbf which i attached in the first post.

    [STAThread];
    FUNCTION Start() AS INT
    LOCAL oXApp AS XApp
    TRY
    oXApp := XApp{}
    oXApp:Start()
    CATCH oException AS Exception
    ErrorDialog(oException)
    END TRY
    RETURN 0

    CLASS XApp INHERIT App

    METHOD Start()
    LOCAL oDBServer AS DBServer
    LOCAL oTB AS TextBox

    SetCentury(TRUE)
    SetDateCountry(GERMAN)
    SetExclusive(FALSE)
    SetSoftSeek(FALSE)

    SetDeleted(TRUE)
    RddSetDefault("DBFCDX")

    SetAnsi(FALSE)
    SetAmPm(FALSE)

    oDBServer := DBServer{"c:\xsharp\artikel.dbf", DBSHARED, FALSE, "DBFCDX"}

    oDBServer:GoTo(83)

    oTB := TextBox{, "Artikel", AllTrim(oDBServer:FieldGet("bBez1"))}
    oTB:Show()

    oDBServer:Close()

    SELF:Quit()
    RETURN SELF

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 04 Sep 2022 15:40 #23621

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3185
  • Hi Kai,
    there is something strange with your DBF: even my VO Dictionary Editor does not shows the correct umlaut data.

    I have to lookup the header.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it
    Attachments:

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 04 Sep 2022 15:54 #23622

    • Kai
    • Kai's Avatar
    • Topic Author


  • Posts: 37
  • Hi Wolfgang!

    My VO application shows everything as it should be. I have attached an image. This VO-Application uses a simple DataBrowser. The artikel.dbf was created by DBFileSpec:create()

    The VO App:Start() -Method uses the following commands, everything else like DBServer and so an is VO-standard without modifications:

    SetCentury(TRUE)
    SetDateCountry(GERMAN)
    SetExclusive(FALSE)
    SetSoftSeek(FALSE)
    SetEpoch(1930)
    SetDeleted(TRUE)
    RddSetDefault("DBFCDX")
    SetAnsi(FALSE)
    SetAmPm(FALSE)


    Regards
    Kai
    Attachments:

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 04 Sep 2022 17:45 #23623

    • Chris
    • Chris's Avatar


  • Posts: 3650
  • Hi Kai, Wolfgang,

    Wolfgang, the dbf is created with SetAnsi() off, so you need to use a SetAnsi(FALSE) in VO, in order to open it correctly.

    But indeed, the same thing does not work correctly in X#. I suspect there's some issue with the recognition of the codepage of the dbf, or there's something iffy in the dbf handling in X# with SetAnsi(FALSE), will open a report for Robert to look more closely into it. Thanks for the report!
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 07:54 #23629

    • Chris
    • Chris's Avatar


  • Posts: 3650
  • Guys,

    Ah, sorry, my previous comment was wrong, SetAnsi(FALSE) should be used in VO only when creating the dbf, in order to create it in OEM format, but SetAnsi(TRUE) should still be used to read it (or otherwise use Oem2Ansi() manually to convert the string read from OEM/DOS format(codepage) to windows readable ANSI).

    So I think Wolfgang is right, there seems to be a problem with the dbf, having the wrong codepage in its header, or format of the data. Kai, how did you create this dbf? Can you also post an aef of a small VO sampleapp showing how you are opening and showing this dbf?
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 08:41 #23630

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3185
  • Hi Chris,
    the strange thing is than when using the code Kai posted earlier and adapting it to VO it shows the correct output.
    function DisplayDBF() as void
    	LOCAL oDBServer AS DBServer
    	LOCAL oTB AS TextBox
    	
    	SetCentury(TRUE)
    	SetDateCountry(GERMAN)
    	SetExclusive(FALSE)
    	SetSoftSeek(FALSE)
    	
    	SetDeleted(TRUE)
    	RddSetDefault("DBFCDX")
    	
    	SetAnsi(FALSE)
    	SetAmPm(FALSE)
    	
    	oDBServer := DBServer{"c:\temp\artikel.dbf", DBSHARED, FALSE, "DBFCDX"}
    	
    	oDBServer:GoTo(83)
    	
    	oTB := TextBox{, "Artikel", AllTrim(oDBServer:FieldGet("bBez1"))}
    	oTB:Show()
    	
    	oDBServer:Close()
    	
    	RETURN
    I have pasted this code into a standard VO Console application.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 08:50 #23631

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3185
  • Hi Chris,
    following the previous message: the sample application uses SetAnsi( false ), so no conversion is done.
    If the DBF is created to use OEM characters, and opened with SetAnsi( false ), then the data is written as ANSI, regardless of the charset that is used in the DBF header. Any application that respects this header will show wrong data.
    The problem could be that X# probably with SetAnsi( true ) does not makes the conversion from the ANSI (that should be used when SetAnsi() is false) to Unicode (that is used internally in .NET).
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 10:17 #23636

    • robert
    • robert's Avatar


  • Posts: 3177
  • Kai,
    Your file has a first byte with value 0x03. This is a standard DBF fle header. Byte 30 is 0x02, which means that it has the codepage "International MS-DOS".
    With this information the RDD has to decide how to decode the bytes in your file.
    At this moment this DOS Codepage is mapped to the "ibm850" codepage from .Net.
    We use this codepage to translate the bytes to the Unicode characters.
    That is what you see.

    Visual Objects works in a different way.
    It translates the 0x03 and the 0x02 to the meaning "this is an OEM DBF" and then when it reads a record from the file it uses the Win32 OemToCharBuff function (docs.microsoft.com/en-us/windows/win32/a...nuser-oemtocharbuffa) to translate the characters from Oem To Ansi.
    This Win32 API function completely ignores the meaning of the codepage byte in the header and uses the Current OEM codepage of the OS for the conversion. I suspect that on the machine where you are running this code the OEM code page is not 850.
    The bad thing of the VO approach is that when you are accessing this DBF from different workstations with different OEM codepages then these different workstations each will use their own conversion rules.
    With X# the conversion is only based on information in the file and not from environment where the program is running.

    3 questions:
    1) How did you create this file
    2) What is the OEM codepage on the machine where you are processing this file in Visual Objects.
    3) Are you sure (enforcing) that all workstations use the same OEM codepage setting ?

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    Last edit: by robert.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 10:45 #23639

    • Chris
    • Chris's Avatar


  • Posts: 3650
  • Hi Wolfgang,

    the strange thing is than when using the code Kai posted earlier and adapting it to VO it shows the correct output.

    It does, but it shouldn't :)
    When you open an OEM dbf in VO, you either need to use SetAnsi(TRUE) so that conversion to ansi when reading happens automatically, or use Oem2Ansi() to convert it manually. The code does neither of the two, so I think it should not be giving "correct" results. So it's probably as Robert said an issue with the dbf header, due to the way the file was created.

    The problem could be that X# probably with SetAnsi( true ) does not makes the conversion from the ANSI (that should be used when SetAnsi() is false) to Unicode (that is used internally in .NET).

    In X#, because of the unicode strings, things are more straightforward, it is not important if the data is written as ansi or oem, all the RDD does is to read from the header what codepage the dbf is using, and then uses this codepage to convert the 8bit data in the dbf, to unicode. and for this reason, the SetAnsi() setting does not make a difference in X# for dbf reading/writing (except for when _creating_ a dbf), since there's no ansi<->oem conversion ever involved at all. But in this case the RDD does not recognize the codepage that was originally used for the dbf (in VO probably), so then it all goes wrong.

    .
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Last edit: by Chris.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 10:51 #23641

    • Kai
    • Kai's Avatar
    • Topic Author


  • Posts: 37
  • Hi everybody!

    Many years ago, when we worked with Clipper, there was a tool calld "DBU". After it stopped working under Windows 7 I wrote a tool "WinDBU" in VO. I had to work with Clipper created DBFs in VO and with VO created DBFs in Clipper. So I chose the SetAnsi(false) setting in VO because in this case I could easily use the DBFs created by VO in Clipper applications.

    I still use my WinDBU-Tool today.

    You can find the tool in the attachments including the source code.

    Robert, I have standard German Windows computers. I haven't changed anything on the code pages, everything is as installed by Microsoft. After having some problems with my Windows 10 notebook (xSharp compiled my application in 30+ minutes, remember?), I bought a brand new notebook with Windows 11, installed VO and everything works fine. No dbf problems.

    And programs that use dbf files work fine for all customers. I've never had problems with the codepages on any computer.

    Regards
    Kai
    Attachments:

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 12:14 #23642

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 773
  • Hi Kai,

    The codepage of your Artikel.dbf is 850. But Robert wants to know the OEM codepage on your machine. Just add both lines to one of your VO apps and let us know the results.
    ? GetOEMCP()   // OEM code page     850
    ? GetACP()     // ANSI code page   1252

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 12:26 #23643

    • Kai
    • Kai's Avatar
    • Topic Author


  • Posts: 37
  • Hello Robert,
    hello Karl-Heinz!

    On my machine the

    result of GetOEMCP() is 850
    result of GetACP() is 1252

    Regards
    Kai
    Attachments:

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 12:46 #23645

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 773
  • Hi Robert,

    i created a VO StdMDIApp and added the settings Kai mentioned. Because the VO docs say that setansi(false) doesn t do any automatic conversion i m wondering how its possible that the VO Databrowser shows "1/2 Hähnchen" instead of "1/2 Hõhnchen". I have also tried Ansi2Oem() / Oem2Ansi() and OemToCHarBUff() but none of them result in "1/2 Hähnchen" - see the attached image.

    regards
    Karl-Heinz
    Attachments:

    Please Log in or Create an account to join the conversation.

    Last edit: by Karl-Heinz.

    German Umlaute üöä ÜÖÄ 05 Sep 2022 18:41 #23653

    • Chris
    • Chris's Avatar


  • Posts: 3650
  • Hi Kai,

    How did you create this dbf in VO, which is the exact code? And how did you fill the data?

    I suspect that maybe you created the file with SetAnsi(FALSE), then added data to it with still using SetAnsi(FALSE) (which means no automatic conversion) without converting it manually to OEM (the DOS codepage) first, so the dbf file has a OEM format flag in the header, but Ansi (Windows codepage used) data in the field data. That would explain why in VO the data can be read with SetAnsi(FALSE) and again no OEM->ANSI conversion (which is not the intended way to do it), but in X# it does not work either way, because X# relies on the codepage specified in the dbf header to match the codepage used by the data itself.

    .
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Last edit: by Chris.

    German Umlaute üöä ÜÖÄ 06 Sep 2022 09:14 #23660

    • Kai
    • Kai's Avatar
    • Topic Author


  • Posts: 37
  • Hi Chris!

    Your suspicion is correct. In the App:start method I set SetAnsi(false). So I created the DBF with setAnsi(false) and added the data with SetAnsi(false) without conversion.

    Regards
    Kai

    Please Log in or Create an account to join the conversation.

    German Umlaute üöä ÜÖÄ 06 Sep 2022 10:58 #23665

    • Chris
    • Chris's Avatar


  • Posts: 3650
  • Hi Kai,

    Your suspicion is correct. In the App:start method I set SetAnsi(false). So I created the DBF with setAnsi(false) and added the data with SetAnsi(false) without conversion.

    OK, so that's the problem then, the dbf is marked as OEM, but it does not contain data in OEM format. Is there a reason why you chose SetAnsi(FALSE), instead of SetANsi(TRUE)? If there's not a particular reason for this, I think the best way to fix this is to correct the dbf file, by adjusting the codepage marker in the header, this is just one byte, so it will be easy to write a small program that does it.

    .
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Last edit: by Chris.

    German Umlaute üöä ÜÖÄ 06 Sep 2022 11:16 #23666

    • Kai
    • Kai's Avatar
    • Topic Author


  • Posts: 37
  • Hello Chris!

    Actually there is no more reason. Many years ago there was a reason because I was looking for a way to work with Clipper created tables in VO and vice versa. SetAnsi(false) was the first working way I found. I had no experience with VO and was glad it worked.

    I wrote a few lines of code to change the header and it seems to work now with SetAnsi(true).

    hFile := FOpen("artikel.dbf", FO_READWRITE)

    IF hFile != F_ERROR
    FSeek(hFile, 29, FS_SET)
    FWrite(hFile, CHR(3)+CHR(0)+CHR(0), 3)
    FClose(hFile)
    ENDIF

    Please Log in or Create an account to join the conversation.

    • Page:
    • 1
    • 2