Sign in to follow this  
Followers 0
charvi

GDI+ Pictures Display Error

5 posts in this topic

Good afternoon,

I think I have a GDI+ problem.

When the below program is run, you will see a first Win logo displayed. I then popup a window, the second logo is not displayed in the popup. Problem 1: should be IN the popup.

Problem 2: when the popup closes, the first logo is no longer there.

What I would like, is that the first logo always remains where he is, and the second logo be displayed in the popup only, and when closed, only the first logo should remain, complete of course.

; ## System File includes ==========================================================
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiStatusBar.au3>
#include <GuiEdit.au3>
#include <GuiMenu.au3>
#include <GuiToolBar.au3>
#include <GuiComboBoxEx.au3>
#include <Array.au3>
#include <Constants.au3>
#include <WinAPI.au3>
#include <File.au3>
#include <Misc.au3>
#include <GDIPlus.au3>
#include <Color.au3>
#include <INet.au3>
#include <Memory.au3>

_MLSAU_()

Func _MLSAU_()
;===================================================================
; Main Program declarations
    Global $h_WinMain; will be used in many programs to attach them as child
    Global $h_MLSAU_Hdc, $h_MLSAU_Wnd, $h_MLSAU_Pen
    Global $h_MLSAU_Image
    Local $h_Graph, $h_Pic
    Local $h_StatusBar, $h_BtnQuit, $h_BtnLogOff, $h_OSStartBar, $h_XP_Close, $h_XP_LogOff, $h_VistaLogo
    Local $ai_Msg[5]
    Local $i_User
    Local $s_UserName
    Global Const $ct_User32 = DllOpen("user32.dll")
    Global Const $ct_gdi32 = DllOpen("gdi32.dll")
;==================================================================

    $h_WinMain = GUICreate("TEST", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP)
    GUISetBkColor(0x838b83, $h_WinMain)

; ## Add Gradient
    $h_Pic = GUICtrlCreatePic("", 0, 0, @DesktopWidth, @DesktopHeight)
    _PicSetGradient_($h_Pic, 0, 0, @DesktopWidth, @DesktopHeight, "0x000000", "0xffffff", 1, False, "", "")
    GUICtrlSetState($h_Pic, $GUI_DISABLE)
;==================================================================
; ## Special Painting with GDI+
    _GDIPlus_Startup()
    $h_MLSAU_Wnd = WinGetHandle($h_WinMain)
    $h_MLSAU_Hdc = _GDIPlus_GraphicsCreateFromHWND($h_MLSAU_Wnd)
    GUIRegisterMsg($WM_PAINT, "_MLSAU_WM_PAINT_")

    $h_xPic = @ScriptDir & "bollogo.gif"
    $h_MLSAU_Image = _GDIPlus_ImageLoadFromFile($h_xPic)

    $h_BtnQuit = GUICtrlCreateButton("Quit", 10, 10, 100, 25)
    
    GUISetState()
    Sleep(2000)
    _Popup_()
    GUICtrlCreateLabel("Press [F5] to refresh the screen", 100, 100, 300, 20)
    
;===================================================================
    While 1
        If _IsPressed("74", $ct_User32) Then _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(),"","",BitOR($RDW_INVALIDATE,$RDW_UPDATENOW,$RDW_FRAME,$RDW_ALLCHILDREN)); F5-key to refresh the screen
        $ai_Msg = GUIGetMsg(1)
        Select
            Case $ai_Msg[0] = $GUI_EVENT_CLOSE And $ai_Msg[1] = $h_WinMain
                Exit
            Case $ai_Msg[0] = $h_BtnQuit And $ai_Msg[1] = $h_WinMain
                Exit
        EndSelect
    WEnd
EndFunc

_GDIPlus_GraphicsDispose($h_MLSAU_Hdc)
_GDIPlus_Shutdown()

;====================================================================
func _Popup_()
    Local $h_Popup, $h_PopupPic, $h_yPic
    Global $h_Popup_Wnd, $h_Popup_Hdc, $h_Popup_Image
    $h_Popup = GUICreate("", 500, 500, 250, 250, $WS_POPUP, 0, $h_WinMain)
    GUISetBkColor(0xeecbad,$h_Popup)
; ## Add Gradient
    $h_PopupPic = GUICtrlCreatePic("", 0, 0, @DesktopWidth, @DesktopHeight)
    _PicSetGradient_($h_PopupPic, 0, 0, @DesktopWidth, @DesktopHeight, "0xeecbad", "0xffffff", 1, False, "", "")
    GUICtrlSetState($h_PopupPic, $GUI_DISABLE)
;==================================================================
; ## Special Painting with GDI+
    _GDIPlus_Startup()
    $h_Popup_Wnd = WinGetHandle($h_WinMain)
    $h_Popup_Hdc = _GDIPlus_GraphicsCreateFromHWND($h_Popup_Wnd)
    GUIRegisterMsg($WM_PAINT, "_Popup_WM_PAINT_")

    $h_yPic = @ScriptDir & "bollogo.gif"
    $h_Popup_Image = _GDIPlus_ImageLoadFromFile($h_yPic)

    GUISetState()
    Sleep(2000)
    GUIDelete($h_Popup)
EndFunc
;==========================================================================

Func _MLSAU_WM_PAINT_($hWnd, $iMsg, $iwParam, $ilParam)
    _WinAPI_RedrawWindow($h_MLSAU_Wnd, 0, 0, $RDW_UPDATENOW); force redraw of pic (Rect=0 Region=0)
; ## BEGIN Drawing WM Paint ============================================
    _GDIPlus_GraphicsDrawImage($h_MLSAU_Hdc, $h_MLSAU_Image, 200, 200)
; ## END Drawing WM Paint ============================================
    _WinAPI_RedrawWindow($h_MLSAU_Wnd, 0, 0, $RDW_VALIDATE); then force no-redraw of pic
    Return $GUI_RUNDEFMSG
EndFunc

Func _Popup_WM_PAINT_($hWnd, $iMsg, $iwParam, $ilParam)
    _WinAPI_RedrawWindow($h_Popup_Wnd, 0, 0, $RDW_UPDATENOW); force redraw of pic (Rect=0 Region=0)
; ## BEGIN Drawing WM Paint ============================================
    _GDIPlus_GraphicsDrawImage($h_Popup_Hdc, $h_Popup_Image, 650, 650)
; ## END Drawing WM Paint ===============================================
    _WinAPI_RedrawWindow($h_Popup_Wnd, 0, 0, $RDW_VALIDATE); then force no-redraw of pic
    Return $GUI_RUNDEFMSG
EndFunc
;========================================================================
;==== PicSetGradient
; When using PicSetGradient(), we need the following elements:
; $hPicID          : the grphic handle, for example $cID = GUICtrlCreatePic("", 0, 0, $iW, $iH)
; $iX              : the left position of the graphical zone
; $iY              : the up position of the graphical zone
; $iW              : the width of the graphical zone
; $iH              : the height of the graphical zone
; $aFactors      : an array containing the color factors, for example: $aFactors[4] = [0.0, 0.4, 0.6, 1.0]
; $aPositions      : an array containing the color positions, for example: $aPositions[4] = [0.0, 0.3, 0.7, 1.0]
; $iClr1            : the color to start from, for example "0x800040"
; $iClr2            : the color to end to, for example "0xFFFFFF"
; $iDirection      : 0=left to right - 1=up to down - 2=left up to right down - 3=right up to left down
; $bGammaCorrection : gamma correction: True or False

Func _PicSetGradient_($hPicID, $iX, $iY, $iW, $iH, $iClr1, $iClr2, $iDirection, $bGammaCorrection, _
                      $an_Factors, $an_Positions)
    
    Local Const $STM_SETIMAGE = 0x0172
    Local Const $IMAGE_BITMAP = 0
    Local $hWnd, $iC1, $iC2, $hBitmap, $hImage, $hGraphic, $hBrushLin, $hbmp, $aBmp
    $hWnd = GUICtrlGetHandle($hPicID)

    If IsArray($an_Factors) = 0 Then Dim $an_Factors[10] = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9]; [4] = [0.0, 0.4, 0.6, 1.0]
    If IsArray($an_Positions) = 0 Then Dim $an_Positions[10] = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9]; [4] = [0.0, 0.3, 0.7, 1.0]

    $iC1 = StringReplace($iClr1, "0x", "0xFF")
    $iC2 = StringReplace($iClr2, "0x", "0xFF")
    $hBitmap = _WinAPI_CreateBitmap($iW, $iH, 1, 32)
    _GDIPlus_Startup()
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
    $hBrushLin = _GDIPlus_CreateLineBrushFromRect(0, 0, $iW, $iH, $an_Factors, $an_Positions, $iC1, $iC2, $iDirection)
    GDIPlus_SetLineGammaCorrection($hBrushLin, $bGammaCorrection)
    _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $iW, $iH, $hBrushLin)
    $hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $aBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hbmp)
    If $aBmp[0] <> 0 Then _WinAPI_DeleteObject($aBmp[0])
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BrushDispose($hBrushLin)
    _GDIPlus_GraphicsDispose($hGraphic)
    _WinAPI_DeleteObject($hbmp)
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_Shutdown()
EndFunc  ;==>PicSetGradient


;==== GDIPlus_CreateLineBrushFromRect === Malkey's function
; Description - Creates a LinearGradientBrush object from a set of boundary points and boundary colors.
; $an_Factors - If non-array, default array will be used.
;          Pointer to an array of real numbers that specify blend factors. Each number in the array
;          specifies a percentage of the ending color and should be in the range from 0.0 through 1.0.
; $an_Positions - If non-array, default array will be used.
;           Pointer to an array of real numbers that specify blend factors' positions. Each number in the array
;           indicates a percentage of the distance between the starting boundary and the ending boundary
;           and is in the range from 0.0 through 1.0, where 0.0 indicates the starting boundary of the
;           gradient and 1.0 indicates the ending boundary. There must be at least two positions
;           specified: the first position, which is always 0.0, and the last position, which is always
;           1.0. Otherwise, the behavior is undefined. A blend position between 0.0 and 1.0 indicates a
;           line, parallel to the boundary lines, that is a certain fraction of the distance from the
;           starting boundary to the ending boundary. For example, a blend position of 0.7 indicates
;           the line that is 70 percent of the distance from the starting boundary to the ending boundary.
;           The color is constant on lines that are parallel to the boundary lines.
; $iArgb1   - First Top color in 0xAARRGGBB format
; $iArgb2   - Second color in 0xAARRGGBB format
; $LinearGradientMode -  LinearGradientModeHorizontal      = 0x00000000
;                       LinearGradientModeVertical       = 0x00000001
;                       LinearGradientModeForwardDiagonal  = 0x00000002
;                       LinearGradientModeBackwardDiagonal = 0x00000003
; $WrapMode  - WrapModeTile    = 0
;             WrapModeTileFlipX  = 1
;             WrapModeTileFlipY  = 2
;             WrapModeTileFlipXY = 3
;             WrapModeClamp   = 4
; GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect, ARGB color1, ARGB color2,
;            LinearGradientMode mode, GpWrapMode wrapMode, GpLineGradient **lineGradient)
; Reference:  http://msdn.microsoft.com/en-us/library/ms534043(VS.85).aspx
;
Func _GDIPlus_CreateLineBrushFromRect($iX, $iY, $iWidth, $iHeight, $an_Factors, $an_Positions, _
        $iArgb1 = 0xFF0000FF, $iArgb2 = 0xFFFF0000, $LinearGradientMode = 0x00000001, $WrapMode = 0)

    Local $tRect, $pRect, $aRet, $tFactors, $pFactors, $tPositions, $pPositions, $iCount, $iI, $hStatus

    If $iArgb1 = Default Then $iArgb1 = 0xFF0000FF
    If $iArgb2 = Default Then $iArgb2 = 0xFFFF0000
    If $LinearGradientMode = -1 Or $LinearGradientMode = Default Then $LinearGradientMode = 0x00000001
    If $WrapMode = -1 Or $LinearGradientMode = Default Then $WrapMode = 1

    $tRect = DllStructCreate("float X;float Y;float Width;float Height")
    $pRect = DllStructGetPtr($tRect)
    DllStructSetData($tRect, "X", $iX)
    DllStructSetData($tRect, "Y", $iY)
    DllStructSetData($tRect, "Width", $iWidth)
    DllStructSetData($tRect, "Height", $iHeight)

   ;Note: Withn _GDIPlus_Startup(), $ghGDIPDll is defined
    $aRet = DllCall($ghGDIPDll, "int", "GdipCreateLineBrushFromRect", "ptr", $pRect, "int", $iArgb1, _
            "int", $iArgb2, "int", $LinearGradientMode, "int", $WrapMode, "int*", 0)

;~   If IsArray($an_Factors) = 0 Then Dim $an_Factors[10] = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9]; [4] = [0.0, 0.4, 0.6, 1.0]
;~   If IsArray($an_Positions) = 0 Then Dim $an_Positions[10] = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9]; [4] = [0.0, 0.3, 0.7, 1.0]

    $iCount = UBound($an_Positions)
    $tFactors = DllStructCreate("float[" & $iCount & "]")
    $pFactors = DllStructGetPtr($tFactors)
    For $iI = 0 To $iCount - 1
        DllStructSetData($tFactors, 1, $an_Factors[$iI], $iI + 1)
    Next
    $tPositions = DllStructCreate("float[" & $iCount & "]")
    $pPositions = DllStructGetPtr($tPositions)
    For $iI = 0 To $iCount - 1
        DllStructSetData($tPositions, 1, $an_Positions[$iI], $iI + 1)
    Next

    $hStatus = DllCall($ghGDIPDll, "int", "GdipSetLineBlend", "hwnd", $aRet[6], _
            "ptr", $pFactors, "ptr", $pPositions, "int", $iCount)
    Return $aRet[6]; Handle of Line Brush
EndFunc  ;==>_GDIPlus_CreateLineBrushFromRect

;===========================================================
; Description:  Specifies whether gamma correction is enabled for this linear gradient brush.
; Parameters
; $hBrush            - [in] Pointer to the LinearGradientBrush object.
; $useGammaCorrection - [in] Boolean value that specifies whether gamma correction occurs
;                    during rendering. TRUE specifies that gamma correction is enabled,
;                    and FALSE specifies that gamma correction is not enabled. By default,
;                    gamma correction is disabled during construction of a
;                    LinearGradientBrush object.
;GdipSetLineGammaCorrection(GpLineGradient *brush, BOOL useGammaCorrection)
;
Func GDIPlus_SetLineGammaCorrection($hBrush, $useGammaCorrection = True)
    Local $aResult  
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetLineGammaCorrection", "hwnd", $hBrush, "int", $useGammaCorrection)
    Return $aResult[0]
EndFunc  ;==>GDIPlus_SetLineGammaCorrection

post-39937-1229354743_thumb.gif

Share this post


Link to post
Share on other sites



Just briefly scanning through, I don't think you can register WM_PAINT twice. You'll have to handle both redraws in the same function. Use the first param of the function, $hWnd, to do a Switch statement for each GUI you want to process. ($hWnd = window handle the message is from)

Share this post


Link to post
Share on other sites

Just briefly scanning through, I don't think you can register WM_PAINT twice. You'll have to handle both redraws in the same function. Use the first param of the function, $hWnd, to do a Switch statement for each GUI you want to process. ($hWnd = window handle the message is from)

Thanks wraithdu for having taken a look at my script, and your answer is what I was afraid of. Switching seems thus to be the only solution. But it's really not easy as the WM PAINT contains the drawings for a specific handle... which are not valid for the other handle...

How shall I do the switch ?

Share this post


Link to post
Share on other sites

Now, I'm not guaranteeing the validity of your GDI+ :)

Func _WM_PAINT_($hWnd, $iMsg, $iwParam, $ilParam)
    Switch $hWnd
        Case $h_MLSAU_Wnd
            _WinAPI_RedrawWindow($h_MLSAU_Wnd, 0, 0, $RDW_UPDATENOW); force redraw of pic (Rect=0 Region=0)
            ; ## BEGIN Drawing WM Paint ============================================
            _GDIPlus_GraphicsDrawImage($h_MLSAU_Hdc, $h_MLSAU_Image, 200, 200)
            ; ## END Drawing WM Paint ============================================
            _WinAPI_RedrawWindow($h_MLSAU_Wnd, 0, 0, $RDW_VALIDATE); then force no-redraw of pic
        Case $h_Popup_Wnd
            _WinAPI_RedrawWindow($h_Popup_Wnd, 0, 0, $RDW_UPDATENOW); force redraw of pic (Rect=0 Region=0)
            ; ## BEGIN Drawing WM Paint ============================================
            _GDIPlus_GraphicsDrawImage($h_Popup_Hdc, $h_Popup_Image, 650, 650)
            ; ## END Drawing WM Paint ===============================================
            _WinAPI_RedrawWindow($h_Popup_Wnd, 0, 0, $RDW_VALIDATE); then force no-redraw of pic
    EndSwitch
        
    Return $GUI_RUNDEFMSG
EndFunc

Share this post


Link to post
Share on other sites

Excellent wraithdu !!! 5 stars assigned to you !!

I reposted my (working) code as there was also an error at line 92: the WinGetHandle in the _Popup_() function was referring to the wrong window handle.

Lines 51 and 94 were also updated to link to the unique WM_PAINT function.

Many many thanks for your help wraithdu !! Now I can continue programming :)

; ## System File includes ==========================================================
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiStatusBar.au3>
#include <GuiEdit.au3>
#include <GuiMenu.au3>
#include <GuiToolBar.au3>
#include <GuiComboBoxEx.au3>
#include <Array.au3>
#include <Constants.au3>
#include <WinAPI.au3>
#include <File.au3>
#include <Misc.au3>
#include <GDIPlus.au3>
#include <Color.au3>
#include <INet.au3>
#include <Memory.au3>

_MLSAU_()

Func _MLSAU_()
;===================================================================
; Main Program declarations
    Global $h_WinMain; will be used in many programs to attach them as child
    Global $h_MLSAU_Hdc, $h_MLSAU_Wnd, $h_MLSAU_Pen
    Global $h_MLSAU_Image
    Local $h_Graph, $h_Pic
    Local $h_StatusBar, $h_BtnQuit, $h_BtnLogOff, $h_OSStartBar, $h_XP_Close, $h_XP_LogOff, $h_VistaLogo
    Local $ai_Msg[5]
    Local $i_User
    Local $s_UserName
    Global Const $ct_User32 = DllOpen("user32.dll")
    Global Const $ct_gdi32 = DllOpen("gdi32.dll")
;==================================================================

    $h_WinMain = GUICreate("TEST", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP)
    GUISetBkColor(0x838b83, $h_WinMain)

; ## Add Gradient
    $h_Pic = GUICtrlCreatePic("", 0, 0, @DesktopWidth, @DesktopHeight)
    _PicSetGradient_($h_Pic, 0, 0, @DesktopWidth, @DesktopHeight, "0x000000", "0xffffff", 1, False, "", "")
    GUICtrlSetState($h_Pic, $GUI_DISABLE)
;==================================================================
; ## Special Painting with GDI+
    _GDIPlus_Startup()
    $h_MLSAU_Wnd = WinGetHandle($h_WinMain)
    $h_MLSAU_Hdc = _GDIPlus_GraphicsCreateFromHWND($h_MLSAU_Wnd)
    GUIRegisterMsg($WM_PAINT, "_WM_PAINT_")

    $h_xPic = @ScriptDir & "bollogo.gif"
    $h_MLSAU_Image = _GDIPlus_ImageLoadFromFile($h_xPic)

    $h_BtnQuit = GUICtrlCreateButton("Quit", 10, 10, 100, 25)
    
    GUISetState()
    Sleep(2000)
    _Popup_()
    GUICtrlCreateLabel("Press [F5] to refresh the screen", 100, 100, 300, 20)
    
;===================================================================
    While 1
        If _IsPressed("74", $ct_User32) Then _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(),"","",BitOR($RDW_INVALIDATE,$RDW_UPDATENOW,$RDW_FRAME,$RDW_ALLCHILDREN)); F5-key to refresh the screen
        $ai_Msg = GUIGetMsg(1)
        Select
            Case $ai_Msg[0] = $GUI_EVENT_CLOSE And $ai_Msg[1] = $h_WinMain
                Exit
            Case $ai_Msg[0] = $h_BtnQuit And $ai_Msg[1] = $h_WinMain
                Exit
        EndSelect
    WEnd
EndFunc

_GDIPlus_GraphicsDispose($h_MLSAU_Hdc)
_GDIPlus_Shutdown()

;====================================================================
func _Popup_()
    Local $h_Popup, $h_PopupPic, $h_yPic
    Global $h_Popup_Wnd, $h_Popup_Hdc, $h_Popup_Image
    $h_Popup = GUICreate("", 500, 500, 250, 250, $WS_POPUP, 0, $h_WinMain)
    GUISetBkColor(0xeecbad,$h_Popup)
; ## Add Gradient
    $h_PopupPic = GUICtrlCreatePic("", 0, 0, @DesktopWidth, @DesktopHeight)
    _PicSetGradient_($h_PopupPic, 0, 0, @DesktopWidth, @DesktopHeight, "0xeecbad", "0xffffff", 1, False, "", "")
    GUICtrlSetState($h_PopupPic, $GUI_DISABLE)
;==================================================================
; ## Special Painting with GDI+
    _GDIPlus_Startup()
    $h_Popup_Wnd = WinGetHandle($h_Popup)
    $h_Popup_Hdc = _GDIPlus_GraphicsCreateFromHWND($h_Popup_Wnd)
    GUIRegisterMsg($WM_PAINT, "_WM_PAINT_")

    $h_yPic = @ScriptDir & "bollogo.gif"
    $h_Popup_Image = _GDIPlus_ImageLoadFromFile($h_yPic)

    GUISetState()
    Sleep(2000)
    GUIDelete($h_Popup)
EndFunc
;==========================================================================

Func _WM_PAINT_($hWnd, $iMsg, $iwParam, $ilParam)
    Switch $hWnd
        Case $h_MLSAU_Wnd
            _WinAPI_RedrawWindow($h_MLSAU_Wnd, 0, 0, $RDW_UPDATENOW); force redraw of pic (Rect=0 Region=0)
           ; ## BEGIN Drawing WM Paint ============================================
            _GDIPlus_GraphicsDrawImage($h_MLSAU_Hdc, $h_MLSAU_Image, 200, 200)
           ; ## END Drawing WM Paint ============================================
            _WinAPI_RedrawWindow($h_MLSAU_Wnd, 0, 0, $RDW_VALIDATE); then force no-redraw of pic
        Case $h_Popup_Wnd
            _WinAPI_RedrawWindow($h_Popup_Wnd, 0, 0, $RDW_UPDATENOW); force redraw of pic (Rect=0 Region=0)
           ; ## BEGIN Drawing WM Paint ============================================
            _GDIPlus_GraphicsDrawImage($h_Popup_Hdc, $h_Popup_Image, 150, 150)
           ; ## END Drawing WM Paint ===============================================
            _WinAPI_RedrawWindow($h_Popup_Wnd, 0, 0, $RDW_VALIDATE); then force no-redraw of pic
    EndSwitch
        
    Return $GUI_RUNDEFMSG
EndFunc
;========================================================================
;==== PicSetGradient
; When using PicSetGradient(), we need the following elements:
; $hPicID          : the grphic handle, for example $cID = GUICtrlCreatePic("", 0, 0, $iW, $iH)
; $iX              : the left position of the graphical zone
; $iY              : the up position of the graphical zone
; $iW              : the width of the graphical zone
; $iH              : the height of the graphical zone
; $aFactors      : an array containing the color factors, for example: $aFactors[4] = [0.0, 0.4, 0.6, 1.0]
; $aPositions      : an array containing the color positions, for example: $aPositions[4] = [0.0, 0.3, 0.7, 1.0]
; $iClr1            : the color to start from, for example "0x800040"
; $iClr2            : the color to end to, for example "0xFFFFFF"
; $iDirection      : 0=left to right - 1=up to down - 2=left up to right down - 3=right up to left down
; $bGammaCorrection : gamma correction: True or False

Func _PicSetGradient_($hPicID, $iX, $iY, $iW, $iH, $iClr1, $iClr2, $iDirection, $bGammaCorrection, _
                      $an_Factors, $an_Positions)
    
    Local Const $STM_SETIMAGE = 0x0172
    Local Const $IMAGE_BITMAP = 0
    Local $hWnd, $iC1, $iC2, $hBitmap, $hImage, $hGraphic, $hBrushLin, $hbmp, $aBmp
    $hWnd = GUICtrlGetHandle($hPicID)

    If IsArray($an_Factors) = 0 Then Dim $an_Factors[10] = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9]; [4] = [0.0, 0.4, 0.6, 1.0]
    If IsArray($an_Positions) = 0 Then Dim $an_Positions[10] = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9]; [4] = [0.0, 0.3, 0.7, 1.0]

    $iC1 = StringReplace($iClr1, "0x", "0xFF")
    $iC2 = StringReplace($iClr2, "0x", "0xFF")
    $hBitmap = _WinAPI_CreateBitmap($iW, $iH, 1, 32)
    _GDIPlus_Startup()
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
    $hBrushLin = _GDIPlus_CreateLineBrushFromRect(0, 0, $iW, $iH, $an_Factors, $an_Positions, $iC1, $iC2, $iDirection)
    GDIPlus_SetLineGammaCorrection($hBrushLin, $bGammaCorrection)
    _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $iW, $iH, $hBrushLin)
    $hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $aBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hbmp)
    If $aBmp[0] <> 0 Then _WinAPI_DeleteObject($aBmp[0])
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_BrushDispose($hBrushLin)
    _GDIPlus_GraphicsDispose($hGraphic)
    _WinAPI_DeleteObject($hbmp)
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_Shutdown()
EndFunc ;==>PicSetGradient


;==== GDIPlus_CreateLineBrushFromRect === Malkey's function
; Description - Creates a LinearGradientBrush object from a set of boundary points and boundary colors.
; $an_Factors - If non-array, default array will be used.
;          Pointer to an array of real numbers that specify blend factors. Each number in the array
;          specifies a percentage of the ending color and should be in the range from 0.0 through 1.0.
; $an_Positions - If non-array, default array will be used.
;           Pointer to an array of real numbers that specify blend factors' positions. Each number in the array
;           indicates a percentage of the distance between the starting boundary and the ending boundary
;           and is in the range from 0.0 through 1.0, where 0.0 indicates the starting boundary of the
;           gradient and 1.0 indicates the ending boundary. There must be at least two positions
;           specified: the first position, which is always 0.0, and the last position, which is always
;           1.0. Otherwise, the behavior is undefined. A blend position between 0.0 and 1.0 indicates a
;           line, parallel to the boundary lines, that is a certain fraction of the distance from the
;           starting boundary to the ending boundary. For example, a blend position of 0.7 indicates
;           the line that is 70 percent of the distance from the starting boundary to the ending boundary.
;           The color is constant on lines that are parallel to the boundary lines.
; $iArgb1   - First Top color in 0xAARRGGBB format
; $iArgb2   - Second color in 0xAARRGGBB format
; $LinearGradientMode -  LinearGradientModeHorizontal      = 0x00000000
;                       LinearGradientModeVertical       = 0x00000001
;                       LinearGradientModeForwardDiagonal  = 0x00000002
;                       LinearGradientModeBackwardDiagonal = 0x00000003
; $WrapMode  - WrapModeTile    = 0
;             WrapModeTileFlipX  = 1
;             WrapModeTileFlipY  = 2
;             WrapModeTileFlipXY = 3
;             WrapModeClamp   = 4
; GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect, ARGB color1, ARGB color2,
;            LinearGradientMode mode, GpWrapMode wrapMode, GpLineGradient **lineGradient)
; Reference:  http://msdn.microsoft.com/en-us/library/ms534043(VS.85).aspx
;
Func _GDIPlus_CreateLineBrushFromRect($iX, $iY, $iWidth, $iHeight, $an_Factors, $an_Positions, _
        $iArgb1 = 0xFF0000FF, $iArgb2 = 0xFFFF0000, $LinearGradientMode = 0x00000001, $WrapMode = 0)

    Local $tRect, $pRect, $aRet, $tFactors, $pFactors, $tPositions, $pPositions, $iCount, $iI, $hStatus

    If $iArgb1 = Default Then $iArgb1 = 0xFF0000FF
    If $iArgb2 = Default Then $iArgb2 = 0xFFFF0000
    If $LinearGradientMode = -1 Or $LinearGradientMode = Default Then $LinearGradientMode = 0x00000001
    If $WrapMode = -1 Or $LinearGradientMode = Default Then $WrapMode = 1

    $tRect = DllStructCreate("float X;float Y;float Width;float Height")
    $pRect = DllStructGetPtr($tRect)
    DllStructSetData($tRect, "X", $iX)
    DllStructSetData($tRect, "Y", $iY)
    DllStructSetData($tRect, "Width", $iWidth)
    DllStructSetData($tRect, "Height", $iHeight)

  ;Note: Withn _GDIPlus_Startup(), $ghGDIPDll is defined
    $aRet = DllCall($ghGDIPDll, "int", "GdipCreateLineBrushFromRect", "ptr", $pRect, "int", $iArgb1, _
            "int", $iArgb2, "int", $LinearGradientMode, "int", $WrapMode, "int*", 0)

;~   If IsArray($an_Factors) = 0 Then Dim $an_Factors[10] = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9]; [4] = [0.0, 0.4, 0.6, 1.0]
;~   If IsArray($an_Positions) = 0 Then Dim $an_Positions[10] = [0,.1,.2,.3,.4,.5,.6,.7,.8,.9]; [4] = [0.0, 0.3, 0.7, 1.0]

    $iCount = UBound($an_Positions)
    $tFactors = DllStructCreate("float[" & $iCount & "]")
    $pFactors = DllStructGetPtr($tFactors)
    For $iI = 0 To $iCount - 1
        DllStructSetData($tFactors, 1, $an_Factors[$iI], $iI + 1)
    Next
    $tPositions = DllStructCreate("float[" & $iCount & "]")
    $pPositions = DllStructGetPtr($tPositions)
    For $iI = 0 To $iCount - 1
        DllStructSetData($tPositions, 1, $an_Positions[$iI], $iI + 1)
    Next

    $hStatus = DllCall($ghGDIPDll, "int", "GdipSetLineBlend", "hwnd", $aRet[6], _
            "ptr", $pFactors, "ptr", $pPositions, "int", $iCount)
    Return $aRet[6]; Handle of Line Brush
EndFunc ;==>_GDIPlus_CreateLineBrushFromRect

;===========================================================
; Description:  Specifies whether gamma correction is enabled for this linear gradient brush.
; Parameters
; $hBrush            - [in] Pointer to the LinearGradientBrush object.
; $useGammaCorrection - [in] Boolean value that specifies whether gamma correction occurs
;                    during rendering. TRUE specifies that gamma correction is enabled,
;                    and FALSE specifies that gamma correction is not enabled. By default,
;                    gamma correction is disabled during construction of a
;                    LinearGradientBrush object.
;GdipSetLineGammaCorrection(GpLineGradient *brush, BOOL useGammaCorrection)
;
Func GDIPlus_SetLineGammaCorrection($hBrush, $useGammaCorrection = True)
    Local $aResult  
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetLineGammaCorrection", "hwnd", $hBrush, "int", $useGammaCorrection)
    Return $aResult[0]
EndFunc ;==>GDIPlus_SetLineGammaCorrection

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0