Vista & WinBlitz3D - clipping region problem?!Blitz3D Forums/Blitz3D Userlibs/Vista & WinBlitz3D - clipping region problem?!
| I use WinBlitz3D to create a windowed application showing a 3D scene; sometimes after I display a floating window (eg. some requester) and then close it - my 3D viewport only renders & updates *inside* the (screen) area that was previously occupied by that floating window!|
The surrounding screen area is totally ignored and not 'repainted' - but inside the area I can move my pointer, draw 2D graphics, animate/drag 3D objects around, etc. everything is rendered & shown perfectly fine; but 'only' within that area!
This remains until I do something "drastically" such as move or re-size the application window, switching to another application, or do some other heavy GUI related stuff (eg. open/close another panels, windows or requesters). Sometimes a keystroke is enough to have my runtime viewport be restored to what it should be, but not always.
This only happens on Vista/Windows7, and is extremely difficult to reproduce. It happens (too) often, but not always and behaves very different per computer - and even per boot! Aero / desktop composition does seem to affect this - but not always, so disabling Aero is not the solution either. Besides making me look like a fool - this is a total show stopper ! :((
Having only limited knowledge of the win32api internals, I'm guessing that some clipping-region remains set at the position+size of the last shown (floating) window, in stead of restoring it back to the full-size of the main app window. I've tried tons of crazy stuff to try and force the main window to repaint correctly again but to no avail :(
Has anyone experienced something similar - or might have an idea how to conquer this problem??
FWIW, these are the styles I use on the main application/runtime window:
WS_CAPTION Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX Or WS_SYSMENU Or WS_THICKFRAME Or WS_CLIPCHILDREN Or WS_CLIPSIBLINGS
These are the styles I use on floating windows:
WS_CHILD or WS_VISIBLE or WS_CAPTION Or WS_POPUP Or WS_SYSMENU
WS_EX_TOOLWINDOW or WS_EX_DLGMODALFRAME
Any help greatly appreciated !!!
| Hi Danny, ive not loooked at the code for some time, i will pull it out later today and see about a fix.|
| That would be amazing Kev, thanks in advance! |
| Hi Kev, just wondering if you had any time or luck with this one?|
| Does anyone else have an idea how I can force the Blitz's runtime-window to repaint fully - as opposed to only a portion of it?|
I'm really desperate to get this showstopper out of the way!
Thanks in advance,
| Ok, I found out the problem is actually easier to reproduce than I thought it would be..|
Check this little program and play with the DOWITHFLIP value at the start. Obviously, this requires WB3D, and you should be able to see the repaint problem manifest in TWO different ways!
Const DOWITHFLIP = True ; TRUE > First the screen will refresh as normal. But after moving or closing the floating window, ; the main window will only redraw where the floating window has been!!! ; ; FALSE > the main window will redraw -even though NO flip statement is given!- when you MOVE the floating window; ; with Aero enabled: it will redraw the enture screen ; with Aero disabled: it will redraw only the rectangle underneath the floating window (or where it has just been) ;init Graphics3D 800,600,0,3 SetBuffer BackBuffer() Cls ;init WinBlitz3D runtimewindow win1 = WB3D_InitializeGUI(SystemProperty("AppHwnd"),133,154,640,480) WB3D_SetGadgetText win1, "A Window" win2 = WB3D_CreateWindow("Move me around the background..",300,200,200,100,win1,-2133917696) but1 = WB3D_CreateButton("Clear BG", 50,20,100,22,win2,0) WB3D_ShowGadget win1 If DOWITHFLIP Then WB3D_SetGadgetText win2, "Close me!" ;main loop While Not KeyDown(1) ;button clears screen If (WB3D_WaitEvent() = $401) And (WB3D_EventSource() = but1) Cls Flip EndIf ;draw random ovals Color Rand(255),Rand(255),Rand(255) w = WB3D_GadgetWidth(win1) h = WB3D_GadgetHeight(win1) Oval Rand(w),Rand(h), Rand(200),Rand(200),Rand(1) ;!! If DOWITHFLIP Then Flip Wend ;release & exit WB3D_EndGUI() EndGraphics() End
Note that the behavior is very system dependent, but it should behave like this on most Vista & Windows7 installations if I'm not mistaken..
The first problem is the one I experienced most often (with Flip ON) and this is what I've tried to describe in my initial post. I'm looking for a method to kick it back into repainting the entire screen - as opposed to only the small area the floating window has just been...
I've had "luck" with some solutions in some cases (forcing a resize event), but for some reason these don't always work :(
| Any solution for this problem ?|
I have a similar problem, see : http://www.blitzbasic.com/Community/posts.php?topic=104741
| Hi RemiD,|
I haven't Read this entire thread, but it sounds like a nightmare I had a long time back... I found two rough hacks, that seem To force a window into repainting it.
NOTE: This is Not just a Vista problem! It can happen in any windows version - depending on ... many things. Hope these hacks help:
Call them when e.g. you regain focus To your app.
Function WB3D_WindowRepaint(win) ; ensure window hasn't been closed in the meanwhile (X button) If Not WB3D_GadgetExists(win) Then Return If Not WB3D_WindowMaximized(win) x = WB3D_GadgetX(win) y = WB3D_GadgetY(win) w = WB3D_GadgetWidth(win) h = WB3D_GadgetHeight(win) If y >= 0 Then WB3D_SetGadgetShape(win,x,y,w,h) EndIf End Function
This one is 'more robust' but also produces a visible flicker (!) so I only use this one when e.g. After the window is resized, returning from hibernation, alt-tab, etc.
Const RDW_INVALIDATE = $0001 Const RDW_INTERNALPAINT = $0002 Const RDW_ERASE = $0004 Const RDW_VALIDATE = $0008 Const RDW_NOINTERNALPAINT = $0010 Const RDW_NOERASE = $0020 Const RDW_NOCHILDREN = $0040 Const RDW_ALLCHILDREN = $0080 Const RDW_UPDATENOW = $0100 Const RDW_ERASENOW = $0200 Const RDW_FRAME = $0400 Const RDW_NOFRAME = $0800 Function WB3D_WindowEraseAndRepaint(win) ; msdn: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162911%28v=vs.85%29.aspx ; forum: http://www.blitzbasic.com/Community/posts.php?topic=32334 ; will cause a flicker! so don't use often! only on e.g. resized windows! ;#>> Might Mav on Vista ?? check MSDN links above! ; ensure window hasn't been closed in the meanwhile (X button) If Not WB3D_GadgetExists(win) Then Return api_InvalidateRect(win, 0, 0) api_RedrawWindow(win, 0,0, RDW_INVALIDATE +RDW_ALLCHILDREN +RDW_UPDATENOW) api_UpdateWindow(win) ;;--> RenderWorld here !! ;;RenderFrame() Delay(1) End Function
I really hope this helps,