AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

eigene Texteingabe programmieren

Ein Thema von delphifan2004 · begonnen am 13. Jan 2022 · letzter Beitrag vom 14. Jan 2022
Antwort Antwort
delphifan2004

Registriert seit: 26. Nov 2004
Ort: Dresden
266 Beiträge
 
Delphi 10.3 Rio
 
#1

eigene Texteingabe programmieren

  Alt 13. Jan 2022, 16:26
Hallo,

Ich versuche gerade im Rahmen eines PC Lehrganges, eine Texteingabe selber zu programmieren, als ob es Delphi nicht gäbe.

Dabei wird die Zeichenposition beim Einfügen von fehlendem Text nicht korrekt inkrementiert.

Was mache ich da falsch?

Delphi-Quellcode:
//keyboard[] ist Boolean Array und enthält die VK_Codes die hier das Präfix KEY_ haben
//FStrXPos ist die aktuelle Zeichenposition
//CursorX ist die aktuelle Cursorposition, die wird in Pixeln gezählt
//Deshalb FCurorX * FontSize, wobei hier die Breite gemeint ist


procedure TmyEdit.ExecKeys(var Keys: WideString);
var i: integer; wc: WideChar;
begin
  //i := Length(Keys);
  //move(Keys[1],wc,i);
  if keyboard[key_back] then
  begin
    if FStrXPos >= 1 then
    begin
      system.Delete(FLine,FStrXPos-1,1);
      //system.Delete(Keys,FStrXPos-1,1);
      HideCursor;
      CursorLeft; //FStrXPos nochmals prüfen
      ShowCursor;
      keyboard[key_back] := false;
    end;
    Paint;
  end;
  if keyboard[key_delete] then
  begin
    if FStrXPos >= 1 then
    begin
      system.Delete(FLine,FStrXPos,1);
      //system.Delete(Keys,FStrXPos,1);
      keyboard[key_delete] := false;
    end;
    Paint;
  end;
  if keyboard[key_insert] then begin ToggleInsmode; keyboard[key_insert] := false; Paint; end else
  if keyboard[key_left] then begin CursorLeft; keyboard[key_left] := false; Paint; end else
  if keyboard[key_right] then begin CursorRight; keyboard[key_right] := false; Paint; end else
  if (key_code IN DecNums) or (key_code IN KeyChrs) or (key_code IN NumPads) or (key_code IN OemKeys) or (key_code = Key_Space) then
  //DecNums,KeyChrs,NumPads,OemKeys sind Mengen der KEY_XXX Codes
  if FStrXPos >= Length(FLine) then
  begin
    {if Length(keys) > 0 then }FLine := FLine + Keys;{[Length(Keys)]}
    HideCursor;
    CursorRight;
    ShowCursor;
    Paint;
  end
  else
  if FInsmode then begin
    
    system.Insert(Keys,FLine,FStrXPos);
    HideCursor;
    CursorRight;
    
    ShowCursor;
    Paint;
  end;
  //for i:=0 to 255 do keyboard[i] := false;
end;

procedure TmyEdit.CursorLeft;
begin
  if FStrXPos > 1 then Dec(FStrXPos);
  if FCursorX > 0 then
  begin
    Dec(FCursorX,FontSize);
    if FCursorX < 0 then FCursorX := 0;
  end;
end;

procedure TMyEdit.CursorRight;
begin
  if FStrXPos <= Length(FLine) then
  begin
    FStrXPos := FStrXPos + 1; //Aktuelle Stringposition
    FCursorX := FCursorX + FontSize; //Aktuelle Cursorposition
  end;
end;
Delphi-Quellcode:
var
  LineStr: WideString;
  ChrCode: WideString; //Weil myKeypressed Rückgabetyp WideString, vorher String aber liest Unicode

  LineStr := ''; ChrCode := '';
  Input := TMyEdit.Create(nil); //Als Kompo im Formular wäre Ownwer natürlich Form1
  
  Input.BoundsRect := Rect(20,20, 20*DefaultFontSize, DefaultFontSize + 20);
  //Ich verwende TFPCustomCanvas aus FCLImage zur Grafikausgabe
  //habe mir dazu eigenes Canvasobjekt abgeleitet und BoundsRecht entspricht ClipRect von TFPCustomCanvas
  
  Input.Paint;
  
  repeat


     //LineStr := myReadKey;

     Input.ShowCursor;

     if myKeypressed then
     begin
       ChrCode := myReadKey; //RückgabeTyp bisher WideString

       LineStr := ChrCode; //nur jeweils ein Zeichen, String wird in Input.ExecKeys gebildet
       
       Input.ExecKeys(LineStr);
       Input.printLengthChrsToXY(0,0); //eine Testroutine zum Debuggen
     end; { von visKeypressed }
     
  until keyboard[key_escape];
Hat jemand den entscheidenden Tipp oder einen Weg, den Algo anders zu programmieren?


.

Das Zeichen, das ich eingegeben habe, wird in der myReadKey Funktion sofort wieder false gesetzt.

Delphi-Quellcode:
function myReadKey:widestring;
begin
        result:='';


        if (keyboard[key_a]) and (not doubleKeyboard[key_a]) then begin
                key_code:=key_a;
                if keyboard[KEY_LSHIFT] or keyboard[KEY_RSHIFT] then result:='Aelse result:='a';
                doubleKeyboard[key_a]:=true;
                exit;
        end;
        if not keyboard[key_a] then doubleKeyboard[key_a]:=false;



        if (keyboard[key_b]) and (not doubleKeyboard[key_b]) then begin
                key_code:=key_b;
                if keyboard[KEY_LSHIFT] or keyboard[KEY_RSHIFT] then result:='Belse result:='b';
                doubleKeyboard[key_b]:=true;
                exit;
        end;
        if not keyboard[key_b] then doubleKeyboard[key_b]:=false;



        if (keyboard[key_c]) and (not doubleKeyboard[key_c]) then begin
                key_code:=key_c;
                if keyboard[KEY_LSHIFT] or keyboard[KEY_RSHIFT] then result:='Celse result:='c';
                doubleKeyboard[key_c]:=true;
                exit;
        end;
        if not keyboard[key_c] then doubleKeyboard[key_c]:=false;


...

Geändert von delphifan2004 (13. Jan 2022 um 17:09 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
614 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: eigene Texteingabe programmieren

  Alt 14. Jan 2022, 08:01
Hallo, Da sind eine ganze Menge Dinge zu beachten.

Normale Fonts haben unterschiedliche Pixel breiten für jedes einzelne Zeichen.

Du brauchst einen Timer der permanent (alle 200,300 ms) via GetAsyncKeyState lauscht was für Tasten gerade gedrückt sind.
Es können unterschiedlich viele Tasten zur gleichen Zeit gedrückt sein, auch mehr als 2.
Am besten ist ein internes Abbild deiner kompletten Eingabe, nach jeder Änderung zeichnest Du die Anzeige komplett neu.

Wie man an die Breiten der Zeichen kommt kann ich dir nicht sagen.
Ich habe lediglich ein Tool mit dem ich jeden Font in mein eigenes internes Format (zum komplett selber ohne GDI zeichnen) convertieren (scannen) kann.
Wie es wirklich geht hat mich nie interessiert. Das sollte, denke ich erstmal der Anfang sein, rausfinden wie man an die ganzen Zeichen Begrenzungen kommt um die Zeichen eines Font einzel anzeigen zu können.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
Sailor

Registriert seit: 20. Jul 2008
Ort: Balaton
112 Beiträge
 
Delphi 2010 Professional
 
#3

AW: eigene Texteingabe programmieren

  Alt 14. Jan 2022, 15:08
Mit GetTextMetrics(Canvas.Handle,tm) holst Du allgemeine Werte des Fonts (Leading, Ascent, Descent usw.), mit GetCharABCWidths Werte einzelner Zeichen oder Blöcke von Zeichen. Damit kannst Du die Zeichen entsprechend positionieren.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#4

AW: eigene Texteingabe programmieren

  Alt 14. Jan 2022, 15:53
Zitat:
// Weil myKeypressed Rückgabetyp WideString, vorher String aber liest Unicode
String = Unicode, seit Delphi 2009

So lange es nicht darum geht mit externen Komponenten/APIs zu reden, würde ich von WideString (OLE-String) eher abraten.
String, oder wenn es "explizit" Unicode sein soll, dann UnicodeString.

UnicodeString ist die Unicode-Variante des AnsiString (des String von D2 bis D2009)

Es funktioniert auch mit WideString, aber dessen Speicherverwaltung muß man sich echt nicht antun,
außerdem gibt es WideString eh nur im Windows (nutzt intern MSDN-Library durchsuchenSysAllocStringLen und seine Freunde) und wenn man sich an MultiPlatform gewöhnen will, dann sollte man besser den delphi-eigenen Typen verwenden)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz