Log On
Embarcadero Home
Watch, Follow, &
Connect with Us
Share This
QualityCentral
Communities
Articles
Blogs
Resources
Downloads
Help
QualityCentral
Delphi-BCB
VCL
8-Byte Alignment
Action Classes
Additional Controls
Core VCL Classes
DFM to TEXT
Dialog Controls
Docking
Drag/Drop
Emulation Classes
Exceptions
Gestures
Graphics
MAPI Support
MDI Support
Multi-Monitor Support
OnGesture event
Printing
Property/Type Editors
Registry / INI Objects
Ribbon Controls
Sample Controls
Services
Standard Controls
Styles
System Controls
Thread support
Touch Controls
Type Info
Win 3.1 Controls
Win 32 Controls
You are not logged in.
Help
Print
Public Report
Report From:
Delphi-BCB/VCL/MDI Support
[ Add a report in this area ]
Report #:
2112
Status:
Need Feedback
MDIChild bug?
Project:
Delphi
Build #:
6.240 Update 2
Version:
6.0
Submitted By:
Paul Stockton
Report Type:
Basic functionality failure
Date Reported:
8/16/2002 1:45:06 AM
Severity:
Serious / Highly visible problem
Last Updated:
1/4/2008 10:46:46 AM
Platform:
All versions
Internal Tracking #:
Resolution:
Test Case Error
(Resolution Comments)
Resolved in Build:
:
None
Duplicate of:
None
Voting and Rating
Overall Rating:
(4 Total Ratings)
2.75 out of 5
Total Votes:
None
Description
I have two MDIChild forms which are identical apart from one has a TLabel on it, they are also being called in identical ways.
However, if I use the mouse to click the cancel button on the form which has the TLabel on I get an Access Violation. I don't get the Access Violation if I use the ESCAPE key, the ENTER key (when the button is selected) or Alt+C (shortcut).
I have tried replacing the TLabel with other controls and some still cause the Violation, TMenu, however the TEdit control did not.
Steps to Reproduce:
****************
Click File, Form 2.
Click Ok.
Click Cancel.
Click Cancel.
Access Violation.
Click File, Form 4.
Click Ok.
Click Cancel.
Click Cancel.
No Access Violation.
Click File, Form 2.
ENTER.
ESCAPE.
ESCAPE.
No Access Violation.
****************
Workarounds
None
Attachment
Project1.zip
Comments
Peter Morris at 8/16/2002 4:45:45 AM
-
I doubt that anyone will be able to reproduce this one.
Why not attach a demo project?
Petr Vones at 8/18/2002 10:36:04 AM
-
In TForm.OnClose event change:
Action := caFree;
and do not call Release method
Paul Stockton at 8/20/2002 3:51:11 AM
-
Thanks but we were already aware of that workaround - which changes the behaviour of the forms and doesn't give us the functionality that we require.
We would really like an explanation as to why we get this problem only on the form with the TLabel
Thanks.
Craig Stuntz at 8/19/2002 9:45:45 AM
-
Petr, you should submit this as a Workaround.
Paul Stockton at 8/22/2002 1:56:44 AM
-
Is there any way to UP the priority on this one - I really need an answer to this please :)
Kristofer Skaug at 8/22/2002 2:08:43 AM
-
I can reproduce this (D6.2 Pro, WinXP Pro).
No idea why it happens though.
Paul Stockton at 8/22/2002 3:55:33 AM
-
Thanks Kristofer, now we just need someone from Borland to explain it to us!!!
Please help Borland!!!
Joe White at 8/22/2002 8:48:28 AM
-
Well, I'm not from Borland, but I figured a few things out:
- The problem does not happen only with Form2 - I've gotten Form4 to crash as well.
- You're freeing Form2 in the middle of processing a message. That's why you're crashing.
Here's a rough outline of the sequence of events, with a lot of details left out (really):
1. User clicks bCancel. Windows sends several messages, including a WM_LBUTTONUP which, in turn, fires off a WM_COMMAND.
2. TButton processes the WM_COMMAND and ends up calling Form2.bCancelClick.
3. bCancelClick calls Close, which calls FormClose.
4. FormClose calls Release, which posts a CM_RELEASE message to the form's message queue. The form will be freed the next time Application.ProcessMessages is called.
5. FormClose then calls ShowForm2.
6. ShowForm2 calls ShowForm3.
7. ShowForm3 calls TForm3.ShowModal.
8. TForm3.ShowModal calls Application.ProcessMessages.
See the problem? When ShowModal calls ProcessMessages, TForm2's CM_RELEASE message is processed, and TForm2 is freed. But the call stack is still in the middle of a large number of nested methods of TForm2.
When TForm3.ShowModal returns, the stack steps backwards, and the TForm2 methods run to completion, which in some cases means calling other methods of Form2. But Form2 has been freed already, so those method calls are likely to generate errors - sometimes. Semi-non-deterministic; depends on exactly what sequence of events led to TForm2.FormClose being called, and what happens to get put in the slot of memory formerly occupied by Form2 after it's freed.
Moral: Use Release with care. When you have a button call Release, your button handler then needs to immediately return. Don't even think about following a call to Release with anything that could process messages.
Paul Stockton at 8/23/2002 6:28:14 AM
-
Thanks for the info. Looks like you spent quite a bit time thinking of that one. We came up with a similar idea but was wondering if anyone could explain the technical reasons why, as you seem to have.
Are you using an earlier version of Delphi? We only managed to get form4 cause the error when it is compiled in Delphi4. We just couldn't understand why it worked fine in Delphi6.
Any ideas why an extra label would cause the problem? Thanks Paul.
Joe White at 8/23/2002 8:04:31 AM
-
File | Form 2
(click OK on Form3)
File | Form 4
(click OK on Form3)
Cancel Form4 (with Form2 still open in the background)
(click OK on Form 3)
This consistently gives me an EAbstractError. Delphi 6.02, Windows XP Professional.
(Yes, an EAbstractError. Why not? The object has been freed; its VMT is pointing into never-never land.)
As for why a label would make a difference - why does it matter? You're accessing an object after it's freed. You can expect Arbitrarily Bad Things (tm) to happen as a result. Don't spend time worrying about why it crashes different ways when you do different things - just fix the code! <grin>
Paul Stockton at 8/27/2002 3:07:10 AM
-
I received this reply from one of the forums and it does work, my only problem now is I want to pass parameters to my showform events. PostMessage does allow for two integer parameters to be passed however I need to pass string variables and more than two.
I have attached a new project with this fix in.
<< in a common place, declare
<<
<< const
<< WM_SHOWFORM2 = WM_USER + $0001;
<<
<< In main form, declare
<<
<< procedure WMShowForm2( var Msg: TMessage ); message WM_SHOWFORM2;
<<
<< as
<<
<< ShowForm2
<<
<< In TForm2.OnClose do
<<
<< If FormStyle = fsMDIChild then
<< begin
<< Action := caFree;
<< PostMessage( Application.MainForm.Handle, WM_SHOWFORM2, 0, 0 );
<< end;
View Your Reports
Search
Server Response from: ETNACODE01
Developer Tools
Blackfish SQL
C++Builder
Delphi
FireMonkey
Prism
InterBase
JBuilder
J Optimizer
HTML5 Builder
3rdRail & TurboRuby
Database Tools
Change Manager
DBArtisan
DB Optimizer
ER/Studio
Performance Center
Rapid SQL
Technical Articles
Tutorials
White Papers
Press Releases
Newsletters
Add Content (GetPublished)
Audio
Audio & Video
Video
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Tags
Technology Partners
Downloads
Free Trials
Registered User Downloads
Beta Programs
Add Content (GetPublished)
Articles
Blogs
Bugs & Suggestions (QualityCentral)
Discussion Forums
Examples (CodeCentral)
Member Services
About
Connect with Us