Search code examples
listviewdelphivclrepaint

Form repaint issues after display resolution change


I have a Delphi GUI application which runs just fine, until a display resolution change automatically causes the GUI window of the program to be repainted. We can catch this display event through the WM_DISPLAYCHANGE message.

On the repaint event, it seems that some TListView components, which are hidden in that moment, are not repainted until they become visible again.

It seems that the repaint is called only on the visible components of the form, and the OS repaints the invisible items just when they become visible again.

However, this causes issues when the code references items in a TListView which, after the WM_DISPLAYCHANGE message, wasn't shown yet. The TListView should have items inside, but TListView.Items.Count returns 0, as if the TListView is empty.

After I make the TListView visible on screen, everything works again, and I can again reference the items in the TListView.

I tried to explicitly call TListView.Repaint() to update it without having to show it, but it does not work.

Is this documented behaviour?

Is there a way to repaint an invisible form component immediately, without having it to be visible on screen?


Solution

  • ListView.Items.Count returns 0 if no handle is allocated. To make it return the correct value call ListView.HandleNeeded right before.