Jump to content

Recommended Posts

Posted (edited)

I've been playin around with the Gdi+ udf and we was getting along fairly well so far but i've fallen out with it when it comes to images in memory.

I'm fine when using a Double Buffer method i found on the forum , i've managed to create the First script which draws a machine table layout then places the amount of components selected in a dropdown on the table. This is all drawing to the buffer graphic so each time im redrawing the table. I wondered about only drawing the table the first time , storing an image of the table in memory, then when the qty is changed redrawing the table from memory and then placing the components ontop of this.

The second script shows my total lack of understanding how the '_GDIPlus_BitmapCreateFromGraphics' functions, my first script works fine as it is but it bugging me that i can't figure it out, anyone care to help me out in understanding.

Cheers Yoriz.

Note: click Continue to exit the first script.

Working script

#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
#include <StringSize.au3>
#include <ComboConstants.au3>
;~ #include "Shared.au3"
#include <String.au3>


Opt('MustDeclareVars', 1)

Global $hTableGui, $sProgramNo, $hQtyCombo = -1, $hOkButton, $hRunTimeLabel, $iQty, $sQtys, $hwndParent, $msg, $iBorder = 15, $iRows = 8, $iColumns = 15
Global $iTotalQty, $iActQty = 1, $iXstartPos, $iYstartPos, $iXIncrement, $iYIncrement, $iXLastPos, $iYLastPos, $iRunTime, $fDisplayOnly = False, $Prefix, $sFirstNo, $sSuffix, $aSerialNos
Global $iWindowWidth, $iTableWidth, $iSquareSize, $iTableHeight, $iWindowHeight, $hWhiteBrush, $hBlackBrush, $hRedBrush, $hOutLinePen
Global $hGraphicGUI, $hBMPBuff, $hGraphic, $hPen, $hFormat, $hFamily, $hFont

_TableLayoutGUI()

Func _TableLayoutGUI()
;~  With $oShared
    $hwndParent = ""
;~      $hwndParent = HWnd($hwndParent)
    $sProgramNo = "TestingGui"
    $iTotalQty = 50
    $iXstartPos = -250
    $iYstartPos = -500
    $iXIncrement = -250
    $iYIncrement = 250
    $iXLastPos = -2500
    $iYLastPos = 500
    $iRunTime = 10
    $Prefix = "Comp"
    $sFirstNo = "01"
    $sSuffix = ""
;~  EndWith
    $iWindowWidth = @DesktopWidth * .8
    $iTableWidth = $iWindowWidth - ($iBorder * 2)
    $iSquareSize = $iTableWidth / ($iColumns - 1)
    $iTableHeight = $iSquareSize * ($iRows - 1)
    $iWindowHeight = ($iTableHeight + $iBorder * 2) + 50

    $hTableGui = GUICreate("Table Layout for " & $sProgramNo, $iWindowWidth, $iWindowHeight, -1, -1, BitOR($WS_POPUP, $WS_CAPTION, $WS_CLIPCHILDREN), -1, $hwndParent)
    GUISetFont(12, 400, -1, "Arial")
    GUISetBkColor(0xE2E2E2)
    If Not $fDisplayOnly Then
        GUICtrlCreateLabel("Please select required quantity, a maximum of " & $iTotalQty, $iBorder, $iTableHeight + 40)
        $hQtyCombo = GUICtrlCreateCombo("", 370, $iTableHeight + 36, 100, 100, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL, $WS_VSCROLL))
        For $iQty = 1 To $iTotalQty
            $sQtys &= "|" & $iQty
        Next
        $sQtys = StringTrimLeft($sQtys, 1)
        GUICtrlSetData(-1, $sQtys, "1")
    EndIf
    $hOkButton = GUICtrlCreateButton(" Continue ", 500, $iTableHeight + 35)
    $hRunTimeLabel = GUICtrlCreateLabel("Total Quantity will take approx: " & Floor(($iActQty * $iRunTime) / 60) & " Hour/s : " & Mod($iActQty * $iRunTime, 60) & " Minute/s", 600, $iTableHeight + 40, 400)

    GUISetState()

    _GDIPlus_Startup()

    ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event
    $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hTableGui)
    $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($iTableWidth + $iBorder * 2, $iTableHeight + $iBorder * 2, $hGraphicGUI)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2)
    ;End Double Buffer add-in 1 of 3

    ;Graphics here
    _GDIPlus_GraphicsClear($hGraphic, 0xFFE2E2E2)
    $hPen = _GDIPlus_PenCreate()
    $hWhiteBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    $hBlackBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
    $hRedBrush = _GDIPlus_BrushCreateSolid(0xBBFF0000)
    $hOutLinePen = _GDIPlus_PenCreate(0xBB000000, 2)
    $hFormat = _GDIPlus_StringFormatCreate()
    _GDIPlus_StringFormatSetAlign($hFormat, 1)
    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    $hFont = _GDIPlus_FontCreate($hFamily, 8, 0, 3)

    _CreateTable()
    _ShowComponents()

    ;End of graphics

    ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event
    GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3)
    GUIRegisterMsg(0x85, "MY_PAINT"); $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize.

    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    _WinAPI_RedrawWindow($hTableGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)); , $RDW_ALLCHILDREN

    ;End Double Buffer add-on 2 of 3


    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $hQtyCombo
                $iActQty = GUICtrlRead($hQtyCombo)
                GUICtrlSetData($hRunTimeLabel, "Total Quantity will take approx: " & Floor(($iActQty * $iRunTime) / 60) & " Hour/s : " & Mod($iActQty * $iRunTime, 60) & " Minute/s")

                _GDIPlus_GraphicsClear($hGraphic, 0xFFE2E2E2)
                _CreateTable()
                _ShowComponents()
                _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
                _WinAPI_RedrawWindow($hTableGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)); , $RDW_ALLCHILDREN
                $aSerialNos = ""
            Case $hOkButton
;~              $oShared.ActQty = $iActQty
                _GDIPlus_FontDispose($hFont)
                _GDIPlus_FontFamilyDispose($hFamily)
                _GDIPlus_StringFormatDispose($hFormat)
                _GDIPlus_BrushDispose($hWhiteBrush)
                _GDIPlus_BrushDispose($hBlackBrush)
                _GDIPlus_BrushDispose($hRedBrush)
                _GDIPlus_PenDispose($hOutLinePen)
                _GDIPlus_PenDispose($hPen)
                _GDIPlus_GraphicsDispose($hGraphic)
                _GDIPlus_GraphicsDispose($hGraphicGUI)
                _WinAPI_DeleteObject($hBMPBuff)
                _GDIPlus_Shutdown()
                GUIDelete($hTableGui)
                ExitLoop
        EndSwitch
    WEnd
EndFunc   ;==>_TableLayoutGUI

;Func to redraw on PAINT MSG
Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    ;_WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_FRAME, $RDW_UPDATENOW );, $RDW_ALLCHILDREN));

    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_PAINT

Func _CreateTable()
    Local $aTableGrid[$iColumns][$iRows][2]
    For $iX = 0 To $iColumns - 1 Step 1
        For $iY = 0 To $iRows - 1 Step 1
            $aTableGrid[$iX][$iY][0] = $iBorder + Round(($iSquareSize * $iX))
            $aTableGrid[$iX][$iY][1] = $iBorder + Round(($iSquareSize * $iY))
        Next
    Next

    For $iY = 0 To $iRows - 1 Step 1
        _GDIPlus_GraphicsDrawLine($hGraphic, $aTableGrid[0][$iY][0], $aTableGrid[0][$iY][1], $aTableGrid[$iColumns - 1][$iY][0], $aTableGrid[$iColumns - 1][$iY][1])
    Next
    For $iX = 0 To $iColumns - 1 Step 1
        _GDIPlus_GraphicsDrawLine($hGraphic, $aTableGrid[$iX][0][0], $aTableGrid[$iX][0][1], $aTableGrid[$iX][$iRows - 1][0], $aTableGrid[$iX][$iRows - 1][1])
    Next

    Local $iSphereSize = $iSquareSize * .2
    _GDIPlus_GraphicsFillPie($hGraphic, $aTableGrid[12][3][0] - $iSphereSize / 2, $aTableGrid[12][3][1] - $iSphereSize / 2, $iSphereSize, $iSphereSize, 0, 360)
    Local $iProbRackWidth = $iSquareSize * 1.1, $iProbeRackHeight = $iSquareSize * .2
    _GDIPlus_GraphicsFillRect($hGraphic, $aTableGrid[13][0][0] - $iProbRackWidth / 2, $aTableGrid[13][0][1] - $iProbeRackHeight / 2, $iProbRackWidth, $iProbeRackHeight)
    _TableLabel("Calibration Sphere", $aTableGrid[12][3][0] - $iSphereSize / 2, $aTableGrid[12][3][1] + $iSquareSize * .15, 1000, 0, 0)
    _TableLabel("Probe Rack", $aTableGrid[13][0][0], $aTableGrid[13][0][1] + $iSquareSize * .15, 1000, 1, 0)

    Local $iXLabel = -250
    For $iPos = 11 To 2 Step -1
        _TableLabel("X" & $iXLabel, $aTableGrid[$iPos][0][0], $aTableGrid[$iPos][0][1], 1000, 1, 1)
        $iXLabel -= 250
    Next

    Local $iYLabel = 500
    For $iPos = 1 To 6 Step 1
        _TableLabel("Y" & $iYLabel, $aTableGrid[0][$iPos][0] + $iSquareSize * .25, $aTableGrid[0][$iPos][1], 1000, 1, 1)
        $iYLabel -= 250
    Next
EndFunc   ;==>_CreateTable

Func _TableLabel($sText, $iX, $iY, $iWidth = 1000, $iLeftPos = 1, $iTopPos = 1)
    Local $iLeftAct, $iTopAct, $iHeight = 1000
    $iX = Round($iX)
    $iY = Round($iY)
    Local $tLayout = _GDIPlus_RectFCreate($iX, $iY, $iWidth, $iHeight)
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $sText, $hFont, $tLayout, $hFormat)
    Local $iStructWidth = Round(DllStructGetData($aInfo[0], "Width"))
    Local $iStructHeight = Round(DllStructGetData($aInfo[0], "Height"))
    If $iLeftPos Then
        $iLeftAct = $iX - ($iStructWidth / 2)
    Else
        $iLeftAct = $iX
    EndIf
    If $iTopPos Then
        $iTopAct = $iY - ($iStructHeight / 2)
    Else
        $iTopAct = $iY
    EndIf
    DllStructSetData($aInfo[0], "X", $iLeftAct)
    DllStructSetData($aInfo[0], "Y", $iTopAct)
    Local $iStructX = Round(DllStructGetData($aInfo[0], "X"))
    Local $iStructY = Round(DllStructGetData($aInfo[0], "Y"))
    _GDIPlus_GraphicsFillRect($hGraphic, $iStructX - 2, $iStructY, $iStructWidth, $iStructHeight, $hWhiteBrush)
    _GDIPlus_GraphicsDrawRect($hGraphic, $iStructX - 2, $iStructY, $iStructWidth, $iStructHeight)
    _GDIPlus_GraphicsDrawStringEx($hGraphic, $sText, $hFont, $aInfo[0], $hFormat, $hBlackBrush)
EndFunc   ;==>_TableLabel

Func _ShowComponents()
    Local $aTableGrid[$iColumns][$iRows][2], $iXSpherePos = 12, $iYSpherePos = 6, $iGuiXstartPos, $iGuiYstartPos, $iGuiXIncrement, $iGuiYIncrement, $iGuiXLastPos, $sSerialNos, $iSnoLength, $sNewSno
    For $iX = 0 To $iColumns - 1 Step 1
        For $iY = 0 To $iRows - 1 Step 1
            $aTableGrid[$iX][$iY][0] = $iBorder + Round(($iSquareSize * $iX))
            $aTableGrid[$iX][$iY][1] = $iBorder + Round(($iSquareSize * $iY))
        Next
    Next
    $iGuiXstartPos = $iXSpherePos - ($iXstartPos * - 1) / 250
    $iX = $iGuiXstartPos
    $iGuiYstartPos = $iYSpherePos - ($iYstartPos + 750) / 250
    $iY = $iGuiYstartPos
    $iGuiXIncrement = ($iXIncrement * - 1) / 250
    $iGuiYIncrement = $iYIncrement / 250
    $iGuiXLastPos = ($iGuiXstartPos - ($iXLastPos * - 1) / 250) + $iGuiXIncrement

    If Not $aSerialNos Or Not IsArray($aSerialNos) Then
        $sSerialNos = ""
        $iSnoLength = StringLen($sFirstNo)
        For $i = 1 To $iActQty Step 1
            $sNewSno = ($sFirstNo - 1) + $i
            $sSerialNos &= "|" & _StringRepeat("0", $iSnoLength - (StringLen($sNewSno))) & $sNewSno
        Next
        $aSerialNos = StringSplit(StringTrimLeft($sSerialNos, 1), "|")
    EndIf

    For $iLoad = 1 To $iActQty
        _GDIPlus_GraphicsFillPie($hGraphic, $aTableGrid[$iX][$iY][0] - $iSquareSize * .25, $aTableGrid[$iX][$iY][1] - $iSquareSize * .25, $iSquareSize * .5, $iSquareSize * .5, 0, 360, $hRedBrush)
        _GDIPlus_GraphicsDrawArc($hGraphic, $aTableGrid[$iX][$iY][0] - $iSquareSize * .25, $aTableGrid[$iX][$iY][1] - $iSquareSize * .25, $iSquareSize * .5, $iSquareSize * .5, 0, 360, $hOutLinePen)
        _TableLabel($Prefix & " " & $aSerialNos[$iLoad] & " " & $sSuffix, $aTableGrid[$iX][$iY][0], $aTableGrid[$iX][$iY][1] + $iSquareSize * .25, $iSquareSize * .95, 1, 0)
        $iX = $iX - $iGuiXIncrement
        If $iX < $iGuiXLastPos Then
            $iX = $iGuiXstartPos
            $iY -= 1
        EndIf
    Next
EndFunc   ;==>_ShowComponents

Script thats driving me :mellow:

#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>

Global $hGraphicGUI, $hPen, $hBMPBuff, $hGraphic, $hStoreAsBitmapInMemory, $hMyGraphicGraphic

_GdiGui()


Func _GdiGui()
    Local $hGui, $GuiSizeX = 300, $GuiSizeY = 300

    $hGui = GUICreate("GDIPlus Example", $GuiSizeX, $GuiSizeY)
    GUISetState()

    _GDIPlus_Startup()
    $hPen = _GDIPlus_PenCreate(0xFFFF0000, 3)

    ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event
    $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) ;Draw to this graphics, $hGraphicGUI, to display on GUI
    $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI); $hBMPBuff is a bitmap in memory
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff); Draw to this graphics, $hGraphic, being the graphics of $hBMPBuff
    ;End Double Buffer add-in 1 of 3

    _GDIPlus_GraphicsDrawRect($hGraphicGUI, 20, 20, 260, 260, $hPen)
    MsgBox(0, "Pause", "Rectangle drawn to $hGraphicGUI")
    $hStoreAsBitmapInMemory = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI)
    $hMyGraphicGraphic = _GDIPlus_ImageGetGraphicsContext($hStoreAsBitmapInMemory)
;~  _GDIPlus_ImageSaveToFile($hStoreAsBitmapInMemory, @ScriptDir & "\TempGdi.Jpg") ; tried saving the bitmap here comes out as a blacked out img
    MsgBox(0, "Pause", "store whats displayed on $hGraphicGUI in $hStoreAsBitmapInMemory")
    _GDIPlus_GraphicsClear($hGraphicGUI, 0xFFFFFFFF)
    MsgBox(0, "Pause", "Cleared $hGraphicGUI")

    _GDIPlus_GraphicsDrawImage($hGraphic, $hMyGraphicGraphic, 0, 0)
    MsgBox(0, "Pause", "Failing to redraw the stored bitmap $hStoreAsBitmapInMemory")
    _GDIPlus_GraphicsDrawLine($hGraphic, 20, 150, 280, 150, $hPen)
    MsgBox(0, "Pause", "Add a line")

    GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3)
    GUIRegisterMsg(0x85, "MY_PAINT") ; $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize.

    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0); Draw bitmap, $hBMPBuff, to the GUI's graphics, $hGraphicGUI.

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            _Exit()
    EndSwitch
WEnd

EndFunc

;Func to auto-redraw on Windows internal PAINT messages.
Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    ;_WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN
    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_PAINT



Func _Exit()
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hMyGraphicGraphic)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _WinAPI_DeleteObject($hStoreAsBitmapInMemory)
    _WinAPI_DeleteObject($hBMPBuff)
    _GDIPlus_Shutdown()
    Exit
EndFunc
Edited by Yoriz
GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.
Posted

First, this is for the table question:

#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>
;~ #include <StringSize.au3>
#include <ComboConstants.au3>
;~ #include "Shared.au3"
#include <String.au3>


Opt('MustDeclareVars', 1)

Global $hTableGui, $sProgramNo, $hQtyCombo = -1, $hOkButton, $hRunTimeLabel, $iQty, $sQtys, $hwndParent, $msg, $iBorder = 15, $iRows = 8, $iColumns = 15
Global $iTotalQty, $iActQty = 1, $iXstartPos, $iYstartPos, $iXIncrement, $iYIncrement, $iXLastPos, $iYLastPos, $iRunTime, $fDisplayOnly = False, $Prefix, $sFirstNo, $sSuffix, $aSerialNos
Global $iWindowWidth, $iTableWidth, $iSquareSize, $iTableHeight, $iWindowHeight, $hWhiteBrush, $hBlackBrush, $hRedBrush, $hOutLinePen
Global $hGraphicGUI, $hBMPBuff, $hGraphic, $hPen, $hFormat, $hFamily, $hFont
Global $hTableBmp, $hTableGraphics

_TableLayoutGUI()

Func _TableLayoutGUI()
;~  With $oShared
    $hwndParent = ""
;~      $hwndParent = HWnd($hwndParent)
    $sProgramNo = "TestingGui"
    $iTotalQty = 50
    $iXstartPos = -250
    $iYstartPos = -500
    $iXIncrement = -250
    $iYIncrement = 250
    $iXLastPos = -2500
    $iYLastPos = 500
    $iRunTime = 10
    $Prefix = "Comp"
    $sFirstNo = "01"
    $sSuffix = ""
;~  EndWith
    $iWindowWidth = @DesktopWidth * .8
    $iTableWidth = $iWindowWidth - ($iBorder * 2)
    $iSquareSize = $iTableWidth / ($iColumns - 1)
    $iTableHeight = $iSquareSize * ($iRows - 1)
    $iWindowHeight = ($iTableHeight + $iBorder * 2) + 50

    $hTableGui = GUICreate("Table Layout for " & $sProgramNo, $iWindowWidth, $iWindowHeight, -1, -1, BitOR($WS_POPUP, $WS_CAPTION, $WS_CLIPCHILDREN), -1, $hwndParent)
    GUISetFont(12, 400, -1, "Arial")
    GUISetBkColor(0xE2E2E2)
    If Not $fDisplayOnly Then
        GUICtrlCreateLabel("Please select required quantity, a maximum of " & $iTotalQty, $iBorder, $iTableHeight + 40)
        $hQtyCombo = GUICtrlCreateCombo("", 370, $iTableHeight + 36, 100, 100, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL, $WS_VSCROLL))
        For $iQty = 1 To $iTotalQty
            $sQtys &= "|" & $iQty
        Next
        $sQtys = StringTrimLeft($sQtys, 1)
        GUICtrlSetData(-1, $sQtys, "1")
    EndIf
    $hOkButton = GUICtrlCreateButton(" Continue ", 500, $iTableHeight + 35)
    $hRunTimeLabel = GUICtrlCreateLabel("Total Quantity will take approx: " & Floor(($iActQty * $iRunTime) / 60) & " Hour/s : " & Mod($iActQty * $iRunTime, 60) & " Minute/s", 600, $iTableHeight + 40, 400)

    GUISetState()

    _GDIPlus_Startup()

    ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event
    $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hTableGui)
    $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($iTableWidth + $iBorder * 2, $iTableHeight + $iBorder * 2, $hGraphicGUI)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2)
    ;End Double Buffer add-in 1 of 3

    ;Graphics here
    _GDIPlus_GraphicsClear($hGraphic, 0xFFE2E2E2)
    $hPen = _GDIPlus_PenCreate()
    $hWhiteBrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    $hBlackBrush = _GDIPlus_BrushCreateSolid(0xFF000000)
    $hRedBrush = _GDIPlus_BrushCreateSolid(0xBBFF0000)
    $hOutLinePen = _GDIPlus_PenCreate(0xBB000000, 2)
    $hFormat = _GDIPlus_StringFormatCreate()
    _GDIPlus_StringFormatSetAlign($hFormat, 1)
    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    $hFont = _GDIPlus_FontCreate($hFamily, 8, 0, 3)

    ; Create and define the table image
    $hTableBmp = _GDIPlus_BitmapCreateFromGraphics($iTableWidth + $iBorder * 2, $iTableHeight + $iBorder * 2, $hGraphicGUI)
    $hTableGraphics = _GDIPlus_ImageGetGraphicsContext($hTableBmp)
    _CreateTable($hTableGraphics)
    _GDIPlus_GraphicsDispose($hTableGraphics)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hTableBmp, 0, 0)
    _ShowComponents()

    ;End of graphics

    ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event
    GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3)
    GUIRegisterMsg(0x85, "MY_PAINT"); $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize.

    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    _WinAPI_RedrawWindow($hTableGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)); , $RDW_ALLCHILDREN

    ;End Double Buffer add-on 2 of 3


    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $hQtyCombo
                $iActQty = GUICtrlRead($hQtyCombo)
                GUICtrlSetData($hRunTimeLabel, "Total Quantity will take approx: " & Floor(($iActQty * $iRunTime) / 60) & " Hour/s : " & Mod($iActQty * $iRunTime, 60) & " Minute/s")

                _GDIPlus_GraphicsClear($hGraphic, 0xFFE2E2E2)
                _GDIPlus_GraphicsDrawImage($hGraphic, $hTableBmp, 0, 0)
;~                 _CreateTable()
                _ShowComponents()
                _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
                _WinAPI_RedrawWindow($hTableGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)); , $RDW_ALLCHILDREN
                $aSerialNos = ""
            Case $hOkButton
;~              $oShared.ActQty = $iActQty
                _GDIPlus_FontDispose($hFont)
                _GDIPlus_FontFamilyDispose($hFamily)
                _GDIPlus_StringFormatDispose($hFormat)
                _GDIPlus_BrushDispose($hWhiteBrush)
                _GDIPlus_BrushDispose($hBlackBrush)
                _GDIPlus_BrushDispose($hRedBrush)
                _GDIPlus_PenDispose($hOutLinePen)
                _GDIPlus_PenDispose($hPen)
                _GDIPlus_GraphicsDispose($hGraphic)
                _GDIPlus_GraphicsDispose($hGraphicGUI)
                _GDIPlus_BitmapDispose($hTableBmp)
                _GDIPlus_BitmapDispose($hBMPBuff)
                _GDIPlus_Shutdown()
                GUIDelete($hTableGui)
                ExitLoop
        EndSwitch
    WEnd
EndFunc   ;==>_TableLayoutGUI

;Func to redraw on PAINT MSG
Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    ;_WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_FRAME, $RDW_UPDATENOW );, $RDW_ALLCHILDREN));

    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_PAINT

Func _CreateTable($hGraphics)

    Local $aTableGrid[$iColumns][$iRows][2]
    For $iX = 0 To $iColumns - 1 Step 1
        For $iY = 0 To $iRows - 1 Step 1
            $aTableGrid[$iX][$iY][0] = $iBorder + Round(($iSquareSize * $iX))
            $aTableGrid[$iX][$iY][1] = $iBorder + Round(($iSquareSize * $iY))
        Next
    Next

    For $iY = 0 To $iRows - 1 Step 1
        _GDIPlus_GraphicsDrawLine($hGraphics, $aTableGrid[0][$iY][0], $aTableGrid[0][$iY][1], $aTableGrid[$iColumns - 1][$iY][0], $aTableGrid[$iColumns - 1][$iY][1])
    Next
    For $iX = 0 To $iColumns - 1 Step 1
        _GDIPlus_GraphicsDrawLine($hGraphics, $aTableGrid[$iX][0][0], $aTableGrid[$iX][0][1], $aTableGrid[$iX][$iRows - 1][0], $aTableGrid[$iX][$iRows - 1][1])
    Next

    Local $iSphereSize = $iSquareSize * .2
    _GDIPlus_GraphicsFillPie($hGraphics, $aTableGrid[12][3][0] - $iSphereSize / 2, $aTableGrid[12][3][1] - $iSphereSize / 2, $iSphereSize, $iSphereSize, 0, 360)
    Local $iProbRackWidth = $iSquareSize * 1.1, $iProbeRackHeight = $iSquareSize * .2
    _GDIPlus_GraphicsFillRect($hGraphics, $aTableGrid[13][0][0] - $iProbRackWidth / 2, $aTableGrid[13][0][1] - $iProbeRackHeight / 2, $iProbRackWidth, $iProbeRackHeight)
    _TableLabel($hGraphics, "Calibration Sphere", $aTableGrid[12][3][0] - $iSphereSize / 2, $aTableGrid[12][3][1] + $iSquareSize * .15, 1000, 0, 0)
    _TableLabel($hGraphics, "Probe Rack", $aTableGrid[13][0][0], $aTableGrid[13][0][1] + $iSquareSize * .15, 1000, 1, 0)

    Local $iXLabel = -250
    For $iPos = 11 To 2 Step -1
        _TableLabel($hGraphics, "X" & $iXLabel, $aTableGrid[$iPos][0][0], $aTableGrid[$iPos][0][1], 1000, 1, 1)
        $iXLabel -= 250
    Next

    Local $iYLabel = 500
    For $iPos = 1 To 6 Step 1
        _TableLabel($hGraphics, "Y" & $iYLabel, $aTableGrid[0][$iPos][0] + $iSquareSize * .25, $aTableGrid[0][$iPos][1], 1000, 1, 1)
        $iYLabel -= 250
    Next
EndFunc   ;==>_CreateTable

Func _TableLabel($hGraphics, $sText, $iX, $iY, $iWidth = 1000, $iLeftPos = 1, $iTopPos = 1)
    Local $iLeftAct, $iTopAct, $iHeight = 1000
    $iX = Round($iX)
    $iY = Round($iY)
    Local $tLayout = _GDIPlus_RectFCreate($iX, $iY, $iWidth, $iHeight)
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sText, $hFont, $tLayout, $hFormat)
    Local $iStructWidth = Round(DllStructGetData($aInfo[0], "Width"))
    Local $iStructHeight = Round(DllStructGetData($aInfo[0], "Height"))
    If $iLeftPos Then
        $iLeftAct = $iX - ($iStructWidth / 2)
    Else
        $iLeftAct = $iX
    EndIf
    If $iTopPos Then
        $iTopAct = $iY - ($iStructHeight / 2)
    Else
        $iTopAct = $iY
    EndIf
    DllStructSetData($aInfo[0], "X", $iLeftAct)
    DllStructSetData($aInfo[0], "Y", $iTopAct)
    Local $iStructX = Round(DllStructGetData($aInfo[0], "X"))
    Local $iStructY = Round(DllStructGetData($aInfo[0], "Y"))
    _GDIPlus_GraphicsFillRect($hGraphics, $iStructX - 2, $iStructY, $iStructWidth, $iStructHeight, $hWhiteBrush)
    _GDIPlus_GraphicsDrawRect($hGraphics, $iStructX - 2, $iStructY, $iStructWidth, $iStructHeight)
    _GDIPlus_GraphicsDrawStringEx($hGraphics, $sText, $hFont, $aInfo[0], $hFormat, $hBlackBrush)
EndFunc   ;==>_TableLabel

Func _ShowComponents()
    Local $aTableGrid[$iColumns][$iRows][2], $iXSpherePos = 12, $iYSpherePos = 6, $iGuiXstartPos, $iGuiYstartPos, $iGuiXIncrement, $iGuiYIncrement, $iGuiXLastPos, $sSerialNos, $iSnoLength, $sNewSno
    For $iX = 0 To $iColumns - 1 Step 1
        For $iY = 0 To $iRows - 1 Step 1
            $aTableGrid[$iX][$iY][0] = $iBorder + Round(($iSquareSize * $iX))
            $aTableGrid[$iX][$iY][1] = $iBorder + Round(($iSquareSize * $iY))
        Next
    Next
    $iGuiXstartPos = $iXSpherePos - ($iXstartPos * - 1) / 250
    $iX = $iGuiXstartPos
    $iGuiYstartPos = $iYSpherePos - ($iYstartPos + 750) / 250
    $iY = $iGuiYstartPos
    $iGuiXIncrement = ($iXIncrement * - 1) / 250
    $iGuiYIncrement = $iYIncrement / 250
    $iGuiXLastPos = ($iGuiXstartPos - ($iXLastPos * - 1) / 250) + $iGuiXIncrement

    If Not $aSerialNos Or Not IsArray($aSerialNos) Then
        $sSerialNos = ""
        $iSnoLength = StringLen($sFirstNo)
        For $i = 1 To $iActQty Step 1
            $sNewSno = ($sFirstNo - 1) + $i
            $sSerialNos &= "|" & _StringRepeat("0", $iSnoLength - (StringLen($sNewSno))) & $sNewSno
        Next
        $aSerialNos = StringSplit(StringTrimLeft($sSerialNos, 1), "|")
    EndIf

    For $iLoad = 1 To $iActQty
        _GDIPlus_GraphicsFillPie($hGraphic, $aTableGrid[$iX][$iY][0] - $iSquareSize * .25, $aTableGrid[$iX][$iY][1] - $iSquareSize * .25, $iSquareSize * .5, $iSquareSize * .5, 0, 360, $hRedBrush)
        _GDIPlus_GraphicsDrawArc($hGraphic, $aTableGrid[$iX][$iY][0] - $iSquareSize * .25, $aTableGrid[$iX][$iY][1] - $iSquareSize * .25, $iSquareSize * .5, $iSquareSize * .5, 0, 360, $hOutLinePen)
        _TableLabel($hGraphic, $Prefix & " " & $aSerialNos[$iLoad] & " " & $sSuffix, $aTableGrid[$iX][$iY][0], $aTableGrid[$iX][$iY][1] + $iSquareSize * .25, $iSquareSize * .95, 1, 0)
        $iX = $iX - $iGuiXIncrement
        If $iX < $iGuiXLastPos Then
            $iX = $iGuiXstartPos
            $iY -= 1
        EndIf
    Next
EndFunc   ;==>_ShowComponents

As for how Graphics and Bitmaps object works. I guess that an example can explain better than words.

#include <GDIPlus.au3>

_GDIPlus_Startup()
Local $hGUI = GUICreate("Test", 400, 400)
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
Local $hPen = _GDIPlus_PenCreate(0xFFFF0000, 10)

GUISetState()
_GDIPlus_GraphicsDrawLine($hGraphics, 20, 95, 180, 95, $hPen)
MsgBox(0x40, "Title", "Text")

Local $hBmp = _GDIPlus_BitmapCreateFromGraphics(400, 400, $hGraphics)
Local $hBmpGraphics = _GDIPlus_ImageGetGraphicsContext($hBmp)

_GDIPlus_GraphicsClear($hGraphics, 0xFFD4D0C8)
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmp, 0, 0)
MsgBox(0x40, "Title", "Nothing, right??")

_GDIPlus_GraphicsClear($hBmpGraphics, 0xFFD4D0C8)
_GDIPlus_GraphicsDrawArc($hBmpGraphics, 20, 95, 160, 100, 180, 180, $hPen)
_GDIPlus_GraphicsClear($hGraphics, 0xFFD4D0C8)
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmp, 0, 0)
MsgBox(0x40, "Title", "..and now?")

_GDIPlus_GraphicsDispose($hBmpGraphics)
_GDIPlus_BitmapDispose($hBmp)
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hGraphics)
GUIDelete()

_GDIPlus_Shutdown()

..but to clarify it. Each Image object stores a Graphics object that defines any transformations, scaling, etc.. of the Image object. A Bitmap object is a descendant of the Image class so you can consider a Bitmap to be an Image object. When you create a Bitmap object from a Graphics object, you just create a Bitmap object that it's Graphics object is defined by the supplied Graphics object. This Graphics object does not contain anything but the properties (transformations, etc..) of the defining Graphics object.

Note that a GDI Bitmap object is not GDI+ Bitmap object, even though both are quite the same. Don't call _WinAPI_DeleteObject on GDI+ Bitmap object, as a good common usage.

Posted

Thank you very much Authenticity,

Its all clear now :party: that i was doing things back to front :mellow: , i read the function '_GDIPlus_BitmapCreateFromGraphics' as if a bitmap is created from the graphics.

I was thinking along the lines of it was taking a screen shot of already drawn graphics, but now i see that it is like creating a canvas/document to then draw on.

I picked up the error on using '_WinAPI_DeleteObject' from using old examples on the forum, now i understand it all better, i should be able to use the correct functions from the helpfile, thanks for pointing this out.

I didnt expect you to alter the first script but i think in you doing so, along with your example script helped me grasp what was going on.

When i first read your '..but to clarify it' i was a bit OMG :party: but its sunk in now and i was able to alter my second script to do what i was trying to do in the first place.

For anyone else thats confused :P here is what i ended up with.

#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstants.au3>
#include <WindowsConstants.au3>

Global $hGraphicGUI, $hPen, $hBMPBuff, $hGraphic, $hStoreAsBitmapInMemory, $hMyGraphicGraphic

_GdiGui()

Func _GdiGui()
    Local $hGui, $GuiSizeX = 300, $GuiSizeY = 300

    $hGui = GUICreate("GDIPlus Example", $GuiSizeX, $GuiSizeY)
    GUISetState()

    _GDIPlus_Startup()
    $hPen = _GDIPlus_PenCreate(0xFFFF0000, 3)

    ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event
    $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) ;Draw to this graphics, $hGraphicGUI, to display on GUI
    $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI); $hBMPBuff is a bitmap in memory
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff); Draw to this graphics, $hGraphic, being the graphics of $hBMPBuff
    ;End Double Buffer add-in 1 of 3

    $hStoreAsBitmapInMemory = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI)
    $hMyGraphicGraphic = _GDIPlus_ImageGetGraphicsContext($hStoreAsBitmapInMemory)
    MsgBox(0, "Pause", "The area in memory is created first to draw on")
    _GDIPlus_GraphicsDrawRect($hMyGraphicGraphic, 20, 20, 260, 260, $hPen)
    MsgBox(0, "Pause", "Line has been drawn but is not visable as it in memory")
    _GDIPlus_GraphicsDrawImage($hGraphic, $hStoreAsBitmapInMemory, 0, 0)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0); Draw bitmap, $hBMPBuff, to the GUI's graphics, $hGraphicGUI.
    MsgBox(0, "Pause", "The bmp from memory has been drawn onto the window")
    _GDIPlus_GraphicsDrawLine($hGraphic, 20, 150, 280, 150, $hPen)
    MsgBox(0, "Pause", "Add a line")

    GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3)
    GUIRegisterMsg(0x85, "MY_PAINT") ; $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize.

    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0); Draw bitmap, $hBMPBuff, to the GUI's graphics, $hGraphicGUI.

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            _Exit()
    EndSwitch
WEnd

EndFunc

;Func to auto-redraw on Windows internal PAINT messages.
Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    ;_WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN
    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_PAINT

Func _Exit()
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _GDIPlus_BitmapDispose($hStoreAsBitmapInMemory)
    _GDIPlus_BitmapDispose($hBMPBuff)
    _GDIPlus_Shutdown()
    Exit
EndFunc
GDIPlusDispose - A modified version of GDIPlus that auto disposes of its own objects before shutdown of the Dll using the same function Syntax as the original.EzMySql UDF - Use MySql Databases with autoit with syntax similar to SQLite UDF.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...