SubClassWndProc (Delphi)
Description
This example shows how to use the WndProc method and the WindowProc property to subclass a custom control's window procedure. This example subclasses the window procedure of a TListBox descendant to respond to a user-defined message, called WM_STYLEMESSAGE. The subclassed window procedure can be turned on or off by pressing a radio button.
Code
type
TMyListBoxDescendant = class(TlistBox)
procedure SubClassWndProc(var Message: TMessage);
procedure ToggleSubClass(On: Boolean);
procedure OnDrawItemProc(
Control: TWinControl;
Index: Integer;
Rect:TRect;
State: TOwnerDrawState);
end;
TForm1 = class(TForm)
SubClassRadioGroup1: TRadioGroup;
Button1: TButton;
ImageList1: TImageList;
Button2: TButton;
procedure SubClassRadioGroup1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
MyListBoxDescendant1: TMyListBoxDescendant;
bitmap0: TBitmap;
implementation
{$R *.dfm}
const WM_STYLEMESSAGE = WM_USER + 2000;
procedure TForm1.Button1Click(Sender: TObject);
begin
PostMessage(
MyListBoxDescendant1.Handle,
WM_STYLEMESSAGE,
Integer(lbOwnerDrawFixed),
0);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
PostMessage(
MyListBoxDescendant1.Handle,
WM_STYLEMESSAGE,
Integer(lbStandard),
0);
end;
procedure TMyListBoxDescendant.SubClassWndProc(var Message: TMessage);
begin
if (Message.Msg = WM_STYLEMESSAGE) then
Style:= TListBoxStyle(Message.WParam)
else
WndProc(Message);
end;
procedure TMyListBoxDescendant.ToggleSubClass(On: Boolean);
begin
if On then
WindowProc := SubClassWndProc
else
WindowProc := WndProc;
end;
procedure TForm1.SubClassRadioGroup1Click(Sender: TObject);
begin
MyListBoxDescendant1.ToggleSubClass(
SubClassRadioGroup1.ItemIndex = 0);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
MyListBoxDescendant1:= TMyListBoxDescendant.Create(self);
MyListBoxDescendant1.Visible:= True;
MyListBoxDescendant1.Parent:= Form1;
MyListBoxDescendant1.Visible:= True;
MyListBoxDescendant1.Left:=
SubClassRadioGroup1.Left + SubClassRadioGroup1.Width + 30;;
MyListBoxDescendant1.Top:= SubClassRadioGroup1.Top;
MyListBoxDescendant1.Height:= SubClassRadioGroup1.Height;
MyListBoxDescendant1.OnDrawItem:=
MyListBoxDescendant1.OnDrawItemProc;
bitmap0 := TBitmap.Create;
ImageList1.GetBitmap(0, bitmap0);
MyListBoxDescendant1.Items.AddObject('Butterfly', bitmap0);
SubClassRadioGroup1.Items.Add('SubClassWndProc');
SubClassRadioGroup1.Items.Add('WndProc');
SubClassRadioGroup1.ItemIndex := 2;
end;
procedure TMyListBoxDescendant.OnDrawItemProc(
Control: TWinControl;
Index: Integer;
Rect:TRect;
State: TOwnerDrawState);
var
Bitmap: TBitmap; { Temporary variable for the item�s bitmap }
Offset: Integer; { Text offset width }
begin
{ Draw on the control canvas, not on the form. }
with (Control as TListBox).Canvas do
begin
FillRect(Rect); { Clear the rectangle. }
Offset := 2; { Provide default offset. }
Bitmap := TBitmap((Control as TListBox).Items.Objects[Index]); { Get the bitmap. }
if Bitmap <> nil then
begin
BrushCopy(
Bounds(Rect.Left + Offset, Rect.Top, Bitmap.Width, Bitmap.Height),
Bitmap,
Bounds(0, 0, Bitmap.Width, Bitmap.Height),
clRed); { Render bitmap }
Offset := Bitmap.width + 6; { Add four pixels between bitmap and text. }
end;
TextOut(Rect.Left + Offset, Rect.Top, (Control as TListBox).Items[Index]) { Display the text. }
end;
end;
Uses
- Vcl.StdCtrls.TCustomListBox.WndProc ( fr | de | ja )
- Vcl.Controls.TWinControl.WndProc ( fr | de | ja )
- Vcl.Controls.TControl.WindowProc ( fr | de | ja )
- Vcl.Controls.TControl.WndProc ( fr | de | ja )