Talking about the production of components from the actual title bar button

zhaozj2021-02-16  60

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.

转载请注明原文地址:https://www.9cbs.com/read-27612.html

New Post(0)