Board index » cppbuilder » Window Message into object inspector

Window Message into object inspector

Hello,

How can I get the WM_ERASEBKGND windows message to appear in the Object
Inspector for my custom component?

My component looks like this:

class TCustPanel :public TPanel
{

    protected:
    void __fastcall OnEraseBkGnd(TMessage & Message);
 BEGIN_MESSAGE_MAP
  MESSAGE_HANDLER(WM_ERASEBKGND,TMessage,OnEraseBkGnd)
END_MESSAGE_MAP(TPanel)

Quote
}

I would like the OnEraseBkGnd to be an event which can be implemented as
used in normal components.
What is the best way to do this?

Regards,

James

 

Re:Window Message into object inspector


You have a good start, you just need to add a new property to your component
in order for the Object Inspector to recognize your event:

class TCustPanel :public TPanel
{
protected:
    TNotifyEvent FOnEraseBkGnd;
    void __fastcall WMEraseBkGnd(TMessage &Message);
public:
    BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(WM_ERASEBKGND, TMessage, WMEraseBkGnd)
    END_MESSAGE_MAP(TPanel)
__published:
    __property TNotifyEvent OnEraseBkGnd =
{read=FOnEraseBkGnd,write=FOnEraseBkGnd};

Quote
};

void __fastcall TCustPanel::WMEraseBkGnd(TMessage &Message)
{
    if(FOnEraseBkGnd)
        FOnEraseBkGnd(this);

Quote
}

Gambit

Quote
"James Williams" <j...@creditview.no> wrote in message

news:3A2ED999.BC9416DC@creditview.no...
Quote
> I would like the OnEraseBkGnd to be an event which can be implemented as
> used in normal components.
> What is the best way to do this?

Re:Window Message into object inspector


Quote
Remy Lebeau wrote:
> You have a good start, you just need to add a new property to your
> component in order for the Object Inspector to recognize your event:
> void __fastcall TCustPanel::WMEraseBkGnd(TMessage &Message)
> {
>     if(FOnEraseBkGnd)
>         FOnEraseBkGnd(this);
> }

Just one little thing to add.  The WM_ERASEBKGND message wants
a return value.  The win32.hlp says:

     An application should return nonzero if it erases the background;
     otherwise, it should return zero.

So presumably if your Event is assigned, you would set Message.Result
to nonzero to prevent the OS from erasing the background.

Re:Window Message into object inspector


Thanks for your help.  Why does borland add this to the standard events.  To
me, it is an important event to prevent flickering in graphics.

Regards,

James

Quote
James Williams wrote:
> Hello,

> How can I get the WM_ERASEBKGND windows message to appear in the Object
> Inspector for my custom component?

> My component looks like this:

> class TCustPanel :public TPanel
> {

>     protected:
>     void __fastcall OnEraseBkGnd(TMessage & Message);
>  BEGIN_MESSAGE_MAP
>   MESSAGE_HANDLER(WM_ERASEBKGND,TMessage,OnEraseBkGnd)
> END_MESSAGE_MAP(TPanel)

> }

> I would like the OnEraseBkGnd to be an event which can be implemented as
> used in normal components.
> What is the best way to do this?

> Regards,

> James

Re:Window Message into object inspector


Yes, but I would like that TMessage &Message is a parameter to the FOnEraseBkGnd
so that anyone can respond on the return value.

How can I change the TNotify FOnEraseBkGnd so that the parameter is TMessage
instead of TObject?

Quote
Remy Lebeau wrote:
> You have a good start, you just need to add a new property to your component
> in order for the Object Inspector to recognize your event:

> class TCustPanel :public TPanel
> {
> protected:
>     TNotifyEvent FOnEraseBkGnd;
>     void __fastcall WMEraseBkGnd(TMessage &Message);
> public:
>     BEGIN_MESSAGE_MAP
>         MESSAGE_HANDLER(WM_ERASEBKGND, TMessage, WMEraseBkGnd)
>     END_MESSAGE_MAP(TPanel)
> __published:
>     __property TNotifyEvent OnEraseBkGnd =
> {read=FOnEraseBkGnd,write=FOnEraseBkGnd};
> };

> void __fastcall TCustPanel::WMEraseBkGnd(TMessage &Message)
> {
>     if(FOnEraseBkGnd)
>         FOnEraseBkGnd(this);
> }

> Gambit

> "James Williams" <j...@creditview.no> wrote in message
> news:3A2ED999.BC9416DC@creditview.no...

> > I would like the OnEraseBkGnd to be an event which can be implemented as
> > used in normal components.
> > What is the best way to do this?

Re:Window Message into object inspector


One nice way to do it wold be to let the user decide:

class TCustPanel :public TPanel
{
protected:
    typedef void __fastcall (__closure *TEraseEvent)(TObject *Sender, bool
&AllowOSControl);
    TEraseEvent FOnEraseBkGnd;
    void __fastcall WMEraseBkGnd(TMessage &Message);
public:
    BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(WM_ERASEBKGND, TMessage, WMEraseBkGnd)
    END_MESSAGE_MAP(TPanel)
__published:
    __property TEraseEvent OnEraseBkGnd =
{read=FOnEraseBkGnd,write=FOnEraseBkGnd};

Quote
};

void __fastcall TCustPanel::WMEraseBkGnd(TMessage &Message)
{
    bool bOSControl = true;
    if(FOnEraseBkGnd)
        FOnEraseBkGnd(this, bOSControl);

    Message.Result = (int)(!bOSControl);

Quote
}

void __fastcall TForm1::CustPanel1EraseBkGnd(TObject *Sender, bool
&AllowOSControl)
{
    // set AllowOSControl to true to allow the OS to handle
    // WM_ERASEBKGND normally

    // set AllowOSControl to false to prevent the OS from
    // handling WM_ERASEBKGND normally

Quote
}

Gambit

Quote
"Lucian Wischik" <ljw1...@cam.ac.uk> wrote in message

news:90mut8$f8g9@bornews.inprise.com...

Quote
> This is a worry! It's kind of a fundamental design principal of all the
VCL
> components that all events act merely as notifications, and that the
> behaviour of the thing shouldn't change merely because you assign an
event.
> But I can't think of a nice way to respect that principle in this case.

Re:Window Message into object inspector


Quote
"James Williams" <j...@creditview.no> wrote in message

news:3A2EFF34.DF64081D@creditview.no...
Quote
> Yes, but I would like that TMessage &Message is a parameter to the
FOnEraseBkGnd
> so that anyone can respond on the return value.

The only data that WM_ERASEBKGND provides is the HDC being erased.  Is that
what you want to provide?  If so, you can do this:

class TCustPanel :public TPanel
{
protected:
    typedef void __fastcall (__closure *TEraseEvent)(TObject *Sender, HDC
hDc, bool &AllowOSControl);
    TEraseEvent FOnEraseBkGnd;
    void __fastcall WMEraseBkGnd(TMessage &Message);
public:
    BEGIN_MESSAGE_MAP
        MESSAGE_HANDLER(WM_ERASEBKGND, TMessage, WMEraseBkGnd)
    END_MESSAGE_MAP(TPanel)
__published:
    __property TEraseEvent OnEraseBkGnd =
{read=FOnEraseBkGnd,write=FOnEraseBkGnd};

Quote
};

void __fastcall TCustPanel::WMEraseBkGnd(TMessage &Message)
{
    bool bOSControl = true;
    if(FOnEraseBkGnd)
        FOnEraseBkGnd(this, (HDC)Message.WParam, bOSControl);

    Message.Result = (int)(!bOSControl);

Quote
}

The event handler for the OnEraseBkGnd event created with the Object
Inspector would then look something like this:
void __fastcall TForm1::CustPanel1EraseBkGnd(TObject *Sender, HDC hDh, bool
&AllowOSControl)
{
    // user code here to handle the event

    // set AllowOSControl = true to allow the OS to continue
    // handling the WM_ERASEBKGND normally

    // set AllowOSControl = false to prevent the OS from
    // continued handling of the WM_ERASEBKGND

Quote
}

This provides the user with easy access to the HDC from the WM_ERASEBKGND
message, and also provides that the user can set in the event handler
whether the system will continue doing the erasing or not.

Quote
> How can I change the TNotify FOnEraseBkGnd so that the parameter is
TMessage
> instead of TObject?

The TObject is a standard for all VCL component events to have, it points to
the component triggering the event.  However you can add additional
parameters, see above for how that's done.

Gambit

Re:Window Message into object inspector


What do you mean?

Gambit

Quote
"James Williams" <j...@creditview.no> wrote in message

news:3A2EFD7F.41A98E0D@creditview.no...
Quote
> Why does borland add this to the standard events.

Re:Window Message into object inspector


Quote
> So presumably if your Event is assigned, you would set Message.Result
> to nonzero to prevent the OS from erasing the background.

This is a worry! It's kind of a fundamental design principal of all the VCL
components that all events act merely as notifications, and that the
behaviour of the thing shouldn't change merely because you assign an event.
But I can't think of a nice way to respect that principle in this case.
--
Lucian

Other Threads