I'm trying to insert a symbol - white square (Unicode 25A1) into Excel spreadsheet but keep getting errors:
I tried following with no avail:
1. WorkSheet.Cells[CurrRow,CurrCol].Formula := '=ChrW(&H25A1)';
2. WorkSheet.Cells[CurrRow,CurrCol].Formula := '=Char(25A1)';
And running macro didn't help either as it said '?'
Really hoping someone could help me with this
The COM interface to Excel is a Unicode API. Excel works internally with Unicode strings. Just pass your special character to Excel in a Delphi WideString. You don't need an Excel formula.
WorkSheet.Cells[CurrRow,CurrCol].Value := WideString(#$25A1);
If you are using a Unicode version of Delphi (i.e. 2009 or later) then you can include the Unicode character in your source code if you make your source code a UTF-8 file.
WorkSheet.Cells[CurrRow,CurrCol].Value := WideString('□');
The IDE will convert your source file to UTF-8 if you start adding non-ANSI characters.
You are probably getting an error message which in Excel would be displayed in the Cell as #VALUE!. For one you are feeding it a hex string while it wants a normal number. For another you are giving the Char function a number outside of its acceptable range. The Excel help for CHAR specifically states:
a number between 1 and 255 specifying
which character you want. The
character is from the character set
used by your computer
It appears that Excel does not have any ChrW function. And I can't find any function that takes a numeric value and converts it to its Unicode character equivalent.
Looking through the help, the way you insert Unicode characters is by using the numeric value from the keyboard (holding down alt) or by using the menu: Insert, text, symbol, Unicode (hex). You should be able to simulate the keyboard input, and the menu should be available through the COM model, but not sure whether the character selection then is.
Having said all that, if you are looking for a way to insert Unicode text from Delphi into Excel cells, then all you should need to do, is:
WorkSheet.Cells[CurrRow, CurrCol].Value := Chr(#$25A1);
And I am only using the Delphi (!) Chr function because you did. You could simply enter assign a text string containing the character you need to the cell in the Delphi source.
Related
I am stuck a bit in decoding. I got a base64-encoded .rtf file.
A little part of this looks like this: Bek\u252\''fcld\u337\''3f
Which represents: Beküldő
But my output data after decoding is: Bekuld?
If I manually replace the characters it works.
StringReplace(Result, 'U337\''3F', '''F5', [rfReplaceAll, rfIgnoreCase]);
Does anyone know a general solution for this? Some conversation or something?
For instance, \u242 means Unicode character #242.
So you could search for \u in the RTF content (ignoring any \\ escaped sequence), then retrieve the following number, and use it as a character.
But RTF is a very complex beast.
Check what the RTF 1.5 specifications says about encoding:
\uN This keyword represents a single Unicode character which has no
equivalent ANSI representation based on the current ANSI code page. N
represents the Unicode character value expressed as a decimal number.
This keyword is followed immediately by equivalent character(s) in
ANSI representation. In this way, old readers will ignore the \uN
keyword and pick up the ANSI representation properly. When this
keyword is encountered, the reader should ignore the next N
characters, where N corresponds to the last \ucN value encountered.
Perhaps the easiest is to use a hidden RichEdit for decoding, under Windows/VCL.
I know that if I want to add an ASCII character in a string like a black space, for example, all I need to do is to add with a call to CHAR(32) and the space will be added to the string.
But what if I want to put the infinite symbol ∞ (U+221E) how should I do it?
If I paste it into a literal string like 'infinite is ∞' then Delphi wants to change the file to UTF8.
Char is a data type, so Char() is a typecast, not a function. Chr() is a function.
In D2009+, you can use either:
Char($221E) or Char(8734) (in earlier versions, use WideChar() instead)
Chr($221E) or Chr(8734)
#$221E or #8734 character constants
TCharacter.ConvertFromUtf32()
TCharHelper.ConvertFromUtf32()
'∞'. There is nothing wrong with using this in code and letting the IDE decide how to save it. This is actually the preferred solution. The only time you would need to avoid this is if you are using other tools to process your source files and they don't support UTF-8 files.
One of our legacy applications is in Delphi6 and we are having trouble in displaying the currency symbol of "Baht" in this application's labels and textedits.
We are using the Unicode of Baht to set the text of the labels/textedits (i.e. 0E3F) but it is always rendered as a '?'.
We tried changing the Font properties of the said labels/textedits to ANSI_CHARSET, DEFAULT_CHARSET (and even THAI_CHARSET) but no luck. And the font type selected is "Microsoft Sans Serif" which has the currency symbol of Baht (not 'MS Sans Serif' which does not have the Baht currency symbol).
Has anyone encountered this in Delphi6 and if so are there any solutions?
Thanks in advance..!!
We are using the Unicode of Baht to set the text of the labels/textedits (i.e. 0E3F) but it is always rendered as a '?'.
The ? character indicates that when the Unicode character was converted to ANSI, no character was found in the ANSI code page in use. Your options:
Use an ANSI code page that includes this character, that is Windows-874.
Stop using ANSI and start using Unicode.
The latter option is better, but of course a little tricky in Delphi 6 which, out of the box, is an ANSI based tool. To make Unicode GUIs with Delphi 6 you need to use the TNT Unicode components.
Windows' application charmap.exe, with advanced view enabled, has a character-set selection, and when you select the character, the status-line at the bottom displays the 256-bits hex code for the character next to the unicode code point.
(Either search for "Character Map" in the start menu, or press Windows-key + R and type "charmap")
If I try it here with "Windows: Thai", I get code 0xDF for the Baht-symbol. So if you write #$DF or #223 in the string, or press Alt while typing 0 2 2 3, it should work.
Native pre-Unicode Delphi controls allow to enter specific local (ex Thai) characters only on a system having this specific system locale.
The workaround used for pre-Unicode Delphi versions is to replace native VCL controls by the TNT Unicode controls.
I am unaware of the TNT Unicode controls status today. You can try to search on google.
Considering this Arabic word(جبل) made of 3 letters .
-the first letter is جـ,
-name is (ǧīm),
-its Unicode value is FE9F when its in the beginning,
-its basic value is 062C and
-its isolated value is FE9D but the last two values return the same shape drawing ج .
Now, Whenever I try to get it as a single character -trying many different ways-, Delphi returns the basic Unicode value.
well,that makes sense,but what happens to the char with transformation? It is a single char too..Looks like it takes the transformed value only when it is within a string, but where? how to extract it?When and which process decides these values?
Again the MAIN QUESTION:
How can I get the Arabic letter or its Unicode value as it is within a string?
just for information: Unlike English which has tow cases for its letters(Capital and Small), Arabic has four cases(Isolated, Beginning,Middle And End) with different rules as well.
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:
U+062C
U+0628
U+0644
You stated:
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));
The output looks like this:
As you can see, the rendering layer knows what to do with a U+062C character that appears at the beginning of the string.
Shaping of Arabic characters for presentation in Windows is served by the Uniscribe services (USP10.dll).
UniScribe
You may find the following blog post useful:
Roozbeh's Programming Blog
I don't think you can do it using string/char related methods. But using pchar, maybe can you access the memory and read the Pword values directly
EDIT: After discussing with David, I think that you will always get the basic/isolated value of the letter. The fact that begin or end glyph is used, is probably just handled by the display framework of the OS
Output: Period: from 11-Ê®¶þÔÂ-10 to 13-Ê®¶þÔÂ-10
The above output is from a line like this:
FormatDateTime('dd-mmm-yy', dateValue)
The IDE is Delphi 2007 and we are trying to gear up our app to the Chinese market.
How can I display the correct characters?
With the setting turn to Hindi (India), instead of the funny characters I have the "?".
I'm trying to display the date on a report, using ReportBuilder 11.
Any help will be much appreciated.
The characters seem to be correct, only IMO they have been rendered wrong.
Here's what I've done:
copied the string as presented by the OP ("11-Ê®¶þÔÂ-10 to 13-Ê®¶þÔÂ-10");
pasted it into a blank plain-text editor window with CP 1252 (Windows Latin-1) and saved;
opened the text file in a browser;
the text showed up the same as the browser chose the same codepage, so I turned on the automatic detection of character encoding, hinting it that the contents was Chinese;
the text changed to "11-十二月-10 to 13-十二月-10" (hope your browser displays correct Chinese characters here, my does anyway) and the codepage changed to GB18030 (and I then tried GB2312, but the text wouldn't change);
well, I was curious and searched for "十二月", and it turned out to stand for "December", quite suitable for the context unless the month names had been mixed up.
So, this is why I think it's a text rendering (or whatever you call it, I'm not really sure about the term) problem.
EDIT: Of course, it must have had something to do with the data type chosen for storing the string. If the function result is AnsiString and the variable is WideString, then maybe the characters get converted as WideChars and so they are no longer one-byte compounds of multi-byte characters but are multi-byte characters on their own? At least that's what happened when the OP posted them here.
I don't know actually, but if it is so then I doubt if they can be rendered correctly unless converted back and rendered as part of an AnsiString.
Another solution is to use TntControls. They're a set of standard Delphi controls enhanced to support Unicode. You'll have to go through all your form files and replace
Button1: TButton
Label1: TLabel
with TTntButton, TTntLabel et cetera.
Please note, that as things stand, it's not only Chinese which will not work. Try any language using symbols other than standard European set (latin + stress marks etc), for instance Russian.
But
By replacing the controls, you'll solve one part of the problem. Another part is that everywhere where you use "string" or "AnsiString" and "char/pchar" or "AnsiChar/PAnsiChar", you can store only strings in default system encoding.
For instance, if your system encoding ("Language for non-unicode programs") is EN/US, Russian characters will be replaced with question marks when you assign them to "string" variable:
a: WideString;
b: string;
...
a := 'ЯУЭФЫЦ'; //WideString can store international characters
b := a; //string cannot, so the data is lost - you cannot restore it from just "b"
To store string data which is independent of system encoding, use WideString/WideChar/PWideChar and appropriate functions. If you have
a, b: WideString;
...
a := UpperCase(b);
then unicode information will still be lost because UpperCase() accepts "string":
function UpperCase(const S: string): string;
Your WideString will be converted to "string" (losing all international characters), given to UpperCase, then the result will be converted back to WideString but it's already too late.
Therefore you have to replace all string functions with Wide versions:
a := WideUpperCase(b);
(for some functions, their wide versions are unavailable or called differently, TntControls also contain a bunch of wide function versions)
The Chinese Market requires support for multi-byte character sets (either WideChar or Unicode).
The Delphi 2007 RTL/VCL only supports single-byte character sets (there is very limited support for WideChar in the RTL and VCL).
The easiest for you is to upgrade to a Delphi version that supports Unicode (Delphi 2009 was the first version that supports Unicode, the current Delphi vesion is Delphi XE).
Or you will need to update all your components to support WideChar, and rewrite the portions of RTL/VCL for which you need WideChar support.
--jeroen
Did you install Far East charset support in Windows? In Windows pre 7 (or Vista) those charset are not installed by default in Western versions, you have to add them in Control Panel -> Regional Settins, IIRC
Using a non-Unicode version of Delphi unluckily what character can be displayed depends on the current codepage. If it is not one of the Chinese ones, for example, it could not display the characters you need. What characters are actually displayed depends on how the codes you're using are mapped in the current codepage. You could use a multi-lingual version of Windows to switch fully to the locale you need, or you have to use a Unicode version of Delphi (from 2009 onwards).