Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1391
  • Last Modified:

Calling DialogBox from a Thread causes crash

When I try to call up a DialogBox from a thread, it crashes
and give me this error message: Projectxxx raised exception class EOSError with message 'System Error, Code: 5. Access is denied'. Process stopped. Use Step or Run to continue.

Same thing when I try to call up a form using ShowModal (well DialogBox is practically a pre-defined Form). I'm using Delphi 6 and been stuck with this problem for a while.

Remember, this error only occur when I'm trying to call up the DialogBox from separate thread.

0
perkedel
Asked:
perkedel
  • 5
  • 4
1 Solution
 
jbshumateCommented:
You cannot directly access the VCL thread from another thread.  If all you are trying to do is bring up a dialog box you just need to create a method in your thread that creates and shows the dialog box and then call that method using the threads synchronize method.  The synchronize method runs the called method in the context of the main VCL thread.
0
 
robert_marquardtCommented:
The VCL is not thread safe. Revert to the Windows functions like MessageBox. As an added value the Windows dialog boxes have localized button texts.
0
 
perkedelAuthor Commented:
jbshumate,

Ill try that although im not sure how. Ill let you know as soon as possible.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
jbshumateCommented:
The comment about using the windows dialogs directly is accurate and will solve your immediate problem.  The approach I gave you will work more generically until you get further along in your learning curve. It's been a while, but here goes some sample code.

procedure AThread.ShowMessage(msg : string);
begin
  applicationMessageBox(msg,'Info',mbOK);
end;

procedure AThread.Execute;
begin
...
  Synchronize(ShowMessage('test'));
...
end;

thats off the top of my head so it may not be completely accurate, but it should get you started.
0
 
jbshumateCommented:
I looked back at the code and if memory  serves the method called by synchronize must not have any parameters so you would have to get the message from a static string or a variable in your thread class.

Sorry for the misdirection.
0
 
perkedelAuthor Commented:
jbshumate,

Ill try that although im not sure how. Ill let you know as soon as possible.
0
 
perkedelAuthor Commented:
jbshumate,

It doesnt raise the exception anymore when I call it up, but when I try to close the form by clicking a button in it it raised the very same error message. Is that mean I have to override the OnClose from the Form?
0
 
perkedelAuthor Commented:
jbshumate,

It doesnt raise the exception anymore when I call it up, but when I try to close the form by clicking a button in it it raised the very same error message. Is that mean I have to override the OnClose from the Form?
0
 
jbshumateCommented:
Not knowing exactly what you are doing makes this tough, but I will suggest what I think may be happening.  Are you sure that your code is not accessing anything outside of the thread once the dialog has been shown.  If some other procedure in your thread is taking the results and then modifying other forms etc. you will still have a problem.  With very few exceptions no VCL code is safe from within a thread.  The design criteria for Delphi is that the user interface is handled by the main thread and tasks that might slow the user interface are handled in threads.  If the two need to communicate with each other they must synchronize in some way.  If only data must be transfered then you can use a critical section to lock the data when it is being accessed.  This will prevent the threads from corrupting the data.  If messages  need to  be passed you have the additional, slightly more complicated, option of posting a windows  message. If all you need is very simple interaction then you can use the synchronize method I originally suggested.  If you use this method you must make sure that all of the VCL code is within your synchronized procedure.  This means that if you dynamically create a form you want to show it and then destroy it all within the synchronized method.  If your form is being automatically created by delphi then you don't have quite as much work as creation and destruction are happening in the VCL thread anyway.  You should carefully look at your thread code and make sure that you are not accessing anything related to VCL from the thread.  The compiler does not enforce or even warn you about this.  The online help topic on threads discusses much of this.
0
 
perkedelAuthor Commented:
jbshumate,

thanks for the explanation. I was trying to handle all the user input directly from the sub-thread by popping up a dialogbox/form. I think ill just post a message from the sub-thread to the main thread and let the main thread handle all the user input from the dialogbox/form.

 

0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now