Delphi-PRAXiS

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 StringGrid DragMode Color (https://www.delphipraxis.net/183666-stringgrid-dragmode-color.html)

PaddyVII 27. Jan 2015 10:46

StringGrid DragMode Color
 
Guten Mittag alle zusammen,

ich hätt da mal ne kleine frage: und zwar färbe ich mit

Delphi-Quellcode:
  if StringGrid.Cells[ACol, ARow] = 'O' then
  begin
    stringGrid.Canvas.Brush.Color := clSkyBlue;
Eine Zelle ein und schreibe ein 'O' Hinein(beim Click) (bzw. schreibe erst ein 'O' hinein und dann färbe ich die Zelle, dies geschieht an einer anderen stelle im code, is ja auch irrelevant;D). Wichtig ist, dass BEIDES passiert, sprich: ein 'O' geschrieben wird UND sich die zelle blau färbt! Das passt soweit auch :-D

Jedoch nicht, wenn ich eine Zelle nehme und sie verschiebe (Drag) innerhalb des stringgrids. Dann werden alle Zellen (Innherhalb der verschiebung) hellblau, jedoch wird kein 'O' hineingeschrieben, was auch nicht die absicht ist- mein ansatz: DRAG MODUS AUSSCHALTEN:D

und schon steh ich vor dem Problem: Kann mir jemand sagen, wie ich diesen Drag mode INNERHALB der stringGrid und der Zellen ausschalten kann??


p.s: Hab schon alle möglichen einstellungen im Objektinspektor die was mit Drag zutunhatten Geändert/deaktiviert - erfolglos!!

Ich habe versucht, mein problem soo genau wie möglich zu umschreiben, tut mir leid wenns bisschen kompliziert klingt...

...kann mir jemand die lösung ERKLÄREN sprich nicht nur code schreiben??

Ich danke euch im Vorraus

LG

Paddy_VII:thumb:

PaddyVII 27. Jan 2015 12:15

AW: StringGrid DragMode Color
 
okay, für die dies interessiert: wenn man eine Farbe vorher nicht initialisiert (in meinem Fall brauchte ich weiß)

Delphi-Quellcode:
stringgrid.Canvas.Brush.Color := clWhite;
dann kommt Delphi etwas durcheinander und nimmt sich für alle Farbaktionen (bei mir der DragMode) einfach die letzte Farbe...

von demher, als tipp wer mit Canvas arbeitet sollte immer vorher seine farbe setzten (das klügste wäre natürlich weiß)...

Jumpy 28. Jan 2015 07:07

AW: StringGrid DragMode Color
 
Zitat:

Zitat von PaddyVII (Beitrag 1287937)
von demher, als tipp wer mit Canvas arbeitet sollte immer vorher seine farbe setzten (das klügste wäre natürlich weiß)...

Ich glaube in vielen On(Custom)Draw Methoden wird das sinngemäß eher so gemacht, das man sich die Farbe merkt:

Delphi-Quellcode:
var oldBrushColor:TColor;
begin
[...]
oldBrushColor:=stringgrid.Canvas.Brush.Color;
stringgrid.Canvas.Brush.Color := clSkyBlue;
//Mach was
stringgrid.Canvas.Brush.Color:=oldBrushColor;
[...]
end;

PaddyVII 28. Jan 2015 07:19

AW: StringGrid DragMode Color
 
könnte klappen, nur muss man doch dann die initialisierung VOR der zuweisung machen oder??

Sir Rufo 28. Jan 2015 07:48

AW: StringGrid DragMode Color
 
Genau für dieses Szenario gibt es extra die Klassen Delphi-Referenz durchsuchenTBrushRecall und Delphi-Referenz durchsuchenTFontRecall.

Eine sinnvolle Ergänzung wäre es, wenn man sich noch ein Interface dafür bauen würde, dann käme man für die meisten mit nur einer Zeile Code aus. Ansonsten sieht das so aus:
Delphi-Quellcode:
procedure WorkWithCanvas( ACanvas : TCanvas );
var
  LBrushRecall : TBrushRecall;
begin
  LBrushRecall := TBrushRecall.Create( ACanvas.Brush );
  try

    ACanvas.Brush.Color := clRed;

  finally
    LBrushRecall.Free;
  end;
  // Jetzt ist ACanvas.Brush wieder wie vorher
end;
Mit einem Interface könnte das so aussehen
Delphi-Quellcode:
procedure WorkWithCanvas( ACanvas : TCanvas );
begin
  TBrushRecallFactory.Construct( ACanvas.Brush ); // erzeugt ein Interface

  ACanvas.Brush.Color := clRed;

end;
// nach dem Verlassen der Methode wird die Interface Referenz zerstört
// damit auch der Recall und damit der ACanvas.Brush wieder hergestellt :o)

PaddyVII 28. Jan 2015 08:06

AW: StringGrid DragMode Color
 
Ist das TBrushRecall denn für diesen "DraMode" innerhalb des grids dann verantwortlich?

Sir Rufo 28. Jan 2015 08:27

AW: StringGrid DragMode Color
 
Zitat:

Zitat von PaddyVII (Beitrag 1288017)
Ist das TBrushRecall denn für diesen "DraMode" innerhalb des grids dann verantwortlich?

Häh? Das
Delphi-Quellcode:
TBrushRecall
hat mit Drag und sonst was nix, aber auch gar nix zu tun.

Du schreibst irgendwo im Paint-Event
Delphi-Quellcode:
procedure FooOnPaint( ... );
begin
  // oh, wer weiß ob die Farbe überhaupt noch richtig ist, vielleicht habe ich ja geschludert
  stringgrid.Canvas.Brush.Color := clWhite;

  if StringGrid.Cells[ACol, ARow] = 'O' then
  begin
    stringGrid.Canvas.Brush.Color := clSkyBlue;
    ...
  end;

end;
Das kann man auch anders schreiben und zwar
Delphi-Quellcode:
procedure FooOnPaint( ... );
begin

  if StringGrid.Cells[ACol, ARow] = 'O' then
  begin
    stringGrid.Canvas.Brush.Color := clSkyBlue;
    ...
  end;

  // sodele, dann wollen wir mal wieder alles so herstellen, damit hier nix durcheinander kommt
  stringgrid.Canvas.Brush.Color := clWhite;
end;
Bzw. so wie schon gezeigt, man merkt sich die Farbe beim Betreten der Methode und stellt diese Farbe wieder her.

Oder, was noch komfortabler ist, man arbeitet mit dem Recall, dann wird die komplette Brush-Einstellung gesichert und wieder hergestellt.

Oder du nimmst diesen generischen Recall
Delphi-Quellcode:
unit GenericRecall;

interface

uses
  System.Classes;

type
  IRecall<T> = interface
    ['{32F2834B-8EA3-4BDD-8467-F21DA78C8F82}']
    function GetReference: T;
    procedure Store;
    procedure Forget;
    property Reference: T read GetReference;
  end;

  TRecall<T: TPersistent> = class( TInterfacedObject, IRecall<T> )
  private
    FRecall: TRecall;
    FStorage: T;
    function GetReference: T;
    procedure Store;
    procedure Forget;
    constructor Create( AStorage, AReference: T );
  public
    destructor Destroy; override;
  end;

  TRecallFactory = class
  public
    class function Construct<T: TPersistent, constructor>( AReference: T ): IRecall<T>; overload;
    class function Construct<T: TPersistent>( AReference, AStorage: T ): IRecall<T>; overload;
  end;

implementation

{ TRecall<T> }

constructor TRecall<T>.Create( AStorage, AReference: T );
begin
  inherited Create;
  FRecall := TRecall.Create( AStorage, AReference );
end;

destructor TRecall<T>.Destroy;
begin
  FRecall.Free;
  inherited;
end;

procedure TRecall<T>.Forget;
begin
  FRecall.Forget;
end;

function TRecall<T>.GetReference: T;
begin
  Result := FRecall.Reference as T;
end;

procedure TRecall<T>.Store;
begin
  FRecall.Store;
end;

{ TRecallFactory }

class function TRecallFactory.Construct<T>( AReference: T ): IRecall<T>;
begin
  Result := Self.Construct( AReference, T.Create );
end;

class function TRecallFactory.Construct<T>( AReference, AStorage: T ): IRecall<T>;
begin
  Result := TRecall<T>.Create( AStorage, AReference );
end;

end.
und änderte deine Zeichen Methode so ab
Delphi-Quellcode:
procedure FooOnPaint( ... );
begin
  // Sichern, Sichern, Sichern

  TRecallFactory.Construct( StringGrid.Canvas.Brush ); // Brush sichern
  TRecallFactory.Construct( StringGrid.Canvas.Font ); // Font sichern

  if StringGrid.Cells[ACol, ARow] = 'O' then
  begin
    stringGrid.Canvas.Brush.Color := clSkyBlue;
    ...
  end;

  // Am Schluss wird nun automatisch der alte Zustand für Brush und Font wieder hergestellt
  // Wir verlassen es also so, wie wir es vorgefunden haben
end;

PaddyVII 28. Jan 2015 08:34

AW: StringGrid DragMode Color
 
Najaa, letzteres klingt relativ kompliziert, die erste (so wie ich das problem jetzt gelöst habe) und die zweite methode klingen doch realtiv plausibel....
Danke für deine Unterstützung^^

Sir Rufo 28. Jan 2015 08:44

AW: StringGrid DragMode Color
 
Zitat:

Zitat von PaddyVII (Beitrag 1288022)
Najaa, letzteres klingt relativ kompliziert, die erste (so wie ich das problem jetzt gelöst habe) und die zweite methode klingen doch realtiv plausibel....
Danke für deine Unterstützung^^

Ähm, wenn das Schreiben von einer Zeile Code schon zu kompliziert ist, wie programmierst du dann? :gruebel:

PaddyVII 28. Jan 2015 08:55

AW: StringGrid DragMode Color
 
Ich meinte das mit Recall..das versteh ich vom prinzip her schoon, vom code her nicht ganz...seii n bisschen nachsichtig mit mir, bin noch nicht soo lang am Programmieren mit delphi, bin erst im ersten ausbilungsjahr...:oops:

Sir Rufo 28. Jan 2015 09:21

AW: StringGrid DragMode Color
 
Zitat:

Zitat von PaddyVII (Beitrag 1288027)
Ich meinte das mit Recall..das versteh ich vom prinzip her schoon, vom code her nicht ganz...seii n bisschen nachsichtig mit mir, bin noch nicht soo lang am Programmieren mit delphi, bin erst im ersten ausbilungsjahr...:oops:

Verstehst du wie so eine Edit-Komponente oder StringGrid-Komponente intern funktioniert?
Wenn Nein, warum verwendest du diese dann?

Du verwendest diese, weil du das Gefühl hast, die macht das was du möchtest, egal wie sie dies macht. Du verlässt dich darauf, dass die zugesicherten Eigenschaften auch gebracht werden.

Genau so arbeitet man mit dem
Delphi-Quellcode:
TBrushRecall
oder mit der der (in der Handhabung) vereinfachten Form über
Delphi-Quellcode:
TRecallFactory
.

Die Unit in die
Delphi-Quellcode:
uses
aufnehmen und in jeder Methode, wo du an dem Brush rumwurschtelst rufst du als Erstes ein (passend zu deinem Code)
Delphi-Quellcode:
TRecallFactory.Construct( stringgrid.Canvas.Brush );
auf. Nun kannst du dich darauf verlassen, dass dieser Brush beim Verlassen der Methode wieder genau so ist, wie der beim Betreten der Methode war. Du räumst also hinter dir auf und verlässt den Ort so, wie du ihn vorgefunden hast.

PaddyVII 28. Jan 2015 09:30

AW: StringGrid DragMode Color
 
Okay, danke das klingt schon einleuchtender....d.h mit dem TBrushRecall stellt es (nachdem ich die grid verlassen habe) den Ursprungszustand der Grid wieder her, als ich sie betreten habe...Kann ich das soo verstehn??

Jumpy 28. Jan 2015 09:54

AW: StringGrid DragMode Color
 
Du verlässt ja nicht das Grid, sondern es geht nur um die OnPaint/OnDraw oder wie auch immer das heißt Methode.

@Sir Rufo: Ich hab das immer wie in meinem ersten Post geschrieben gemacht, weil ich das so öfters in Beispielen auch hier in der DP gesehen habe und das TBrushRecall nicht kannte. Aber jetzt wo ich das kenne werde ich das sicher öfters nutzen, denn wenn man mehr als nur die Farbe ändern will muss man sich ja auch mehr merken. Wunderbarerweise habe ich das auch in meinem D6 gefunden.
Nur diese TRecallFactory hab ich nicht in D6 gesehen. Ab welche Delphiversion gibt es denn die bereits fertig? Oder muss man die generell, wie in deinem Beispiel selber bauen?

Sir Rufo 28. Jan 2015 10:17

AW: StringGrid DragMode Color
 
Zitat:

Zitat von PaddyVII (Beitrag 1288032)
Okay, danke das klingt schon einleuchtender....d.h mit dem TBrushRecall stellt es (nachdem ich die grid verlassen habe) den Ursprungszustand der Grid wieder her, als ich sie betreten habe...Kann ich das soo verstehn??

Da wir mit dem Recall ja nicht das Grid ansprechen, sondern vom Grid, den Canvas und davon den Brush, wird genau dieser (Brush) wieder auf den Zustand gebracht, wie er beim Recall Aufruf war.

@Jumpy

Die RecallFactory habe ich selber gebaut um dieses Backup/Restore mit genau einer Zeile hinzubekommen. Und wie du siehst benutze ich dafür die Generics, die es mWn bei Delphi 6 noch nicht gibt ;)

Ergo, wird das so nix, da musst du dir etwas ähnliches bauen, was aber kein Problem sein sollte.

PaddyVII 28. Jan 2015 10:46

AW: StringGrid DragMode Color
 
Was ich grade bemerkt hab...

es geht auch

Delphi-Quellcode:
stringGrid.repaint
damit ruft es die Zeichenroutine automatisch wieder auf

Jumpy 28. Jan 2015 11:41

AW: StringGrid DragMode Color
 
Das bekämpft mMn das Symptom aber nicht die Ursache. Oder ist es umgekehrt?

PaddyVII 28. Jan 2015 12:05

AW: StringGrid DragMode Color
 
najaa, es ruft immerhin die draw Methode auf von demher, denkich, wenn man da den richtigen code stehn hat, dann ist das schon realativ nützlich...


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:27 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