How to remove the client edge of a MDI parent form (Views: 714)
Problem/Question/Abstract: How to remove the client edge of a MDI parent form Answer: Apparently, in Delphi 4, the logic for the MDI client window edge was changed. If you have the source for Forms.pas, you can see the MDI client window procedure (TCustomForm.ClientWndProc) explicitly changes the client edge on a certain mysterious message ($3F) by calling ShowMDIClientEdge. Unfortunately, simply replacing the client window procedure doesn't work well. I've finally been able to work out a hack, that replaces the client window procedure, and changes the form style on the fly. This makes sure the form's FormStyle property is not fsMDIForm when the client window procedure wants to call ShowMDIClientEdge, which it does only if the FormStyle property is fsMDIForm. When the FormStyle property changes, however, the window is destroyed (to be recreated when needed). To prevent this, I've overriden the DestroyWnd method. The following unit is my MDI main form, displayed without a sunken edge: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } FUpdating: Boolean; OldWndProc: TFarProc; NewWndProc: Pointer; procedure ClientWndProc(var Message: TMessage); protected procedure DestroyWnd; override; public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.ClientWndProc(var Message: TMessage); procedure DefProc; begin with Message do Result := CallWindowProc(OldWndProc, ClientHandle, Msg, wParam, lParam); end; begin if Message.Msg = $3F then begin FUpdating := True; FormStyle := fsNormal; DefProc; FormStyle := fsMDIForm; FUpdating := False; end else DefProc; end; procedure TForm1.DestroyWnd; begin if not FUpdating then inherited DestroyWnd; end; procedure TForm1.FormCreate(Sender: TObject); begin OldWndProc := Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC)); NewWndProc := MakeObjectInstance(ClientWndProc); SetWindowLong(ClientHandle, GWL_WNDPROC, Longint(NewWndProc)); SetWindowLong(ClientHandle, GWL_EXSTYLE, GetWindowLong(ClientHandle, GWL_EXSTYLE) and not WS_EX_CLIENTEDGE); SetWindowPos(ClientHandle, 0, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_FRAMECHANGED); end; procedure TForm1.FormDestroy(Sender: TObject); begin if Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC)) = NewWndProc then begin SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(OldWndProc)); FreeObjectInstance(NewWndProc); end; end; end. |