Discussion:
What is wrong with this code?
(too old to reply)
Zahir Saleh
2008-06-23 07:22:30 UTC
Permalink
Hello,
I had earlier inquired about exe icon disapering when i usen my personal component. Here is the code for the component. Please assist....note: I am not very familiar with component creation...

//---------------------------------------------------------------------------

#ifndef ToggleSwitchH
#define ToggleSwitchH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------


class PACKAGE TToggleSwitch : public TCustomPanel
{
enum TStates { stOn,stOff };
typedef void __fastcall (__closure *TMyClick)(TObject *Sender, TStates State);

private:
TMyClick FOnMyClick;
TStates FState;
TColor FColorOff;
TColor FColorOn;
String FDeviceName;
void __fastcall SetState(TStates Value);
void __fastcall SetOffColor(TColor Value);
void __fastcall SetOnColor(TColor Value);
void __fastcall SetDeviceName(String Value);

protected:
DYNAMIC void __fastcall DblClick();
void __fastcall RaiseClickEvent(TObject* Sender);
void __fastcall Resized(TObject *Sender);
void __fastcall TabClick(TObject *Sender);
void __fastcall ToggleState();
TButton *SwitchPanel;
void __fastcall Paint();

public:
__fastcall TToggleSwitch(TComponent* Owner);
__fastcall ~TToggleSwitch();

__published:
__property TMyClick OnStateChange = {read=FOnMyClick, write=FOnMyClick};
__property Font;
__property TStates State = {read=FState, write=SetState, default = stOn};
__property TColor OffColor = {read=FColorOff, write=SetOffColor,default = clRed};
__property TColor OnColor = {read=FColorOn, write=SetOnColor,default = clLime};
__property String DeviceName= {read=FDeviceName, write=SetDeviceName, nodefault};

};
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
//=========the header file .h ends here================
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <ToggleSwitch.h>
#pragma package(smart_init)
#pragma resource "ToggleSwitch.res"
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TToggleSwitch *)
{
new TToggleSwitch(NULL);
}
//---------------------------------------------------------------------------
__fastcall TToggleSwitch::TToggleSwitch(TComponent* Owner)
: TCustomPanel(Owner)
{
SwitchPanel = new TButton(this);
SwitchPanel->Parent = this;
SwitchPanel->Caption = "ON";
SwitchPanel->OnClick = RaiseClickEvent;//;OnDblClick;
SwitchPanel->Font->Size = 8;
SwitchPanel->Font->Pitch = fpFixed;
SwitchPanel->Font->Style = TFontStyles()<< fsBold;
//-------------------------

FColorOff = clRed;
FColorOn = clLime;
Color = clLime;
BevelInner = bvLowered;
BevelOuter = bvNone;
FState = stOn;
Width = 28;
Height = 49;
Caption = " ";
SwitchPanel->Width = Width;
OnResize = Resized;
}
//---------------------------------------------------------------------------
__fastcall TToggleSwitch::~TToggleSwitch()
{
}
//---------------------------------------------------------------------------
namespace Toggleswitch
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TToggleSwitch)};
RegisterComponents("Jillion", classes, 0);
}
}
//---------------------------------------------------------------------------
void __fastcall TToggleSwitch::DblClick()
{
ToggleState();
if( FOnMyClick )
FOnMyClick(this, FState);
}

//---------------------------------------------------------------------------

void __fastcall TToggleSwitch::RaiseClickEvent(TObject* Sender)
{
ToggleState();
if( FOnMyClick )
FOnMyClick(this, FState);
}
//----------------------------------------------------------------------------

void __fastcall TToggleSwitch::ToggleState()
{
FState = !FState;
Invalidate(); // repaints the component
}
//---------------------------------------------------------------------------

void __fastcall TToggleSwitch::SetState(TStates Value)
{
FState = Value;
Invalidate(); // repaints the component
}
//---------------------------------------------------------------------------
void __fastcall TToggleSwitch::Paint()
{
TabClick(NULL);
}
//---------------------------------------------------------------------------

void __fastcall TToggleSwitch::TabClick(TObject *Sender)
{
switch(FState)
{

case stOn:
{
SwitchPanel->Top = Height-SwitchPanel->Height;
SwitchPanel->Caption = "OFF";
Color = FColorOff;
}
break;
case stOff:
{
SwitchPanel->Top = 0;
SwitchPanel->Caption = "ON";
Color = FColorOn;
}
break;
default:
break;
}
Caption = FDeviceName;
}
//---------------------------------------------------------------------------
void __fastcall TToggleSwitch::SetOffColor(TColor Value)
{
FColorOff = Value;
Invalidate(); // repaints the component
}
//---------------------------------------------------------------------------
void __fastcall TToggleSwitch::SetOnColor(TColor Value)
{
FColorOn = Value;
Invalidate(); // repaints the component
}
//---------------------------------------------------------------------------
void __fastcall TToggleSwitch::Resized(TObject *Sender)
{
SwitchPanel->Width = Width;
}
//---------------------------------------------------------------------------
void __fastcall TToggleSwitch::SetDeviceName(String Value)
{
FDeviceName = Value;
Invalidate(); // repaints the component
}
//---------------------------------------------------------------------------
Remy Lebeau (TeamB)
2008-06-23 16:56:07 UTC
Permalink
Post by Zahir Saleh
I had earlier inquired about exe icon disapering when i usen
my personal component. Here is the code for the component.
Please assist....note: I am not very familiar with component creation...
There is nothing in your code that can be effecting the icons.

There are other bugs in your code, though.
Post by Zahir Saleh
enum TStates { stOn,stOff };
typedef void __fastcall (__closure *TMyClick)(TObject *Sender, TStates State);
Those should be declared outside the class.
Post by Zahir Saleh
OnResize = Resized;
A component should NEVER assign handlers to its own events like that. It
prevents the user from assigning their own handlers. You should be
overriding the virtual Resize() method instead:

protected
DYNAMIC void __fastcall Resize();

void __fastcall TToggleSwitch::Resize()
{
SwitchPanel->Width = Width;
TCustomPanel::Resize(); // fire user's OnResize handler
}
Post by Zahir Saleh
void __fastcall TToggleSwitch::SetState(TStates Value)
{
FState = Value;
Invalidate(); // repaints the component
}
In general, you should always make sure the input value is actually a
different value than the class member before performing any update
operations, ie:

void __fastcall TToggleSwitch::SetState(TStates Value)
{
if( FState != Value )
{
FState = Value;
Invalidate(); // repaints the component
}
}
Post by Zahir Saleh
void __fastcall TToggleSwitch::Paint()
{
TabClick(NULL);
}
That is a bad place to call that. Paint() is called every time the
component is re-drawn onscreen. Paint() should only be performing drawing
operations and nothing else. DO NOT manipulate controls or properties
inside of Paint(). The way you have the code set up, you will be calling
Invalidate() indefinately, causing bad flicker for the lifetime of your
component.


Gambit
Zahir Saleh
2008-06-24 05:45:46 UTC
Permalink
Post by Remy Lebeau (TeamB)
There is nothing in your code that can be effecting the icons.
There are other bugs in your code, though.
Post by Zahir Saleh
void __fastcall TToggleSwitch::Paint()
{
TabClick(NULL);
}
That is a bad place to call that. Paint() is called every >time the .......
Thanks alot for the corrections, I implemented them, the display doesnt flicker any more.
But, the .exe icon still disapears! and I and sure it is related to this component because if I remove it from the form and its header file, the .exe icon appears.... something is a mess somewhere...
Zahir Saleh
2008-06-24 13:08:18 UTC
Permalink
OK gentlemen, I found the problem. I am surpposed to use "ToggleSwitch.DCR" and not "ToggleSwitch.RES" for the icon resource....thats what was causing the trouble.
Remy, thanks a lot, my component works better after all the bugs you ironed out!
Continue reading on narkive:
Loading...