Author: Jonas Bilinkevicius
How to create a sizeable form with a 3D look
Answer:
Try these handlers for the WMNCPaint and WMNCHitTest messages. The form should have
the Sizeable border style as the code uses the sizeable border area for drawing the
3D effect, whether or not you want the user to be able to resize. To prohibit
resizing, include the WMNCHitTest handler, to allow it, leave it out.
1
2 procedure TForm1.WMNCPaint(var Msg: TWMNCPaint);
3 var
4 DC: HDC;
5 Frame_H: Integer;
6 Frame_W: Integer;
7 Menu_H: Integer;
8 Caption_H: Integer;
9 Frame: TRect;
10 Extra: Integer;
11 Canvas: TCanvas;
12 begin
13 { Predetermine some window parameters }
14 Frame_W := GetSystemMetrics(SM_CXFRAME);
15 Frame_H := GetSystemMetrics(SM_CYFRAME);
16 if (Menu <> nil) then
17 Menu_H := GetSystemMetrics(SM_CYMENU)
18 else
19 Menu_H := -1;
20 Caption_H := GetSystemMetrics(SM_CYCAPTION);
21 GetWindowRect(Handle, Frame);
22 Frame.Right := Frame.Right - Frame.Left - 1;
23 Frame.Left := 0;
24 Frame.Bottom := Frame.Bottom - Frame.Top - 1;
25 Frame.Top := 0;
26 { Let standard frame draw }
27 inherited;
28 { Repaint frame area in 3-D style }
29 DC := GetWindowDC(Handle);
30 Canvas := TCanvas.Create;
31 try
32 with Canvas do
33 begin
34 Handle := DC;
35 { Left and Top edges }
36 Pen.Color := clBtnShadow;
37 PolyLine([Point(Frame.Left, Frame.Bottom), Point(Frame.Left, Frame.Top),
38 Point(Frame.Right, Frame.Top)]);
39 { Right and Bottom edges }
40 Pen.Color := clWindowFrame;
41 PolyLine([Point(Frame.Left, Frame.Bottom), Point(Frame.Right, Frame.Bottom),
42 Point(Frame.Right, Frame.Top - 1)]);
43 { Left and Top edge, 1 pixel in }
44 Pen.Color := clBtnHighlight;
45 PolyLine([Point(Frame.Left + 1, Frame.Bottom - 1), Point(Frame.Left + 1,
46 Frame.Top + 1),
47 Point(Frame.Right - 1, Frame.Top + 1)]);
48 { Right and Bottom edge, 1 pixel in }
49 Pen.Color := clBtnFace;
50 PolyLine([Point(Frame.Left + 1, Frame.Bottom - 1), Point(Frame.Right - 1,
51 Frame.Bottom - 1),
52 Point(Frame.Right - 1, Frame.Top)]);
53 { Remainder of Sizing border }
54 for Extra := 2 to (GetSystemMetrics(SM_CXFRAME) - 1) do
55 begin
56 Brush.Color := clBtnFace;
57 FrameRect(Rect(Extra, Extra, Frame.Right - Extra + 1, Frame.Bottom - Extra +
58 1));
59 end;
60 { Left and Top Edge of Caption Area }
61 Pen.Color := clBtnShadow;
62 PolyLine([Point(Frame_W - 1, Frame_H + Caption_H + Menu_H - 1), Point(Frame_W
63 -
64 1,
65 Frame_H - 1), Point(Frame.Right - Frame_W + 1, Frame_H - 1)]);
66 { Right and Bottom Edge of Caption Area }
67 Pen.Color := clBtnHighlight;
68 PolyLine([Point(Frame_W - 1, Frame_H + Caption_H + Menu_H - 1),
69 Point(Frame.Right - Frame_W + 1, Frame_H + Caption_H + Menu_H - 1),
70 Point(Frame.Right - Frame_W + 1, Frame_H - 1)]);
71 end;
72 finally
73 Canvas.Free;
74 ReleaseDC(Handle, DC);
75 end;
76 end;
77
78 procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
79 var
80 HitCode: LongInt;
81 begin
82 inherited;
83 HitCode := Msg.Result;
84 if ((HitCode = HTLEFT) or (HitCode = HTRIGHT) or (HitCode = HTTOP) or (HitCode =
85 HTBOTTOM)
86 or (HitCode = HTTOPLEFT) or (HitCode = HTBOTTOMLEFT) or (HitCode = HTTOPRIGHT)
87 or
88 (HitCode = HTBOTTOMRIGHT)) then
89 begin
90 HitCode := HTNOWHERE;
91 end;
92 Msg.Result := HitCode;
93 end;
|