为什么发生财产写错误?

时间:2015-06-01 06:56:11

标签: properties borland-c++

c ++:发生运行时错误,错误消息如下:

RevStrings1->Height of reading included in error: The property is write-protected.
RevStrings1->Height の読み込中のエラー : プロパティは書き込み禁止です.

我正在使用c ++ builder 3.

可以成功编译此源代码 设置库,包括路径等。

但是发生了运行时错误。

我猜这个问题是关于财产阅读&写。

我如何简单地解决问题?

变量RevStrings1由类TRevStrings创建。

//---------------------------------------------------------------------------
#ifndef RevStringsH
#define RevStringsH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#include <Grids.hpp>
//---------------------------------------------------------------------------
class PACKAGE TRevStrings : public TStringGrid
{
private:
//  void __fastcall SetWidth(int W);
//  int __fastcall GetWidth(void);
//  int FColCount ;
  int FRowCount;
  int FFixedCols ;
  int FFixedRows ;
  int FDefaultColWidth ;
  int FDefaultRowHeight ;
  int FHeight;
//  int FWidth;
  int FScrollBars;
  int FMaxLength;
  bool ColColors[24];

protected:
public:
    __fastcall TRevStrings(TComponent* Owner);
  void __fastcall DrawCellText(TRect ARect,int ALeft,String S);
  virtual void __fastcall DrawCell(int ACol, int ARow,const Windows::TRect &ARect, TGridDrawState AState);
  void __fastcall SetColor_Col(int Col,int Row);
  void __fastcall SetColorFlag(int Col,bool flag);
  bool __fastcall GetColorFlag(int Col);
  void __fastcall SetEditText(int ACol, int ARow,const System::AnsiString Value);
  void __fastcall Clear(bool ALLorONE,int Position);
  void __fastcall DblClick(void);
__published:
//  __property int ColCount = {read = FColCount};//FColCount};
  __property int RowCount = {read=FRowCount};
  __property int FixedCols = {read=FFixedCols};
  __property int FixedRows = {read=FFixedRows};
  __property int DefaultColWidth = {read=FDefaultColWidth};
  __property int DefaultRowHeight = {read=FDefaultRowHeight};
  __property int Height = {read=FHeight};
//  __property int Width = {read=GetWidth,write=SetWidth};
  __property int ScrollBars = {read=FScrollBars};
  __property int MaxLength = {read=FMaxLength,write=FMaxLength};
/*
*/
};
//---------------------------------------------------------------------------
#endif

2 个答案:

答案 0 :(得分:0)

之前从未听说过TRevStrings

所以它是 BCB 3 已停产的东西(我的 BDS2006 没有它可以使用)或者您安装了第3方自定义程序包但是头文件建议它基于TStringGrid,因此,如果下面的文字无效,那么您可以切换到TStringGrid

TStringGrid

中的

尺寸属性可以正常访问:

StringGrid1->Height=256;
StringGrid1->Width=128;

如果您想要具有可调整大小的col / rows,请不要忘记打开Options属性并将goRowSizing,goColSizing设置为true,并且起始大小为DefaultColWidth,DefaultRowHeight。这里是用法示例

// resize the grid
StringGrid1->Height=128;
StringGrid1->Width=256;
// access to Cell AnsiStings
StringGrid1->Cells[0][0]="(0,0)";
StringGrid1->Cells[1][1]="(1,1)";
StringGrid1->Cells[1][2]="(1,2)";
StringGrid1->Cells[2][1]="(2,1)";
// resizing row/col
StringGrid1->RowHeights[0]=15;
StringGrid1->RowHeights[1]=20;
StringGrid1->ColWidths[0]=20;
StringGrid1->ColWidths[1]=15;

由于你的课程是从这里得到的,所以如果没有更多的可能性,这也应该适用于它:

  1. 你在某处有无关的错误

    覆盖您不应该损坏正在运行的应用程序的 C ++ 引擎或者内存泄漏或内存管理器无效的内容,请参阅

    但情况可能并非如此,或者您从线程中调用 VCL / Winapi 可视内容。

  2. 检查所有这些:

    创建空应用程序,添加TRevString并尝试在运行时设置其高度。如果没有错误发生,那么如果发生错误,则会出现错误:

    1. 此组件无法在运行时以这种方式调整大小

      尝试使用SetSize,SetBounds之类的功能,或者将组件放在某个面板上与客户端对齐并调整面板

    2. 即使这样也无法切换到标准TStringGrid

      您还可以尝试先将RevString投射到StringGrid

      ((TStringGrid*)(RevString1))->Height=25;
      
    3. Borland编译器有时会变得奇怪

      多年来(我大约10年),我使用 BCB / BDS ,编译器有时会编译错误。该应用程序正在运行,但有些代码被扭曲或丢弃,所以有什么帮助呢?

      • 关闭 IDE ,甚至重新启动Windows
      • 在编译重建之前删除所有map,obj,tds临时文件
      • 有时需要添加空行代码或交换2行代码
    4. 标识符/名称冲突

      如果您以与 VCL 函数类似的方式命名您的内容,那么您会遇到问题,通常错误就是命名函数Draw() ...(而不是使用draw()很好)

    5. 适用于大型项目

      如果您将源代码作为新单元添加到项目而不是仅包含它(它存在于对象管理器中),那么在大型项目中,您将遇到大问题。看起来单位编译方式不同,然后正常包含的文件单位是期望的公式和其他 VCL 东西组件所以如果你有自己的非视觉类作为单位他们有时会停止按预期工作创建奇怪的行为(甚至你的错误可能是由它造成的。)

      我在 BCB5 BDS2006 上观察到这一点。在 BCB3,BCB4 中,我没有做足够大的项目来发现这一点, BCB6 是如此的错误所以无论如何它无法用于大型项目。通过大项目,我的意思是&gt; 1 MB纯 C ++ 代码

答案 1 :(得分:0)

错误不言自明 - Height对象的RevStrings1属性不允许分配其值。通过查看Height类中TRevStrings属性的声明,可以看出这一点:

__property int Height = {read=FHeight};

TRevStrings正在竭尽全力使Height属性成为只读,覆盖继承自的本地读写Height属性TControl

__property int Height = {read=FHeight, write=SetHeight, nodefault};

这对TRevString来说很奇怪,因为它是一个需要大小的可视组件。除非它需要用户无法更改的特定高度(在这种情况下,将Height属性声明为只读不是处理该属性的正确方法 - 组件应该覆盖虚拟SetBounds()方法而不是只需忽略分配的任何新Height值。

话虽如此,您在运行时看到错误的原因是因为IDE在编译时将Height对象的设计时RevStrings1值存储在父Form的DFM资源中时间。这就是为什么你没有在代码中找到任何RevStrings1->Height的原因 - 它来自表单设计器。 TRevStrings类不会覆盖Height属性的DFM行为,因此当VCL的DFM流式传输系统在运行时解析Form的DFM资源时,它会看到存储的Height值并检测到对象的Height属性实际上是只读的,因此抛出异常来取消DFM流(以及Form的构造)。

这是TRevStrings实施中的错误。至少,如果作者想要阻止Height进行流式传输(从而防止运行时错误),那么Height属性应该被声明为:

__property Height = {read=FHeight, stored=false};

在旁注中,TRevStrings数据成员<{1>} FColCountFRowCountFFixedColsFFixedRows ,等)永远根本没有声明,但应该从基类TStringGrid类继承。

谁写了这个组件显然不知道他们在做什么。