hmm...yes i belive it is.
the "Owner" property is used for garbage disposal in BCB; but that's WAAAY up in the inheritance tree, so anything used in that function should be totally initialized at that point.
anyway, i changed it to memo=new TLabel, and it still occurred.
i wrapped all the new systemMessage statements with try/catch blocks, where the catch just retries to instatntiate the message, and it's working pretty well. i've gotten a lot of messages displayed with no problems.
here's the complete code. if someone sees something, please let me know!
Code:
//---------------------------------------------------------------------------
#ifndef SystemMessageScreenH
#define SystemMessageScreenH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Controls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
//---------------------------------------------------------------------------
class TSystemMessageScreen;
class systemMessage : public TPanel
{
protected:
TLabel *memo;
bool READ;
TSystemMessageScreen *owner;
String __fastcall gettime()
{
String timeString;
TDateTime timeStamp = Now();
DateTimeToString(timeString,"yyyy-mm-dd hh:nn:ss.zz",timeStamp);
return timeString;
}
__property String timeStamp={read=gettime};
public:
__property bool read={read=READ};
__fastcall systemMessage(TSystemMessageScreen *Owner,String msg);
};
class urgentMessage : public systemMessage
{
protected:
virtual void __fastcall acknowledgeClick(TObject *Sender);
public:
__fastcall urgentMessage(TSystemMessageScreen *Owner,String msg);
};
class warningMessage : public urgentMessage
{
public:
__fastcall warningMessage(TSystemMessageScreen *Owner,String msg);
};
class alarmMessage : public urgentMessage
{
public:
__fastcall alarmMessage(TSystemMessageScreen *Owner,String msg);
};
class PACKAGE TSystemMessageScreen : public TScrollBox
{
private:
DynamicArray<systemMessage *>messages;
unsigned int UNREAD;
protected:
public:
__fastcall TSystemMessageScreen(TComponent* Owner);
__property unsigned int unread={read=UNREAD};
void __fastcall ShowMessage(String msg);
void __fastcall ShowWarning(String msg);
void __fastcall ShowAlarm(String msg);
void __fastcall setAcknowledged(systemMessage *msg);
__published:
};
//---------------------------------------------------------------------------
#endif
Code:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "SystemMessageScreen.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(TSystemMessageScreen *)
{
new TSystemMessageScreen(NULL);
}
//---------------------------------------------------------------------------
__fastcall TSystemMessageScreen::TSystemMessageScreen(TComponent* Owner)
: TScrollBox(Owner),
UNREAD(0)
{
AutoScroll = true;
}
//---------------------------------------------------------------------------
namespace Systemmessagescreen
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TSystemMessageScreen)};
RegisterComponents("custom", classes, 0);
}
}
//---------------------------------------------------------------------------
void __fastcall TSystemMessageScreen::ShowMessage(String msg)
{
try
{
systemMessage *m = new systemMessage(this,msg);
m->Align = alTop;
messages.Length++;
messages[messages.High]=m;
}
catch(...)
{
ShowMessage(msg);
}
}
void __fastcall TSystemMessageScreen::setAcknowledged(systemMessage *s)
{
UNREAD--;
}
void __fastcall TSystemMessageScreen::ShowWarning(String msg)
{
try
{
systemMessage *m = new warningMessage(this,msg);
m->Align = alTop;
messages.Length++;
messages[messages.High]=m;
UNREAD++;
}
catch(...)
{
ShowWarning(msg);
}
}
void __fastcall TSystemMessageScreen::ShowAlarm(String msg)
{
try
{
systemMessage *m = new alarmMessage(this,msg);
m->Align = alTop;
messages.Length++;
messages[messages.High]=m;
UNREAD++;
}
catch(...)
{
ShowAlarm(msg);
}
}
__fastcall systemMessage::systemMessage(TSystemMessageScreen *Owner,String msg) :
TPanel(Owner),
owner(Owner)
{
try
{
memo=new TLabel(this);
msg = timeStamp+": "+msg;
Width = Owner->Width-1;
Parent = Owner;
Align = alTop;
Height = 64;
int numchars = Width/Canvas->TextWidth("0");
TSysCharSet bchars;
bchars << '.' << '-' << ' ';
msg = WrapText(msg, "\n", bchars, numchars);
memo->Transparent = true;
memo->Parent = this;
memo->Align = alTop;
memo->Height = Height-1;
memo->Caption = msg;
}
catch(...){}
}
void __fastcall urgentMessage::acknowledgeClick(TObject *Sender)
{
READ = true;
Color = clWhite;
owner->setAcknowledged(this);
}
__fastcall urgentMessage::urgentMessage(TSystemMessageScreen *Owner,String msg) :
systemMessage(Owner,msg)
{
memo->OnClick= acknowledgeClick;
OnClick= acknowledgeClick;
}
__fastcall warningMessage::warningMessage(TSystemMessageScreen *Owner,String msg) :
urgentMessage(Owner,msg)
{
Color= clYellow;
}
__fastcall alarmMessage::alarmMessage(TSystemMessageScreen *Owner,String msg) :
urgentMessage(Owner,msg)
{
Color= clRed;
}