| Autor |
Beitrag |
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Mo 01.01.07 19:56
Hallo Leute.
Mein Problem ist das folgende:
Ich möchte eine Art Komponente schreiben, die einem Edit ähnelt, bzw ziemlich genau eines sein soll.
Beim Eingeben des Textes muss natürlich darauf geachtet werden, dass nicht ein tastendruck gleich 5 buchstaben erzeugt. Ich habe (höchstwahrscheinlich) keinen Zugriff auf ein onKeyPress-Event, da ich das ganze in eine Unit packen will.
Gibt es eine möglichkeit, das onKeyPress Event einfach zu kopieren oder so? Gibts eine einfache Lösung, oder muss ich alles manuell machen?
Mein Ansatz:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| If NoChar > 0 Then dec(NoChar); FEngine.TextOut(Position.X - 50, Position.Y + 20, Text + '|'; i := ord('A'); While i <= ord('z') Do Begin If ((GetKeyState(i) And 128) = 128) And ((NoChar = 0) Or Not (LastChar = i)) Then Begin Text := Text + Char(i); LastChar := i; NoChar := Round(FEngine.FPS) Div 15; break; End; inc(i); End; |
Ich hoffe, das geht einfacher...
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 02.01.07 08:38
Schreibe den Event-Handler doch selbst. Du musst nur die richtige Windows-Nachricht abfangen. Wie die Nachricht heißt, kann ich Dir aus dem Kopf nicht sagen, sollte aber feststellbar sein.  Steht vermutlich irgendwo in der Hilfe (WM_KEYPRESSED ?).
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Di 02.01.07 16:44
Nicht schlecht, nur an welches Handle wird die Nachricht gesendet? Ich habe eine Unit ohne TForm Objekt. Mein Code aktuell:
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:
| Type TF2D_Edit = Class(TGraphicObject) Public Text : String; Private Procedure MyKeydown(Var Msg: TMessage); Message WM_KEYDOWN; Procedure MyKeyUp(Var Msg: TMessage); Message WM_KEYUP; End;
Procedure TF2D_Edit.MyKeydown(Var Msg: TMessage); Begin If Msg.WParam In [ord('A')..ord('Z')] Then If shiftdown Then Text := Text + Char(Msg.WParam) Else Text := Text + lowercase(Char(Msg.WParam)) Else Case Msg.WParam Of VK_Shift: shiftdown := true; End; End;
Procedure TF2D_Edit.MyKeyUp(Var Msg: TMessage); Begin Case Msg.WParam Of VK_Shift: shiftdown := false; End; End; |
Das Problem: Die Nachrichten werden an das TForm-Objekt gesendet, nicht an mein Objekt (das.. vielleicht nichtmal ein Handle hat ... ? )
Der Code des TGraphicObject ist ziemlich simpel und in Fears F2D_Objects Unit zu finden:
Besteht nur aus einem Constructor und ein paar Eigenschaften. nur position und größe.
Der Code funktioniert, wenn die Message Proceduren dem TForm Objekt gehören, aber auch nur dann, wenn kein Edit oder Memo den Focus hat, da dann das die Nachrichten empfängt...
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 02.01.07 16:51
Dann musst Du Dich (ääh das Objekt  ) in die Nachrichtenwarteschlange reinhängen. Zumindest würde ich es so versuchen. Allerdings hatte ich bisher nicht den Bedarf, so etwas zu programmieren. Daher kann ich Dir keine Anleitung dazu geben.
|
|
jakobwenzel
      
Beiträge: 1889
Erhaltene Danke: 1
XP home, ubuntu
BDS 2006 Prof
|
Verfasst: Di 02.01.07 16:53
Ich bin auch am proggen von nem OpenGl-Edit (für die Lemminge) und mein Code für den Teil sieht so aus:
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: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91:
| function SCtoASCII(key:Word;shift:TshiftState):Word; begin result:=MapVirtualKey(key,2); if result=0 then result:=key else begin if (ssShift in Shift) or ((GetKeyState(VK_CAPITAL) AND 1) = 1) then begin case key of 48: result:=Integer('?'); 49: result:=Integer('!'); 50: result:=Integer('"'); 51: result:=Integer('§'); 52: result:=Integer('$'); 53: result:=Integer('%'); 54: result:=Integer('&'); 55: result:=Integer('/'); 56: result:=Integer('('); 57: result:=Integer(')'); 220:result:=Integer('°'); 219:result:=Integer('?'); 221:result:=Integer('`'); 188:result:=Integer(';'); 190:result:=Integer(':'); 189:result:=Integer('_'); 191:result:=Integer(''''); 187:result:=Integer('*'); else result:=Integer(AnsiUpperCase(STring(Chr(result)))[1]) end; end else if (ssCTRL in shift) and (ssAlt in shift) then begin case result of 55: result:=Integer('{'); 56: result:=Integer('['); 57: result:=Integer(']'); 58: result:=Integer('}'); 223:result:=Integer('\'); 43: result:=Integer('~'); 81: result:=Integer('@'); 69: result:=Integer('€'); else result:=0 end; end else result:=Integer(AnsiLowerCase(STring(Chr(result)))[1]) end; end;
function IsSpecialKey(Key:Word):Boolean; begin if not (key in [8,13]) then result:=MapVirtualKey(key,2)=0 else result:=true; end;
procedure TglEdit.KeyDown(key: Word;shift:TShiftState); var before,after:String; begin inherited; if not IsSpecialKey(key) then begin before:=Copy(FText,1,FSelSTart); after:=Copy(FText,FSelStart+1,length(FText)-FSelStart); FTExt:=before+Chr(SCtoASCII(key,shift))+after; SelStart:=SelStart+1; end else begin case key of VK_BACK: if FSelStart>0 then begin before:=Copy(FText,1,FSelSTart-1); after:=Copy(FText,FSelStart+1,length(FText)-FSelStart); FText:=before+after; SelStart:=SelStart-1; end; VK_Delete: if FSelStart<length(FText) then begin before:=Copy(FText,1,FSelSTart); after:=Copy(FText,FSelStart+2,length(FText)-FSelStart); FText:=before+after; end; VK_Left: if FSelStart>0 then Dec(FSelStart); VK_Right: if FSelStart<Length(FText) then Inc(FSelStart); end; end; end; |
_________________ I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 02.01.07 16:55
Überschreib die WndProc, dort bekommst du alle Messages an das Control...
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Di 02.01.07 16:55
TGraficObject hat keine Prozedur "WndProc" ...
Alternative wäre natürlich, das ganze von einem TEdit zu vererben. Das hat ja auch ein OnKeyDown Ereignis, mit dem ich arbeiten könnte, vermute ich.
Nur, funktioniert das dann so wie ich das gern hätte? Sorry, aber in diesem Bereich der Programmierung bin ich recht neu ...
kannst du das ganze vielleicht mal etwas ... simpler erklären, etwas früher anfangen? 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jasocul
      
Beiträge: 6395
Erhaltene Danke: 149
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Di 02.01.07 17:03
Leider kenne ich TGraphicObject nicht genug. Möglicherweise hat ein Vorfahr schon die Methode, aber nicht public.
Sollte auch das nicht der Fall sein, könnte Dir dieser Link evtl. helfen.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 02.01.07 17:04
Du musst, wenn du von einem TEdit ableitest, lediglich die Methode KeyDown überschreiben.
Delphi-Quelltext 1:
| procedure KeyDown(Key: Word; Shift: TShiftState); override; |
|
|
jakobwenzel
      
Beiträge: 1889
Erhaltene Danke: 1
XP home, ubuntu
BDS 2006 Prof
|
Verfasst: Di 02.01.07 17:05
Er leitet aber nicht von einem TEdit ab.
@JayEff: Haste meinen Code gesehn?
_________________ I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
Zuletzt bearbeitet von jakobwenzel am Di 02.01.07 17:05, insgesamt 1-mal bearbeitet
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Di 02.01.07 17:05
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
Zuletzt bearbeitet von JayEff am Di 02.01.07 17:08, insgesamt 1-mal bearbeitet
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 02.01.07 17:07
Es wäre aber deutlich einfacher von einem TEdit abzuleiten. Man nehme die dem Ziel ähnlichste Klasse, die nicht schon etwas enthält, was man nicht möchte.
Und wenn du lediglich was bei den Tastendrücken verändern willst, dann ist TEdit doch schon das, was du willst, du musst lediglich auf Tastendrücke anders reagieren. Oder?
|
|
jakobwenzel
      
Beiträge: 1889
Erhaltene Danke: 1
XP home, ubuntu
BDS 2006 Prof
|
Verfasst: Di 02.01.07 17:09
Er hat ein mittels Fear2d erzeugtes OpenGl-Fenster und möchte ein eigenes Edit-Control für OpenGL erstellen.
Und dafür ist auch der Code den ich gepostet hab.
_________________ I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Di 02.01.07 17:12
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 02.01.07 17:15
jakobwenzel hat folgendes geschrieben: | Er hat ein mittels Fear2d erzeugtes OpenGl-Fenster und möchte ein eigenes Edit-Control für OpenGL erstellen.
Und dafür ist auch der Code den ich gepostet hab. |
Ok, das hatte ich nicht mitbekommen. Das stand in der Frage nicht...
Aber dazu kann ich dann nix sagen. Das kenne ich nicht und da richte ich mich ganz nach AXMDs Avatar... 
|
|
jakobwenzel
      
Beiträge: 1889
Erhaltene Danke: 1
XP home, ubuntu
BDS 2006 Prof
|
Verfasst: Di 02.01.07 17:22
*ganz weit aushol*
Ich hab eine Unit in der ganz normal eine Form liegt, da wird dann mit Fear2D OpenGl initialisiert. Dann hab ich n Objekt, das alle Tastendrücke, Mausbewegungen und Klicks in den Ereignissen übergeben bekommt. Diese Klasse leitet Mausbewegungen erstmal an alle meine OpenGl-Komponenten (das Teil hat ne Liste von denen) weiter (alle wegen RollOver-Effekten), Mausklicks nur an die, die im angeklickten Bereich liegen und Tastendrücke werden nur an die Komponente weitergelseitet, die den Fokus hat. Der Fokus wird dabei entweder durch Tab gesetzt, oder durch anklicken. Die eigentlichen Komponenten sind dabei vein einer Basisklasse abgeleitet, die alle möglichen Methoden definiert, die in den abgeleiteten Komponenten überschrieben werden können.
Ein paar Codeausschnitte:
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:
| procedure TForm1.JvAppEvents1Idle(Sender: TObject; var Done: Boolean); begin Done:=false;
Engine.DoBegin;
manager.Draw; Engine.DoEnd;
FPSLabel.Caption:='FPS: '+FloatToStrF(Engine.FPS,ffNumber,20,0);
end;
procedure TForm1.FormDestroy(Sender: TObject); begin Engine.Free;
Manager.Free;
ShowCursor(true); end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin Manager.KeyDown(Key,shift); end;
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin Manager.KeyUp(Key); end;
procedure TForm1.CMDialogKey(var Message: TCMDialogKey); begin end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Manager.MouseDown(button,shift,x,y); end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin Manager.MouseMove(x,y); end;
procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin Manager.MouseUp(shift,x,y); end; |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TglManager.KeyDown(Key: Word;shift:TShiftState); begin if Key=VK_TAB then begin if ActiveTab=HighestTabOrder then ActiveTab:=0 else ActiveTab:=ActiveTab+1; end else ActiveControl.KeyDown(key,shift); end; |
_________________ I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Di 02.01.07 17:29
jakobwenzel hat folgendes geschrieben: | | Ich hab eine Unit in der ganz normal eine Form liegt, da wird dann mit Fear2D OpenGl initialisiert. |
Ok, dann hilft mir das nicht wirklich, da ich ja keinen zugriff auf die Form hab, auf der OpenGL initialisiert wurde... Oder? Ich meine.. Ach, hier meine komplette Unit:
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: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88:
| Unit F2D_Edit;
Interface
Uses F2D_Core, F2D_Objects, F2D_Vectors, Graphics, Windows, SysUtils, Messages,StdCtrls;
Type TF2D_Edit = Class(TGraficObject) Public position,size:TVector2D; Text: String; Font: String; Color: TColor; Procedure Focus; Procedure DeFocus; Constructor Create(pEngine: TEngine); Procedure Draw; Private obj: TSimpleObject; Focused: Boolean; FEngine: TEngine; NoChar, LastChar: integer; End;
Const NoCharConst = 10;
Implementation
Constructor TF2D_Edit.Create(pEngine: TEngine); Begin Inherited Create; FEngine := pEngine; obj := TSimpleObject.Create(FEngine); obj.Z := 2 End;
Procedure TF2D_Edit.Focus; Begin Focused := true; End;
Procedure TF2D_Edit.DeFocus; Begin Focused := false; End;
Procedure TF2D_Edit.Draw; Begin obj.Size := Size; obj.Position := Position; obj.Draw(false); FEngine.FontManager.BindFont(Font, clBlue); If Focused Then Begin If NoChar > 0 Then dec(NoChar); FEngine.TextOut(Position.X - 50, Position.Y + 20, Text + '|' + IntToStr(NoChar)); i := ord('A'); While i <= ord('z') Do Begin If ((GetKeyState(i) And 128) = 128) And ((NoChar = 0) Or Not (LastChar = i)) Then Begin Text := Text + Char(i); LastChar := i; NoChar := Round(FEngine.FPS) Div 1; break; End; inc(i); End; End Else If Focused Then FEngine.TextOut(Position.X - 50, Position.Y + 20, Text + '|') Else FEngine.TextOut(Position.X - 50, Position.Y + 20, Text); End; |
Hatte vor, dass man nur in die uses diese Unit einbinden muss, um dann das Objekt TF2D_Edit genauso wie auch TSimpleObject benutzen zu können... Das scheint nicht zu gehn, hm? Dann muss ich das wohl erstmal zurückstellen .. *seufzt*
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
|