4

I try code published by Freddie Bell at What is the best way to make a Delphi Application completely full screen? question, as is what i needed.

I also set minimun size to be the original size.

  with msg.MinMaxInfo^.ptMinTrackSize do
    begin
       // maximum size when maximised
      x := original_width;
      y := original_height;
    end;

And in Form OnShow event:

  original_width  := Width;
  original_height := Height;

But i have this issue: - Mainform has two panels, one of it is aligned as alRight, the other as alLeft; so the working_area is the space between the panels. Mainform has no borders and it is fully maximizad to the work area with

SystemParametersInfo(SPI_GETWORKAREA, 0, @working_desktop, 0);
  • When i move the form, it keeps inside the working_area between the panels.
  • When i size the form, it keeps inside that working_area.
  • But, when i size the form in either way (left or right) passing the edge of the working_area, the form increased its size to the other side. i.e., if the form is on left edge, and you select it to resize it and you move to the left (towards the edge), the form increase its width to the right (but it stop at right edge!).

I try with some code (catching WMSIZE or WMSIZING), but i can prevent that behavior? Thanks you all in advance!

EDIT (David Heffernan): The key code appears to be in this unit.

unit uFormularios;

interface

uses Windows, Messages, Forms, DBGrids, StdCtrls, Menus, Graphics, ComCtrls;

type
  TForm_en_ventana = class(TForm)
  private
    ancho_original, alto_original: integer;
    procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW;
    procedure WMWindowPosChanging(Var Msg: TWMWindowPosChanging); Message WM_WINDOWPOSCHANGING;
    procedure WMGetMinMaxInfo(Var msg: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
    procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
  end;

  TForm_en_ventana_centrado = class(TForm_en_ventana)
  private
    ancho_original, alto_original: integer;
    procedure WMShowWindow(var Message: TWMShowWindow); message WM_SHOWWINDOW;
  end;

procedure MaximizarFormulario(var F; MaximaAltura: integer = 0; MaximoAncho: integer = 0; Centrado: boolean = TRUE);
procedure InicializarVentanaTrabajo(const izq, der, arr, aba: integer);

var ESPACIO_DE_TRABAJO,
    VENTANA_DE_TRABAJO      : TRect;

implementation


procedure MaximizarFormulario(var F; MaximaAltura: integer = 0; MaximoAncho: integer = 0; Centrado: boolean = TRUE);
begin
  LockWindowUpdate(TForm(F).Handle);
  TForm(F).Left   := ESPACIO_DE_TRABAJO.Left;
  if MaximoAncho = 0 then
    TForm(F).Width  := ESPACIO_DE_TRABAJO.Right
  else
    begin
      if ESPACIO_DE_TRABAJO.Right < MaximoAncho then
        TForm(F).Width := ESPACIO_DE_TRABAJO.Right
      else
        TForm(F).Width := MaximoAncho;
    end;
  TForm(F).Top    := ESPACIO_DE_TRABAJO.Top;
  if MaximaAltura = 0 then
    TForm(F).Height := ESPACIO_DE_TRABAJO.Bottom
  else
    begin
      if ESPACIO_DE_TRABAJO.Bottom < MaximaAltura then
        TForm(F).Height := ESPACIO_DE_TRABAJO.Bottom
      else
        TForm(F).Height := MaximaAltura;
    end;
  if ((MaximoAncho <> 0) or (MaximaAltura <> 0)) and (Centrado) then
    begin
      TForm(F).Left := (ESPACIO_DE_TRABAJO.Right  - TForm(F).Width ) div 2;
      TForm(F).Top  := (ESPACIO_DE_TRABAJO.Bottom - TForm(F).Height) div 2;
    end;
  LockWindowUpdate(0);
end;

procedure InicializarVentanaTrabajo(const izq, der, arr, aba: integer);
begin
  VENTANA_DE_TRABAJO.Left   := izq;
  VENTANA_DE_TRABAJO.Right  := der;
  VENTANA_DE_TRABAJO.Top    := arr;
  VENTANA_DE_TRABAJO.Bottom := aba;
end;

procedure TForm_en_ventana.WMWindowPosChanging(var Msg: TWMWINDOWPOSCHANGING);
begin
  with Msg.WindowPos^ do
  {
   x: int;  The position of the left edge of the window.
   y: int;  The position of the top edge of the window.
   cx: int; The window width, in pixels.
   cy: int; The window height, in pixels.
  }
  begin
    if x <= VENTANA_DE_TRABAJO.Left then
      x := VENTANA_DE_TRABAJO.Left;
    if x + cx >= VENTANA_DE_TRABAJO.Right then
      x := (VENTANA_DE_TRABAJO.Right) - cx;
    if y <= VENTANA_DE_TRABAJO.Top then
      y := VENTANA_DE_TRABAJO.Top;
    if y + cy >= VENTANA_DE_TRABAJO.Bottom then
      y := (VENTANA_DE_TRABAJO.Bottom) - cy;
  end;
end;

Procedure TForm_en_ventana.WMGetMinMaxInfo(Var msg: TWMGetMinMaxInfo);
begin
  inherited;
  with msg.MinMaxInfo^.ptMaxPosition do
    begin
      // position of top when maximised
      x := VENTANA_DE_TRABAJO.Left;
      y := VENTANA_DE_TRABAJO.Top;
    end;
  with msg.MinMaxInfo^.ptMaxSize do
    begin
       // width and height when maximized
      x := VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left;
      y := VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top;
    end;
  with msg.MinMaxInfo^.ptMaxTrackSize do
    begin
       // maximum size when maximised
      x := VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left;
      y := VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top;
    end;
  with msg.MinMaxInfo^.ptMinTrackSize do
    begin
       // maximum size when maximised
      x := ancho_original;
      y := alto_original;
    end;
end;

procedure TForm_en_ventana.WMSysCommand(var Msg: TWMSysCommand);
begin
  if Msg.CmdType and $FFF0 = SC_MINIMIZE then
    Application.Minimize
  else
    inherited;
end;

procedure TForm_en_ventana.WMShowWindow(var Message: TWMShowWindow);
begin
  ancho_original := Width;
  alto_original  := Height;
end;

procedure TForm_en_ventana_centrado.WMShowWindow(var Message: TWMShowWindow);
begin
  ancho_original := Width;
  alto_original  := Height;
  Left := (((VENTANA_DE_TRABAJO.Right - VENTANA_DE_TRABAJO.Left) - Width) div 2) + VENTANA_DE_TRABAJO.Left;
  Top  := (((VENTANA_DE_TRABAJO.Bottom - VENTANA_DE_TRABAJO.Top) - Height) div 2) + VENTANA_DE_TRABAJO.Top;
end;

initialization
  SystemParametersInfo(SPI_GETWORKAREA, 0, @ESPACIO_DE_TRABAJO, 0);
  VENTANA_DE_TRABAJO := ESPACIO_DE_TRABAJO;

end.
Community
  • 1
  • 1
Speaker
  • 189
  • 2
  • 10
  • I cannot understand the question. – David Heffernan Jan 23 '12 at 23:09
  • Sorry is related to the post i say. I can post the code (i don't know how). Is something really simple if you see it, perhaps dificult to explain, and my english is too much "me tarzan, you jane" :). The problem is when you size the form from the left edge and you reach the border of the left panel (which set the left limit of the working area), and pass over it, without releasing mouse button, the form still resizing but to the right size. – Speaker Jan 23 '12 at 23:22
  • The form stop sizing to the left (as it reach the left limit), but begin to increase it width to the right. – Speaker Jan 23 '12 at 23:24
  • What aspect of your code is inducing this off behaviour? Is it the `WM_GETMINMAXINFO` handling? – David Heffernan Jan 23 '12 at 23:26
  • I cannot say. I try to catch the moment or message to avoid resizing when either limit is reached but i can found the way. I am not familiar with Windows Messages. – Speaker Jan 23 '12 at 23:29
  • All other aspects, works very good. Maximize to my working area, moving within it, minimizing to original size. And resizing until borders of the working area are reached (to the same side of the resizing). I do not try, but i think this will happen if i put a top panel and a bottom panel, too. – Speaker Jan 23 '12 at 23:31
  • [The project is right here](https://skydrive.live.com/redir.aspx?cid=fa96881128ce2026&resid=FA96881128CE2026!347&parid=FA96881128CE2026!346&authkey=!AGResbAMzpWyxus) – Speaker Jan 23 '12 at 23:37
  • Try removing the minmaxinfo message handler and see how it behaves. – David Heffernan Jan 24 '12 at 07:49

1 Answers1

2

Your handler for WM_WINDOWPOSCHANGING is fine for moving operations but needs to be different for sizing operations. You can't detect those from within that message handler so you need an alternative. Instead use WM_SIZING and WM_MOVING like this:

procedure WMSizing(Var msg: TMessage); message WM_SIZING;
procedure WMMoving(Var msg: TMessage); message WM_MOVING;

....

procedure TForm_en_ventana.WMSizing(var msg: TMessage);
var
  R: PRect;
begin
  R := PRect(msg.LParam);
  R.Left := Max(R.Left, VENTANA_DE_TRABAJO.Left);
  R.Right := Min(R.Right, VENTANA_DE_TRABAJO.Right);
  R.Top := Max(R.Top, VENTANA_DE_TRABAJO.Top);
  R.Bottom := Min(R.Bottom, VENTANA_DE_TRABAJO.Bottom);
end;

procedure TForm_en_ventana.WMMoving(var msg: TMessage);
var
  R: PRect;
  dx, dy: Integer;
begin
  R := PRect(msg.LParam);
  dx := 0;
  dy := 0;
  if R.Left<VENTANA_DE_TRABAJO.Left then
    dx := VENTANA_DE_TRABAJO.Left-R.Left;
  if R.Right>VENTANA_DE_TRABAJO.Right then
    dx := VENTANA_DE_TRABAJO.Right-R.Right;
  if R.Top<VENTANA_DE_TRABAJO.Top then
    dy := VENTANA_DE_TRABAJO.Top-R.Top;
  if R.Bottom>VENTANA_DE_TRABAJO.Bottom then
    dy := VENTANA_DE_TRABAJO.Bottom-R.Bottom;
  OffsetRect(R^, dx, dy);
end;

You will need to remove the WM_WINDOWPOSCHANGING altogether.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I only add this code to WMSHOWWINDOW message `procedure TForm_en_ventana.WMShowWindow(var Message: TWMShowWindow); begin ancho_original := Self.Width; alto_original := Self.Height; Constraints.MinHeight := height; Constraints.MinWidth := width; end;` – Speaker Jan 24 '12 at 11:14
  • I don't know what you mean by that comment. Are you asking another question? – David Heffernan Jan 24 '12 at 11:26
  • No, sorry!!! just to complete the code for people who see this question (for me the question is closed and answered). In WMShowWindow i set minimun size by setting then constraint of the form. Thanks again!!! – Speaker Jan 24 '12 at 12:27