HI, not my code but i found it almost by accident so i thought i would share it.
when updating a listbox on windows you get the flickering as it redraws.
conventional wisdom is to make it invisible before the load then make it visible afterwards.
if you add this to a module
Sub LockWindow(hw as integer)
#if TargetWin32 Then
Declare Sub LockWindowUpdate Lib "user32" (ByVal hWnd As Integer)
LockWindowUpdate hw
#endif
End Sub
you can then do :-
lockwindow listbox.handle
load your data
lockwindow 0
this doesn’t make it invisible but it stops it being updated so no flicker
which is clever enough, but i also discovered that if you need to popup a control over your listbox (or i guess any other control)
you can use it to stop the flickering effect.
i have a listbox subclass that has lookup columns which display another listbox subclass and this effect has worked really well
anyways, maybe you knew all about it, but if not, enjoy!
I wish to experiment with this method to solve some flicker problem.
There is one drawback on using this method: you can only lock one window at time.
Or, perhaps, you can lock more than one, but when you unlock, I think the behavior its not defined. It will probably unlock all locked windows.
yes, it only locks a single window, but for me that is enough
it seems designed to allow drag and drop to not be affected by controls beneath the drag,
i’m not using it as intended, but it seems to work great for me in this scenario.
…“The purpose of the LockWindowUpdate function is to permit drag/drop feedback to be drawn over a window without interference from the window itself. The intent is that the window is locked when feedback is drawn and unlocked when feedback is complete. LockWindowUpdate is not intended for general-purpose suppression of window redraw. Use the WM_SETREDRAW message to disable redrawing of a particular window.”…
If anyone gets around to implementing the “WM_SETREDRAW” I would love to do some further testing with it. I mostly only have flickering problems when resizing a window or scrolling content.
Sub AllowRedraw(extends w as Window, allow as Boolean = true)
#if targetWin32
If allow then
const WM_SETREDRAW = &h000B
declare sub SendMessage lib "User32" alias "SendMessageW" (hwnd As integer, msg As integer, wParam As Boolean, lParam as Integer)
' SendMessage((HWND) hWnd, WM_SETREDRAW, (WPARAM) wParam, (LPARAM) lParam);
SendMessage(w.handle, WM_SETREDRAW, true, 0)
w.Refresh
else
const WM_SETREDRAW = &h000B
declare sub SendMessage lib "User32" alias "SendMessageW" (hwnd As integer, msg As integer, wParam As Boolean, lParam as Integer)
' SendMessage( (HWND) hWnd, WM_SETREDRAW, (WPARAM) wParam,(LPARAM) lParam);
SendMessage(w.handle, WM_SETREDRAW, false, 0)
end
#endif
End Sub
Here’s a condensed version of what Massimo wrote. It does it in one method:
Simply call:
myWindow.AllowRedraw(false)
//Flickering stuff here
myWindow.AllowRedraw(true)
I also included a w.Refresh when you turn on allowRedraw, I don’t know if this will suffice for RedrawWindow command or not - Anyone know?
btw this is in the pro channel because thats where I’ve been asking questions about the listbox lately, i agree it would benefit all windows users, maybe it can be moved to the windows channel?
Sub AllowRedraw(extends w as Window, allow as Boolean = true)
#if targetWin32
const WM_SETREDRAW = &h000B
declare sub SendMessage lib "User32" alias "SendMessageW" (hwnd As integer, msg As integer, wParam As Boolean, lParam as Integer)
If allow then
SendMessage(w.handle, WM_SETREDRAW, true, 0)
w.Refresh
else
SendMessage(w.handle, WM_SETREDRAW, false, 0)
end
#endif
end Sub