Board index » cppbuilder » Custom event handler

Custom event handler


2004-09-02 06:42:58 AM
cppbuilder22
Hello, all. I am trying to develop my first component and I am trying to
figure something out. I created a MouseMove event handler for my component
(TMyComponent::MouseMove) and it works fine. I added my component to a new
project (TMyComponent *MyComponent1) and I want perform a task in the
MyComponent1MouseMove event. My problem is that the TMyComponent::MouseMove
function is executing, but the TForm1::MyComponent1MouseMove function is
not. I set the OnMouseMove event to MouseMove for the MyComponent1
instance, but it still only calls the component handler, not the custom
handler. Why won't it call my custom handler? Actually, I will need both
functions to execute. Will I need to explicitly call
TMyComponent::MouseMove() from within the TForm1::MyComponent1MouseMove
function to get both to execute? Any feedback will be greatly appreciated.
Thanks,
Mark
 
 

Re:Custom event handler

"Mark Atkin" < XXXX@XXXXX.COM >wrote in message
Quote
My problem is that the TMyComponent::MouseMove function is
executing, but the TForm1::MyComponent1MouseMove function
is not.
Please show your actual code. Did you call the inherited MouseMove()?
Quote
I set the OnMouseMove event to MouseMove for the
MyComponent1 instance
That sounds suspiciously wrong, but I cannot be sure without seeing your
actual code first.
Gambit
 

Re:Custom event handler

Ok. In my original message, I changed the names to protect the innocent.
Here is a trimmed down version that I tested and has the same behavior. To
test it, I created a new project, added a TStatusBar and added two panels to
it. I then pasted the contents below into the corresponding files.
Remember, this is my first attempt at designing a component, so be gentle.
I want to have TForm1::Grid1MouseMove() to execute, but it isn't.
Thanks,
Mark
== Unit1.cpp file: ===================================================
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma link "Grid"
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Grid1 = new TGrid(this);
Grid1->Parent = this;
Grid1->Top = 10;
Grid1->Left = 10;
Grid1->OnMouseMove = Grid1MouseMove;
}
void __fastcall TForm1::Grid1MouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
StatusBar1->Panels->Items[0]->Text = Grid1->HighlightedRow;
StatusBar1->Panels->Items[1]->Text = Grid1->HighlightedCol;
}
== Unit1.h file: =====================================================
#ifndef Unit1H
#define Unit1H
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "Grid.h"
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
class TForm1 : public TForm
{
__published: // IDE-managed Components
TStatusBar *StatusBar1;
private: // User declarations
public: // User declarations
TGrid *Grid1;
__fastcall TForm1(TComponent* Owner);
void __fastcall Grid1MouseMove(TObject *Sender, TShiftState Shift,
int X, int Y);
};
extern PACKAGE TForm1 *Form1;
#endif
== Grid.cpp file: ================================================
#include <vcl.h>
#pragma hdrstop
#include "Grid.h"
#pragma package(smart_init)
static inline void ValidCtrCheck(TGrid *)
{
new TGrid(NULL);
}
namespace Grid
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TGrid)};
RegisterComponents("Samples", classes, 0);
}
}
__fastcall TGrid::TGrid(TComponent* Owner)
: TPaintBox(Owner)
{
BlockSize = 25;
Cols = 10;
Rows = 10;
Width = BlockSize * Cols + 2;
Height = BlockSize * Rows + 2;
HighlightedCol = -1;
HighlightedRow = -1;
}
void __fastcall TGrid::Paint(void)
{
int col, row;
Canvas->MoveTo(0, 0);
Canvas->LineTo(Width - 1, 0);
Canvas->LineTo(Width - 1, Height - 1);
Canvas->LineTo(0, Height - 1);
Canvas->LineTo(0, 0);
for(col = 0; col < Cols; col++)
{
for(row = 0; row < Rows; row++)
{
DrawCell(col, row);
}
}
}
void __fastcall TGrid::DrawCell(int col, int row)
{
Canvas->MoveTo(BlockSize * col + 1, BlockSize * row + 1);
Canvas->LineTo(BlockSize * (col + 1), BlockSize * row + 1);
Canvas->LineTo(BlockSize * (col + 1), BlockSize * (row + 1));
Canvas->LineTo(BlockSize * col + 1, BlockSize * (row + 1));
Canvas->LineTo(BlockSize * col + 1, BlockSize * row + 1);
}
void __fastcall TGrid::SetBlockSize(int Value)
{
FBlockSize = Value < 10 ? 10 : Value;
Width = FBlockSize * Cols + 2;
Height = FBlockSize * Rows + 2;
Update();
}
void __fastcall TGrid::SetCols(int Value)
{
FCols = Value;
Width = BlockSize * Value + 2;
Update();
}
void __fastcall TGrid::SetRows(int Value)
{
FRows = Value;
Height = BlockSize * Value + 2;
Update();
}
void __fastcall TGrid::MouseMove(Classes::TShiftState Shift, int X, int Y)
{
int old_col = HighlightedCol;
int old_row = HighlightedRow;
bool refresh = false;
if(old_col != X / BlockSize)
{
HighlightedCol = X / BlockSize;
refresh = true;
}
if(old_row != Y / BlockSize)
{
HighlightedRow = Y / BlockSize;
refresh = true;
}
if(refresh)
{
UpdateSelections(HighlightedCol, HighlightedRow);
UpdateSelections(old_col, old_row);
}
}
void __fastcall TGrid::UpdateSelections(int col, int row)
{
if(col == HighlightedCol && row == HighlightedRow)
{
Canvas->Pen->Color = clYellow;
DrawCell(col, row);
Canvas->Pen->Color = clBlack;
}
else
{
DrawCell(col, row);
}
}
== Grid.h file: ================================================
#ifndef GridH
#define GridH
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Controls.hpp>
#include <ExtCtrls.hpp>
class PACKAGE TGrid : public TPaintBox
{
private:
int FBlockSize;
int FCols;
int FRows;
int FHighlightedCol;
int FHighlightedRow;
void __fastcall SetBlockSize(int Value);
void __fastcall SetCols(int Value);
void __fastcall SetRows(int Value);
void __fastcall UpdateSelections(int col, int row);
DYNAMIC void __fastcall MouseMove(Classes::TShiftState Shift,
int X, int Y);
protected:
public:
void __fastcall Paint(void);
void __fastcall DrawCell(int col, int row);
__fastcall TGrid(TComponent* Owner);
__published:
__property int BlockSize = {read=FBlockSize, write=SetBlockSize};
__property int Cols = {read=FCols, write=SetCols};
__property int Rows = {read=FRows, write=SetRows};
__property int HighlightedCol = {read=FHighlightedCol,
write=FHighlightedCol};
__property int HighlightedRow = {read=FHighlightedRow,
write=FHighlightedRow};
__property OnMouseMove;
};
#endif
 

{smallsort}

Re:Custom event handler

"Mark Atkin" < XXXX@XXXXX.COM >wrote in message
Quote
I want to have TForm1::Grid1MouseMove() to execute, but it isn't.
As I suspected, you did not call the inherited MouseMove() from your own.
void __fastcall TGrid::MouseMove(Classes::TShiftState Shift, int X, int
Y)
{
//...
TPaintBox::MouseMove(Shift, X, Y);
//...
}
Gambit
 

Re:Custom event handler

"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote

As I suspected, you did not call the inherited MouseMove() from your own.

void __fastcall TGrid::MouseMove(Classes::TShiftState Shift, int X,
int
Y)
{
//...
TPaintBox::MouseMove(Shift, X, Y);
//...
}

I added this line to the TGrid::MouseMove function and that didn't help.
TGrid is derived from TPaintBox, so TPaintBox is the base class. I want to
override the TGrid::MouseMove function (and then call the default
TGrid::MouseMove function from the overriding function). As an analogy, if
I needed to define a MouseMove function for say a TPanel contained in a form
Form1, I write the function TForm1::Panel1MouseMove and inside that
function, if I needed to, I would call the base function TPanel::MouseMove.
Isn't that correct? I'm sorry if I am way off in left field. The whole VCL
programming environment is still a little new to me. Trying to actually
write my own component may be biting off a little more than I can chew.
Applying my analogy to the current code, I want to have
TForm1::Grid1MouseMove perform some tasks and then call TGrid::MouseMove (or
call TGrid::MouseMove first; I don't think it will matter which one executes
first).
 

Re:Custom event handler

"Mark Atkin" < XXXX@XXXXX.COM >wrote in message
Quote
I added this line to the TGrid::MouseMove function
and that didn't help.
Then you are not using it properly.
Quote
TGrid is derived from TPaintBox, so TPaintBox is the
base class. I want to override the TGrid::MouseMove
function (and then call the default TGrid::MouseMove
function from the overriding function).
That is exactly what I just showed you how to do.
Quote
As an analogy, if I needed to define a MouseMove function
for say a TPanel contained in a form Form1, I write the
function TForm1::Panel1MouseMove and inside that function,
if I needed to, I would call the base function TPanel::MouseMove.
Isn't that correct?
No, it is not correct.
Quote
Applying my analogy to the current code, I want to have
TForm1::Grid1MouseMove perform some tasks and then
call TGrid::MouseMove
It cannot. What you have to do is make TGrid::MouseMove() call the
inherited MouseMove() to trigger the native OnMouseMove event, and then
TGrid::MouseMove() can continue on its way after the event handler returns.
In other words:
void __fastcall TGrid::MouseMove(TShiftState Shift, int X, int Y)
{
// call the OnMouseMove event handler...
TPaintBox::MouseMove(Shift, X, Y);
// your other operations here...
}
Gambit
 

Re:Custom event handler

Thanks, Gambit. It works now. I don't know what I was doing wrong last
night, but I tried it again this morning, and it works fine. Thanks, for
your help.
Mark