Главная страница | назад





Article #22225: How to use a VCL class member-function as a Win32 callback.

Question

How do make one of my VCL class member-functions act as a Win32 callback function?

Answer

This problem is a lot easier to solve than most people think. Most of the time, you will see callbacks implemented either as static members or global functions with the class instance pointer set as extra data (to the window or lParam or whatever). The VCL provides two undocumented functions that are designed to do exactly what we want: use member-functions as callbacks. Those functions are MakeObjectInstance and FreeObjectInstance.

Example:


//---------Function Protypes from Forms.hpp----------------
//extern PACKAGE void * __fastcall MakeObjectInstance(Controls::TWndMethod Method);
//extern PACKAGE void __fastcall FreeObjectInstance(void * ObjectInstance);
//---------------------------------------------------------
//------------------------------Unit1.h--------------------------------------
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
void __fastcall FormClick(TObject *Sender);
private: // User declarations
void *oldproc;
void *newproc;
void __fastcall myproc(TMessage &msg);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
//-----------------------End Unit1.h-----------------------------------------
//-----------------------Unit1.cpp-------------------------------------------
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
newproc = MakeObjectInstance(myproc);
oldproc = (void *)SetWindowLong(Handle,GWL_WNDPROC,(LONG)newproc);
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
SetWindowLong(Handle,GWL_WNDPROC,(LONG)oldproc);
FreeObjectInstance(newproc);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::myproc(TMessage &msg)
{
if (msg.Msg == WM_LBUTTONUP)
ShowMessage("click");
msg.Result = CallWindowProc((FARPROC)oldproc,Handle,msg.Msg,msg.WParam,msg.LParam);
}
void __fastcall TForm1::FormClick(TObject *Sender)
{
ShowMessage("click_event");
}
//---------------------------------------------------------------------------
//-----------------------End Unit1.cpp---------------------------------------

Last Modified: 17-NOV-00