Probleme mit Grafischen Zeichen in der Windows Console

Re: Probleme mit Grafischen Zeichen in der Windows Console

Beitragvon visualteam » 24. Jan 2014, 17:25 Re: Probleme mit Grafischen Zeichen in der Windows Console

Blocktronic hat geschrieben:...
Insofern sehe ich es als sehr Positiv an, da nun etwas neues entstehen wird.
Vermutlich werde ich dieses Terminal für Windows dann auch als Freeware in die Welt entlassen.

...


Danke - und laß hören/sehen :-)

Gruß VT
________________
:-)
visualteam
 
Beiträge: 1
Registriert: 24. Jan 2014, 16:36
OS, Lazarus, FPC: LMDE + Win7prof (L 1.0.x FPC 2.2.x) | 
CPU-Target: 64 Bit
Nach oben

Beitragvon Mathias » 24. Jan 2014, 17:33 Re: Probleme mit Grafischen Zeichen in der Windows Console

Vieleicht hilf dir das weiter, mit diesem Code aus einem Delphi-Programm, konnte ich alle 256-ASCII auf eine Bitmap ausgeben.
Code: Alles auswählen
      with Font do begin
        Charset := OEM_CHARSET;
        Color := 0;
        Height := 0;
        Name := 'Terminal';
        Pitch := fpDefault;
        Size := 24;
        Style := [fsBold, fsItalic, fsUnderline, fsStrikeOut];
        Style := [];
      end;
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3194
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Mathias » 31. Mai 2014, 20:13 Re: Probleme mit Grafischen Zeichen in der Windows Console

So bringe ich sogar alle 256 ASCII-Zeichen in die Console, inklusive der Steuerzeichen.

Interessante währe noch, wen man über einen Pointer direkt in die Konsole zugreiffen könnte, so ählich wie unter DOS mit Mem[$B800:0000].

Code: Alles auswählen
program project1;
uses
  Windows;
 
  procedure OutCharXY(x, y: integer; ch: char; col: byte);
  var
    numChars: integer = 1;
    c: coord;
    p: longword = 0;
  begin
    c.X := x;
    c.Y := y;
    FillConsoleOutputAttribute(GetStdHandle(STD_OUTPUT_HANDLE), col,
      numChars, c, p);
    FillConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), ch,
      numChars, c, p);
  end;
 
 
var
  i: integer;
begin
  for i := 0 to 255 do begin
    OutCharXY(i mod 16 * 2, i div 16, char(i), 7);
  end;
  readln;
end
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3194
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Iceman_03 » 25. Apr 2016, 13:42 Re: Probleme mit Grafischen Zeichen in der Windows Console

Ich hatte das gleiche Probleme, konnte es jetzt jedoch lösen. Vorweg, ich arbeite noch mit FPC 2.6.4.

Das Problem mit der Darstellung der Zeichen in einer Konsolenanwendung liegt an den Windows-Schriftarten. Die Rasterschriftart (Terminal) basiert auf der Codepage 850 und hat damit zum Beispiel als Zeichen 185 ($b9) das "╣" (Doppelte vertikale Linie nach links). Die den beiden anderen Schriftarten die unter Win7 für eine Konsolenanwendung zur Verfügung stehen, "Consolas" und "Lucida Console", haben einen Unicode-Zeichensatz und da ist das Zeichen 185 ein "Ù".

Das Problem liegt, IMHO, in der Procedure WriteStr aus der crt.pp von Free Pascal.

Code: Alles auswählen
procedure WriteStr(const s: string);
var
  WritePos: Coord; { Upper-left cell to write from }
  numWritten : DWord;
  WinAttr : word;
  i: integer;
begin
  WritePos.X:=currX-2;
  WritePos.Y:=currY-1;
 
  WinAttr:=TextAttr;
  for i:=1 to Length(s) do
    begin
      Inc(WritePos.X);
      WriteConsoleOutputCharacter(GetStdhandle(STD_OUTPUT_HANDLE), @s[i], 1, writePos, numWritten);
      WriteConsoleOutputAttribute(GetStdhandle(STD_OUTPUT_HANDLE),@WinAttr, 1, writePos, numWritten);
      Inc(CurrX);
      if CurrX>WindMaxX then
        begin
          CurrX:=WindMinX;
          Inc(CurrY);
          While CurrY>WindMaxY do
            begin
              RemoveLine(1);
              Dec(CurrY);
            end;
          WritePos.X:=currX-2;
          WritePos.Y:=currY-1;
        end;
    end;
end;


Hier wird die Function WriteConsoleOutputCharacter aus der kernel32.dll verwendet. Es wird char für char einzeln an diese Funktion übergeben. Ergo wird unter Consolas oder Lucida Console ein "Ù" ausgegeben.

Eine Konvertierung des AnsiStrings nach UTF-8 bringt auch nichts. Ich konnte das Problem erst beseitigen, indem ich den AnsiString nach UTF-8, AnsiChar(185) -> U+2563 ($e2+$95+$a3), und danach nach WideSting konvertiert habe.
wString := UTF8Decode(CP850toUTF8(aString))

Danach noch schnell die WriteStr aus der CRT.PP umgeschrieben auf WriteConsoleOutputCharacterW und schon werden die Zeichen auch unter Consolas und Lucida Console korrekt ausgegeben. Bei der Schriftart Terminal darf natürlich keine Umwandlung in UTF-8 erfolgen -> wString := WideString(aString). Ergo mache ich vorweg eine Abfrage des gewählten Font über die Kernel32-Funktion GetCurrentConsoleFontEx. Siehe hierzu den Post von Michl weiter oben.

Da es mir auch nicht klar ist, warum die Procedure WriteStr jedes Zeichen einzeln an die Function WriteConsoleOutputCharacterW übergibt, wo diese doch eigentlich dafür gedacht ist auch mehrere Zeichen auf einmal auszugeben, habe ich gleich mal die gesamte Procedure umgeschrieben.

Code: Alles auswählen
procedure WriteStr(const s: WideString);
var WritePos                 : Coord; { Upper-left cell to write from }
    numWritten               : DWord;
    numWrite                 : DWord;
    sLen                     : DWord;
    WinAttr                  : Array [1..255] of word;
    i                        : integer;
begin
  WritePos.X := currX-2;
  WritePos.Y := currY-1;
  FillWord(WinAttr,255,TextAttr);
 
  sLen := Length(s);
  i := 1;
  Repeat
    Inc(WritePos.X);
    numWrite := Min(WindMaxX-CurrX+1,sLen+1-i);
    WriteConsoleOutputCharacterW(GetStdhandle(STD_OUTPUT_HANDLE), @s[i], numWrite, writePos, numWritten);
    WriteConsoleOutputAttribute(GetStdhandle(STD_OUTPUT_HANDLE),@WinAttr, numWrite, writePos, numWritten);
    inc(CurrX,numWrite);
    inc(i,numWrite);
    if CurrX>WindMaxX then
    begin
      CurrX:=WindMinX;
      Inc(CurrY);
      While CurrY>WindMaxY do
      begin
        RemoveLine(1);
        Dec(CurrY);
      end;
      WritePos.X:=currX-2;
      WritePos.Y:=currY-1;
    end;
  Until (i>sLen);
end;


Ich habe es jetzt noch nicht getestet, aber ich gehe davon aus, dass dadurch die Ausgabe im Konsolenfenster auch beschleunigt werden sollte.
Borland Pascal 7.0 | Delphi 5 Enterprise | Delphi XE6 Enterprise | Lazarus 1.2.2 - FPC 2.6.4 Win7
Iceman_03
 
Beiträge: 8
Registriert: 18. Jun 2010, 10:57

Beitragvon Mathias » 25. Apr 2016, 17:03 Re: Probleme mit Grafischen Zeichen in der Windows Console

Du könntest das mal hier melden:
Vielleicht haben die Entwickler ein Argument, das sie dies so lösen.

http://lists.freepascal.org/cgi-bin/mai ... /fpc-devel
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3194
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon Michl » 25. Apr 2016, 19:22 Re: Probleme mit Grafischen Zeichen in der Windows Console

Mathias hat geschrieben:Du könntest das mal hier melden:
Braucht mMn nicht. Mit dem aktuellen Lazarus 1.6 kann man problemlos die verwendete Codepage der Windows Console verändern. Sie kann sogar UTF-8. Z.B.:

Code: Alles auswählen
uses
  ..., setdefaultcodepages;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  Writeln('Hallo Welt ÄÖÜ');
  WriteLn('Hallo Welt, Hello world, Γειά σου κόσμος, Witaj świecie, Olá mundo und Здравствуйте мир');
end;
Einfach die Unit setdefaultcodepages von hier verwenden (durch den Hack, den Lazarus macht und als DefaultSystemCodepage UTF-8 verwendet, wird mit setdefaultcodepages UTF-8 als ConsoleCodepage genutzt).
Code: Alles auswählen
type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 
Michl
 
Beiträge: 2169
Registriert: 19. Jun 2012, 11:54
OS, Lazarus, FPC: Win7 Laz 1.7 Trunk FPC 3.1.1 Trunk | 
CPU-Target: 32Bit/64bit
Nach oben

• Themenende •
Vorherige

Zurück zu Windows



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

porpoises-institution
accuracy-worried