动态控件的删除,急!!!

fidt982 2004-12-23 09:03:39
我编了一段程序,当鼠标单击时,在单击的地方动态创建一个EDIT,然后输完字符后回车或者这个控件失去焦点清时,在EDIT的位置又动态生成LABEL控件,而且删除掉刚才动态生成的EDIT控件,可为什么下面这段代码在,,,在动态生成的EDIT里面回车就会报错,说什么地址越界,可当它失去焦点时却又没有错了。哪位大哥帮帮忙啊,代码如下
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TForm1::PaintBox1MouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
TEdit *newTempStr;
newTempStr=new TEdit(this);
newTempStr->Parent=Form1;
newTempStr->Left=X+this->PaintBox1->Left;
newTempStr->Top=Y+this->PaintBox1->Top;
newTempStr->Font->Size=25;
newTempStr->AutoSize=true;
newTempStr->BorderStyle=bsNone;
newTempStr->SetFocus();
newTempStr->OnKeyPress=TempEditKeyPress;
newTempStr->OnExit=TempEditLoseFocus;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TempEditLoseFocus(TObject *Sender)
{

TEdit *newEdit;
newEdit=(TEdit *)Sender;
if(newEdit->Text.IsEmpty())
{
delete newEdit;
newEdit=NULL;
return;
}
TLabel *newLabStr;
newLabStr=new TLabel(this);
newLabStr->Parent=Form1;
newLabStr->Left=newEdit->Left;
newLabStr->Top=newEdit->Top;
newLabStr->Font->Size=newEdit->Font->Size;
newLabStr->AutoSize=true;
newLabStr->Transparent=true;
newLabStr->Caption=newEdit->Text;
delete newEdit;
newEdit=NULL;

}
//---------------------------------------------------------------------------


void __fastcall TForm1::TempEditKeyPress(TObject *Sender, char &Key)
{
if(Key=='\r')
{
TempEditLoseFocus(Sender);
}

}
...全文
261 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
fidt982 2004-12-31
  • 打赏
  • 举报
回复
只有先结帖了,,还是没有找到问题在哪.:(
庄鱼 2004-12-24
  • 打赏
  • 举报
回复
方法很多:
简单的,有设定静态计数变量,然后命名控件的方法,这样,你可以随时对不用的控件进行删除;
你也可以将某类动态控件的Tag属性赋予不同的数值,将不需要的赋值为-1,编一个回收函数,将所有Tag为-1的控件删除;
也可用容器管理的方法,将当前容器里非活动的控件删除;
还有就是在Form的释放函数里手工用delete删除。
不要过于相信系统会自动帮你回收由new生成的控件,手工new的控件一定要记着用手工的方式回收,这是一个好习惯。
有哥 2004-12-24
  • 打赏
  • 举报
回复
应该就是成员函数删除对象自身引起的错误了。
最好就不动态创建这个Edit,而是一开始就放在窗体上隐藏着,需要时把它在鼠标位置上显示出来,焦点离开后隐藏,同时在相同的位置一个同样大小的Label。这样也可以减少点new、delete它时的系统消耗。
有哥 2004-12-23
  • 打赏
  • 举报
回复
delete newEdit;
newEdit=NULL;
我想后面这句是多余的。
samchoy 2004-12-23
  • 打赏
  • 举报
回复
我想应该是因为:

void __fastcall TForm1::TempEditKeyPress(TObject *Sender, char &Key)
{
if(Key=='\r')
{
TempEditLoseFocus(Sender); // TempEdit已经被删除了,因此函数返回后会出错
}

}

改成这样看看

void __fastcall TForm1::TempEditKeyPress(TObject *Sender, char &Key)
{
if(Key=='\r')
{
SelectNext((TWinControl *)Sender, true, true);
}

}

其实你也不用动态创建,只要在同一个地方放置一个TEdit和一个TLabel,动态切换它们的Enabled及Visible状态就可以达到你的要求了。
fidt982 2004-12-23
  • 打赏
  • 举报
回复
顶啊
fidt982 2004-12-23
  • 打赏
  • 举报
回复
acneyouth(豆子)
newEdit=NULL是为了防止newEdit变成野指针,使newEdit指向空,问题不会出现在这里,,这也是经常的用法,

fidt982 2004-12-23
  • 打赏
  • 举报
回复
再TO chiengod(钱神爷)
不好意思,,我看错了,我在程序确实没有delete newLabStr,,但是这跟程序出错会有问题么,还有我顺便的问一下,如果我在程序中不DELETE 掉动态创建的控件的话,会对整个程序有什么影响?
fidt982 2004-12-23
  • 打赏
  • 举报
回复
TO futulove(福途£爱)
我跟踪了,但是却也看不出问题在哪,,报错为MESSAGE: Acess violation address 00000012,read of address 00000012, 还有你说的什么隐藏啊,不懂了,

TO chiengod(钱神爷)
newLabStr 和后面的newEdit 不是指向同一个地方的么,这就是我所有的代码了,我没有在其它的地方再进行删除了,

两位回复得好快啊,,有人帮忙感觉真好,呵呵,
对了,我发现更有趣的是也不是每次都会报错,是时不时的,
chiengod 2004-12-23
  • 打赏
  • 举报
回复
有没有delete newLabStr呀
futulove 2004-12-23
  • 打赏
  • 举报
回复
你最好跟一下我想就能看出来了
可能 是你崇山删除EDIT时出的错误,
可以隐藏试试
白水山路 2004-12-23
  • 打赏
  • 举报
回复
留个脚印!
oldtab 2004-12-23
  • 打赏
  • 举报
回复
按 samchoy() 说得,重写吧。
还可以写成,TEdit和TLabel 一大一小。动态改变大小啊。
acneyouth 2004-12-23
  • 打赏
  • 举报
回复
自己delete自己不是不可以,不过以前好象看过,是有些讲究的。
delete newEdit使newEdit已经被删除,TempEditLoseFocus(TObject *Sender)过程自然也就不存在了,但TempEditLoseFocus(TObject *Sender)过程还有一句newEdit=NULL没有执行完,错误可能就在这里,把两个newEdit=NULL去掉试试。
oldtab 2004-12-23
  • 打赏
  • 举报
回复
to fidt982
我错了。

另外“如果我在程序中不DELETE 掉动态创建的控件的话”,结束时,CB自己会删除。
我记得Parent就是为这个目的而设的。
fidt982 2004-12-23
  • 打赏
  • 举报
回复
TO oldtab(汇铁)
加不加那句else 无所谓吧,,newTempStr为空时程序走到if 语句里面,,到return 就返回了,跟后面没关系了,,
而且现在当newTempStr不为空也会报错了,
会不会是错在这里,在tempedit事件里面删除自己时会报错,
oldtab 2004-12-23
  • 打赏
  • 举报
回复
void __fastcall TForm1::TempEditLoseFocus(TObject *Sender)
{
TEdit *newEdit;
newEdit=(TEdit *)Sender;
if(newEdit->Text.IsEmpty())
{
delete newEdit;
newEdit=NULL; //可无可有
return;
}
else //加这一句
{
TLabel *newLabStr;
newLabStr=new TLabel(this);
newLabStr->Parent=Form1;
newLabStr->Left=newEdit->Left;
newLabStr->Top=newEdit->Top;
newLabStr->Font->Size=newEdit->Font->Size;
newLabStr->AutoSize=true;
newLabStr->Transparent=true;
newLabStr->Caption=newEdit->Text;
delete newEdit;
newEdit=NULL;
}
}
不加,则newTempStr空时回车,必错。
newEdit已经删除。后边却用到它的属性值。
fidt982 2004-12-23
  • 打赏
  • 举报
回复
TO samchoy() 我把程序改成你的那个样子,还是会报错,不过你说的另外一个方法到不错。
1.兼容msi,自动高亮目标程序,实时生成脚本 2.可导入其他非i-Autoit创建的Au3脚本并编译为EXE 3.自动读取安装程序图标,编译时也可以选择其他图标 4.可自定义编译EXE版本信息 5.支持组件多控件选择(例如标准树形treeviw、列表listview控件)、文本edit控件修改文本(例如安装路径、序列号输入) 6.新增隐藏自动安装模式,不过尚未完美 7.模式切换分为控件模式和鼠标位置模式,切换快捷键和暂停捕捉快捷键均可自定义设置 8.可自定义是否在控件点击时左上角提示相关信息 9.可自定义运行脚本是否需要托盘提示目前代码行数和对应代码 10.其他功能(打包、删除文件,添加、删除启动项,查杀进程和随机窗口)可方便生成相应代码并可一键复制 日后根据反馈陆续推出动画教程,暂时补个简单文字教程: 1.将目标程序拖到“安装程序”的文本框,点击运行 2.程序启动并高亮置顶,此时别太,尤其是那些需要释放文件的程序,稍等片刻再开始按照正常安装步骤点击相应按钮 3.如果需要修改安装路径或输入注册码,请在第1步前将路径复制好,然后单击文本框,会弹出一个提示框,输入需要修改的路径即可 4.检测到点击其他控件(标准树形treeviw、列表listview控件)会自动转换成相对位置点击 5.某些控件如果发现不支持或者控件结构非常复杂,可以尝试切换为鼠标模式用相对位置模拟点击 6.如果需要关闭进程或者窗口之类的,可以在“其他功能”里面的选项使用对应功能生成代码并一键复制后转到“安装脚本”选择合适位置右键选择粘贴代码即可 7.测试代码:在“安装脚本”界面右键选择“测试代码”即可生成临时测试程序并运行 8.编译代码:选择图标或保留源程序图标后再自定义版本信息(也可不定义)编译即可,在目标程序同目录下生成安装脚本程序 9.导入脚本:将目标脚本拖入“运行编译”的“安装脚本”右侧文本框,点击导入即可 10.隐藏安装模式:部分软件无法兼容,还需继续更新完善,有兴趣的可以自行测试

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧