Announcement

Collapse
No announcement yet.

Seitenverhältnis der Form bei Größenänderung beibehalten (via Hook)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Seitenverhältnis der Form bei Größenänderung beibehalten (via Hook)

    Hallo zusammen,

    hab zwar schon in im Delphi-PRAXiS Forum gefragt (wer's nachlesen will: http://www.delphipraxis.net/topic835...ibehalten.html), da hab ich allerdings noch keinen passende Lösungvorschlag bekommen. Und da hab ich mir gedacht, die Leute aus zwei Foren wissen vielleicht mehr als aus einem.

    Problem:
    Ich hab ein Form, dessen Seitenverhältnis bei Größenänderung gleich bleiben soll.
    Hierzu habe ich auch schon Code gefunden:

    Code:
    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);
    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;
    
    end.
    Dieser funktioniert auch einwandfrei. Ich möchte diese Funktionalität jetzt in eine DLL auslagern und via Hook realisieren. Dies scheint jedoch nicht zu funktionieren und mir wurde der Tipp gegeben, dies über PostMessage bzw. SendMessage an das jeweilige Fenster zu schicken. Die wird aber bisher einfach ignoriert.
    Der Code hierzu (ausgelagert in eine Unit):

    Code:
    unit TestSizeHook;
    
    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;
      glbSizing: boolean = FALSE;
    
    
    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) and (not glbSizing) 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;
              PostMessage(currentCWP.hwnd, WM_SIZING, w, integer(PWindowRect)); // Hier ist wohl der Knackpunkt
            end;
          end;
          glbSizing := TRUE;
        end else
          glbSizing := FALSE;
    
      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.
    Wobei im DLL Quellcode StartProportionalSizing() und StopProportionalSizing() exportiert werden.

    Frage:
    Was muss ich anstellen, dass die proportionale Größenänderung auch via Hook funktioniert?

    Danke schonmal!
Working...
X