PDA

Ver la Versión Completa : maximizar un MDI Child dentro del area cliente del Form Padre


_CALI
24-12-2012, 21:46:52
Buenas a todos,
teango una Aplicacion MDI y quisiera saber la manera mas "elegante" de maximimar un formulario Hijo al tamaño del area cliente del formulario padre, es decir que cuando maximize un form hijo este no se fusione con la barra de herramientas del form padre, hice un acercamiento con el siguiente código, pero mmm solo hago la simulacion de maximizar,
por ahi lei de manejar los mesanajes de WM_WINDOWPOSCHANGING , WM_GETMINMAXINFO SetWindowLong, pero la verdad probe con todo y nada, Gracias de antemano y FELIZ NAVIDAD!!



//procedmiento de ventana que maneja los mensajes de los formularios hijos
//donde F es el form hijo y MaxRect es el Rect de dicho form

function MDIChildProc(hwnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
F: TChild;
begin
F := TChild(FindControl(hwnd));
begin
case uMsg of
WM_MOVE,
WM_SIZE:
begin
if biMaximize in (F.BorderIcons) then
begin
if (F.WindowState = wsNormal) and (F.BoundsRect <> MaxRect)then
F.Rect := Bounds(F.Left, F.Top, F.Width, F.Height);
end;
end;
WM_SYSCOMMAND:
begin
case wParam and $FFF0 of
end;

SC_MAXIMIZE:
begin
if F.WindowState = wsMinimized then //minimizado
begin
Windows.ShowWindow(F.Handle, SW_RESTORE);
F.BoundsRect := MaxRect;
end
else
if F.BoundsRect = MaxRect then //maximizado
F.BoundsRect := F.Rect
else //normal
F.BoundsRect := MaxRect;
Result := 0;
Exit;
end;
SC_RESTORE:
begin
if biMaximize in (F.BorderIcons) then
F.BoundsRect := F.Rect;
end;
end;
end;
end;
Result := CallWindowProc(Pointer(F.Tag), hwnd, uMsg, wParam, lParam);
end;
end;

ecfisa
24-12-2012, 22:25:22
Hola _CALI.

Fijate si te sirve de este modo:

...
type
TfrmMDIChild = class(TForm)
private
procedure WMSysCommand(var Msg: TMessage); message WM_SYSCOMMAND;
...
end;
...

implementation

uses Unit1; // frmMDIForm

procedure TfrmMDIChild.WMSysCommand(var Msg: TMessage);
begin
if Msg.WParam = SC_MAXIMIZE then
begin
ShowWindow(Handle, SW_RESTORE);
Left := 0;
Top := 0;
Width := frmMDIForm.ClientWidth - 4;
Height := frmMDIForm.ClientHeight - 4
end
else
inherited
end;
...


Saludos.

_CALI
25-12-2012, 00:40:33
Gracias por responder ecfisa, al parecer tu procedimiento restaura la ventana cuando se maximiza el formulario, pero el windowState del form no llega a estar como wsMaximized es un buen truco, pero si notas el boton de maximizar no cambia al de restaurar, pero claramente me ahorra lineas, Gracias!!

ecfisa
25-12-2012, 22:32:37
Hola _CALI.

Al maximizar un MDIChild este ocupa el área cliente del MDIForm, ese es su comportamiento natural y al menos yo no conozco manera de cambiar eso. Pero podes interceptar el maximizado, redimensionar y mostrarlo normalmente, como en el código anterior.

Una pequeña "mejora" al código anterior podría ser:

procedure TForm2.WMSysCommand(var Msg: TWMSysCommand);
begin
if Msg.CmdType = SC_MAXIMIZE then
begin
Left := 0;
Top := 0;
Width := frmMDIForm.ClientWidth - 4;
Height := frmMDIForm.ClientHeight - 4;
BorderIcons:= BorderIcons - [biMaximize]; // desactivar maximize
WindowState:= wsNormal;
end
else
begin
BorderIcons:= BorderIcons + [biMaximize]; // activar maximize
DefaultHandler(Msg);
end
end;

Cuando la ventana está restaurada al valor fijado y al estar deshabilitado el ícono maximizar, el usuario no intentará hacer click inútilmente sobre él.

Para que pudiera verse el ícono restaurar, el MDIChild tendría que estar maximizado. Pero si lo está, tenemos que atenernos su comportamiento natural que es ocupar todo el área cliente del MDIForm.

Saludos.

_CALI
27-12-2012, 16:23:23
Muchas Gracias por el aporte!!