• Welcome to PlanetSquires Forums.
 

FB Image box

Started by ji_vildaasen, April 05, 2021, 12:00:04 PM

Previous topic - Next topic

ji_vildaasen

Hi

I'm trying to put together some code to easily draw a FreeBasic ImageBuffer that the internal gfx library uses, in a WinFBE project. I have working code that shows a ImageBuffer drawn on a Window, but I'm hoping someone has some good tips to avoid flickering when the window gets resized.

Here is the code that draws the FB Imagebuffer, it gets called when the Window gets a WM_PAINT message:

Sub FBImageBox.Draw()

PrintMSG "FBImageBox.Draw()"

If Buffer = 0 then exit sub
If TempBuffer = 0 Then TempBuffer = ImageCreate(MaxW, MaxH, 0, 32)

Put TempBuffer, (0, 0), Buffer, Pset

Dim As BITMAPV4HEADER bmi

With BMI
.bV4Size = Len(BITMAPV4HEADER)
.bv4width = TempBuffer->Pitch / 4
.bv4height = -(TempBuffer->Height)
.bv4planes = 1
.bv4bitcount = 32
.bv4v4compression = 0
.bv4sizeimage = ((TempBuffer->Pitch / 4) * TempBuffer->Height) * 4
.bV4RedMask = &h0f00
.bV4GreenMask = &h00f0
.bV4BlueMask = &h000f
.bV4AlphaMask = &hf000
End With

Var hdc = GetDC(Parent.hWindow)
StretchDIBits(hDC, x, y, Buffer->Width, Buffer->Height, 0, 0, Buffer->Width, Buffer->Height, CPtr(Any Ptr, TempBuffer) + SizeOf(FB.Image), CPtr( BITMAPINFO Ptr, @BMI), DIB_RGB_COLORS, SRCCOPY )
DeleteDC(hdc)

end sub


Most of the code I think I found on the FB forum years ago, I have also attached a test WinFBE project if anyone is interested.

PS: Is there an option in WinFB to save the code the way it is displayed?

Paul Squires

Hi, I downloaded your example but I have zero experience with FB's ScreenRes and built in graphics controls. I doubt that the FB graphic control exposes a Windows handle so it doesn't act like a normal Windows child control, therefore even adding the WS_CLIPCHILDREN style would not excluded it from the drawing region and thus contributes to flicker.

Being a Windows programmer, I would approach this by creating a custom control by creating a simple blank window via CreateWindowEx and then return TRUE from WM_ERASEBKGND and do all of the drawing in the WM_PAINT message handler and use double buffering and primitive GDI or GDI+ api commands. This requires a bit of knowledge about how to create custom controls but you can look in the Afx folder and find several from Jose (eg. CxpButton.inc).

This would be a prime case where WinFBE could use a dedicated built-in control like a "Canvas Control" or "Graphic Drawing Control".   :-)


Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

> This would be a prime case where WinFBE could use a dedicated built-in control like a "Canvas Control" or "Graphic Drawing Control".   :-)

You have forgot that WinFBX has a graphic control, CGraphCtx, that allows to work with GDI, GDI+ and OpenGL? It also features persistence and flicker free resizing (it uses double buffering). And there are hundreds of GDI+ examples (in the Examples/CGdiPlus folder) that use it (and are DPI aware).

See: https://github.com/JoseRoca/WinFBX/blob/master/docs/Graphics/CGraphCtx%20Class.md

Paul Squires

Lol, yes I did forget! I am getting old and forgetful. You have already built the wheel.  I just need to use it.  :-)

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

ji_vildaasen

Thanks for the tips. I'm hoping to not have to learn to much new stuff to avoid the flicker, I dont really have much time to use on my programing hobby.

FBs ScreenRes function is usually used to create a window where you can draw with FBs gfx functions. There is a option to create a hidden "screen" which lets you use the drawing functions, but you need to show the result your self(like I do with StretchDIBits). FB.Image buffers are just a block of memory where the first 32bytes is a header with info on BBP and width and height of the buffer. After that the rest of the memory block contain the color of each pixel in the buffer.

Maybe I could create a child window and draw on that instead of directly on the "main" window.

Or maybe I can use the ValidateRect function in the WM_ERASEBKGND message to stop the background being drawn over the area I draw on with StretchDIBits? Will have to do some testing later..