Solved

Block ProcessMessages (possible at all?)

Posted on 2004-10-04
9
146 Views
Last Modified: 2010-04-05
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!
0
Comment
Question by:__alex
9 Comments
 
LVL 2

Author Comment

by:__alex
ID: 12216270
Oops, forgot to mention: I want to call it from a non VCL thread.
0
 
LVL 17

Accepted Solution

by:
Wim ten Brink earned 100 total points
ID: 12216860
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
 
LVL 2

Author Comment

by:__alex
ID: 12217154
> 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
Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

 
LVL 13

Assisted Solution

by:BlackTigerX
BlackTigerX earned 100 total points
ID: 12217912
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
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12218452
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
 
LVL 12

Assisted Solution

by:Lee_Nover
Lee_Nover earned 100 total points
ID: 12219202
:)
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
 
LVL 2

Author Comment

by:__alex
ID: 12224523
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
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12228207
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
 
LVL 2

Author Comment

by:__alex
ID: 12235277
Ok, I'll go for the cascading dialogs. Thanks to all!
0

Featured Post

ScreenConnect 6.0 Free Trial

Discover new time-saving features in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question