![]() |
Name von Unicode-Zeichen
Hallo!
Gibt es eigentlich eine API wo man die Namen der Unicode-Zeichen abfragen kann? Gemeint ist das so: Einfach mal charmap.exe aufrufen. Wenn man eines der Zeichen auswählt oder drüber maust, dann erscheint der Name des Zeichens in der Sprache, die das System verwendet. Hat Microsoft dafür irgendwo eine API eingebaut mit der man die Namen abfragen kann? Grüße Cody |
AW: Name von Unicode-Zeichen
|
AW: Name von Unicode-Zeichen
Ich sage mal, die Betonung liegt auf Systemsprache ;-)
|
AW: Name von Unicode-Zeichen
Die Zeichentabelle hat ihre eigene DLL:
![]() Vielleicht sicherer ist aber sich bei Unicode.org die entsprechende Tabelle zu laden und selbst nachschauen. |
AW: Name von Unicode-Zeichen
Danke das war der Einstieg! Und wie ich gesehen habe, wenn man erstmal das richtige Stichwort weiß findet man auch
![]() |
AW: Name von Unicode-Zeichen
Wo ich schon mal dabei bin: Kann man eigentlich auch feststellen, ob eine Schriftart ein Symbol für ein bestimmtes Zeichen enthält oder nicht? Ich schau schon alles bei den
![]() |
AW: Name von Unicode-Zeichen
Nicht das es dir jetzt weiterhilft. Aber
diese Seiten finde ich auch ganz interessant ![]() |
AW: Name von Unicode-Zeichen
Es gibt die Unit Characters, aber da kann man sich nur die Typen/Gruppen/Eigenschaften der Chars holen,
aber leider nirgendwo die Namen. Ich hatte auch in der GDI+ noch keine Funktion gefunden, welche den Namen liefert oder ob es das Zeichen überhaupt im Font gibt. Du könntest zwar die Font-Datei selber auslesen/parsen und nachgucken, welche Zeichen darin definiert sind, aber das hilft nur bedingt, da in Windows auch ein Ersatzfont definiert sein könnte, welchen Windows zum Zeichnen des fehlenden Chars verwendet. PS: Die großen Unicodefonts von Windows (z.B. Arial und MingLiU) bestehen auch nicht nur aus einer Datei. (die Chars wurden da auf mehrere Dateien verteilt) Außerdem gibt die GDI "absichtlich" keinerlei Fehlerinformationen aus, wenn man ein nicht-vorhandenes Zeichen oder gar mit einem nicht-vorhandenen Font etwas schreiben will. Das Einzige, was mir damals auf die schnelle eingefallen war, ist ein Bildvergleich. * erst ein nie vorhandenes Char auf ein Bitmap zeichnen (da kommt dann das Ersatzzeichen des Fonts raus, was meistens ein Rechteck ist) * dann das gewünschte Char zeichnen * und die Bilder dann vergleichen :freak: Und die Fontnamen, da hatte ich auch von unicode.org (das ist ja die Vergabestelle für die Unicodedefinition) die CSV's besorgt und die benötigten Daten als Resource an meine Anwendung gehängt. |
AW: Name von Unicode-Zeichen
Zugegeben ich habe es nicht getestet aber vieleicht hilft das:
![]() |
AW: Name von Unicode-Zeichen
Ist schon über 10 Jahre her, als ich das Thema CJK und solche Probleme mal hatte. Um die alten Programme zu testen müsste ich allerdings erst mal die Tnt-Controls umbauen.
Aber laut Quelltexten z.B. ![]() Falls noch weitere Fragen auftauchen lohnt sich vermutlich ein Blick in die ![]() PS: ![]() |
AW: Name von Unicode-Zeichen
Zitat:
Delphi-Quellcode:
function TfrmMain.GetCharExists(const Chr: Char): Boolean;
var Buf: Word; begin Result:= FALSE; if GetGlyphIndices(tvChars.Canvas.Handle, PChar(Chr), 1, @Buf, GGI_MARK_NONEXISTING_GLYPHS) <> GDI_ERROR then begin Result:= (Buf <> $FFFF); end; end; |
AW: Name von Unicode-Zeichen
Mal schnell was rauskopiert. Funktioniert mit japanischen Text und Tahoma vs. Arial Unicode MS.
Delphi-Quellcode:
Edit: War noch von D2005.
var pwOutGlyphs: PWord;
i, cwstr: Integer; wstr: String; erg: Cardinal; begin wstr:=Edit1.Text; cwstr:=Length(wstr); if wstr='' then exit; GetMem(pwOutGlyphs, cwstr*2); ZeroMemory(pwOutGlyphs, cwstr*2); erg:=GetGlyphIndices(Canvas.Handle, @wstr[1], cwstr, pwOutGlyphs, GGI_MARK_NONEXISTING_GLYPHS); if erg=GDI_ERROR then RaiseLastOSError; ExtTextOut(Canvas.Handle, 10, 6, ETO_GLYPH_INDEX, Nil, PChar(pwOutGlyphs), cwstr, Nil); Memo1.Clear; for i:=0 to cwstr-1 do Memo1.Lines.Add(IntToHex(PWordArray(pwOutGlyphs)[i], 4)); end; |
AW: Name von Unicode-Zeichen
Zitat:
Delphi-Quellcode:
Und dann noch die fehlende #0-Terminierung
PChar(@Chr)
// bzw. @Chr Und C=1 ? Was ist, wenn pgi größer sein muß? |
AW: Name von Unicode-Zeichen
Ähm, OK.
Dann halt noch die Uniscribe-Version. Der Rest stimmt überein.
Delphi-Quellcode:
var sc: TScriptCache;
hr: HRESULT; sc:=Nil; hr:=ScriptGetCMap(Canvas.Handle, @sc, @wstr[1], cwstr, SGCM_RTL, pwOutGlyphs); if (hr<>S_OK) and (hr<>S_FALSE) then RaiseLastOSError; ScriptFreeCache(@sc); |
AW: Name von Unicode-Zeichen
Du kannst dich auch mal mit DirectWrite beschäftigen!
Da steckt sehr viel drin, was du sicherlich gebrauchen kannst. Bspw. hat das IDWriteFont Interface eine HasCharacter-Methode. Daneben gibt es noch eine Vielzahl weiterer Sachen, die sicherlich weiterhelfen: ![]()
Delphi-Quellcode:
unit Unit1;
interface uses Winapi.Windows, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Direct2D, Winapi.D2D1; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private function GetCharExists(const Chr: Char): Boolean; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin Caption := GetCharExists('†').ToString(TUseBoolStrs.True); end; function TForm1.GetCharExists(const Chr: Char): Boolean; var hr: HRESULT; FontHandle: HFont; LogFont: TLogFont; GdiInterop: IDWriteGdiInterop; WriteFont: IDWriteFont; CharacterExists: BOOL; begin Result := False; hr := DWriteFactory.GetGdiInterop(GdiInterop); if SUCCEEDED(hr) and Assigned(GdiInterop) then begin FontHandle := Self.Font.Handle; if GetObject(FontHandle, SizeOf(LogFont), @LogFont) <> 0 then begin hr := GdiInterop.CreateFontFromLOGFONT(LogFont, WriteFont); if SUCCEEDED(hr) and Assigned(WriteFont) then begin hr := WriteFont.HasCharacter(Ord(Chr), CharacterExists); Result := SUCCEEDED(hr) and CharacterExists; end; end; end; end; end. |
AW: Name von Unicode-Zeichen
Vielleicht als Einstieg, wenn man von der alten GDI/WinApi-Welt kommt:
![]() |
AW: Name von Unicode-Zeichen
Liste der Anhänge anzeigen (Anzahl: 1)
Also bei der ganzen Experimentiererei ist quasi nebenbei noch etwas Nützliches entstanden: Eine Art Zeichentabelle wie die von Windows, nur ein bisschen komfortabler, nicht so klein und fuddelig.
|
AW: Name von Unicode-Zeichen
Mir fehlen da ein paar Komponenten, aber ist der Font Fallback Absicht? Die angezeigten Glyphen sind nicht unbedingt in den Schriftarten enthalten.
|
AW: Name von Unicode-Zeichen
Zitat:
Nebenbei zeigt sich, dass manche VCL-Komponenten bis heute Probleme mit Unicode haben. So funktioniert z.B. die Selektion von bestimmten Unicode-Zeichen in TLabeledEdit nicht. Die Anwendung ist eigentlich nur als Testanwendung entstanden. Die Quellen sind ja dabei, Vorschläge gerne willkommen. |
AW: Name von Unicode-Zeichen
Zitat:
Und ein echtes Add on, einen Font (temporär) laden? (die notwendigen Sourcen kann ich Dir heraus suchen) Muß ich noch erwähnen, daß mir Dein Programm gefällt? Gruß K-H |
AW: Name von Unicode-Zeichen
An den Spaß kann ich mich noch gut erinnern. Habe mich dann sogar bei
![]() Bei GetGlyphIndices zeigt ein Index von $FFFF an, dass die Glyphe nicht enthalten ist (bei ScriptGetCMap ist es selbstverständlich die 0). Dann braucht man noch die jeweilige default Glyphe. Letztlich habe ich dann die ganz harte Methode benutzt, das direkte Auslesen der ![]() ![]() Und ich erwähne noch einmal: ![]() |
AW: Name von Unicode-Zeichen
Da ich leider nicht im Besitz der Komponenten bin (TB2..., SpTBX...), kann ich dein Programm nicht kompilieren.
Zwei Sachen fallen mir jedoch beim durchschauen auf: Es ist etwas suboptimal, bei jedem Aufruf von GetCharName die DLL getuname.dll zu laden und entzuladen. Hier wäre es besser, einmal statisch die Funktion GetUName in Quelltext zu definieren und zu verwenden. Du hast meine GetCharExists-Funktion im Prinzip einfach nur kopiert, ohne zu verstehen das dort passiert. Mein Code diente zu Testzwecken und muss natürlich angepasst werden. So wird nämlich hier immer die Schrift des Hauptformulars verwendet, ohne auf Änderungen in cbbFontListChange einzugehen. Hier weist du ja explizit die Schrift von cbbFontList.SelectedFont den TreeView und dem Vorschaufenster zu. Es wäre auch Ressourcen schonender, wenn du dir die Instanzen von IDWriteGdiInterop einmalig beim Programmstart holst und als Membervariable des Formulars führst. Eine Neuerzeugung von IDWriteFont ist dann nur noch notwendig, wenn cbbFontListChange aufgerufen wird. Somit würde sich die GetCharExists-Funktion verkürzen auf:
Delphi-Quellcode:
Die einmalige Erzeugung von IDWriteGdiInterop und die Neuerzeugung von IDWriteFont beim Schriftartwechsel überlasse ich dir mal als Fingerübung. :thumb:
function TfrmMain.GetCharExists(const Chr: Char): Boolean;
var HR: HRESULT; CharacterExists: BOOL; begin Result := btnShowAllChars.Checked; if Result then Exit; if Assigned(FWriteFont) then begin HR := FWriteFont.HasCharacter(Ord(Chr), CharacterExists); Result := SUCCEEDED(HR) and CharacterExists; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz