AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Größenverhältnis der Form bei Größenänderung beibehalten
Thema durchsuchen
Ansicht
Themen-Optionen

Größenverhältnis der Form bei Größenänderung beibehalten

Offene Frage von "sebastianz1983"
Ein Thema von TheAn00bis · begonnen am 19. Mai 2006 · letzter Beitrag vom 4. Feb 2010
Antwort Antwort
Seite 1 von 3  1 23      
TheAn00bis

Registriert seit: 7. Jun 2004
386 Beiträge
 
#1

Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 19. Mai 2006, 17:37
Hey,

Ich will das Verhältnis von Höhe und Größe meiner Form beim Verändern der Größe beibehalten.

Da ich ja wissen muss, ob die Breite oder Höhe verändert wurde habe ich folgenden Code geschrieben:

Delphi-Quellcode:
procedure TForm1.FormResize(Sender: TObject);
begin
  if (OldSizeX <> form1.Width) then //-> form1's width has been changed
    form1.Height := form1.Width
  else form1.Width := form1.Height; //height has been changed
  OldSizeX := Form1.Width;
end;
Dieser funktioniert auch halbwegs, allerdings sieht das ganze sehr(!) unschön aus, da die Form beim
Verändern der Größe scheinbar wie verrückt ihre Größe ändert; dies hat auf den eigentlichen Vorgang
keine Auswirkungen, da der Cursor davon nicht betrofen ist, aber es sieht wie gesagt absolut unprofessionell
aus. Gibt es da eine bessere Lösung?
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 19. Mai 2006, 17:46
professioneller wird es wohl nur klappen wenn du direkt die messages abfängst.

[Edit]WM_SIZING ist die Message welche du dafür verarbeiten solltest[/Edit]
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
TheAn00bis

Registriert seit: 7. Jun 2004
386 Beiträge
 
#3

Re: Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 19. Mai 2006, 18:07
Die müsste ich über einen Hook abfangen und dann die Größe manuel verändern, richtig?
Scheint aufwändig, aber vielversprechend. Habe noch nie mit Messages gearbeitet, ich sehe mich mal um. Wenn jemand sowas in der Art schon haben sollte, oder sowas in einer halben Minute schreiben kann würde ich mich natürlich auch freuen.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 19. Mai 2006, 18:16
nein, ein Hook ist völlig unnötig. Diesen würdest du nur benötigen wenn du die Message einer anderen Anwendung bearbeiten willst
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
  private
    procedure FWM_Sizing(var AMsg: TMessage); message wm_sizing;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FWM_Sizing(var AMsg: TMessage);
begin
  //Message abändern
  inherited;
end;


end.
Hier mal eine Möglichkeit wie die Messageroutine aussehen kann.
[Edit]
Delphi-Quellcode:
procedure TForm1.FWM_Sizing(var AMsg: TMessage);
var lRect : PRect;
    lRatio : TPoint;
    lNewHeight,
    lNewWidth : Integer;
begin
  lRatio := Point(4, 3);
  lRect := PRect(AMsg.LParam);
  lNewHeight := lRect.Bottom - lRect.Top + 1;
  lNewWidth := lRect.Right - lRect.Left + 1;
  case AMsg.WParam of
    WMSZ_BOTTOM, WMSZ_TOP: lRect.Right := lRect.Left + Round(lNewHeight * lRatio.X / lRatio.Y);
    WMSZ_LEFT, WMSZ_RIGHT: lRect.Bottom := lRect.Top + Round(lNewWidth * lRatio.Y / lRatio.X);
    //übrig bleibt noch was passieren soll wenn jemand direkt eine Ecke anpackt
  end;
  inherited;
end;
[/Edit]
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
TheAn00bis

Registriert seit: 7. Jun 2004
386 Beiträge
 
#5

Re: Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 19. Mai 2006, 18:40
Wow, das ist weltklasse!

Vielen dank; funktioniert wunderbar.

Ich bezweifel, dass ich das jemals hinbekommen hätte.

Vielleicht was für die Code Libary? Kann man doch bestimmt öfters gebrauchen.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#6

Re: Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 19. Mai 2006, 18:43
eigentlich nix für die Codelibrary da es nur das verarbeiten einer Message ist (zählt fast zu Grundlagen) und die Beschreibung der Message im MSDN zu finden ist.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
sebastianz1983

Registriert seit: 26. Jan 2010
Ort: Regensburg
14 Beiträge
 
#7

Re: Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 26. Jan 2010, 15:00
Hi zusammen,

auch wenn der letzte Beitrag hier schon recht lange her ist, hab ich trotzdem 'ne Frage zu diesem Thema.
Der Code von SirThornberry funktioniert bei mir soweit einwandfrei. Wenn ich das ganze allerdings in eine DLL auslagern und über eine Hookfunktion realisieren möchte, geht das leider nicht. Und ich komm einfach nicht drauf, woran das liegen könnte.
Hier mal mein Code:

Delphi-Quellcode:
unit WinSizeHook;

interface

procedure StartProportionalSizing; stdcall; forward;
procedure StopProportionalSizing; stdcall; forward;

implementation
uses Windows, Forms, Dialogs, Messages, SysUtils, Math, Classes, Controls;

var
  glbSizeHook: cardinal = 0;
  glbRatio: single;


function Hook(code: Integer; W: wParam; L: lParam): LResult; stdcall;
type
  pCWPStruct = ^CWPSTRUCT;

var
  currentCWP: CWPSTRUCT;
  windowRect: TRect;
  PWindowRect: PRect;
  newSize: integer;

begin
  try
    if code >= HC_ACTION then begin
      currentCWP := pCWPStruct(L)^;

      case currentCWP.message of
        WM_ENTERSIZEMOVE: begin
          if GetWindowRect(currentCWP.hwnd, windowRect) then
            glbRatio := (windowRect.Right - windowRect.Left) / (windowRect.Bottom - windowRect.Top);
        end;

        WM_SIZING: begin
          PWindowRect := PRect(currentCWP.LParam);
          case currentCWP.WParam of
            WMSZ_BOTTOM, WMSZ_TOP,
            WMSZ_TOPLEFT, WMSZ_TOPRIGHT, WMSZ_BOTTOMLEFT, WMSZ_BOTTOMRIGHT: begin
              newSize := trunc(SimpleRoundTo((PWindowRect.Bottom - PWindowRect.Top + 1) * glbRatio, 0));
              PWindowRect.Right := PWindowRect.Left + newSize;
            end;

            WMSZ_LEFT, WMSZ_RIGHT: begin
              newSize := trunc(SimpleRoundTo((PWindowRect.Right - PWindowRect.Left + 1) / glbRatio, 0));
              PWindowRect.Bottom := PWindowRect.Top + newSize;
            end;
          end;
        end;
      end;
    end;
  except
  end;

  result := CallNextHookEx(glbSizeHook, code, w, l);
end;


procedure StartProportionalSizing;
begin
  if glbSizeHook = 0 then
    glbSizeHook := SetWindowsHookEx(WH_CALLWNDPROC, @Hook, 0, GetCurrentThreadID());
end;


procedure StopProportionalSizing();
begin
  if glbSizeHook <> 0 then
    UnhookWindowsHookEx(glbSizeHook);
end;
end.
(Kann sein, dass der Code nicht auf Anhieb funktioniert, hab meine ganzen Versuche, Debuginfos und zusätzlichen Code entfernt, bevor ich ihn hier reingestellt hab.)
Beim Debuggen werden mir die korrekten Werte für "newSize" zurückgeliefert und auch in die jeweiligen Werte in PWindowRect geschrieben, jedoch kann ich das Fenster immernoch nach Belieben in der Größe verändern, ohne dass die Proportionen eingehalten werden. Daher ist meine Vermutung, dass (im Gegensatz zu SirThornberrys Lösung via normalem Event Handler) im Hook in lParam nicht auf die tatsächlichen Werte verwiesen wird, sondern nur auf eine Kopie derselbigen.
Kann mir das einer bestätigen? Und kennt jemand eine Lösung zu diesem Problem?

Danke schonmal!
  Mit Zitat antworten Zitat
sebastianz1983

Registriert seit: 26. Jan 2010
Ort: Regensburg
14 Beiträge
 
#8

Re: Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 28. Jan 2010, 08:21
Bisher noch keiner eine Idee? Mir würde auch schon genügen, wenn mir einer sagt, dass das nicht möglich ist und mir dafür eine Erklärung liefert. Wär zwar nicht die erhoffte Lösung, aber immerhin wüsst ich dann woran ich bin.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 28. Jan 2010, 08:39
Hallo,

natürlich enthält der Pointer in LParam nicht die Original-Koordinaten des Fensters.

Stell dir vor, die setzt den Pointer auf NIL ...
Wen das Windows zulassen würde, dann gute Nacht

Es gibt keinen Record in Windows, der nur die Fensterkoordinaten abbildet
Der Record zum Erzeugen eines Windows (Wndows API) ist viel größer,
RECT ist hier nur ein Hilfsmittel.

Ein Ändern der Werte im RECT macht dann natürlich nichts.

Du musst schon per PostMessage (oder SendMessage)
die Koordinaten selber setzen.

Das es in Delphi so einfach geht, liegt an der VCL,
die alles so schön kapselt.


Heiko
Heiko
  Mit Zitat antworten Zitat
sebastianz1983

Registriert seit: 26. Jan 2010
Ort: Regensburg
14 Beiträge
 
#10

Re: Größenverhältnis der Form bei Größenänderung beibehalten

  Alt 28. Jan 2010, 09:19
Danke Heiko für die schnelle Antwort.
Verstehe, heißt, ich kann die Fenstergröße nur indirekt steuern, indem ich dem Fenster sage "Hey du, ändere mal bitte deine Größe auf die Werte, die ich dir vorgebe!"
Bin allerdings noch recht neu in Delphi, deswegen wär's gut, wenn du das ganze ein wenig ausformulieren könntest.
Welche Window Message soll ich dann an das Fenster via PostMessage bzw. SendMessage senden? Nochmal ein WM_SIZING oder doch WM_SIZE? Und ändert dann Windows nicht automatisch wieder die Größe des Fensters zurück nachdem das Fenster meine Nachricht verarbeitet hat? Schließlich wird bei Größenänderung bereits eine entsprechende Nachricht an das Fenster geschickt?
Hatte vorher schon ähnliche Ansätze ausprobiert, bei denen haben dann aber die Fenster geflackert, heißt, kurz wird die korrekte Größe dargestellt, aber dann springt sie (wohl aus oben genanntem Grund) wieder zur normalen Fenstergröße bei Größenänderung zurück.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:21 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