SubClassWndProc (C++)
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 an option button.
Code
class TMyListBoxDescendant : public TListBox
{
__published: IDE-managed Components
void __fastcall SubClassWndProc(Messages::TMessage &Message);
void __fastcall ToggleSubClass(bool On);
void __fastcall OnDrawItemProc(
TWinControl *Control, int Index, const TRect &Rect,
TOwnerDrawState State);
private: // User declarations
public: // User declarations
__fastcall TMyListBoxDescendant(TComponent* Owner);
};
TForm1 *Form1;
TMyListBoxDescendant *MyListBoxDescendant1;
Graphics::TBitmap *bitmap0;
const WM_STYLEMESSAGE = WM_USER + 2000;
__fastcall TMyListBoxDescendant::TMyListBoxDescendant(TComponent* Owner)
: TListBox(Owner)
{
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
PostMessage(
MyListBoxDescendant1->Handle,
WM_STYLEMESSAGE,
Integer(lbOwnerDrawFixed),
0);
}
void __fastcall TForm1::Button2Click(TObject *Sender)
{
PostMessage(
MyListBoxDescendant1->Handle,
WM_STYLEMESSAGE,
Integer(lbStandard),
0);
}
void __fastcall TForm1::SubClassRadioGroup1Click(TObject *Sender)
{
MyListBoxDescendant1->ToggleSubClass(SubClassRadioGroup1->ItemIndex == 0);
}
void __fastcall TMyListBoxDescendant::SubClassWndProc(Messages::TMessage &Message)
{
if (Message.Msg == WM_STYLEMESSAGE)
Style = (TListBoxStyle)Message.WParam;
else
WndProc(Message);
}
void __fastcall TMyListBoxDescendant::ToggleSubClass(bool On)
{
if (On)
WindowProc = SubClassWndProc;
else
WindowProc = WndProc;
}
#include <memory> //For STL auto_ptr class
void __fastcall TMyListBoxDescendant::OnDrawItemProc(TWinControl *Control, int Index,
const TRect &Rect, TOwnerDrawState State)
{
Graphics::TBitmap *bitmap; // Temporary variable for the item's bitmap
int Offset = 2; // Default text offset width
// Note that you draw on the list box's canvas, not on the form
TCanvas *canvas = dynamic_cast<TListBox *>(Control)->Canvas;
canvas->FillRect(Rect); // Clear the rectangle.
bitmap = dynamic_cast<Graphics::TBitmap *>((dynamic_cast<TListBox *>(Control))->Items->Objects[Index]);
if (bitmap)
{
canvas->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 + 4; // Add four pixels between bitmap and text.
}
// Display the text
canvas->TextOut(Rect.Left + Offset, Rect.Top, dynamic_cast<TListBox *>(Control)->Items->Strings[Index]);
}
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
MyListBoxDescendant1 = new TMyListBoxDescendant(Form1); // The owner cleans this up.
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;
static std::auto_ptr<Graphics::TBitmap> _bitmap0Cleaner(bitmap0 = new Graphics::TBitmap);
ImageList1->GetBitmap(0, bitmap0);
MyListBoxDescendant1->Items->AddObject("Butterfly", bitmap0);
SubClassRadioGroup1->Items->Add("SubClassWndProc");
SubClassRadioGroup1->Items->Add("WndProc");
SubClassRadioGroup1->ItemIndex = 2;
}
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 )