Delphi-PRAXiS
Seite 2 von 3     12 3      

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 Komponente im Raster verschieben (https://www.delphipraxis.net/97756-komponente-im-raster-verschieben.html)

oki 16. Aug 2007 10:58

Re: Komponente im Raster verschieben
 
Hallo Hawkeye219

auch wenn es jetzt blöd klingt, aber ich möchte (muss) meine eigene Collektion von Controls erstellen. Wird für mich im Nachgang einfacher, wenn alle meine Controls den gleichen Vorfahren haben. Das Moving/Sizing ist auch kein Problem. Hab ich schon alles zu meiner Zufriedenheit gelöst. Das Thema SnaptoGrid ist ja auch keine Gewalt. Hätte ich halt etwas schicker (wie beschrieben während der Bewegung). Somit stehe ich eigentlich nicht vor dem Problem der gesamten Lösung, sondern nur für ein "kleines Detail". ehrlich gesagt würde ich eher auf dieses Detail verzichten, als meine Kompo weg werfen und eine Fremdkompo verwenden.


Zitat:

Zitat von _frank_
die macht leider das snapToGrid erst, wenn das Control gedroppt wird.
evtl hat jemand eine Idee, wie man den Rahmen auch "snappen" kann.
Meine Versuche haben damals nicht funktioniert.

Gruß Frank

Und genau das ist im Moment mein Problem! Wie gesagt, mit meiner einfachen Lösung im Paint klappt das erstaunlicher weise mit der Größenänderung zur "Ziehzeit". Beim Moving halt erst beim Drop.

Ich habe das Gefühl, dass folgender Code nicht dazu führt, dass mein vererbtes Paint aufgerufen wird:
Delphi-Quellcode:
   ReleaseCapture;
   TWinControl(self).Perform(WM_SYSCOMMAND, $F012, 0);
Aber warum bei den anderen?
Delphi-Quellcode:
   ReleaseCapture;
      ...
        cps_LeftTop:
          TWinControl(self).Perform(WM_SYSCOMMAND, $F004, 0);
        cps_RightTop:
          TWinControl(self).Perform(WM_SYSCOMMAND, $F005, 0);
        cps_LeftBottom:
          TWinControl(self).Perform(WM_SYSCOMMAND, $F007, 0);
        cps_RightBottom:
          TWinControl(self).Perform(WM_SYSCOMMAND, $F008, 0);
        cps_Left:
          TWinControl(self).Perform(WM_SYSCOMMAND, $F001, 0);
        cps_Top:
          TWinControl(self).Perform(WM_SYSCOMMAND, $F003, 0);
        cps_Right:
          TWinControl(self).Perform(WM_SYSCOMMAND, $F002, 0);
        cps_Bottom:
          TWinControl(self).Perform(WM_SYSCOMMAND, $F006, 0);
gruß oki

oki 16. Aug 2007 11:02

Re: Komponente im Raster verschieben
 
Noch ein Nachtrag,

mein Control wird auch während des verschiebens immer sauber gezeichnet. Halt ohne einrasten.

Gruß oki

SirThornberry 16. Aug 2007 11:38

Re: Komponente im Raster verschieben
 
es im Paint zu korrigieren halte ich für den falschen Weg, dann kannst du auch gleich einen Timer nehmen der korrigiert. Richtiger finde ich, das gleich zu verhindern durch eben behandeln der Messages wm_sizing und wm_moving.

oki 16. Aug 2007 11:41

Re: Komponente im Raster verschieben
 
Zitat:

Zitat von SirThornberry
es im Paint zu korrigieren halte ich für den falschen Weg, dann kannst du auch gleich einen Timer nehmen der korrigiert. Richtiger finde ich, das gleich zu verhindern durch eben behandeln der Messages wm_sizing und wm_moving.

Joop, war auch erst mal nur eine Notlösung mit dem Korrogieren im Paint.
Teste heute noch das Message-Thema.

Gruß oki

oki 16. Aug 2007 14:18

Re: Komponente im Raster verschieben
 
Habe jetzt das ganze mal in den Messages wmsizing und wmmoving getestet.
Delphi-Quellcode:
procedure TBaseCustomControl.WMMoving(var Message: TWMMove);
begin
  if Grid then
    RastControl;
end;

procedure TBaseCustomControl.WMSizing(var Message: TWMSize);
begin
  if Grid then
    RastControl;
end;

procedure TBaseCustomControl.RastControl;
var ALeft, ATop, AHeight, AWidth : Integer;
begin
  if not Grid then
    Exit;
  ALeft := (Left Div FGridWidth) * FGridWidth;
  ATop := (Top Div FGridWidth) * FGridWidth;
  AWidth := (Width Div FGridWidth) * FGridWidth;
  AHeight := (Height Div FGridWidth) * FGridWidth;
  SetBounds(ALeft, ATop, AWidth, AHeight);
end;
Gute Nachricht: Er rastet jetzt auch während des Movens.
Schlechte Nachricht: Das Control "zappelt" am Mauszeiger. Dabei habe ich den Eindruck, dass das Control beim bewegen auf die neue "krumme" Koordinate verschoben und gezeichnet und dann wmmoving ausgeführt wird. Dort wird dann korrigiert und wieder neu an den Gitterkoordinaten gezeichnet (SetBounds siehe Code).

Ein Problem gelöst, nächste da. :wall:

Somit müsste vor dem Zeichnen korrigiert werden. Aber wie?

Gruß oki

jim_raynor 16. Aug 2007 15:29

Re: Komponente im Raster verschieben
 
Rufe das RastControl mal nur in einer der beiden Messages aus. Vielleicht hilft das ja schon.

oki 16. Aug 2007 15:42

Re: Komponente im Raster verschieben
 
Hab ich getestet. Zappeln bleibt, halt nur bei der entsprechenden aktion.

Gruß oki

_frank_ 16. Aug 2007 15:46

Re: Komponente im Raster verschieben
 
Liste der Anhänge anzeigen (Anzahl: 1)
ich hab das mal in die SizeControl-Komponente von Angus Johnson integriert (da ich dieses Feature auch im DFM-Editor haben wollte):

Delphi-Quellcode:
  TTargetObj = class
  private
    ....
    procedure AlignToGrid(Ctrl: TControl; ProposedBoundsRect: TRect; GridSize: integer);
...
  TSizeCtrl = class(TComponent)
  private
...
    fSnapToGrid: boolean;
...
  published
...
    property SnapToGrid: boolean read fSnapToGrid write fSnapToGrid;
...
//changed global function AlignToGrid to method of TTargetObj
procedure TTargetObj.AlignToGrid(Ctrl: TControl; ProposedBoundsRect: TRect; GridSize: integer);
begin
  //AlignToGrid() assumes 'Control' is assigned.
  if (GridSize > 1) and (FSizeCtrl.SnapToGrid) then
  begin
...

procedure TTargetObj.MoveFocus(dx,dy: integer);
begin
  fFocusRect := fStartRec;
  if fSizeCtrl.SnapToGrid then
  begin
    dx:=dx div fsizectrl.GridSize * fsizectrl.GridSize;
    dy:=dy div fsizectrl.GridSize * fsizectrl.GridSize;
  end;
  offsetRect(fFocusRect, dx,dy);
end;
//------------------------------------------------------------------------------

procedure TTargetObj.SizeFocus(dx,dy: integer; BtnPos: TBtnPos);
begin
  fFocusRect := fStartRec;
  if fSizeCtrl.SnapToGrid then
  begin
    dx:=dx div fsizectrl.GridSize * fsizectrl.GridSize;
    dy:=dy div fsizectrl.GridSize * fsizectrl.GridSize;
  end;
...
für die faulen unter euch ist die komplette Komponente im Anhang

Gruß Frank

SirThornberry 16. Aug 2007 19:15

Re: Komponente im Raster verschieben
 
schau dir mal die Hilfe zu wm_sizing und wm_moving an!
Mit der Message kommt ein Pointer auf die neuen Koordinanten des Forms. Diese solltest du direkt korrigieren. Andernfalls änderst du eben die Korrdinanten durch deine Methode und beim rückkehren aus der Messageroutine wird nochmal korrigiert - daher auch das zappeln.

Schau dir zur Orientierung mal folgendes an:
http://www.delphipraxis.net/internal...=699256#699256

oki 17. Aug 2007 09:21

Re: Komponente im Raster verschieben
 
Hallo SirThomberry,

erst mal herzlichen Dank für die Hilfe. Das klappt jetzt super für wm_Sizing. Alles ohne Zappeln und wie gewollt im Raster. Für wm_moving aber leider nicht.
Folgende Erscheinung. Bewege ich das Control mit der Maus nach rechts oben, macht er aus einem Pixel Move 10 Pixel. Somit wandert das Control mit 10-facher Geschwindigkeit von meiner Maus nach oben/rechts weg. Nach links/unten geht gar nichts. Das erscheint normal, wenn man davon ausgeht, das jedes neue moving von den aktuellen Controlposition + Mausoffset ausgeht. Das es dann nicht nach rechts/unten klappt ist logischerweise auf mein Div zurückzuführen. aber warum ist das nur beim Moving und nicht beim Sizing so? Sizing ist in alle Richtungen so wie ich es haben will.

Hier der veränderte Code:
Delphi-Quellcode:
Procedure TBaseCustomControl.GetRastControlRect(var ARect: PRect);
begin
  if not Grid then begin
    Exit;
  end;
  ARect.Left := (ARect.Left Div FGridWidth) * FGridWidth;
  ARect.Top := (ARect.Top Div FGridWidth) * FGridWidth;
  ARect.Right := (ARect.Right Div FGridWidth) * FGridWidth;
  ARect.Bottom := (ARect.Bottom Div FGridWidth) * FGridWidth;
end;

procedure TBaseCustomControl.WMMoving(var AMsg: TMessage);
var ARect : PRect;
begin
  if not Grid then
    Exit;
  ARect := PRect(AMsg.lParam);
  GetRastControlRect(ARect);
end;

procedure TBaseCustomControl.WMSizing(var AMsg: TMessage);
var ARect : PRect;
begin
  if not Grid then
    Exit;
  ARect := PRect(AMsg.lParam);
  GetRastControlRect(ARect);
end;
Herzlichen Dank für deine Gedult und Gruß oki


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:29 Uhr.
Seite 2 von 3     12 3      

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