procedure TForm1.MakeTransparent;
var
AControl: TControl;
A, Margin, X, Y, CtlX, CtlY: Integer;
FullRgn, ClientRgn, CtlRgn: THandle;
cXBorder, cYBorder, cWidth, cHeight: LongInt;
begin
// calculate different border styles
case Self.BorderStyle of
bsDialog:
begin
cXBorder := 0;
cYBorder := GetSystemMetrics(SM_CYCAPTION);
end;
bsNone:
begin
cXBorder := GetSystemMetrics(SM_CXBORDER);
cYBorder := GetSystemMetrics(SM_CYBORDER);
end;
bsSingle:
begin
cXBorder := 0;
cYBorder := GetSystemMetrics(SM_CYCAPTION);
end;
bsSizeable:
begin
cXBorder := GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CXFOCUSBORDER);
cYBorder := GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYEDGE) + GetSystemMetrics(SM_CYFOCUSBORDER) + GetSystemMetrics(SM_CYCAPTION);
end;
bsSizeToolWin:
begin
cXBorder := GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CXEDGE) + GetSystemMetrics(SM_CXFOCUSBORDER);
cYBorder := GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYEDGE) + GetSystemMetrics(SM_CYFOCUSBORDER) + GetSystemMetrics(SM_CYCAPTION);
end;
bsToolWindow:
begin
cXBorder := 0;
cYBorder := GetSystemMetrics(SM_CYCAPTION);
end;
end;
// set client dimension
cWidth := Self.ClientRect.Width - cXBorder;
cHeight:= Self.ClientRect.Height - cYBorder;
Margin := (Self.Width - cWidth) div 2;
// get form and client area region
X := Margin;
case Self.BorderStyle of
bsDialog:
begin
FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Self.Height + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
Y := Self.Height - cHeight - Margin + GetSystemMetrics(SM_CYDLGFRAME);
ClientRgn := CreateRectRgn(X, Y, X + cWidth + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Y + cHeight + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
end;
bsNone:
begin
FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder, Self.Height + cYBorder);
Y := Self.Height - cHeight - Margin - GetSystemMetrics(SM_CYBORDER);
ClientRgn := CreateRectRgn(X, Y, X + cWidth + GetSystemMetrics(SM_CXBORDER), Y + cHeight + GetSystemMetrics(SM_CYBORDER));
end;
bsSingle:
begin
FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Self.Height + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
Y := Self.Height - cHeight - Margin + GetSystemMetrics(SM_CYDLGFRAME);
ClientRgn := CreateRectRgn(X, Y, X + cWidth + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Y + cHeight + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
end;
bsSizeable:
begin
FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder, Self.Height + cYBorder);
Y := Self.Height - cHeight - Margin - GetSystemMetrics(SM_CYBORDER);
ClientRgn := CreateRectRgn( X, Y, X + cWidth + cXBorder, Y + cHeight + cYBorder);
end;
bsSizeToolWin:
begin
FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder, Self.Height + cYBorder);
Y := Self.Height - cHeight - Margin - GetSystemMetrics(SM_CYBORDER);
ClientRgn := CreateRectRgn( X, Y, X + cWidth + cXBorder, Y + cHeight + cYBorder);
end;
bsToolWindow:
begin
FullRgn := CreateRectRgn(0, 0, Self.Width + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Self.Height + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
Y := Self.Height - cHeight - Margin + GetSystemMetrics(SM_CYDLGFRAME);
ClientRgn := CreateRectRgn(X, Y, X + cWidth + cXBorder + GetSystemMetrics(SM_CXDLGFRAME), Y + cHeight + cYBorder + GetSystemMetrics(SM_CYDLGFRAME));
end;
end;
// 'Mask' out all but non-client areas
CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF);
// Now, walk through all the controls on the form and 'OR' them into the existing Full region.
for A := 0 to Pred(ControlCount) do
begin
AControl := Controls[A];
if ((AControl is TWinControl) or (AControl is TGraphicControl) or (AControl is TControl)) then
if AControl.Visible then
begin
CtlX := X + AControl.Left;
CtlY := Y + AControl.Top;
case Self.BorderStyle of
bsDialog:
begin
CtlRgn := CreateRectRgn(CtlX + GetSystemMetrics(SM_CXDLGFRAME), CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXDLGFRAME), CtlY + AControl.Height);
end;
bsNone:
begin
CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + AControl.Width, CtlY + AControl.Height);
end;
bsSingle:
begin
CtlRgn := CreateRectRgn(CtlX + GetSystemMetrics(SM_CXDLGFRAME), CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXDLGFRAME), CtlY + AControl.Height);
end;
bsSizeable:
begin
CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXEDGE), CtlY + AControl.Height + GetSystemMetrics(SM_CYEDGE));
end;
bsSizeToolWin:
begin
CtlRgn := CreateRectRgn(CtlX, CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXEDGE), CtlY + AControl.Height + GetSystemMetrics(SM_CYEDGE));
end;
bsToolWindow:
begin
CtlRgn := CreateRectRgn(CtlX + GetSystemMetrics(SM_CXDLGFRAME), CtlY, CtlX + AControl.Width + GetSystemMetrics(SM_CXDLGFRAME), CtlY + AControl.Height);
end;
end;
CombineRgn(FullRgn, FullRgn, CtlRgn, RGN_OR);
end;
end;
// When the region is all ready, put it into effect:
SetWindowRgn(Handle, FullRgn, TRUE);
// clean up the mess
DeleteObject(ClientRgn);
DeleteObject(FullRgn);
DeleteObject(CtlRgn);
end;