Comment faire flotter une forme dans une travail car c'est l'écran (déplacer, taille, maximiser, minimiser)?
Question
J'essaye le code publié par Freddie Bell à Quelle est la meilleure façon de rendre une application Delphi complètement pleine écran? Question, comme c'est ce dont j'avais besoin.
J'ai également réglé la taille minimun pour être la taille d'origine.
with msg.MinMaxInfo^.ptMinTrackSize do
begin
// maximum size when maximised
x := original_width;
y := original_height;
end;
Et en forme sur l'événement sur le biais:
original_width := Width;
original_height := Height;
Mais j'ai ce problème: - MAINFORM a deux panneaux, l'un d'eux est aligné comme correct, l'autre comme un précaution; Le working_area est donc l'espace entre les panneaux. Mainform n'a pas de frontières et il est entièrement maximizad dans la zone de travail avec
SystemParametersInfo(SPI_GETWORKAREA, 0, @working_desktop, 0);
- Lorsque je déplace le formulaire, il se garde à l'intérieur du working_area entre les panneaux.
- Lorsque je taille le formulaire, il conserve à l'intérieur de Working_area.
- Mais, lorsque je taille la forme de toute façon (gauche ou à droite) en passant le bord du Working_area, la forme a augmenté sa taille de l'autre côté. c'est-à-dire, si le formulaire est sur le bord gauche, et que vous le sélectionnez pour le redimensionner et que vous vous déplacez vers la gauche (vers le bord), la forme augmente sa largeur vers la droite (mais elle s'arrête au bord droit!).
J'essaie avec un code (attraper WMSIZE ou WMSIZing), mais je peux empêcher ce comportement? Merci tous à l'avance!
Edit (David Heffernan): Le code clé semble être dans cette 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.
La solution
Votre gestionnaire pour WM_WINDOWPOSCHANGING
est bien pour le déplacement des opérations mais doit être différent pour le dimensionnement des opérations. Vous ne pouvez pas les détecter à l'intérieur de ce gestionnaire de messages, vous avez donc besoin d'une alternative. Utiliser plutôt WM_SIZING
et WM_MOVING
comme ça:
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;
Vous devrez supprimer le WM_WINDOWPOSCHANGING
tout à fait.