Hi Aurel,
The following FBSL script (and of course its equivalent in OxygenBasic if its main window
doesn't have CS_HREDRAW/CS_VREDRAW and
has WS_CLIPCHILDREN) will provide you with a GUI that's
perfectly flicker-free under XP Classic and in absolutely all modes under Vista and subsequent Windows operating systems' DWM. The only slight problem it may have is the listbox' currently highlited line under any XP theme. Unlike Vista+ DWM, the XP theme manager draws highlighted backgrounds directly on screen rather than in the backbuffer, so some faint flicker is unavoidable.
#Include <Include\Windows.inc>
#Define LST_STYLE WS_CHILD BOr WS_VISIBLE BOr WS_TABSTOP BOr LBS_NOINTEGRALHEIGHT
#Define LST_EXTSTYLE WS_EX_CLIENTEDGE
Macro ListAddString(s) = SendMessage(hList, LB_ADDSTRING, 0, s)
Macro ResizeStatusBar() = SendMessage(hStatus, WM_SIZE, 0, 0)
Macro ResizeListBox() = MoveWindow(hList, 40, 40, LoWord(CBLPARAM) - 80, HiWord(CBLPARAM) - 100, TRUE)
Type RECT: Left As Long, Top As Long, Right As Long, Bottom As Long: End Type
Dim hList, hStatus, rc As RECT
Resize(ME, 0, 0, 500, 300) ' FBSL resizes based on non-client, rather than client, area dimensions, so ...
GetClientRect(ME, @rc) ' ... get whatever client area the main window actually has into rc.Right/rc.Bottom
hList = FbslControl("ListBox", ME, "", 1000, 40, 40, rc.Right - 80, rc.Bottom - 100, LST_STYLE, LST_EXTSTYLE)
hStatus = FbslControl("MSCtls_StatusBar32", ME, "Ready...", 1001, 0, 0, 0, 0, 0, 0)
ListAddString("Some")("listbox")("strings")("added")("for")("your")("enjoyment")
Center(ME): Show(ME)
Begin Events
Select Case CBMSG
Case WM_SIZE
' NB: the order in which controls are
' resized and/or moved by MoveWindow()
' or SetWindowPos() may matter much!
ResizeListBox()
ResizeStatusBar()
End Select
End Events
The general rule here is to first, resize/reposition all manually resizable controls, and then, allow auto-resizable controls such as statusbars, toolbars and/or rebars to do their job automatically.
It should however be noted that separate calls to MoveWindow() and/or SetWindowPos() for each manually resizable control isn't the best solution. It will not be noticeable with just a couple of controls on the form, but if the number of controls is a dozen or more, you will clearly see each control crawling to its new place like a cockroach one at a time, and especially on a slow PC.
MS Windows offers a method to eliminate that unwanted behavior and resize/reposition some or all of the manually resizable controls instantaneously in one single repaint of the main window. There are three matching Win32 APIs used for that purpose: BeginDeferWindowPos(), DeferWindowPos(), and EndDeferWindowPos().
--
BeginDeferWindowPos() accepts the number of child control windows you wish to resize/reposition instantaneously, and returns a
sys hDwp handle that should be used in subsequent calls to the other APIs. Note that all child controls
must belong to a common immediate parent. If at least one has some other parent, e.g. if it is located on another form, the entire method will silently fail and all the controls will remain in their original places.
--
DeferWindowPos() accepts the hDwp handle from a previous call to BeginDeferWindowPos() or DeferWindowPos() and has the other parameters exactly like those of SetWindowPos() function. DeferWindowPos() again returns a new hDwp handle that must be used in the next function call.
--
EndDeferWindowPos() accepts the last hDwp handle returned from the last DeferWindowPos() call and actually repositions instantaneously all the controls that have just been supplied with a corresponding DeferWindowPos() call.
Pseudocode might look as follows:
' ........
Case WM_SIZE
Dim hDwp = BeginDeferWindowPos(3) ' plan to resize/move 3 child controls
hDwp = DeferWindowPos(hDwp, hCtrl1, ...) ' prepare resize/move of control #1; other params as per SetWindowPos
hDwp = DeferWindowPos(hDwp, hCtrl2, ...) ' prepare resize/move of control #2
hDwp = DeferWindowPos(hDwp, hCtrl3, ...) ' prepare resize/move of control #3
EndDeferWindowPos(hDwp) ' actually move all 3 controls instantaneously
SendMessage(hStatus, WM_SIZE, 0, 0) ' let auto-resizable controls do their job
' ........
Hope this helps.