Site icon Embarcadero RAD Studio, Delphi, & C++Builder Blogs

The VCL LockDrawing method in TWinControl

vcl110 lockdrawing text

One of the features added to the VCL library in Delphi 11 is the ability to handle Windows WM_SETREDRAW message easily with two specific methods added to the TWinControl class: LockDrawing and UnlockDrawing


I was going over my to do list earlier this week and found a not that indicated I should follow up to the blog post I did on new VCL features in Delphi and C++Builder 11 about LockDrawing. In fact I wrote: “The base TWinControl class now offers LockDrawing and UnlockDrawing methods, to disable and control updating. This triggers the execution of the WM_SETREDRAW Windows message. This is probably worth its own blog post…” but than I totally forgot about this. So here is the blog post, with a few months delay.

Let’s start from the Windows API. The message WM_SETREDRAW is send to a window to “allow changes in that window to be redrawn, or to prevent changes in that window from being redrawn.” Any time you need to perform a set of operations, each requiring to repaint, you can put them on hold and repaint only at the end, avoiding flickering and making the process faster. It is of course important to remove the lock and than call a special function to force repaint (RedrawWindow).

All of this is properly encapsulated in two TWinControl methods added to the VCL library in RAD Studio 11, LockDrawing and UnlockDrawing, which send the WM_SETREDRAW message with proper parameters. They also implement a “lock count logic” so that if you lock the same control twice, you need to unlock it twice to resume painting. Additionally, the UnlockDrawing automatically calls the RedrawWindow API.

Having said this, which are the use cases? I wrote a demo showing two scenarios, and you can also check this nice blog post by Radek Cervinka.

A first case in my demo is adding a bunch of elements to a list box. While Delphi traditionally offered and still has the ability to avoid repainting by “freezing” the string list update, it does make sense to lock the UI repaint instead. These are the two alternative coding styles:
[crayon-6768051e8d70b876835631/]
In both cases the performance is much higher (and visible noticeable) than without one of the two solutions. Another scenario is that of a set of changes to a component causing a repaint. This is not trivial to simulate in a simple example, but one way to to cause flicker “on purpose” with code like this:
[crayon-6768051e8d715795772233/]
I know, this is fairly stupid, but you can see there is no flicker with the Lock/Unlock calls, while the effect look quite horrible without locking the UI. Not that I can easily render this in a screenshot, but here is the form at runtime anyway:

PS: It is worth pointing out that one of the reason we added these methods was to use them in the RAD Studio IDE code, to improve the performance and reduce flickering.

Exit mobile version