SubClassWndProc

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.

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;
}

 

动态转换:

dynamic_cast

TForm2 * p=dynamic_cast<TForm2*>(Form2);

 

dynamic_cast<TListBox *>
posted on 2015-07-13 21:50  lypzxy  阅读(389)  评论(0编辑  收藏  举报