How to prevent processes in Delphi

The Application.ProcessMessages command is well known, and I use it in long processes to ensure that my program will not bind the computer.

But I have a pretty fast processing suite where I buffer the view to a file. During the buffering procedure, several system messages can be sent (for example, redrawing or moving scrollbars or other events). I want them not to be processed by ProcessMessages until my buffering is complete.

Is there any way:

  • Prevent Application.ProcessMessages before completing my procedure or

  • Trap all messages generated during my procedure and do not release them until the end of the procedure.

+4
source share
4 answers

Allowing ProcessMessages to continue, even if it sends messages that you do not want, should not be classified as problematic. With a bit of code refactoring, you can move the buffering method to a separate thread and go from there.

If you are trying to copy the “visual content” of a control to a file,

  • see the WM_PRINT (xxx) message, which allows child controls to draw in bitmaps
  • try calling the LockWindowUpdate Win32 API method, which will turn off all coloring messages to this control
  • override the WndProc / DefaultWndProc in your control class or even the parent class if you need and simply return "true" for each message sent.
  • override certain control methods (such as "moving the scroll bar", " OnPaint ", " OnPaintBackground ", etc.) in the control class or even the parent object and just do nothing if your buffering is done.

Overriding WndProc or DefaultWndProc and just returning true for each message is essentially “disabled” by ProcessMessages , but this is not safe for this, because management may require processing one or more messages to work correctly.

Disabling ProcessMessages not possible (without overwriting the VCL code for message processing) because it is part of how the VCL form message loop was configured.

+5
source

Trap all messages generated during my procedure and do not release them until the end of the procedure.

There is a dirty hack you can do (only if you cannot find a better way):

You can watch (capture) any messages using Win32 Hooks .
In particular, use SetWindowsHookEx with WH_CALLWNDPROC as the idHook value.
You can then write them to a list / queue and resubmit them whenever you want.

+2
source

I found out again in Windows 2 that Windows messages will occur sometimes when you do not expect them. Any part of the library can lead to the processing of messages in your application. Instead of holding back the flow, make your code resilient to the situation. It can be as simple as using a BeginUpdate / EndUpdate pair or more complex (using a temporary and final update at the end).

+1
source

At the pedantic level, the way you “prevent” Application.ProcessMessages is not to call code that

  • shows modal dialogue
  • calls sendMessage
  • starts its own local message loop
  • calls Application.ProcessMessages (which is the outline of the local message)

If you write a loop that does nothing but numerical calculations and file I / O, your user interface will be frozen until you exit the loop because no messages are processed.

If you want your user interface to react during a long run of unknown arbitrary code (third-party library), but you do not want certain actions to appear in your application during this time, another problem arises - what about preventing repeated participation. You want some parts of your code not to be used during a specific action. For example, modal dialogs prohibit you from interacting with application windows under the dialog, disabling all top-level windows of the application except the modal dialog itself.

0
source

All Articles