Block ProcessMessages (possible at all?)

I need a modal dialog and I want no messages to be processed until the dialog has been closed. As a matter of course I want to close it but I don't know how to do it without processing messages. Tricky, isn't it? Up to 500 points available!
LVL 2
__alexAsked:
Who is Participating?
 
Wim ten BrinkSelf-employed developerCommented:
Forget it. If you block processing all messages, the dialog will be dead. It needs to process messages or else it won't notice the user pressing the close button. (Or typing some key or whatever.) Besides, if you're not calling your dialog from the VCL then whatever process is handling messages is just outside your reach.

The only trick could be if you create your dialog from a resource dialog (create *.rc and compile to *.res) and build a separate thread with it's internal message handler. Then, when your dialog is called, you suspend the main thread until your own thread receives a message that it's closed. After which you resume the main thread, of course.
Very complex API stuff, though...

What exactly are you trying, btw?
0
 
__alexAuthor Commented:
Oops, forgot to mention: I want to call it from a non VCL thread.
0
 
__alexAuthor Commented:
> What exactly are you trying, btw?
Debugging of course. If an exception is risen in a constructor and the destructor is not able to handle non initialized members it will raise another exception and the first exception is gone. Thus I need a dialog that will show up whether the first exception is handled or not. Since the dialog is to be modal to prevent further user interaction the exception can't be handled until the dialog is closed. If my application is still processing messages some more exceptions might occur and my screen is going to be covered with dialogs which is not exactly what I want to have.
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
BlackTigerXCommented:
the preferred way to debug that kind of thing is to use simple log files

you write everything that would normally go to a dialog box to a file and there you have all the information without having to close a million windows
0
 
Wim ten BrinkSelf-employed developerCommented:
I agree with BlackTigerX. Use a log file and write exceptions to this log file. It's a proven technology that I've been using for years now. Especially useful when you also include timestamps in your logfile.

I have a simple DLL with special unit at http://www.workshop-alex.org/Sources/debug/debug.zip which is quite useful for this. All you need to do is compile the debug.dpr into a DLL file, then include untDebug.pas (and intTextfile.pas) in your project. It introduces two textfile types. One is called Log and the other is called Debug. Now, if you build your project, put the debug.dll in the same folder as your binary executable. Then, if you run your project, it will generate two files called Project1.log and Project1.debug. (Or whatever else you called your project.) The debug file includes timestamps for EVERY line, so it's pretty useful with timing issues, although it isn't very accurate. (It can be several milliseconds off.)
Now, in my exception handlers, I always have something like this:

uses untDebug;
...
try
  // Do something crashy...
except on E:Exception do WriteLn(Log, E.Message);
end;

And voila, one log file with the exceptions generated by your code.

Give the same binary to someone else without the debug.dll file and a miracle happens. They DON'T get any log files...
And if need be, just view those log files while the application is running. They've been especially created to support being viewed by other applications while the application is still running.

Now, other techniques for capturing exceptions is e.g by overriding the method:
  function SafeCallException( ExceptObject: TObject; ExceptAddr: Pointer ): HResult; override;
Which handles all exceptions that happen in a routine that is declared as safecall. Don't forget to call "Result := inherited SafeCallException( ExceptObject, ExceptAddr );" so the rest of the system will also handle the error once you're done with it.

I could also mention the MadExcept components from http://www.madshi.net but hey, who doesn't know these excellent exception handling components? ;-)

Keep It Simple, S*****! :-)
0
 
Lee_NoverCommented:
:)
I use JclDebug for exception tracking and log those to a file in the way I like it :)
.. and back to the topic .. hook the ExceptProc and use MessageBox api .. no messages will be processed until that box is closed .. and the calling thread is suspended :)
0
 
__alexAuthor Commented:
Unfortunately writing to disk is not an option. My application runs in a helicopter thus hard disc access is to be minimized to avoid damage.

@Lee
I made a tiny test app. A timer, a label and a button. In the timer event I change the caption of the label to see if messages get processed (WM_TIMER). In the OnClick event of the button I open a message box (MessageBox() in Windows.pas) but the caption is still changing. Maybe I got you wrong?
0
 
Wim ten BrinkSelf-employed developerCommented:
Writing to a log file is only required while you're testing the software, which is why I suggested my debug DLL as solution. If the DLL is in the same folder as the application, it will write log information. Remove the DLL and absolutely nothing is written to disk! (My untDebug will just discard whatever you write to it in that case.)

MessageBox won't stop any messages from being triggered or handled. It relies on those handles by itself. As I said, the only option I see is by suspending the main thread after you capture an exception, with a dialog that runs in a separate thread (message-handler in separate thread) that will start the main thread again once the messagebox is closed. But you will need a messagehandler in a separate thread otherwise the messagebox freezes with the rest of your application.

To freeze the main thread, you can use the Windows event API. CloseHandle(), CreateEvent(), PulseEvent(), ResetEvent(), SetEvent(), WaitForSingleObject() are the API functions you would need for it. You create an event and in the main thread use WaitForSingleObject() for it to wait for infinite time until the event is triggered. The other thread should display the messagebox before the main thread starts waiting and with it's own messageloop it should wait for the user to close the messagebox again. On close, it sets the event, which triggers the main thread and forces it to start running again.
0
 
__alexAuthor Commented:
Ok, I'll go for the cascading dialogs. Thanks to all!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.