GDI+ Streamer v1.0 build 2018-01-22 [Windows only]

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

GDI+ Streamer v1.0 build 2018-01-22 [Windows only]

Post by UEZ »

Here another example in usage of the windows api more precisely GDIPlus.

Code: Select all

'coded by UEZ build 2018-01-22
#Include "fbgfx.bi"

#Ifdef __FB_64BIT__
    #Inclib "gdiplus"
    #Include once "win/gdiplus-c.bi"
#Else
    #Include once "win/gdiplus.bi"
    using gdiplus
#Endif

Using FB


'init GDIPlus
Dim Shared gdipToken As ULONG_PTR
Dim Shared GDIp As GdiplusStartupInput 
GDIp.GdiplusVersion = 1
If GdiplusStartup(@gdipToken, @GDIp, NULL) <> 0 Then End
'--------------------------------------------------------

Const As UShort iW = 1000, iH = 800, iWh = iW \ 2, iHh = iH \ 2

ScreenControl SET_DRIVER_NAME, "GDI"
ScreenRes iW, iH, 32, 1, GFX_HIGH_PRIORITY Or GFX_NO_SWITCH

Dim As String sTitle = "GDI+ Streamer v1.0 / FPS: "
WindowTitle sTitle

'center windows by adding the taskbar to the calculation
Dim as Integer iDW, iDH
ScreenControl GET_DESKTOP_SIZE, iDW, iDH
Dim tWorkingArea As RECT
SystemParametersInfo(SPI_GETWORKAREA, null, @tWorkingArea, null)
ScreenControl SET_WINDOW_POS, (iDW - iW) \ 2, _
                              ((tWorkingArea.Bottom - iH) - (iDH - tWorkingArea.Bottom)) \ 2

'init GDI / GDI+ canvas, pens, brushes, etc. for drawing
Dim as HWND hHWND
ScreenControl(FB.GET_WINDOW_HANDLE, Cast(Integer, hHWND))

Dim As Any Ptr hDC = GetDC(hHWND), _
					hHBitmap = CreateCompatibleBitmap(hDC, iW, iH), _
					hDC_backbuffer = CreateCompatibleDC(hDC), _
					hCanvas, hPenOut, hBrushInner, hMatrix, hFamily, hStringFormat, hPath
Var hObjOld = SelectObject(hDC_backbuffer, hHBitmap) 

GdipCreateFromHDC(hDC_backbuffer, @hCanvas)
GdipGraphicsClear(hCanvas, &hFFFFFFFF)
GdipSetSmoothingMode(hCanvas, SmoothingModeAntiAlias)
GdipSetPixelOffsetMode(hCanvas, PixelOffsetModeHalf)
GdipCreatePen1(&hB0000000, 1.66666, 2, @hPenOut)
GdipCreateSolidFill(&hFFFFFFFF, @hBrushInner)
GdipCreateFontFamilyFromName("Times New Roman", Null, @hFamily)
GdipCreateStringFormat(0, 0, @hStringFormat)
GdipSetStringFormatAlign(hStringFormat, StringAlignmentCenter)
GdipSetStringFormatLineAlign(hStringFormat, StringAlignmentCenter)
GdipSetTextRenderingHint(hCanvas, PixelOffsetModeHalf)
GdipSetTextRenderingHint(hCanvas, TextRenderingHintAntiAliasGridFit)
GdipCreateMatrix(@hMatrix)
DIm tLayout as RectF
tLayout.width = 99
tLayout.height = 99

'--------------------------------------------------------

Dim as Single j = 2^16, k = -2^16, fRadius = iHh * 0.8, fRadiusX, fRadiusY
Dim as UShort c, iCenterX = iWh - 50, iCenterY = iHh - 50

Dim As ULong iFPS = 0
Dim as String aText(0 to ...) = {"GDI+ Streamer", "coded", "by", "UEZ"}
Dim as UByte iUB = Ubound(aText) + 1
Dim as Single aTextConf(0 to Ubound(aText), 2) = {{10, 22}, {5, 24}, {4, 40}, {30, 35}}
Dim tPoints(0 to 3) as GpPointF

Dim As Double fTimer = Timer, fTimer2 = Timer

Do
   fRadiusX = fRadius * Sin((j + k) / 150)
   fRadiusY = fRadius * Cos((k - j) / 250)
   tPoints(0).x = iCenterX + Sin(j / 100) * fRadiusX
   tPoints(0).y = iCenterY + Cos(j / 100) * fRadiusY
   tPoints(1).x = (iCenterX + 100) + Sin(j / 100) * fRadiusX
   tPoints(1).y = iCenterY + Cos(j / 100) * fRadiusY
   tPoints(2).x = (iCenterX + 100) + Sin(j / 100) * fRadiusX
   tPoints(2).y = (iCenterY + 100) + Cos(j / 100) * fRadiusY
   tPoints(3).x = iCenterX + Sin(j / 100) * fRadiusX
   tPoints(3).y = (iCenterY + 100) + Cos(j / 100) * fRadiusY
   j -= 0.025
   k += 2.5
   
   GdipCreatePath(0, @hPath)
   'GdipSetPathFillMode(hPath, FillModeWinding)
   GdipAddPathPolygon(hPath, @tPoints(0), 4)
   tLayout.x = tPoints(0).x
   tLayout.y = tPoints(0).y
   If Timer - fTimer2 > aTextConf(c, 0) Then
      c = (c + 1) Mod iUB
      fTimer2 = Timer
   End If
   GdipAddPathString(hPath, aText(c), -1, hFamily, 0, aTextConf(c, 1), @tLayout, hStringFormat)
   
   GdipTranslateMatrix(hMatrix, iWh, iHh, False)
   GdipRotateMatrix(hMatrix, 0.5 + Cos((j - k) / 10) * 2.5, false)
   GdipTranslateMatrix(hMatrix, -iWh, -iHh, False)
   GdipSetLineTransform(hBrushInner, hMatrix)
   GdipTransformPath(hPath, hMatrix)
   
   GdipFillPath(hCanvas, hBrushInner, hPath)
   GdipDrawPath(hCanvas, hPenOut, hPath)
   
   GdipDeletePath(hPath)
   
   BitBlt(hDC, 0, 0, iW, iH, hDC_backbuffer, 0, 0, SRCCOPY)
   
   Sleep(10, 1)
   
  	If Timer - fTimer > 0.99 Then
		WindowTitle sTitle & iFPS
		iFPS = 0
		fTimer = Timer
	Else
		iFPS += 1
	EndIf 

Loop Until InKey = Chr(27)

'release resources
SelectObject(hDC_backbuffer, hObjOld)
DeleteDC(hDC_backbuffer)
ReleaseDC(hHWND, hDC)
DeleteObject(hHBitmap)
GdipDeleteGraphics(hCanvas)
GdipDeletePen(hPenOut)
GdipDeleteBrush(hBrushInner)
GdipDeleteFontFamily(hFamily)
GdipDeleteStringFormat(hStringFormat)
GdipDeleteMatrix(hMatrix)
GdiplusShutdown(gdipToken)
Image

Because it is fast enough I did not use faster Sin/Cos functions.

Thanks to Josep Roca for the header to compile also in 64-bit!
Last edited by UEZ on Jan 22, 2018 22:38, edited 5 times in total.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: GDI+ Streamer v1.0 build 2018-01-21 [Windows only]

Post by jj2007 »

Lovely! (where is that thumbs up icon? I need it!)
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: GDI+ Streamer v1.0 build 2018-01-21 [Windows only]

Post by D.J.Peters »

Works only in 32-bit mode here
on 64-bit I get a bunch of errors.

Joshy
fbc 64-bit wrote:D:\FreeBASIC\inc\win\winnt.bi(336) error 123: Symbols defined inside namespaces cannot be removed, found '_rotl' in '#undef _rotl'
D:\FreeBASIC\inc\win\winnt.bi(337) error 123: Symbols defined inside namespaces cannot be removed, found '_rotr' in '#undef _rotr'
D:\FreeBASIC\inc\win\winnt.bi(338) error 4: Duplicated definition in 'declare function _rotl cdecl(byval Value as ulong, byval Shift as long) as ulong'
D:\FreeBASIC\inc\win\winnt.bi(339) error 4: Duplicated definition in 'declare function _rotr cdecl(byval Value as ulong, byval Shift as long) as ulong'
D:\FreeBASIC\inc\win\winerror.bi(3515) error 123: Symbols defined inside namespaces cannot be removed, found '__IN__WINERROR_' in '#undef __IN__WINERROR_'
D:\FreeBASIC\inc\win\winuser.bi(1093) error 123: Symbols defined inside namespaces cannot be removed, found 'GWL_WNDPROC' in '#undef GWL_WNDPROC'
D:\FreeBASIC\inc\win\winuser.bi(1094) error 123: Symbols defined inside namespaces cannot be removed, found 'GWL_HINSTANCE' in '#undef GWL_HINSTANCE'
D:\FreeBASIC\inc\win\winuser.bi(1095) error 123: Symbols defined inside namespaces cannot be removed, found 'GWL_HWNDPARENT' in '#undef GWL_HWNDPARENT'
D:\FreeBASIC\inc\win\winuser.bi(1096) error 123: Symbols defined inside namespaces cannot be removed, found 'GWL_USERDATA' in '#undef GWL_USERDATA'
D:\FreeBASIC\inc\win\winuser.bi(1117) error 123: Symbols defined inside namespaces cannot be removed, found 'GCL_MENUNAME' in '#undef GCL_MENUNAME'
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: GDI+ Streamer v1.0 build 2018-01-21 [Windows only]

Post by UEZ »

D.J.Peters wrote:Works only in 32-bit mode here
on 64-bit I get a bunch of errors.

Joshy
This is caused by the broken 64-bit libs. I don't know whether FB is still developed or not. As far as I can remember the "boat is without a captain" (same as for AutoIt). So, no hope that it will be fixed... :-(


@jj2007: thanks for your feedback. :-)
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: GDI+ Streamer v1.0 build 2018-01-21 [Windows & 32-bit only]

Post by Josep Roca »

This compiles in both 32 and 64 bit:

Code: Select all

'coded by UEZ build 2018-01-21
#Include "fbgfx.bi"

#include once "windows.bi"
#ifdef __FB_64BIT__
    #inclib "gdiplus"
    #include once "win/gdiplus-c.bi"
#else
    #include once "win/ddraw.bi"
    #include once "win/gdiplus.bi"
    using gdiplus
#endif

Using FB

'init GDIPlus
Dim Shared gdipToken As ULONG_PTR
Dim Shared GDIp As GdiplusStartupInput
GDIp.GdiplusVersion = 1
If GdiplusStartup(@gdipToken, @GDIp, NULL) <> 0 Then End
'--------------------------------------------------------

Const As UShort iW = 1000, iH = 800, iWh = iW \ 2, iHh = iH \ 2

ScreenControl SET_DRIVER_NAME, "GDI"
ScreenRes iW, iH, 32, 1, GFX_HIGH_PRIORITY Or GFX_NO_SWITCH

Dim As String sTitle = "GDI+ Streamer v1.0 / FPS: "
WindowTitle sTitle

'center windows by adding the taskbar to the calculation
Dim as Integer iDW, iDH
ScreenControl GET_DESKTOP_SIZE, iDW, iDH
Dim tWorkingArea As RECT
SystemParametersInfo(SPI_GETWORKAREA, null, @tWorkingArea, null)
ScreenControl SET_WINDOW_POS, (tWorkingArea.Right - iW) \ 2, ((tWorkingArea.Bottom - iH) - (iDH - tWorkingArea.Bottom)) \ 2

'init GDI / GDI+ canvas, pens, brushes, etc. for drawing
Dim as HWND hHWND
ScreenControl(FB.GET_WINDOW_HANDLE, Cast(Integer, hHWND))

Dim As Any Ptr hDC = GetDC(hHWND), _
               hHBitmap = CreateCompatibleBitmap(hDC, iW, iH), _
               hDC_backbuffer = CreateCompatibleDC(hDC), _
               hCanvas, hPenOut, hBrushInner, hMatrix, hFamily, hStringFormat, hPath
Var hObjOld = SelectObject(hDC_backbuffer, hHBitmap)

GdipCreateFromHDC(hDC_backbuffer, @hCanvas)
GdipGraphicsClear(hCanvas, &hFFFFFFFF)
GdipSetSmoothingMode(hCanvas, 5)
GdipSetPixelOffsetMode(hCanvas, 2)
GdipCreatePen1(&hB0000000, 1.66666, 2, @hPenOut)
GdipCreateSolidFill(&hFFFFFFFF, @hBrushInner)
GdipCreateFontFamilyFromName("Times New Roman", Null, @hFamily)
GdipCreateStringFormat(0, 0, @hStringFormat)
GdipSetStringFormatAlign(hStringFormat, StringAlignmentCenter)
GdipSetStringFormatLineAlign(hStringFormat, StringAlignmentCenter)
GdipSetTextRenderingHint(hCanvas, PixelOffsetModeHalf)
GdipSetTextRenderingHint(hCanvas, TextRenderingHintAntiAliasGridFit)
GdipCreateMatrix(@hMatrix)
DIm tLayout as RectF
tLayout.width = 99
tLayout.height = 99

'--------------------------------------------------------

Dim as Single j = 2^16, k = -2^16, fRadius = iHh * 0.8, fRadiusX, fRadiusY
Dim as UShort c, iCenterX = iWh - 50, iCenterY = iHh - 50

Dim As ULong iFPS = 0
Dim as String aText(0 to 2) = {"Coded", "by", "UEZ"}
Dim as Single aTextConf(0 to 2, 2) = {{5, 24}, {4, 40}, {30, 35}}
Dim tPoints(0 to 4) as GpPointF
Dim As Double fTimer = Timer, fTimer2 = Timer

Do
   fRadiusX = fRadius * Sin((j + k) / 150)
   fRadiusY = fRadius * Cos((k - j) / 250)
   tPoints(0).x = iCenterX + Sin(j / 100) * fRadiusX
   tPoints(0).y = iCenterY + Cos(j / 100) * fRadiusY
   tPoints(1).x = (iCenterX + 100) + Sin(j / 100) * fRadiusX
   tPoints(1).y = iCenterY + Cos(j / 100) * fRadiusY
   tPoints(2).x = (iCenterX + 100) + Sin(j / 100) * fRadiusX
   tPoints(2).y = (iCenterY + 100) + Cos(j / 100) * fRadiusY
   tPoints(3).x = iCenterX + Sin(j / 100) * fRadiusX
   tPoints(3).y = (iCenterY + 100) + Cos(j / 100) * fRadiusY
   j -= 0.025
   k += 2.5
   
   GdipCreatePath(0, @hPath)
   GdipSetPathFillMode(hPath, FillModeWinding)
   GdipAddPathPolygon(hPath, @tPoints(0), 4)
   tLayout.x = tPoints(0).x
   tLayout.y = tPoints(0).y
   If Timer - fTimer2 > aTextConf(c, 0) Then
      c = (c + 1) Mod 3
      fTimer2 = Timer
   End If
   GdipAddPathString(hPath, aText(c), -1, hFamily, 0,aTextConf(c, 1), @tLayout, hStringFormat)
   
   GdipTranslateMatrix(hMatrix, iWh, iHh, False)
   GdipRotateMatrix(hMatrix, 0.5 + Cos((j - k) / 10) * 2.5, false)
   GdipTranslateMatrix(hMatrix, -iWh, -iHh, False)
   GdipSetLineTransform(hBrushInner, hMatrix)
   GdipTransformPath(hPath, hMatrix)
   
   GdipFillPath(hCanvas, hBrushInner, hPath)
   GdipDrawPath(hCanvas, hPenOut, hPath)
   
   GdipDeletePath(hPath)
   BitBlt(hDC, 0, 0, iW, iH, hDC_backbuffer, 0, 0, SRCCOPY)
   Sleep(10, 1)
   
     If Timer - fTimer > 0.99 Then
      WindowTitle sTitle & iFPS
      iFPS = 0
      fTimer = Timer
   Else
      iFPS += 1
   EndIf

Loop Until InKey = Chr(27)

'release resources
SelectObject(hDC_backbuffer, hObjOld)
DeleteDC(hDC_backbuffer)
ReleaseDC(hHWND, hDC)
DeleteObject(hHBitmap)
GdipDeleteGraphics(hCanvas)
GdipDeletePen(hPenOut)
GdipDeleteBrush(hBrushInner)
GdipDeleteFontFamily(hFamily)
GdipDeleteStringFormat(hStringFormat)
GdipDeleteMatrix(hMatrix)
GdiplusShutdown(gdipToken)
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: GDI+ Streamer v1.0 build 2018-01-21 [Windows only]

Post by UEZ »

@Josep Roca Muchas gracias! Is this your web site: http://www.jose.it-berater.org/ ?

I updated the code from post #1.
Last edited by UEZ on Jan 21, 2018 22:31, edited 1 time in total.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: GDI+ Streamer v1.0 build 2018-01-21 [Windows only]

Post by Josep Roca »

> @Josep Roca Muchas gracias! Is this your web site: http://www.jose.it-berater.org/ ?

It was when I worked with Power Basic. Now I'm working with Paul Squires in an Windows editor (WInFBE) and a framework (WinFBX) for Free Basic: http://www.planetsquires.com/protect/forum/index.php
UEZ
Posts: 988
Joined: May 05, 2017 19:59
Location: Germany

Re: GDI+ Streamer v1.0 build 2018-01-21 [Windows only]

Post by UEZ »

http://www.jose.it-berater.org/ is still a great resource for GDI / GDI+ ;-) and of course other stuff, too! I took a lot of information from there... ^^

Thanks for your efforts!
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: GDI+ Streamer v1.0 build 2018-01-21 [Windows only]

Post by srvaldez »

@UEZ and @Josep Roca
I got UEZ's original code to work by using Josep Roca's Afx include found here http://www.planetsquires.com/protect/fo ... pic=4073.0

Code: Select all

'coded by UEZ build 2018-01-21
#Include "fbgfx.bi"
'#Include "win/gdiplus.bi"
#include "Afx\AfxGdiplus.inc"
Using FB
Using Afx 'GDIPLUS
with that change it compiles and runs Ok in both 32 and 64-bit
Post Reply