RAD Studio VCL Reference
|
Allocates a block of memory to be used by an instance of a class.
function MakeObjectInstance(AMethod: TWndMethod): Pointer;
void * MakeObjectInstance(TWndMethod AMethod);
Call MakeObjectInstance to obtain memory to associate with an instance of a class.
This can be particularly useful when using classes that do not have a Windows handle but need to receive Windows Messages. MakeObjectInstance registers a message handling function into the Windows Message Processing Chain, effectively trapping the Windows Messages. This way the messages sent to the parent window are redirected and processed by the correct function.
C++ Examples:
/* This example uses the MakeObjectInstance function to subclass a form's WinProc for the purpose of trapping Windows messages. This needs to be done for components that are not decendents of TWinControl. MakeObjectInstance is used here to allocate a block of memory for the class object. Then we fill the memory with the machine code necessary to jump to a unique class object member function, and then use the address of that block of memory as the callback address. This example was furnished by Robert Dunn and nicely described at: http://home.att.net/~robertdunn/Papers/MethodCallbacks.html Copyright © 1998-2001 Thin Air Enterprises and Robert Dunn. All rights reserved. */ class TMyComponent : public TComponent { protected: void* FNewWndProcInst; void* FOldWndProcInst; virtual void __fastcall MyWndProc(Messages::TMessage& Msg); public: __fastcall TMyComponent(TComponent* Owner); __fastcall ~TMyComponent(void); }; __fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner) { } // This is the constructor. Create the instance callback and // save it to FNewWndProcInst and save the old window proc to // FOldWndProcInst. Subclass the form. // __fastcall TMyComponent::TMyComponent(TComponent* Owner) : TComponent(Owner), FOldWndProcInst(0), FNewWndProcInst(0) { // if the owner is a form... (your needs may differ) TForm* form = dynamic_cast<TForm*>(Owner); if (form) { FNewWndProcInst = MakeObjectInstance(MyWndProc); FOldWndProcInst = (void*) ::SetWindowLong( form->Handle, GWL_WNDPROC, (LONG) FNewWndProcInst); if (!FOldWndProcInst) { /* error */ }; } // other initialization } // This is the destructor. Restore the original WndProc and // free the instance callback. // __fastcall TMyComponent::~TMyComponent(void) { if (FNewWndProcInst) { (void*)SetWindowLong( Form1->Handle, GWL_WNDPROC, (LONG) FOldWndProcInst); FreeObjectInstance(FNewWndProcInst); } } // This is the callback method, in this example it is used // to filter messages to the underlying Windows control. // TMessage oldMsg; void __fastcall TMyComponent::MyWndProc(Messages::TMessage& msg) { // Do whatever you want with the message before calling // (or not calling) the the original WndProc() to handle // the message call to the original WndProc. // Note that, if you have instantiated multiple objects // of this class, then you are actually chaining back to // MyWndProc() in each earlier instantiation until you get // back to the original WndProc. msg.Result = CallWindowProc( (int(__stdcall*)()) FOldWndProcInst, Form1->Handle, msg.Msg, msg.WParam, msg.LParam); // do whatever you want after the original WndProc() has handled the message if (oldMsg.Msg != msg.Msg) { Form1->ListBox1->Items->Add( "Message recieved: Msg: " + IntToStr((int)msg.Msg) + " WParam: " + IntToStr((int)msg.WParam) + " LParam: " + IntToStr((int)msg.LParam)); oldMsg = msg; } } TMyComponent *mycomp; void __fastcall TForm1::FormCreate(TObject *Sender) { mycomp = new TMyComponent(this); oldMsg.Msg = 0; oldMsg.WParam = 0; oldMsg.LParam = 0; } void __fastcall TForm1::FormDestroy(TObject *Sender) { delete mycomp; }
Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
|
What do you think about this topic? Send feedback!
|