Alien_SM
asked on
CBuilder 5 messages and custom components
Hi i need to access the CM_MOUSEENTER and CM_MOUSELEAVE messages in this cusomised button.
The idea is to change the glyph of the button as you move your mouse ovvr the button.
This is some of the basic code so far but it doesn't work. It is suppose to change the caption of the button it self.
Can anybody help ?
========================== ========== =======
.h file:
========================== ========== =======
//------------------------ ---------- ---------- ---------- ---------- ---------- -
#ifndef UltBitBtnH
#define UltBitBtnH
//------------------------ ---------- ---------- ---------- ---------- ---------- -
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <Buttons.hpp>
#include <StdCtrls.hpp>
//------------------------ ---------- ---------- ---------- ---------- ---------- -
class PACKAGE TUltBitBtn : public TBitBtn
{
private:
Graphics::TBitmap* FOffGlyph;
Graphics::TBitmap* FOnGlyph;
MESSAGE void __fastcall CMMouseEnter(Messages::TWM Mouse &Message);
MESSAGE void __fastcall CMMouseLeave(Messages::TWM Mouse &Message);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(CM_MOUSEEN TER, TWMMouse, CMMouseEnter)
MESSAGE_HANDLER(CM_MOUSELE AVE, TWMMouse, CMMouseLeave)
END_MESSAGE_MAP(TControl)
protected:
public:
__fastcall TUltBitBtn(TComponent* Owner);
__fastcall ~TUltBitBtn();
__published:
};
//------------------------ ---------- ---------- ---------- ---------- ---------- -
#endif
========================== ========== =======
.cpp file:
========================== ========== =======
//------------------------ ---------- ---------- ---------- ---------- ---------- -
#include <vcl.h>
#pragma hdrstop
#include "UltBitBtn.h"
#pragma package(smart_init)
//------------------------ ---------- ---------- ---------- ---------- ---------- -
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TUltBitBtn *)
{
new TUltBitBtn(NULL);
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
__fastcall TUltBitBtn::TUltBitBtn(TCo mponent* Owner)
: TBitBtn(Owner)
{
FOffGlyph = new Graphics::TBitmap();
FOnGlyph = new Graphics::TBitmap();
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
__fastcall TUltBitBtn::~TUltBitBtn()
{
delete FOffGlyph;
delete FOnGlyph;
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
namespace Ultbitbtn
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TUltBitBtn)};
RegisterComponents("Own", classes, 0);
}
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
// Message handlers
MESSAGE void __fastcall TUltBitBtn::CMMouseEnter(M essages::T WMMouse &Message)
{
Caption = "Enter";
Invalidate();
}
MESSAGE void __fastcall TUltBitBtn::CMMouseLeave(M essages::T WMMouse &Message)
{
Caption = "Leave";
Invalidate();
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
The idea is to change the glyph of the button as you move your mouse ovvr the button.
This is some of the basic code so far but it doesn't work. It is suppose to change the caption of the button it self.
Can anybody help ?
==========================
.h file:
==========================
//------------------------
#ifndef UltBitBtnH
#define UltBitBtnH
//------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <Buttons.hpp>
#include <StdCtrls.hpp>
//------------------------
class PACKAGE TUltBitBtn : public TBitBtn
{
private:
Graphics::TBitmap* FOffGlyph;
Graphics::TBitmap* FOnGlyph;
MESSAGE void __fastcall CMMouseEnter(Messages::TWM
MESSAGE void __fastcall CMMouseLeave(Messages::TWM
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(CM_MOUSEEN
MESSAGE_HANDLER(CM_MOUSELE
END_MESSAGE_MAP(TControl)
protected:
public:
__fastcall TUltBitBtn(TComponent* Owner);
__fastcall ~TUltBitBtn();
__published:
};
//------------------------
#endif
==========================
.cpp file:
==========================
//------------------------
#include <vcl.h>
#pragma hdrstop
#include "UltBitBtn.h"
#pragma package(smart_init)
//------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TUltBitBtn *)
{
new TUltBitBtn(NULL);
}
//------------------------
__fastcall TUltBitBtn::TUltBitBtn(TCo
: TBitBtn(Owner)
{
FOffGlyph = new Graphics::TBitmap();
FOnGlyph = new Graphics::TBitmap();
}
//------------------------
__fastcall TUltBitBtn::~TUltBitBtn()
{
delete FOffGlyph;
delete FOnGlyph;
}
//------------------------
namespace Ultbitbtn
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TUltBitBtn)};
RegisterComponents("Own", classes, 0);
}
}
//------------------------
// Message handlers
MESSAGE void __fastcall TUltBitBtn::CMMouseEnter(M
{
Caption = "Enter";
Invalidate();
}
MESSAGE void __fastcall TUltBitBtn::CMMouseLeave(M
{
Caption = "Leave";
Invalidate();
}
//------------------------
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
It is very strange, next code i get from
some project (not mine!):
//in header...
Controls::TWndMethod OldBitBtnWP;
void __fastcall NewBitBtnWP(TMessage &Msg);
//in source...
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
//subclass the BitBtn
OldBitBtnWP = BitBtn1->WindowProc;
BitBtn1->WindowProc = NewBitBtnWP;
}
void __fastcall TForm1::NewBitBtnWP(TMessa ge &Msg)
{
if (Msg.Msg == CM_MOUSELEAVE)
BitBtn1->Glyph = Image1->Picture->Bitmap;
if (Msg.Msg == CM_MOUSEENTER)
BitBtn1->Glyph = Image2->Picture->Bitmap;
OldBitBtnWP(Msg);
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
//restore the BitBtn's original window procedure
BitBtn1->WindowProc = OldBitBtnWP;
}
It is very close to my code!
If it is not helps, reject my reply.
Alex
some project (not mine!):
//in header...
Controls::TWndMethod OldBitBtnWP;
void __fastcall NewBitBtnWP(TMessage &Msg);
//in source...
__fastcall TForm1::TForm1(TComponent*
: TForm(Owner)
{
//subclass the BitBtn
OldBitBtnWP = BitBtn1->WindowProc;
BitBtn1->WindowProc = NewBitBtnWP;
}
void __fastcall TForm1::NewBitBtnWP(TMessa
{
if (Msg.Msg == CM_MOUSELEAVE)
BitBtn1->Glyph = Image1->Picture->Bitmap;
if (Msg.Msg == CM_MOUSEENTER)
BitBtn1->Glyph = Image2->Picture->Bitmap;
OldBitBtnWP(Msg);
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
//restore the BitBtn's original window procedure
BitBtn1->WindowProc = OldBitBtnWP;
}
It is very close to my code!
If it is not helps, reject my reply.
Alex
hi Alien_SM
The TBitBtn has no CM_MOUSEENTER,CM_MOUSELEAV E messages, why TSpeedButton has the two messages,you can see the source code of Delphi's code of TSpeedButton and you will know why.
procedure TSpeedButton.UpdateTrackin g;
var
P: TPoint;
begin
if FFlat then
begin
if Enabled then
begin
GetCursorPos(P);
FMouseInControl := not (FindDragTarget(P, True) = Self);
if FMouseInControl then
Perform(CM_MOUSELEAVE, 0, 0)
else
Perform(CM_MOUSEENTER, 0, 0);
end;
end;
end;
Good Luck!
shenqw
The TBitBtn has no CM_MOUSEENTER,CM_MOUSELEAV
procedure TSpeedButton.UpdateTrackin
var
P: TPoint;
begin
if FFlat then
begin
if Enabled then
begin
GetCursorPos(P);
FMouseInControl := not (FindDragTarget(P, True) = Self);
if FMouseInControl then
Perform(CM_MOUSELEAVE, 0, 0)
else
Perform(CM_MOUSEENTER, 0, 0);
end;
end;
end;
Good Luck!
shenqw
Sorry, I'am wrong! :(
In D5,I had test your code ,it works fine. I'll try in BCB later. Sorry!
In D5,I had test your code ,it works fine. I'll try in BCB later. Sorry!
ASKER
The tihing is Alec i tried the last code you posted exactly like you showed me and for some reson it didn't work.
here is the code
========================== =========
header
========================== =========
class PACKAGE TUltBitBtn : public TSpeedButton
{
private:
Graphics::TBitmap* FOffGlyph;
Graphics::TBitmap* FOnGlyph;
Controls::TWndMethod OldWinProc;
void __fastcall NewWinProc(TMessage &Msg);
protected:
public:
__fastcall TUltBitBtn(TComponent* Owner);
__fastcall ~TUltBitBtn();
__published:
};
========================== =========
cpp file
========================== =========
static inline void ValidCtrCheck(TUltBitBtn *)
{
new TUltBitBtn(NULL);
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
__fastcall TUltBitBtn::TUltBitBtn(TCo mponent* Owner)
: TSpeedButton(Owner)
{
FOffGlyph = new Graphics::TBitmap();
FOnGlyph = new Graphics::TBitmap();
OldWinProc = WindowProc;
WindowProc = NewWinProc;
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
__fastcall TUltBitBtn::~TUltBitBtn()
{
delete FOffGlyph;
delete FOnGlyph;
WindowProc = OldWinProc;
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
namespace Ultbitbtn
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TUltBitBtn)};
RegisterComponents("Own", classes, 0);
}
}
//------------------------ ---------- ---------- ---------- ---------- ---------- -
// Message handlers
void __fastcall TUltBitBtn::NewWinProc(TMe ssage &Msg)
{
switch (Msg.Msg)
{
case CM_MOUSEENTER:
{
// mouse cursor has entered control
MessageDlg("Enter", mtInformation , TMsgDlgButtons() << mbYes , 0);
break;
}
case CM_MOUSELEAVE:
{
// mouse cursor has left control
MessageDlg("Leave", mtInformation , TMsgDlgButtons() << mbYes , 0);
break;
}
case WM_DESTROY:
{
WindowProc = OldWinProc;
break;
}
}
OldWinProc(Msg);
}
========================== =========
========================== =========
now like i said this code works fine with Tspeedbutton and i can see why also . But why can't it work with Tbitbtn
here is the code
==========================
header
==========================
class PACKAGE TUltBitBtn : public TSpeedButton
{
private:
Graphics::TBitmap* FOffGlyph;
Graphics::TBitmap* FOnGlyph;
Controls::TWndMethod OldWinProc;
void __fastcall NewWinProc(TMessage &Msg);
protected:
public:
__fastcall TUltBitBtn(TComponent* Owner);
__fastcall ~TUltBitBtn();
__published:
};
==========================
cpp file
==========================
static inline void ValidCtrCheck(TUltBitBtn *)
{
new TUltBitBtn(NULL);
}
//------------------------
__fastcall TUltBitBtn::TUltBitBtn(TCo
: TSpeedButton(Owner)
{
FOffGlyph = new Graphics::TBitmap();
FOnGlyph = new Graphics::TBitmap();
OldWinProc = WindowProc;
WindowProc = NewWinProc;
}
//------------------------
__fastcall TUltBitBtn::~TUltBitBtn()
{
delete FOffGlyph;
delete FOnGlyph;
WindowProc = OldWinProc;
}
//------------------------
namespace Ultbitbtn
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TUltBitBtn)};
RegisterComponents("Own", classes, 0);
}
}
//------------------------
// Message handlers
void __fastcall TUltBitBtn::NewWinProc(TMe
{
switch (Msg.Msg)
{
case CM_MOUSEENTER:
{
// mouse cursor has entered control
MessageDlg("Enter", mtInformation , TMsgDlgButtons() << mbYes , 0);
break;
}
case CM_MOUSELEAVE:
{
// mouse cursor has left control
MessageDlg("Leave", mtInformation , TMsgDlgButtons() << mbYes , 0);
break;
}
case WM_DESTROY:
{
WindowProc = OldWinProc;
break;
}
}
OldWinProc(Msg);
}
==========================
==========================
now like i said this code works fine with Tspeedbutton and i can see why also . But why can't it work with Tbitbtn
Sorry, i have'n idea, why it is not work.
hi Alien_SM
I had tried in BCB5, Your code also works fine. but there maybe a bug.when i add my component into the package dclusr50.bpk,It doesn't work(I mean that when i run the app,it raise a exception before the mainform be shown).
So i put it in my own package,It works.
Oh,My god,BCB5. :(
I had tried in BCB5, Your code also works fine. but there maybe a bug.when i add my component into the package dclusr50.bpk,It doesn't work(I mean that when i run the app,it raise a exception before the mainform be shown).
So i put it in my own package,It works.
Oh,My god,BCB5. :(
ASKER
Tnks for the help Alex
As I said I got the stuph to work with a speedbutton as an ansestor ill try again l8r with a bitbtn.
As I said I got the stuph to work with a speedbutton as an ansestor ill try again l8r with a bitbtn.
ASKER
I tried what you suggested an ovverided wndproc and also the method you posted but nothing.
I then went and inherited from a TSpeedButton and that worked fine.
Why can't i use TBitBtn ?? I thought maybee only Components that inherits from TGraphicControl can fire CM_MOUSELEAVE and CM_MOUSEENTER.
any idea cause i need this to work with TBitBtn ??