![]() |
eigene Texteingabe programmieren
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:
Hat jemand den entscheidenden Tipp oder einen Weg, den Algo anders zu programmieren?
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]; . 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:='A' else 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:='B' else 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:='C' else result:='c'; doubleKeyboard[key_c]:=true; exit; end; if not keyboard[key_c] then doubleKeyboard[key_c]:=false; ... |
AW: eigene Texteingabe programmieren
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. |
AW: eigene Texteingabe programmieren
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.
|
AW: eigene Texteingabe programmieren
Zitat:
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 ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:33 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