German Umlaute üöä ÜÖÄ

Public support forum for peer to peer support with related to the Visual Objects and Vulcan.NET products
User avatar
robert
Posts: 4258
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

German Umlaute üöä ÜÖÄ

Post by robert »

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 (https://docs.microsoft.com/en-us/window ... ocharbuffa) 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
robert@xsharp.eu
User avatar
Chris
Posts: 4584
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

German Umlaute üöä ÜÖÄ

Post by Chris »

Hi Wolfgang,
wriedmann post=23630 userid=336 wrote: 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.
wriedmann post=23631 userid=336 wrote: 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.

.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Kai
Posts: 37
Joined: Fri Dec 15, 2017 10:43 am
Location: D

German Umlaute üöä ÜÖÄ

Post by Kai »

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
WinDBU.zip
(2.93 MiB) Downloaded 60 times
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

German Umlaute üöä ÜÖÄ

Post by Karl-Heinz »

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.

Code: Select all

? GetOEMCP()   // OEM code page     850
? GetACP()     // ANSI code page   1252
regards
Karl-Heinz
Kai
Posts: 37
Joined: Fri Dec 15, 2017 10:43 am
Location: D

German Umlaute üöä ÜÖÄ

Post by Kai »

Hello Robert,
hello Karl-Heinz!

On my machine the

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

Regards
Kai
Attachments
codepage.jpg
codepage.jpg (42.21 KiB) Viewed 487 times
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

German Umlaute üöä ÜÖÄ

Post by Karl-Heinz »

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
Artikel.png
Artikel.png (69.44 KiB) Viewed 487 times
User avatar
Chris
Posts: 4584
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

German Umlaute üöä ÜÖÄ

Post by Chris »

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.

.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Kai
Posts: 37
Joined: Fri Dec 15, 2017 10:43 am
Location: D

German Umlaute üöä ÜÖÄ

Post by Kai »

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
User avatar
Chris
Posts: 4584
Joined: Thu Oct 08, 2015 7:48 am
Location: Greece

German Umlaute üöä ÜÖÄ

Post by Chris »

Hi Kai,
Kai post=23660 userid=4500 wrote: 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.

.
Chris Pyrgas

XSharp Development Team test
chris(at)xsharp.eu
Kai
Posts: 37
Joined: Fri Dec 15, 2017 10:43 am
Location: D

German Umlaute üöä ÜÖÄ

Post by Kai »

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
Post Reply