//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "SubClassWndProc.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

// BeginExample: SubClassWndProc
// Method: StdCtrls.TCustomListBox.WndProc
// Method: Controls.TWinControl.WndProc
// Property: Controls.TControl.WindowProc
// Method: Controls.TControl.WndProc

// BeginCode
/*
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.
*/
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 TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}

__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 item’s bitmap
  int Offset = 2;   // default text offset width
  // note that we draw on the listbox’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]);
}

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  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;
}
// EndCode
// EndExample: SubClassWndProc


