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
German Umlaute üöä ÜÖÄ
German Umlaute üöä ÜÖÄ
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
German Umlaute üöä ÜÖÄ
Hi Wolfgang,
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.
.
It does, but it shouldn'twriedmann 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.
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.
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.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).
.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
German Umlaute üöä ÜÖÄ
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
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 137 times
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
German Umlaute üöä ÜÖÄ
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.
regards
Karl-Heinz
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
Karl-Heinz
German Umlaute üöä ÜÖÄ
Hello Robert,
hello Karl-Heinz!
On my machine the
result of GetOEMCP() is 850
result of GetACP() is 1252
Regards
Kai
hello Karl-Heinz!
On my machine the
result of GetOEMCP() is 850
result of GetACP() is 1252
Regards
Kai
- Attachments
-
- codepage.jpg (42.21 KiB) Viewed 891 times
-
- Posts: 774
- Joined: Wed May 17, 2017 8:50 am
- Location: Germany
German Umlaute üöä ÜÖÄ
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
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 (69.44 KiB) Viewed 891 times
German Umlaute üöä ÜÖÄ
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.
.
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
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
German Umlaute üöä ÜÖÄ
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
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
German Umlaute üöä ÜÖÄ
Hi Kai,
.
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.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.
.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
German Umlaute üöä ÜÖÄ
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
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