Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Nach InplaceEditor kein Löschen Form (TStringGrid) (https://www.delphipraxis.net/58879-nach-inplaceeditor-kein-loeschen-form-tstringgrid.html)

HPW 14. Dez 2005 07:44


Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Ich erzeuge folgende Form mit Stringgrid:

Delphi-Quellcode:
type
  TMyStringGrid = class(TStringGrid)
    procedure WMSetFocus(var msg: TWMSetFocus); message WM_SETFOCUS;
    procedure WMKillFocus(var Msg: TMessage); message WM_KillFocus;
    procedure SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);reintroduce;
    procedure SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);reintroduce;
    procedure DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);reintroduce;
    procedure MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);reintroduce;
    procedure DblClick(Sender: TObject);reintroduce;
    procedure GetEditText(Sender: TObject; ACol, ARow: Integer; var Value: String);reintroduce;
    procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);reintroduce;
    procedure KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);reintroduce;
  end;

  TMyForm = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    ......
  public
    { Public-Deklarationen }
       StringGrid1      : TMyStringGrid;
  end;

var
  MyForm: TMyForm;

implementation

{$R *.DFM}

procedure TMyStringGrid.WMSetFocus( VAR Msg : TWMSetFocus );
BEGIN
  INHERITED;
  showmessage('SetFocus');
END;

procedure TMyStringGrid.WMKillFocus( VAR Msg : TMessage );
BEGIN
  INHERITED;
  showmessage('KillFocus');
END;

procedure TMyForm.FormCreate(Sender: TObject);
begin
  inherited;
  StringGrid1 := TMyStringGrid.Create(self);
  with StringGrid1 do
   begin
     Parent       := Self;
     Align        := alClient;
     Visible      := true;
     OnSelectCell := StringGrid1.SelectCell;
     OnSetEditText := StringGrid1.SetEditText;
     OnDrawCell   := StringGrid1.DrawCell;
     OnMouseMove  := StringGrid1.MouseMove;
     OnDblClick   := StringGrid1.DblClick;
     OnGetEditText := StringGrid1.GetEditText;
     OnMouseUp    := StringGrid1.MouseUp;
     OnKeyDown    := StringGrid1.KeyDown;
   end;
end;

procedure TMyForm.FormDestroy(Sender: TObject);
begin
 StringGrid1.Free;
 inherited;
end;

.....
Das funktioniert soweit einwandfrei. Wenn ich aber einmal den InplaceEditor aktiviere
und anschliessend die Form löschen will, bekomme ich eine Access-Violation.
Hängt das InplaceEditor-Object nicht am Stringrid und wird damit gelöscht?

Wenn ich in einer Testapp das Stringgrid normal in eine Form einfüge und dasselbe tue, funktioniert das einwandfrei. Was mache ich da noch falsch?

dataspider 14. Dez 2005 09:17

Re: Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Hallo HPW,
deine Klasse sieht sehr abenteuerlich aus.
Du weist den Ereignissen die eigenen internen Methoden zu.
Du überschreibst die Methoden wie KeyDown ohne Override ...
Ich denke, das die Methoden wie KeyDown sich im Kreis totlaufen.
Was willst du denn erreichen. Vielleicht können wir die dann die saubere Klassendefinition liefern.
Gruß, Frank

HPW 14. Dez 2005 11:21

Re: Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Hallo Frank,

mit eigenen Klassen kenne ich mich noch nicht so gut aus. (Wie man sieht) :oops:

Ich wollte eigentlich nur ein TStringgrid machen, das einige der vorhandenen Methoden benutzte.
Dann stellte ich fest das das Standard-Grid keine OnSetFocus und OnKillFocus besitzt.

Daher dann die Umstellung auf eine eigene Klasse.
Dort sollten dann aber auch die davor benutzen Methoden weiter laufen.
Das habe ich dann mit meinem Halbwissen und Code-Schnipseln hier auch dem Forum so gebastelt.

Also wo soll ich besser override einsetzen?

Für jede Anregung/Verbesserung wie immer danbkbar!

:wall:

Lannes 14. Dez 2005 11:46

Re: Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Hallo,
Zitat:

Zitat von HPW
...Dann stellte ich fest das das Standard-Grid keine OnSetFocus und OnKillFocus besitzt.

wenn ich es richtig verstehe müssten die Standard-Ereignisse ausreichen:
OnEnter > StringGrid bekommt Focus
OnExit > StringGrid verliert Focus
OnSelection > Zelle wird verlassen, Zelle wird gewählt

Beispiel zu OnSelection:
Delphi-Quellcode:
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
begin
  Memo1.Lines.Add('Alte Markierung >'
                  +' Spalte: '+IntToStr(StringGrid1.Col)
                  +' Zeile: '+IntToStr(StringGrid1.Row));
  Memo1.Lines.Add('Neue Markierung >'
                  +' Spalte: '+IntToStr(ACol)
                  +' Zeile: '+IntToStr(ARow));
end;

dataspider 14. Dez 2005 11:49

Re: Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Hi,
wenn es nur um die Änderung des Focus geht, dan nutze doch onEnter und onExit.
Und warum definierst du die virtuellen Methoden MouseUp, KeyDown etc neu.
Wenn du KeyDown überschreibst, dann so:
Delphi-Quellcode:
  MyStringGrid = class(TStringGrid)
  protected
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  end;

implementation

procedure MyStringGrid.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  // und mache noch irgend was
end;
die ganzen Zuweisungen wie:
OnKeyDown := StringGrid1.KeyDown;
sind tötlich. Normalerweise wird das Ereignis onKeyDown in der Basisklasse im KeyDown ausgelöst.
Damit erhälst du ziemlichen Salat :)
Gruß, Frank

HPW 14. Dez 2005 12:25

Re: Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Frank,

Zitat:

OnKeyDown := StringGrid1.KeyDown; sind tötlich.
Normalerweise wird das Ereignis onKeyDown in der Basisklasse im KeyDown ausgelöst.
Wieso tötlich? Wie soll ich denn sonst bei einem Grid das ich erst im FormCreate mittels .Create erzeuge die Events zuweisen. Ich habe ja keine neue Komponente in der IDE erstellt und auf eine Form gezogen, wo ich dann die Ereignisse reinklicken kann.
Das hat auch alles so funktioniert, bis auf das Problem mit dem Inplace-editor.

Lannes,

Zitat:

OnEnter > StringGrid bekommt Focus
OnExit > StringGrid verliert Focus
OnSelection > Zelle wird verlassen, Zelle wird gewählt
Im Prizip stimmt das, was ich auch mit einer normalen Testapp ausprobiert habe.
Zur Vereinfachung hatte ich aber keine Details zu meiner Anwendung gepostet.

Dabei ist das eine DLL, die als Plugin zu einer ander Applikation eine eigene From auf ein Object der Host-Applikation draufsetzt. Nun soll der Focus zwischen den unterschiedlichen Forms halt wechseln und auch per Event mitgeteilt werden. Und hier funktionieren die OnEnter/OnExit/OnSelection events eben nicht mehr.

dataspider 14. Dez 2005 13:12

Re: Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Hi,

@HPW
Du verbirgst mit:
Delphi-Quellcode:
  procedure KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);reintroduce;
die virtuelle Methode der Klasse TStringGrid bzw. TCustomGrid. Ohne dem reintroduse wird dir der Compiler das auch mitteilen. Das sollte man nur mit einem triftigen Grund tun.
Das Published Property (Ereignis) onKeyDown ist eine Schnittstelle für den Anwender der Komponente.
Du biegst den Zeiger dann von außen auf Methoden deiner Klasse um.
Wenn du im KeyDown immer etwas machen willst, dann überschreibe die Methode richtig und füge nach dem Inherited deinen Code ein (siehe: // und mache noch irgend was).
Genau so kannst du es mit den anderen Methoden machen.

Delphi-Quellcode:
procedure MyStringGrid.KeyDown(var Key: Word; Shift: TShiftState);
begin
  inherited KeyDown(Key, Shift);
  // und mache noch irgend was
  // Sag: Hallo, ich hab den Fokus
end;
Du kannst ja in WMSetFocus ein Ereignis onGetFocus implementieren.
Gruß, Frank

dataspider 14. Dez 2005 13:33

Re: Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Ich wüde es z.B. so machen:
Delphi-Quellcode:
unit Unit3;

interface

uses Classes, Messages, Grids;

type
  TMyStringGrid = class(TStringGrid)
  private
    FOnKillFocus: TNotifyEvent;
    FOnSetFocus: TNotifyEvent;
    procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
    procedure WMSetFocus(var Msg: TWMSetFocus); message WM_SETFOCUS;
  published
    property OnKillFocus: TNotifyEvent read FOnKillFocus write FOnKillFocus;
    property OnSetFocus: TNotifyEvent read FOnSetFocus write FOnSetFocus;
  end;

implementation

procedure TMyStringGrid.WMKillFocus(var Msg: TWMKillFocus);
begin
  inherited;
  if Assigned(FOnKillFocus) then
    FOnKillFocus(Self);
end;

procedure TMyStringGrid.WMSetFocus(var Msg: TWMSetFocus);
begin
  inherited;
  if Assigned(FOnSetFocus) then
    FOnSetFocus(Self);
end;

end.
Grid erzeugen:
Delphi-Quellcode:
constructor TForm2.Create(AOwner: TComponent);
begin
  inherited;
  StringGrid := TMyStringGrid.Create(Self);
  with StringGrid do
  begin
    Parent     := Self;
    Align      := alTop;
    // zum Test am unteren Fensterrand ein Edit
    Visible    := True;
    OnSetFocus := doSetFocus;
    OnKillFocus := doKillFocus;
  end;
end;

procedure TForm2.doSetFocus(Sender: TObject);
begin
  // kein Dialog, sonst bekommst du endlose modale Messageboxen
  // lieber eine Statusbar zum Testen
  sBar.SimpleText := 'Focus gesetzt...';
end;

procedure TForm2.doKillFocus(Sender: TObject);
begin
  sBar.SimpleText := 'Focus gekillt...';
end;
Gruß, Frank

HPW 14. Dez 2005 14:49

Re: Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Frank,

Danke für das Beispiel mit dem Focus.

Zitat:

Wenn du im KeyDown immer etwas machen willst, dann überschreibe die Methode richtig und füge nach dem Inherited deinen Code ein (siehe: // und mache noch irgend was).
Genau so kannst du es mit den anderen Methoden machen.
Wenn ich es mit den anderen Methoden dann so wie im Beispiel mache:

Delphi-Quellcode:
TYPE
  ThpwStringGrid = class(TStringGrid)
  protected
    procedure KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);override;
....
....


procedure ThpwStringGrid.KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
    inherited KeyDown(Sender,Key,Shift);
.....
bekomme ich:

Deklaration von 'KeyDown' unterscheidet sich von vorheriger Deklaration

:wall:

dataspider 14. Dez 2005 14:57

Re: Nach InplaceEditor kein Löschen Form (TStringGrid)
 
Hi,
in TWinControl ist KeyDown wie folgt definiert:
Delphi-Quellcode:
procedure KeyDown(var Key: Word; Shift: TShiftState); dynamic;
Es gibt den Parameter Sender nicht. Er wird in der Klasse auch nicht benötigt.
Im Zweifelsfall kannst du in der Unit Grids (TCustomGrid) oder Controls (TWinControl) der Delphi Sourcen nachsehen.

Cu, Frank


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:25 Uhr.
Seite 1 von 2  1 2      

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