Rectangle 27 6

Since you are porting from Delphi 7 to XE6, you will also have to deal with the Unicode migration as well (which was introduced in Delphi 2009):

Thanks, must I compile twice to get 64bit and 32bit target paltforms by selecting the target platform (bold) in the Project Manager, or are the 2 EXEs created at once when I add 64 and 32 as target patforms. (In other words: Must I select the active target platform manually and compile for each separately?)

@Walter No. You can compile from the command line in an automated way. Building from the IDE is for dev not for release building.

There are build groups too to get this with one action, no need for command line

@David a small couple of clicks against your script building :o)

@David that is what I mean talking about the pros and cons. Scripts are much more powerful than the groups. Everyone has to decide which is better to use to reach the desired goal. For a real decision you have to know your possibilities to choose from and the limitations of each

How to make 32bit and 64bit Delphi Applications in DELPHI XE6? - Stack...

delphi delphi-xe6
Rectangle 27 4

Checking for CPUARM is the correct solution. iOS binaries compiled for the simulator are not ARM, they are actually x86. Just make sure to wrap your iOS code with {$IFDEF IOS}:

{$IFDEF IOS}
  {$IFDEF CPUARM}
s := 'iOS device';
  {$ELSE}
s := 'iOS Simulator';
  {$ENDIF}
{$ENDIF}

Delphi uses an ARM compiler for iOS devices, but uses an x86 compiler for the iOS simulator.

The available compiler conditionals are documented on Embarcadero's DocWiki:

CPUARM
CPU386
CPUX86

A look at the conditional values that are physically present in XE6's DCCIOSARM.EXE and DCCIOS32.EXE executable files confirms that:

**CPUARM**
DCC
NEXTGEN
AUTOREFCOUNT
WEAKINSTREF
WEAKINTFREF
WEAKREF
EXTERNALLINKER
NATIVECODE
POSIX
POSIX32
MACOS
MACOS32
**IOS**
VER270
CONSOLE
BCB
PIC
UNICODE
CONDITIONALEXPRESSIONS
**CPU386**
**CPUX86**
DCC
NEXTGEN
AUTOREFCOUNT
WEAKINSTREF
WEAKINTFREF
WEAKREF
NATIVECODE
POSIX
POSIX32
MACOS
MACOS32
**IOS**
ALIGN_STACK
UNDERSCOREIMPORTNAME
PC_MAPPED_EXCEPTIONS
ASSEMBLER
VER270
CONSOLE
BCB
PIC
UNICODE
CONDITIONALEXPRESSIONS

I had checked the documentation and I used CPUARM and IOS as you write, but surprisingly it didn't work.

I assure you, it does. There is no possible way that CPUARM can be defined when compiling for the iOS Simulator, unless something else in your project is defining it manually. As you can see in my answer, CPUARM does not physically exist in DCCIOS32.

How to check if the app is running on iOS device or simulator in Delph...

delphi delphi-xe6
Rectangle 27 3

SaveToFile
TXMLDocument

Whether the file would be or not UTF8 you have to check using local tools like aforementioned Notepad++ or Hex Editor or anything else.

If you insist of using intermediate string and file stream, you should use the proper variable. AnsiToUTF8 returns UTF8String type and that is what to be used. Compiling `WideStringVar := AnsiStringSource' would issue compiler warning and

It is a proper warning. Googling for "Delphi WideString" - or reading Delphi manuals on topic - shows that WideString aka Microsoft OLE BSTR keeps data in UTF-16 format. http://delphi.about.com/od/beginners/l/aa071800a.htm Thus assignment UTF16 string <= 8-bit source would necessarily convert data and thus dumping WideString data can not be dumping UTF-8 text by the definition of WideString

Procedure SaveAsUTF8( const Name:String; Data: TStrings );
const
  cUTF8: array [1..3] of byte = ($EF,$BB,$BF)
var
  W_TXT: UTF8String;
  fs: TFileStream;
  Trimmed: AnsiString;
begin
  Trimmed := TRIM(Data.Text);
  if Trimmed <> '' then begin    
    W_TXT:= AnsiToUTF8(Trimmed);
    fs:= TFileStream.Create( Name, fmCreate );
    try
      fs.WriteBuffer( cUTF8[1], sizeof(cUTF8) );
      fs.WriteBuffer( W_TXT[1], Length(W_TXT)*Sizeof( W_TXT[1] ));
    finally
      fs.free
    end;
  end;
end;

BTW, this code of yours would not create even empty file if the source data was empty. It looks rather suspicious, though it is you to decide whether that is an error or not wrt the rest of your program.

The proper "uploading" of received file or stream to web is yet another issue (to be put as a separate question on Q&A site like SO), related to testing conformance with HTTP. As a foreword, you can readsome hints at WWW server reports error after POST Request by Internet Direct components in Delphi

however that part of webservice is unnecessary I think it is not. The webservice checklist demonstrated a number of "check points" thus giving you directions for future investigation of the problem. Every option there is not saying "you've overlooked it, fool" but "you may have problem here, check this too". Well, up to you.

unicode - How to Convert Ansi to UTF 8 with TXMLDocument in Delphi - S...

delphi unicode utf-8 delphi-6 txmldocument
Rectangle 27 2

In order to have the correct encoding inside the document, you should set it by using the Encoding property in your XML Document, like this:

myXMLDocument.Encoding := 'UTF-8';

I don't understand. If it's already set that way, then why is this marked as the solution? What else did you have to change in your code to resolve your problem?

unicode - How to Convert Ansi to UTF 8 with TXMLDocument in Delphi - S...

delphi unicode utf-8 delphi-6 txmldocument
Rectangle 27 2

You simply need to call the SaveToFile method of the document:

XMLDoc.SaveToFile(FileName);

Since you specified the encoding already, the component will use that encoding.

This won't include a BOM, but that's generally what you want for an XML file. The content of the file will specify the encoding.

As regards your SaveAsUTF8 method, it is not needed, but it is easy to fix. And that may be instructive to you.

The problem is that you are converting to UTF-16 when you assign to a WideString variable. You should instead put the UTF-8 text into an AnsiString variable. Changing the type of the variable that you named W_TXT to AnsiString is enough.

Procedure SaveAsUTF8(const Name: string; Data: TStrings);
const    
  UTF8BOM: array [0..2] of AnsiChar = #$EF#$BB#$BF;
var
  utf8: AnsiString;
  fs: TFileStream;
begin
  utf8 := AnsiToUTF8(Data.Text);
  fs:= Tfilestream.create(Name, fmCreate);
  try
    fs.WriteBuffer(UTF8BOM, SizeOf(UTF8BOM));
    fs.WriteBuffer(Pointer(utf8)^, Length(utf8));
  finally
    fs.free;
  end;
end;

Thanks a lot David

not merely "that you had already done" but "that did not (alone) solved the problem"

unicode - How to Convert Ansi to UTF 8 with TXMLDocument in Delphi - S...

delphi unicode utf-8 delphi-6 txmldocument
Rectangle 27 1

procedure SaveAsUTF8(const Name: string; Data: TStrings);
var
  fs: TFileStream;
  vStreamWriter: TStreamWriter;
begin
  fs := TFileStream.Create(Name, fmCreate);
  try
    vStreamWriter := TStreamWriter.Create(fs, TEncoding.UTF8);
    try
      vStreamWriter.Write(Data.Text);
    finally
      vStreamWriter.Free;
    end;
  finally
    fs.free;
  end;
end;

unicode - How to Convert Ansi to UTF 8 with TXMLDocument in Delphi - S...

delphi unicode utf-8 delphi-6 txmldocument
Rectangle 27 0

It depends what your definition of conversion is. If you want to map the 127 lowest characters to the Unicode equivalent, you can use an explicit cast. But this creates garbage if the string contains higher characters.

If you want mappings like -> e and -> u, you can write your own code. But be aware that there are always characters that can't be converted.

How can I convert unicode characters to ascii codes in delphi 7? - Sta...

delphi unicode ascii
Rectangle 27 0

In order to have the correct encoding inside the document, you should set it by using the Encoding property in your XML Document, like this:

myXMLDocument.Encoding := 'UTF-8';

I don't understand. If it's already set that way, then why is this marked as the solution? What else did you have to change in your code to resolve your problem?

unicode - How to Convert Ansi to UTF 8 with TXMLDocument in Delphi - S...

delphi unicode utf-8 delphi-6 txmldocument
Rectangle 27 0

There is unofficial hack, but it will bring more problems that solve.

How to disable unicode in Delphi xe2 - Stack Overflow

delphi delphi-xe2
Rectangle 27 0

varchar fields do NOT store Unicode characters. They store ASCII values in the codepage specified by the field's collation. SQL Server will try to convert characters to the correct codepage when you try to store Unicode or data from a different codepage. You can disable this feature but the best option is to avoid the whole mess by using nvarchar fields and UnicodeString in your application.

You mention that you changes all character types to ANSI, not UNICODE types in your application. If you want to use UNICODE you should be using a UNICODE type like UnicodeString. Otherwise your values will be converted to ANSI when they are sent to your server. This conversion is done by your code when you create the AnsiString that is sent to the server.

BTW, your select statement stores an ASCII value in the field. You have to prepend the value with N if you want to store it as a unicode value, eg.g

SELECT id FROM table WHERE name = N'something'

Even this will not guarantee that your data will reach the server in a Unicode form. If you store the statement in an AnsiString the entire statement is converted to ANSI before it is sent to the server. If your app makes a wrong conversion, you will end up with mangled data on the server.

The solution is very simple, just use parameterized statements to pass unicode values as unicode parameters and store them in NVarchar fields. It is much faster, avoids all conversion errors and prevents SQL injection attacks.

Unfortunately, I am very limited by what I can change. I would love to completely embrace Unicode, but half of the system is written with Visual C++ 4.2. We also share some code with a vastly more complicated system where a true Unicode conversion isn't fiscally possible. I will take what you've said and try to better diagnose where the the issue is occurring.

sql server - Unicode conversion, database woes (Delphi 2007 to XE2) - ...

sql-server sql-server-2008 delphi unicode ansi
Rectangle 27 0

If I understand you correctly then you want to use some of the box drawing characters, which are in the Unicode range 2500-257F. So you just need to show a message with Unicode text. If you are on Delphi 2009 or later it's very simple, you just insert the characters into your string:

procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
begin
  s := 'Test ' + #$2523;
  MessageBox(Handle, PChar(s), nil, MB_OK);
end;

Even if you were on an earlier version of Delphi you could still call the Unicode variant of for example the MessageBox() function, by using MessageBoxW() and passing it a WideString.

Sorry, mghie, correct symbol is not shown. Trued Both MessageBoxW(); ... PWideChar() param ... and WideString declaration ... :( Instead default "unknown" char - Rectangle - is shown. Also, I am passing string as parameter, not as variable.

+1. We're in Delphi XE, so we may as well use the Unicode characters directly instead of trying to get to them via two levels of code-page conversion. In either case, you'll still rely on the message-box font to include the box characters and for the widths of those characters to work well with the width of the enclosed text; good ASCII art requires knowing the dimensions of the characters.

@HX_unbanned: If the font doesn't contain the glyph you want displayed, then no amount of coding will help you get around that. I don't think you should try to use these box characters at all, Rob already wrote a perfect comment on your question why that is.

I know, I know, just it is always interesting what metamorphoisis of binary char representations happens "under the hood" .. in the world that people usually do not think about. I already feel like idiot ... please don't be so aggressive .. ;)

How to use ASCII Art symbols in Message Dialogs of Unicode-by-default ...

delphi dialog ascii delphi-xe ascii-art
Rectangle 27 0

I have this working function, if you like. It's not Unicode-aware. It can be easily modified to return a chunk

Function HexStringToBytes(Const Value: String): TBytes;
Var
  i, v: Integer;
  dg0, dg1: Byte;
  HexStr: String;
Begin
  HexStr := '';
  For i:= 1 To Length(Value) Do If Value[i] <> #32 Then HexStr := HexStr + Value[i];
  SetLength( Result, Length(HexStr) Div 2 );
  For i:= 1 To Length(HexStr) Div 2 Do
    Begin
      dg0 := 0;
      dg1 := 1;
      If TryStrToInt( '$' + HexStr[i*2 -1], v ) Then dg0 := Byte(v) Shl 4;
      If TryStrToInt( '$' + HexStr[i*2], v )    Then dg1 := Byte(v);
      Result[i-1] := dg0 + dg1;
    End;
End;

With Delphi 2010, how can I convert a Unicode string to a hexadecimal ...

delphi unicode
Rectangle 27 0

I get the impression that Gu is moving from Delphi 7 to a Unicode enabled version (D2009+) and is looking for advice on how to deal with the new strings.

Cary Jensen's white paper Delphi Unicode Migration for Mere Mortals, addresses most if not all of the issues raised in the question.

How to use the new types of strings in Delphi Xe2? - Stack Overflow

string delphi dll
Rectangle 27 0

The declaration of CharInSet is

function CharInSet(C: AnsiChar; const CharSet: TSysCharSet): Boolean; overload; inline;
function CharInSet(C: WideChar; const CharSet: TSysCharSet): Boolean; overload; inline;
TSysCharSet = set of AnsiChar;

Thus CharInSet can only compare to a set of AnsiChar. That is why your accented character is converted to AnsiChar.

There is no equivalent to a set of WideChar as sets are limited to 256 elements. You have to implement some other means to check the character.

const
  specials: string = '';

if CharInSet(InputText[i], ['0'..'9', 'a'..'z']) or (Pos(InputText[I], specials) > 0) then

might be a try. You can add more characters to specials as needed.

Sadly you can not keep using inline sets [...] and then stick unicode literals in there.

Wrong Unicode conversion, how to store accent characters in Delphi 201...

delphi unicode character-encoding
Rectangle 27 0

I'm not sure I understand the question. If you want to know how to write U+FE9F in Delphi source code, in a modern Unicode version of Delphi. Do that simply like so:

Char($FE9F)

If you want to read individual characters from then do it like this:

const
  MyWord = '';
var
  c: Char;
....
c := MyWord[1];//this is U+062C

Note that the code above is fine for your particular word because each code point can be encoded with a single UTF-16 WideChar character element. If the code point required multiple elements, then it would be best to transform to UTF-32 for code point level processing.

Now, let's look at the string that you included in the question. I downloaded this question using wget and the file that came down the wires was UTF-8 encoded. I used Notepad++ to convert to UTF16-LE and then picked out the three UTF-16 characters of your string. They are:

The first letter is , name is (m), its Unicode value is U+FE9F.

But that is simply incorrect. As can be seen from the above, the actual character you posted was U+062C. So the reason why your attempts to read the first character yield U+062C is that U+062C really is the first character of your string.

The bottom line is that nothing in your Delphi code is transforming your character. When you do:

S[1] := Char($FE9F);

the compiler performs a simple two byte copy. There is no context aware transformation that occurs. And likewise when reading S[1].

Let's look at how these characters are displayed, using this simple code on a VCL forms application that contains a memo control:

Memo1.Clear;
Memo1.Lines.Add(StringOfChar(Char($FE9F), 2));
Memo1.Lines.Add(StringOfChar(Char($062C), 2));

As you can see, the rendering layer knows what to do with a U+062C character that appears at the beginning of the string.

IMHO, this is not the expected answer. The question is "how do we get U+FE9F instead of U+062C when reading the char value of the string"

@loursonwinny If you want a character to contain U+FE9F, then put U+FE9F into the char. But if the string contains U+062C that's because U+062C was placed there. There's no magic fairy that changes characters from one value to another. In other words, if you write S[1] := Char($FE9F) then you are safe to assert that S[1]=Char($FE9F).

I don't think it is that easy when playing with unicode ;) I think that the OS reworks the string when it deals with arabic to finalize the ligatures

@loursonwinny Where does the OS come into play? I'm just talking about reading and writing elements of a Delphi string.

Do this test: Copy the first char of in the clipboard (remember that the first char in an arabic word is the one at the right side) and paste it in an editor. the result is , which is the same letter but not the same glyph. The same happens when accessing MyWord[1]

How to get a single Arabic letter in a string with its Unicode transfo...

delphi
Rectangle 27 0

It's an educated guess, but does the Data function return an UTF-8 string instead of a WideString? I think the error could be in this Data function that you're calling, which returns the data in the wrong string format.

delphi - how to handle unicode data in delphi7 - Stack Overflow

delphi delphi-7
Rectangle 27 0

As David mentions, the issue is the font used in your string grid. However, it is not strictly accurate to say that the default font in Delphi is MS Sans Serif. It used to be MS Sans Serif but was changed (in Delphi 2006) to Tahoma.

You can see how a particular version of Delphi chooses the default font by inspecting the source of the Graphics unit in the RTL source of that particular Delphi version (since the IDE is built using that code). Specifically the InitDefFontData procedure (and, in older versions of Delphi, the DefFontData record).

As of (at least) Delphi XE4 the default Tahoma font will be replaced by any setting for a font substitution for a value identified as MS Shell Dlg 2, as set in the registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes\

NB - from inspecting the code in XE4 it is possible that if this key does not exist or cannot be accessed, or if there is no substitution entry for MS Shell Dlg 2 font, then MS Sans Serif will still be used. It is hard to tell since this is the behaviour when "CLR" is defined, which should not be the case any more since Delphi no longer supports .NET and the IDE is presumably not compiled with CLR defined, but there is no way to be certain simply from inspecting the code what conditional defines might be applied when the IDE is compiled.

However, whichever font the IDE is using and however it is choosing that font, this affects only new forms created in the IDE.

For existing forms, as in this case, the issue is not with TStringGrid as such but rather the fact that you created the project in a version of Delphi which applied a default font which did/does not support Unicode.

The act of opening the project in the newer version of Delphi did not change the font used in your form(s), so the form saved in Delphi 7 using the MS Sans Serif font is still using that font when opened in Delphi XE5.

The TStringGrid control is then using the MS Sans Serif font because this is the font set on the form, and the default for controls on a form is to use their parent control font.

In such cases you should change the form font to Tahoma or a. n. other suitable, Unicode enabled font.

All controls on the form still set to use their parent control's font will then adopt this font also. When performing this on an actual application you may find some controls with ParentFont set FALSE which will need to be addressed individually and that even where font settings are being "inherited" your form designs may need further work to tidy things up due to changes in appearance resulting from the change of font.

Note that even this change to Tahoma has been overtaken by changes in Windows itself, and if you wish to apply some other default font (in new forms/projects) you may find useful information here.

Actually, for me anyway, a new project in XE7 uses MS Sans Serif. Try it. Maybe it's just me. XE7 is where I did all my testing. This doesn't tally with the info in the Q. Not sure why.

@David - I updated the answer with info that might shed some light. Do you have a MS Shell Dlg 2 value in FontSubstitutions that specifies MS Sans Serif ? If not, and in particular if this entry or the entire key is missing on your system, then it might be that the $IF DEFINED(CLR) code is actually active in the IDE (or that the XE7 InitDefFontData procedure has changed yet again with some new condition(s) that might result in MS Sans Serif being chosen).

Perhaps you already followed the advice in that article you linked to. It's all kind of irrelevant anyway. The point is that the control is no good with that font.

Argh. It could be the design time package that I have installed. I'll update.

@David - nope, this was in a Windows 7 VM with an install of Delphi (7 and XE4 as it happened). The only non-vanilla aspects being the installation of GExperts, Delphi Speedup, DDevExtensions etc etc. But I don't believe these play any part - the behaviour I see is consistent with the InitDefFontData code (My MS Shell Dlg 2 setting is "Tahoma", which is the default setting for Windows 7 as documented by Microsoft).

unicode - How to convert TStringGrid from Delphi 7 to Delphi XE - Stac...

delphi unicode tstringgrid stringgrid
Rectangle 27 0

byte.Parse("12", NumberStyles.HexNumber);
byte[]
Encoding.UTF8.GetString(byteStr)

Thanks, that worked fine for , carriage return and German! I still can't get Japanese or Greek characters to work, but I will worry about that later. Thanks again.

Delphi 10, .NET, how do I convert a hex UTF-8 string to its unicode ch...

delphi unicode utf-8 delphi-2006
Rectangle 27 0

If there was a "Ansi switch" for Delphi 2009/2010/XE/XE2 (the unicode versions), you would simply be exchanging the problem you have now, with far worse problems.

For that reason, there can not be a switch. This idea was discussed carefully, I happen to know from first-hand conversations with the people who made the decision, and the decision to break your code was not undertaken without due diligence. There was simply no other way to go. To make Delphi truly Unicode, it was essential to alias String=UnicodeString.

Therefore, you must change all your String declarations to AnsiString, and Char to AnsiChar if you wish to have single-byte non-unicode character and string types in your application code. In most of your code, and in most places, that is not necessary. But where you explicitly need byte-size processing, such as binary protocols over RS232 and RS485, or binary file formats (EDA, etc), you need to change your code.

If you don't want to port your code yourself, pay someone to do it. I ported a huge library of scientific components and applications up myself, and it took me several weeks to test and find all the bugs. Afterwards, I had a reasonable modern codebase that has not broken again since 2009 when I upgraded.

When you get to the XE/XE2 divide, you may encounter some more pain having to do with your code's assumptions that Pointer types are the same size as Integer or Cardinal, which is no longer true in Win64. Again, Delphi guys have no desire to break your code, they're just following sane engineering practices, in that case, Win64 dictates certain things.

Why didn't they change every VCL control property to USTRING instead of String? Why didn't they make every RTL function take both USTRING and STRING and provide overloads?

Because normative Delphi development is now purely Unicode. USTRING is, and would be a special case. String is the native (normative) string type, and it is, in fact, also known now as UnicodeString.

It so happens you were already using a type alias. Strings in delphi 1.0 were limited to 255 characters in length. When they introduced Delphi 2.0, and the long string type, internally called AnsiString, they aliased the existing common type String as String=AnsiString. When we got to Unicode, every VCL component and every VCL method that takes a string still takes a string. However String is now String=UnicodeString.

Delphi 7 already has WideString for example. We don't need a half-way move to unicode. Whether you realize it or not the entire software development world now expects string types to be unicode. Delphi is part of a global phenomenon. The internet is unicode. Your Windows 7 operating system is pure native unicode.

Reading the embaracadero unicode white paper convinced me that migration is too horrendous to tackle at this time. I guess I'm stuck with D2007 for the foreseeable future.

It's actually not that bad.

Your parallel with Windows 7 is actually quite ironic since we had to ditch 7 due to incompatibility with several of our key tool chains. We only use XP and xp64 now which is a bit sad since it proves Microsoft did have a painless migration path to 64 bits, they just chose not to promote it.

Well, you're painting yourself into several corners then. Enjoy the long slow slide into obsolescence. Windows XP is also native unicode, or didn't you know?

Warren, I am not anti unicode, I am sure there are plenty of people that want unicode. I just can't use unicode in my applications and am frustrated at being forced to use old tools. Even localisation is causing me headaches in delphi, I'm fed up of having to poke a decimal point char into the decimalseparator variable every time I need to do a floattostr or vice versa. I can't be having users save a file in England only to have customers in france complain it doesn't load because delphi is expecting a comma. There should be compiler switches to turn these features off, its just common sense.

How to disable unicode in Delphi xe2 - Stack Overflow

delphi delphi-xe2
Rectangle 27 0

There's another similar question, but I'll repeat my reply here too, to make sure as many people see this info:

First up, a disclaimer: although I work for Embarcadero. I can't speak for my employer. What I'm about to write is based on my own opinion of how a hypothetical 64-bit Delphi should work, but there may or may not be competing opinions and other foreseen or unforeseen incompatibilities and events that cause alternative design decisions to be made.

64bit - How to also prepare for 64-bits when migrating to Delphi 2010 ...

delphi 64bit migration