Title: Creating Custom Microsoft .NET Framework Controls in Delphi
1Creating Custom Microsoft .NET Framework Controls
in Delphi
2Agenda
- .NET Component Model
- Comparing the FCL to the VCL
- Custom Events
- Custom Painting
- Component Related Attributes
- Sample Control
3.NET Component Model
- Defined in the System.ComponentModel namespace
- Includes
- System.ComponentModel.Component declaration
- Common Delegates
- Component Related Attribute declarations
- Licensing Classes
- Design-time Support Classes
4Component Class
- System.ComponentModel.Component provides the base
implementation of IComponent in the FCL - Defines the following properties
- DesignMode
- Container
- Site
- Events
- Descend from System.ComponentModel.Component to
create a nonvisual component
5Two Control Classes in .NET
- Most visual controls in .NET will descend from
one of two classes - System.Windows.Forms.Control
- Base WinForms Control class
- Most similar to existing component models (e.g.
VCL) - Rendering handled through Graphics class (i.e.
GDI) - System.Web.UI.Control
- Base ASP.NET Server Control class
- Renders markup text used by a clients browser or
viewing device to display visual elements.
6System.Windows.Forms.Control
- Implements basic functionality for visualization
- Defines the controls bounds (i.e. its Position
and Size) - Provides a window handle (Handle)
- Provides access to keyboard events
- Provides access to mouse events
- Provides access to paint events
- Supports ambient properties
- Cursor, Font, BackColor, ForeColor, RightToLeft.
7Comparing the FCL to the VCL
- FCL is quite similar to the VCL, but there are
significant differences - No equivalent to TGraphicControl
- Actually, no TWinControl or TCustomControl
classes either - System.Windows.Forms.Control is more like
TCustomControl than TControl - Significantly fewer TCustomXxxx class
- called XxxxBase in FCL
8Where is the Align property?
- Most of the functionality implemented in the VCL
base classes is available in the base FCL classes - However, there are many property name changes
- Align ? Dock
- Caption ? Text
- Color ? BackColor
- Font.Color ? ForeColor
- PopupMenu ? ContextMenu
- ModalResult ? DialogResult
- etc.
- Tag is an Object
- ParentXxxx properties replaced with ambient
properties
9Control Styles
- TControl.ControlStyle replaced with
GetStyle/SetStyle method pair - Some, but not all, styles have corresponding
public properties - ResizeRedraw
SetStyle( ControlStyles.ResizeRedraw, True
) SetStyle( ControlStyles.Opaque, True ) //
Double Buffering SetStyle( ControlStyles.UserPaint
, True ) SetStyle( ControlStyles.AllPaintingInWmP
aint, True ) SetStyle( ControlStyles.DoubleBuffer
, True )
10Component Notifications
- Component notifications allow descendants to
react to state changes implemented in an ancestor
class - In the VCL, a component responds to notifications
by handling special messages - e.g. cm_EnabledChanged
- In .NET, a component responds to notifications by
overriding a method - OnEnabledChanged Event Dispatch Method
- .NET even surfaces component notifications as
public events - EnabledChanged Event
11FCL and VCL Events
- Unfortunately, the naming convention used for
events in the FCL is opposite that used in the
VCL - In the VCL
- OnPaint is the event
- Paint is the event dispatch method
- In the FCL
- OnPaint is the event dispatch method
- Paint is the event
12FCL and VCL Events
- Please Note
- Unfortunately, it is common in .NET literature to
see statements like - take a look at the OnPaint event handler
- Problem is that base (ancestor) does not get
called and thus the real event never gets raised
13Events
- Events allow customization through delegation
- Events are properties
- Implemented using Delegates
- Events are optional
14Creating a Custom Event
- Determine the action that triggers event
- Define the event type (i.e. the Delegate)
- Specifies the parameters that will be sent to an
event handler - Declare the event property
- Singleton Event (read/write)
- Multicast Event (add/remove)
- Dispatch the event when it occurs.
15Determine Event Trigger
- Events allow developers to hook into normal
processing - Example
- Generate a ValueChanged event when data
represented by the component changes
16Delegates
- The FCL utilizes Delegates to support events
- A delegate is a class that encapsulates a
linked-list of method pointers - With delegates an event can be sent to multiple
subscribers - Specify the parameters that will be sent to event
handlers.
17Define the Delegate
- May be possible to use predefined delegate
- e.g. EventHandler
- First parameter always object sender
- Second parameter always EventArgs or descendant
- If you require passing additional parameters,
youll need to create a new EventArgs descendant
ValueChangingEventHandler procedure (
sender System.Object e
ValueChangingEventArgs ) of object
18Declare the Event Property
- Unlike the VCL, by convention event names in the
FCL do not start with On
// Multicast Event property ValueChanged
EventHandler add FValueChanged remove
FValueChanged // Singleton Event property
ValueChanging ValueChangingEventHandler read
FValueChanging write FValueChanging
19Raise the Event
- Use an Event Dispatch Method
- In FCL, event dispatch methods start with On
- Usually defined as strict protected and virtual
- Calling the event (e.g. FValueChanged) causes all
of the event handlers in the delegates list to
be called
procedure RkSpinner.OnValueChanged( E EventArgs
) begin if Assigned( FValueChanged ) then
FValueChanged( Self, E ) end
20Custom Painting
- Custom painting is supported by Graphics class
(i.e. GDI) - System.Drawing
- System.Drawing.Drawing2D
- System.Drawing.Imaging
- System.Drawing.Text
- GDI Features
- Alpha Blending Anti-Aliased 2D Drawing
- Gradient Brushes
- Universal Transformations Floating Point
coordinates - Support for more Image formats
- BMP, GIF, JPEG, PNG, TIFF, ICON, WMF, EMF.
21GDI Programming Model
- No more device contexts (DC) Graphics Object
- GDI is Stateless
- No more selecting pens and brushes into a DC
- Pens, Brushes, etc. are passed to each GDI
drawing method - Graphic elements are no longer drawn with both
Pen and Brush - Draw methods use a Pen (eg. DrawRectangle)
- Fill methods use a Brush (eg. FillEllipse).
22GDI Programming Model
- Colors support Alpha Channels
- ARGB format
- 0x880000FF semi-transparent blue
- A 0x00 fully transparent
- A 0xFF fully opaque
- Rectangles, Points, etc. are classes
- r.Inflate( 5, 5 ) // Instead of
InflateRect( r, 5, 5 ) - Rectangles are defined differently!
- Left, Top, Width, Height.
23GDI Programming Model
- Obtaining a Graphics Object
- Passed to OnPaint methods in PaintEventArgs
- Request one using Graphics.FromHwnd( Handle )
- If utilizing double-buffering, do not use
FromHwnd - Cleaning Up
- Dispose all GDI objects
- Dispose Graphics object if requested via FromHwnd
24Attributes
- Attributes used to modify the behavior of
properties, methods, events
Category( 'Appearance' ), Description( 'The
width of buttons, in pixels.' ), DefaultValue(
18 ) property ButtonWidth Integer read
FButtonWidth write SetButtonWidth
25Attributes
- Category
- Description
- Browsable
- DefaultValue
- DefaultProperty DefaultEvent
- Localizable
- ToolboxBitmap
26Example
- RayKonopka.Delphi.Controls Assembly
- RkSpinner Component
27References
- Microsoft Development Network (MSDN)
- Design Guidelines for Class Library Developers
- Developing Components
- Developing Windows Forms Controls
- Applied .NET Framework Development
- Jeffrey Richter
- Programming Microsoft .NET
- Jeff Prosise
28The Finish Line
- Contact Information
- Evaluation Forms
- Questions Answers
Ray Konopka rkonopka_at_raize.com http//www.raize.co
m