Second question, how do I go about freeing the memory used by the TButtons? If I execute the code within the ATTEMPT_TO_FREE_BUTTONS block, the code gets an invalid pointer exception error on the indicated line. If I don't try to free the memory then the buttons will still be on the screen after pressing the Clear button and then, on pressing the Add button again, all buttons will still be there.
Code: Select all
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#define ATTEMPT_TO_FREE_BUTTONS
#include "Unit1.h"
#include "RichView.hpp"
#include "RVStyle.hpp"
#include "RVTable.hpp"
#include "RVScroll.hpp"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "RichView"
#pragma link "RVScroll"
#pragma link "RVStyle"
#pragma link "RVEdit"
#pragma resource "*.dfm"
TcurrRichViewEdit *currRichViewEdit;
int docCount=0;
//---------------------------------------------------------------------------
__fastcall TcurrRichViewEdit::TcurrRichViewEdit(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TcurrRichViewEdit::OnButtonAClick(TObject *Sender) {
TButton * btn = (TButton *) Sender;
ShowMessage("Hi from Button " + btn->Name + ", Event A" );
btn->Visible = false;
}
void __fastcall TcurrRichViewEdit::OnButtonBClick(TObject *Sender) {
TButton * btn = (TButton *) Sender;
ShowMessage("Hi from Button B");
}
int GetParaNoWithLeftMargin(TRVStyle* rvs, TRVStyleLength LeftIndent)
{
TParaInfo* ParaStyle = new TParaInfo(NULL);
ParaStyle ->Assign(rvs->ParaStyles->Items[0]);
ParaStyle ->LeftIndent = LeftIndent;
int r = rvs->FindParaStyle(ParaStyle);
delete ParaStyle;
return r;
}
//---------------------------------------------------------------------------
void __fastcall TcurrRichViewEdit::btnAddClick(TObject *Sender)
{
TRVTableItemInfo *table;
TRVTableCellData * Cell;
TButton *btn;
int paraNo;
for (int j = 0; j < 100; j++) {
rv->AddCheckpoint("Chk" + UnicodeString(++docCount), true);
for (int i = 0; i < 5; i++) {
table = new TRVTableItemInfo(1, 3 + i, rv->RVData);
paraNo = GetParaNoWithLeftMargin(rv->Style, 40 * i);
table->ParaNo = paraNo;
Cell = table->Cells[0][0];
Cell->Clear();
Cell->AddNL("Hi from cell 1", 0, 0);
table->SetCellTag(UnicodeString(i), 0, 0);
Cell = table->Cells[0][2];
Cell->Clear();
Cell->AddNL("Hi from cell 3", 0, 0);
Cell = table->Cells[0][i+2];
Cell->Clear();
Cell->AddNL("Hi from last cell. I am writing this from the last cell", 0, 0);
rv->AddItem("Row_" + UnicodeString(j*5+i) , table);
free(table);
btn = new TButton((TComponent*) NULL); // Note: keyword NEW used here
btn->Name = "Btn" + UnicodeString(i);
switch (i % 2) {
case 0:
btn->OnClick = OnButtonAClick;
btn->Caption = "A button";
btn->Name = "btnA" + UnicodeString(i);
break;
case 1:
btn->OnClick = OnButtonBClick;
btn->Caption = "B button";
btn->Name = "btnB" + UnicodeString(i);
break;
}
rv->AddControl("Btn_" + UnicodeString(j*5 + i), btn, paraNo, rvvaAbsMiddle);
// free(btn); // Can't free the button or removes the instance I just set up
rv->FormatTail();
}
}
rv->ScrollTo(0);
}
//---------------------------------------------------------------------------
void __fastcall TcurrRichViewEdit::btnClearClick(TObject *Sender)
{
TButton *btn;
TCustomRVItemInfo *item;
#ifdef ATTEMPT_TO_FREE_BUTTONS
for (int i = 0; i < rv->ControlCount; i++) {
item = rv->GetItem(i);
if (item->ItemText.SubString(1,4) == "Btn_") {
free(item);
}
}
#endif
rv->ClearAll(); // Doesn't seem to clear the buttons
rv->FormatAll(); // First chance exception at $75083442. Exception class EInvalidPointer with message 'Invalid pointer operation'. Process Project1.exe (23160) //
}
//---------------------------------------------------------------------------