翻阅两种表格
我只是想知道我是否做了一些可能不好的事情,尽管这对我来说似乎是一个非常实用的解决方案......
我有两种用户必须遍历的表单。用户单击按钮并弹出 form1。用户按下“确定”,然后弹出第二个。用户再次单击“确定”,屏幕就会消失。或者用户单击“重试”,屏幕将返回到第一个屏幕。两个屏幕尺寸完全不同,显示的信息也不同。
所以我想出了这段代码:
Form1 := TForm1.Create(SharedData);
Form2 := TForm2.Create(SharedData);
repeat
ModalResult := Form1.ShowModal;
if (ModalResult = mrOK) then ModalResult := Form2.ShowModal;
until (ModalResult <> mrRetry);
Form1.Release;
Form2.Release;
我已经测试了这段代码,它看起来很有魅力。在此代码中,SharedData 是一个对象,其中包含由两种表单操作的数据。我在创建两个表单之前创建此对象,当 ModalResult==mrOK 时,我将数据写回数据库。
问题是,虽然我认为这是处理两种形式之间翻转的干净解决方案,但我不记得以前见过类似的结构。当然,我是天才。 (至少,我的自我告诉我我是。)但是是否会有人反对使用这段代码,还是这样就可以了?
I am just wondering if I'm doign something that might be bad, although it seems a very practical solution to me...
I have two forms which the user will have to walk through. The user clicks on a button and form1 pops up. The user presses OK and the second one pops up. The user click OK again and the screens are gone. Or the user clicks on Retry and the screen goes back to the first one. The two screens are completely different sizes with different information.
So I came up with this code:
Form1 := TForm1.Create(SharedData);
Form2 := TForm2.Create(SharedData);
repeat
ModalResult := Form1.ShowModal;
if (ModalResult = mrOK) then ModalResult := Form2.ShowModal;
until (ModalResult <> mrRetry);
Form1.Release;
Form2.Release;
I've tested this code and it seems to work like a charm. In this code, SharedData is an object that contains data that's manipulated by both forms. I create this object before the two forms are created and when ModalResult==mrOK I just write the data back to the database.
Problem is, while I think this is a clean solution to handle flipping between two forms, I can't remember ever seeing something like this construction before. Of course, I'm a Genius. (At least, me Ego tells me I am.) But would there be something against using this piece of code or is it just fine?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果代码能够完成它应该做的事情,我认为就很好了。我之前也没有见过类似的东西,但它的作用非常明显……在我的书中,这比盲目跟随其他人的工作要好得多。 :-)
If the code does what it's supposed to, I think it's fine. I've not seen anything quite like it before either, but it's pretty obvious what it's doing... which in my book is far better than just blindly following other people's work. :-)
我没有看到代码有什么问题。然而,我确实质疑将 SharedData 传递给两种形式的构造函数。除非您重写了构造函数(也使用重新引入),否则 TForm.Create() 的参数接受所有者;该所有者负责释放其拥有的对象。由于您自己释放它们,因此无需指定所有者;只需将 nil 传递给对 Create() 的调用,以避免保存引用、在释放对象时访问拥有的对象列表以删除引用等的开销。
此外,Release 被设计为从控件本身,例如在按钮单击事件中。它确保在实际释放控件之前处理所有挂起的消息,以避免 AV。以您现在的方式使用它会再次增加不必要的开销,因为您没有在事件处理程序中使用它们。您可以安全地使用 Form1.Free;反而。
为了阐明 Release 的使用,它用于表单本身的代码中。例如,如果表单上有一个按钮,并且您希望单击该按钮来释放表单,则可以使用 Release:
这允许单击按钮来释放表单,但确保对 Close 的后续调用运行第一的。如果您使用 Free 而不是上面的 Release,您最终可能会在不存在的 Form1 上调用 Close。 (很可能它仍然没问题,因为上面的代码很愚蠢;表单仍然驻留在内存中。不过,这仍然是一个坏主意。)
I don't see anything wrong with the code. I do question, however, the passing of SharedData to the constructor of both forms. Unless you've overridden the constructor (using reintroduce as well), the argument to TForm.Create() accepts an owner; that owner is responsible for freeing the objects it owns. Since you're freeing them yourself, there's no need to assign an owner; just pass nil to the call to Create() to avoid the overhead of saving the reference, accessing the list of owned objects when one is freed to remove the reference, etc.
Also, Release is designed to be called from within the event handler of the control itself, such as in a button click event. It makes sure that all pending messages are handled before the control is actually freed, in order to avoid AVs. Using it the way you are again adds unnecessary overhead, as you're not using them inside an event handler. You can safely just use Form1.Free; instead.
To clarify use of Release, it's for use in code of the Form itself. For instance, if you have a button on the form, and you want that button's click to cause the form to be freed, you use Release:
This allows the button click to free the form, but makes sure that the subsequent call to Close runs first. If you use Free instead of Release above, you could end up calling Close on a non-existent Form1. (Chances are it would still be OK, because of the silliness of the code above; the form would still be resident in memory. Still a bad idea, though.)