Autor |
Beitrag |
Palladin007
      
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Mo 09.09.13 12:39
Moin,
Kennt jemand eine Möglichkeit, wie ich aus der Kodierung der Konsole heraus finden kann, ob die Konsole ein Zeichen darstellen kann, oder nicht?
Ich möchte einen Adapter schreiben, der Zeichen für Zeichen prüft, ob die Eingabe akzeptiert wird und andernfalls einfach nichts tut.
Wenn aber kein Zeichensatz angegeben wurde, dann soll der Satz genommen werden, der alle Zeichen enthält, die dargestellt werden können.
Kennt da wer eine Möglichkeit, bei allen 65535 möglichen Zeichen?
Gruß
PS:
Da ich darauf leider ziemlich schnell eine Antwort benötige, habe ich die gleiche Frage auf einem anderen Forum gestellt. Hier der [url=www.mycsharp.de/wbb2...d=109327]Link[/URL].
Wurde geschlossen -.-
|
|
Th69
      

Beiträge: 4798
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mo 09.09.13 13:25
Hallo Palladin007,
unter WPF (genauer der PresentationCore.dll) gibt es die GlyphTypeface-Klasse, welche Informationen über einen Font enthält. Ansonsten direkt die WinAPI-Funktion GetGlyphIndices() benutzen, s. z.B. C#: Check for unsupported characters/glyphs in a font.
|
|
Palladin007 
      
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Mo 09.09.13 13:41
Da ich WPF gerne außen vor lassen möchte, habe ich mir gleich die zweite Möglichkeit angeschaut und das scheint bisher genau das zu sein, was ich suche.
Aber eine Frage hab ich noch: Der Font, kann ich davon aus gehen, dass "Courier New" der Font der Konsole ist, oder gibt es da Andere?
Gruß
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 09.09.13 13:43
Consolas und Lucida Console. Das ist zumindest bis Windows 7 noch einstellbar. Weiß nicht ob ab 8 da nochwas hinzugekommen ist.
Edit: Raymond Chen mit der Historie zum Thema. Kann also theoretisch ein fast beliebiger Font sein.
|
|
Palladin007 
      
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Mo 09.09.13 13:52
Leider hat sich damit jetzt ein weiteres Problem ergeben
Scheinbar ist es nicht ohne Weiteres möglich, den aktuellen Font der Konsole heraus zu finden, da es auf der einen Seite einen Font gibt, der von der Konsole selber gerendert wird (Rasterschrift, hab ich irgendwo gelesen) und eine Reihe anderer Fonts, die der Nutzer aber selber fest legen und ich von der Konsole nicht abfragen kann.
Gibt es in C# und .NET eine Möglichkeit, das irgendwie heraus zu finden?
|
|
Th69
      

Beiträge: 4798
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Mo 09.09.13 13:59
Hallo nochmal,
das müßte mit der GetCurrentConsoleFontEx-Funktion gehen, d.h. per P/Invoke: pinvoke.net/default....ntConsoleFontEx.html (schau dir die Benutzung dazu bei pinvoke.net/default....rentConsoleFont.html an): FaceName sollte dann der Name des Fonts sein.
|
|
Palladin007 
      
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Mo 09.09.13 14:44
Ich hab es jetzt so versucht:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public class CONSOLE_FONT_INFOEX { private int cbSize; public CONSOLE_FONT_INFOEX() { cbSize = Marshal.SizeOf(typeof(CONSOLE_FONT_INFOEX)); } public int FontIndex; public short FontWidth; public short FontHeight; public int FontFamily; public int FontWeight; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string FaceName; }
class ConsoleHelper { [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] extern static bool GetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool bMaximumWindow, [In, Out] CONSOLE_FONT_INFOEX lpConsoleCurrentFont);
public static void GetConsoleFont() { Type consoleType = typeof(Console);
IntPtr _consoleOutputHandle = (IntPtr)consoleType.InvokeMember( "_consoleOutputHandle", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, null, null, null);
CONSOLE_FONT_INFOEX currentFont = new CONSOLE_FONT_INFOEX(); bool success = GetCurrentConsoleFontEx( _consoleOutputHandle, false, currentFont);
} } |
Ich verstehe nur wenig, daher fällt es mir ziemlich schwer, den Fehler zu finden, aber der Inhalt von currentFont ist leer. :/
Ich habe testweise auch mal den Font der Konsole immer geändert und dann geschaut, was drin steht, aber es bleibt leer.
Edit:
Ich habe gerade gesehen, dass ich diese Methode aus deinem dritten Link nutzen kann:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| public static IntPtr getConsoleOutputHandle() { Type consoleType = typeof(System.Console);
FieldInfo _consoleOutputHandle_fieldinfo = consoleType.GetField("_consoleOutputHandle", BindingFlags.NonPublic | BindingFlags.Static);
IntPtr RetVal;
System.Console.BackgroundColor = System.Console.BackgroundColor;
try { RetVal = (IntPtr)_consoleOutputHandle_fieldinfo.GetValue(null); }
catch (Exception) { RetVal = IntPtr.Zero; }
return RetVal; } |
Und damit funktioniert es jetzt
Ich schreibe das ganze noch ordentlich zusammen und poste dann die ganze Klasse, wenn jemand Anderes das gleiche Problem haben sollte ^^
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mo 09.09.13 14:55
Schreib mal vor den currentFont Parameter ref beim GetCurrentConsoleFontEx Aufruf. hat sich erledigt.
|
|
Palladin007 
      
Beiträge: 1282
Erhaltene Danke: 182
Windows 11 x64 Pro
C# (Visual Studio Preview)
|
Verfasst: Mo 09.09.13 15:13
Ein Problem hab ich noch:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] private class CONSOLE_FONT_INFOEX { private int cbSize;
public int FontIndex; public short FontWidth; public short FontHeight; public int FontFamily; public int FontWeight; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string FaceName;
public CONSOLE_FONT_INFOEX() { cbSize = Marshal.SizeOf(typeof(CONSOLE_FONT_INFOEX)); } } |
Das Objeckt davon enthält ja die ausgelesenen Daten.
Aber wie bekomme ich aus Diesen jetzt den passenden Font raus?
Der Name ist ja der Anzeigename des Fonts, nicht der Familien-Namen. Außerdem - wie bekomme ich emSize raus?
Oder die FontFamilie aus dieser Zahl?
Der Style sollte ja unwichtig sein, für das, was ich brauche.
Edit:
Ich hab es jetzt erst einmal so gelöst:
C#-Quelltext 1:
| new Font(fontInfo.FaceName, fontInfo.FontHeight) |
Es funktioniert, wenn aber da ein Fehler drin sein sollte, oder das nicht ganz genau ist, würde ich mich über Korrekturen freuen.
Für die Neugierigen, hier die ganze Klasse (neben der Klasse CONSOLE_FONT_INFOEX):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78:
| public class ConsoleHelper { [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private extern static bool GetCurrentConsoleFontEx(IntPtr hConsoleOutput, bool bMaximumWindow, [In, Out] CONSOLE_FONT_INFOEX lpConsoleCurrentFont);
[DllImport("gdi32.dll", EntryPoint = "GetGlyphIndicesW")] private static extern uint GetGlyphIndices([In] IntPtr hdc, [In] [MarshalAs(UnmanagedType.LPTStr)] string lpsz, int c, [Out] ushort[] pgi, uint fl);
[DllImport("gdi32.dll")] private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
private const uint GGI_MARK_NONEXISTING_GLYPHS = 0x01; private static Graphics _graphics = Graphics.FromImage(new Bitmap(1, 1));
public static bool DoesGlyphExist(char c) { var fontInfo = GetCurrentConsoleFontEx(); return DoesGlyphExist(c, new Font(fontInfo.FaceName, fontInfo.FontHeight)); }
public static bool DoesGlyphExist(char c, Font font) { IntPtr hdc = _graphics.GetHdc(); ushort[] glyphIndices;
try { IntPtr hfont = font.ToHfont();
SelectObject(hdc, hfont);
string testString = new string(c, 1); glyphIndices = new ushort[testString.Length];
GetGlyphIndices(hdc, testString, testString.Length, glyphIndices, GGI_MARK_NONEXISTING_GLYPHS);
} finally { _graphics.ReleaseHdc(hdc); }
return (glyphIndices[0] != 0xffff); }
public static CONSOLE_FONT_INFOEX GetCurrentConsoleFontEx() { Type consoleType = typeof(Console); IntPtr _consoleOutputHandle = getConsoleOutputHandle();
CONSOLE_FONT_INFOEX currentFont = new CONSOLE_FONT_INFOEX(); bool success = GetCurrentConsoleFontEx( _consoleOutputHandle, false, currentFont);
return currentFont; }
private static IntPtr getConsoleOutputHandle() { Type consoleType = typeof(System.Console); FieldInfo _consoleOutputHandle_fieldinfo = consoleType.GetField("_consoleOutputHandle", BindingFlags.NonPublic | BindingFlags.Static); Console.BackgroundColor = System.Console.BackgroundColor;
IntPtr RetVal;
try { RetVal = (IntPtr)_consoleOutputHandle_fieldinfo.GetValue(null); } catch (Exception) { RetVal = IntPtr.Zero; }
return RetVal; } } |
|
|
|