The process of developing components is actually a new object from an object, and new properties, methods, and events are declared for this object. Below I will make components by making a title bar button.
The title bar button component TTITLEBARBUTTON inherits the object with Tcomponent, which is a component that can display buttons on the form header bar, like maximizing, minimizes, and off buttons. The latest WINAMP MP3 player, which has a plugin to display a row of playback buttons on any form, I want to be implemented by the following technology.
1. The initiality determines the properties of the component. The attribute is an important part of the component, which is equivalent to the facade of the component, because once a component is placed in a form, the user must impember to set various properties of the component to write a process process of various events. TTITLEBARBUTTON has the following properties:
Color: Used to determine the color of the button surface.
GLYPH: The picture used to determine the surface of the button.
PopupMenu: Used to determine the pop-up menu when you right-click the button.
Rightmargin: The location of the button is used to be based on the form of the form.
Visible: Used to determine if the button is visible.
2. Determine the method of the component. The method is one of the basic components of the component. When writing methods, minus the dependencies between methods, and determine the visibility of the method, and whether it is virtual function. In this example, the main methods are as follows:
Function getBoundSRect: TRECT; Used to determine the boundary rectangle of the button, visibility is private
Procedure NewWndProc (Var Message: TMessage); New window process for the form, Private
PROCEDURE PAINT; Virtual; the successor of this class can override this method, but users cannot directly adjust the method
Procedure repaint; is an external interface of the Paint method, the user can call this method to force the re-draw button
3. Determine the event of the component. The event is actually a special attribute, which is also an important part of the component, and an event is executed for a piece of code executed by the behavior of the component response system. The event is the method pointer, which is the trigger of the method. TTITLEBARBUTTON has only one event:
Onclick event, used to respond to the user's Click event code.
In addition, reduce the dependencies of components. This is one of the main goals of development components when performing their code, which is one of the main goals of development components. It is also one of the important criteria for measuring a component performance.
Implement the title bar button to solve the following major issues:
1. How to determine the boundary of the button, ie Left, Top, Width, Height
Get the boundary rectangle of the form via getWindowRect, obtain the form of the frame width and the height, width of the title bar button through GetSystemMetrics. Coupled with the Right Margin property, you can basically determine the boundaries of the button.
2, how to draw the appearance of the button (including pressing and raising)
Get form DC (including the title bar, menu, scroll bar, etc.) through getWindowdc, and we can picture the button on this DC.
3, how to let the button response message (such as Click, click Right click pop-up menu, etc.)
We can get the window process of the form through getWindowlong, then put our new window process to this form via setWindowlong, then we will let the button response message during your own window.
All code is as follows:
Unit titlebarbutton;
Interface
Uses
Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, Menus, Dialogs; Type
TTITLEBARBATON = Class (Tcomponent)
Private
Fcolor: Tcolor;
FGLYPH: TBITMAP;
FFORM: TCUSTOMFORM;
FoldWndproc: Pointer;
FButtondown: boolean;
Fvisible: boolean;
FRIGHTMARGIN: Cardinal
FPOPUP: TPOPUPMENU;
FONCLICK: TNOTIFYEVENT;
Procedure setglyph (const value: tbitmap);
Procedure setvisible (const value: boolean);
Procedure Setright Margin (Const Value: Cardinal);
Function GetBoundSRect: TRECT;
Procedure NewWndProc (Var Message: TMESSAGE);
protected
Procedure Notification (Component: Tcomponent; Operation); OVERRIDE;
PROCEDURE PAINT; Virtual;
public
Constructor Create (Aowner: Tcomponent); OVERRIDE;
DESTRUCTOR DESTROY; OVERRIDE;
PROCEDURE Repaint;
Property BoundSRect: TRECT ReadBoundSRect;
Published
Property Color: Tcolor Read Fcolor Write Fcolor Default CLBTNFACE;
Property Glyph: Tbitmap Read Fglyph Write setGlyph;
Property Popupmenu: TPopupMenu Read FPOPUP WRITE FPOPUP;
Property Right Margin: Cardinal Read FRight Margin Write Stright Margin Default 66;
Property Visible: Boolean Read Fvisible Write SetVisible Default False;
Property Onclick: TNotifyEvent Read Fonclick Write Fonclick;
END;
PROCEDURE register;
IMPLEMENTATION
PROCEDURE register;
Begin
Registercomponents ('LIAO', [TTITLEBARBARBUTTON]);
END;
{TTITLEBARBATON}
Constructor TtitlebarButton.create (Aowner: Tcomponent);
VAR
PTR: POINTER;
Begin
inherited;
Fform: = getParentform (TControl (aowner);
FGLYPH: = Tbitmap.create;
Fcolor: = CLBTNFACE;
FVISIBLE: = FALSE;
FRIGHTMARGIN: = 66;
FButtondown: = false;
FoldWndProc: = Pointer (getWindowl ";
PTR: = MakeObjectInstance (NewWndProc); SetWindowl (Fform.handle, GWL_WndProc, Longint (PTR));
END;
Destructor TtitlebarButton.Destroy;
Begin
IF not (csdestroying in fform.componentstate) THEN
Begin
Setvisible (false);
Setwindowlong (Fform.Handle, GWL_WndProc, Longint (FoldWndProc);
END;
Fglyph.free;
inherited;
END;
Procedure TtitlebarButton.NewWndProc (Var Message: TMESSAGE);
Function Hitbutton (apoint: tpoint): boolean;
Begin
Apoint.x: = apoint.x - fform.left;
Apoint.y: = apoint.y - fform.top;
Result: = PtinRect (BoundSRect, Apoint);
END;
VAR
p: tpoint;
Begin
WITH MESSAGE DO
Begin
IF Visible Then
Begin
Case msg of
WM_NCPAINT, WM_NCActivate:
Begin
Result: = CallWindowProc (FoldWndProc, Fform.handle, MSG, WPARAM, LPARAM);
Repaint;
END;
WM_NCHITTEST:
Begin
Result: = CallWindowProc (FoldWndProc, Fform.handle, MSG, WPARAM, LPARAM);
if Result = htcaption then
Begin
Repaint;
P.X: = loword (lparam);
ScreenToClient (Fform.handle, P);
WITH BoundSRect Do // minus the frame width
IF (p.x> = left-4) and (p.x <= right-4) THEN Result: = 888;
END;
END;
Wm_nclbuttondown, WM_NCLBUTTONDBLCLK:
Begin
Result: = CallWindowProc (FoldWndProc, Fform.handle, MSG, WPARAM, LPARAM);
WITH TWMNCLBUTTONDOWN (Message) DO
IF NOT HITBUTTON (Point (xcursor, ycursor).
IF wparam = 888 THEN
Begin
FButtondown: = true;
Repaint;
SetCapture (fform.handle);
END;
END;
Wm_ncrbuttondown, WM_NCRBUTTONDBLCLK:
Begin
IF wparam = 888 THEN
Begin
IF assigned (fpopup) THEN
Begin
P.x: = fform.Left BoundSRect.Left;
p.y: = fform.top boundsRect.bottom;
Fpopup.Popup (P.X, P.Y);
END;
end
Else
Result: = CallWindowProc (FoldWndProc, Fform.handle, MSG, WPARAM, LPARAM); END;
Wm_nclbuttonup, wm_lbuttonup:
Begin
IF FButtondown Then
Begin
FButtondown: = false;
Repaint;
Releasecapture;
IF Assigned (Fonclick) THEN FONCLICK (Self);
end
Else
Result: = CallWindowProc (FoldWndProc, Fform.handle, MSG, WPARAM, LPARAM);
END;
Else
Result: = CallWindowProc (FoldWndProc, Fform.handle, MSG, WPARAM, LPARAM);
END;
end
Else
Result: = CallWindowProc (FoldWndProc, Fform.handle, MSG, WPARAM, LPARAM);
END;
END;
Procedure TTITLEBARBUTTON.SETGLYPH (Const Value: Tbitmap);
Begin
Fglyph.assign (value);
SendMessage (fform.handle, wm_ncactivate, 0, 0);
END;
Procedure TtitlebarButton.setright Margin (Const Value: Cardinal);
Begin
FRIGHTMARGIN: = Value;
SendMessage (fform.handle, wm_ncactivate, 0, 0);
END;
Procedure TtitlebarButton.SetVisible (Const Value: Boolean);
Begin
Fvisible: = Value;
SendMessage (fform.handle, wm_ncactivate, 0, 0);
END;
Procedure TtitlebarButton.Notification (Component: Tcomponent;
Operation: TOPERATION);
Begin
inherited;
IF (Operation = Opremove) and (Component = fpopup) THEN
FPOPUP: = NIL;
END;
Function TTITLEBARBATON.GETBOUNDSRECT: TRECT
VAR
Re: TRECT;
Framethick: integer; // Form frame thickness
BtnWidth, BtnHeight: integer; // The width and height of the title bar button
Begin
GetWindowRect (fform.handle, rec); // Get the form boundary rectangle, relative to the upper left corner of the screen
WITH RESULT DO
Begin
Framethick: = GetSystemMetrics (SM_CYFRAME);
Left: = (Rec.right - rec.left) - Right Margin - framethick;
Top: = framethick;
IF fform.Borderstyle In [Bssizetoolwin, Bssizeable] THEN
Begin
DEC (Left, 2); Inc (TOP, 2);
end
Else Begin
Dec (Left); Inc (TOP);
END;
IF (Fform. Borderwin, BSTOOLWINDOW])
Begin
BtnWidth: = GetSystemMetrics - 2; btnHeight: = GetSystemMetrics - 4;
end
Else Begin
BtnWidth: = GetSystemMetrics (SM_CXSIZE) - 2;
Btnheight: = GetSystemMetrics (SM_CYSIZE) - 4;
END;
Right: = Left btnwidth;
Bottom: = TOP BTNHEIGHT;
END;
END;
Procedure ttitlebarbutton.paint;
VAR
GlyphRect: TRECT;
Begin
IF not fvisible kiln
With tcanvas.create do
Begin
Try
Handle: = getWindowdc (fform.handle); // Get form DC, including title bar, menu, scroll bar, etc.
Brush.color: = fcolor; // draws button bumps and pressing the appearance
IF FButtondown Then
Pen.color: = CLBTNHighlight
Else
Pen.color: = CL3DDKSHADOW;
Rectangle (BoundSRect);
With BoundSRect Do
Begin
IF FButtondown Then
Pen.color: = CL3DDKSHADOW
Else
Pen.color: = CLBTNHighlight;
MoveTo (Left, Bottom-2);
LINETO (LEFT, TOP);
LINETO (Right-1, TOP);
Pen.color: = CLGRAY;
IF FButtondown Then
Begin
MoveTo (Left 1, Bottom-3);
LINETO (Left 1, TOP 1);
LINETO (Right-2, TOP 1);
end
Else Begin
MoveTo (Left 1, Bottom-2);
LINETO (Right-2, Bottom-2);
LINETO (Right-2, TOP);
END;
END;
If Assigned (Glyph) Then // If you associate pictures, draw pictures
Begin
GlyphRect: = BoundSRECT;
GlyphRect.right: = GlyphRect.right - 7;
GlyphRect.bottom: = GlyphRect.bottom - 5;
IF FButtondown Then
OffsetRect (GlyphRect, 4, 3)
Else
OFFSETRECT (GlyphRect, 3, 2);
With GlyphRect Do
Stretchblt (Handle, Left, Top, Right-LEFT, BOTTOM-TOP,
Fglyph.canvas.handle, 0, 0, fglyph.width, fglyph.height, srcopy;
END;
Finally
ReleaseDC (Fform.Handle, Handle);
FREE;
END;
END;
END;
Procedure ttitlebarbutton.repaint;
Begin
Paint;
END;
End.
In addition, it is also possible to further expand this component, extending any other form, as long as the Handle of the form is known.