Jump to content

Repainting background image


Recommended Posts

Hi everyone

See below my script. I have two problems/questions

1) Is there way to keep the image during the winanimate sequence when ` is pressed. Why does the image not restore after winanimate

2) Why does it inconsistently or have a delay redraw of the image when restored (tap Win+D a couple times) or winanimate it a few times to see what I mean.

Thanks for any advice.

Picea892

#include <WindowsConstants.au3>
#Include <Constants.au3>
#include <GuiConstants.au3>
#include <GUIConstantsEx.au3>
#include <winapi.au3>
#include <GDIPlus.au3>

OnAutoItExitRegister("ended")
HotKeySet("`","togglequick")
global $quickonoff=1, $view=1
Global $hImage,$listviewGui

_starting()

func _starting()
    Global    $reqwidth=1280
    _GDIPlus_Startup()
    Global $hImage1 = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\metal_small.jpg")
    Global $iX1 = _GDIPlus_ImageGetWidth($hImage1)
    Global $iY1 = _GDIPlus_ImageGetHeight($hImage1)
    Global $listviewGui = GUICreate("listviews", $reqwidth,$iY1, 10, @DesktopHeight-185, $WS_POPUP,$WS_EX_TOOLWINDOW)

    GUISetState()
    ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event
    global $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($listviewGui) ;Draw to this graphics, $hGraphicGUI, to display on GUI
    Global $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($reqwidth, $iY1, $hGraphicGUI); $hBMPBuff is a bitmap in memory
    Global $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff); Draw to this graphics, $hGraphic, being the graphics of $hBMPBuff

    $num=Int($reqwidth/$iX1)
    for $i = 0 to $num
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage1,$i*$iX1,0,$iX1,$iY1)
    Next
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)

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

while 1
    Sleep (1000)
WEnd


Func togglequick()
if $quickonoff=0 then
    _Win_xPlode(WinGetHandle($listviewGui,""), 300,"0x00040008")
    $quickonoff=1   
Else
    _Win_xPlode(WinGetHandle($listviewGui,""), 300,"0x00050004")
    $quickonoff=0
EndIf
EndFunc


Func _Win_xPlode($hWnd, $tDel = 600, $ty="0x00040001")
  DllCall("user32.dll", "int", "AnimateWindow", "hwnd", WinGetHandle($hWnd,""), "int", $tDel, "long", $ty)
    If StringMid($ty,6,1) = 4 Then
      GUISetState(@SW_SHOW, $hWnd)
    Else
      GUISetState(@SW_Hide, $hWnd)
    EndIf
EndFunc   ;==>_Win_Plode

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 ended()
        _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _WinAPI_DeleteObject($hBMPBuff)
    _GDIPlus_Shutdown()
    ConsoleWrite("ended")
EndFunc

post-45064-0-69380800-1307117871_thumb.j

Link to comment
Share on other sites

If I have to guess on #1, WinAnimate doesn't play well with GDI+. You can at least redraw the window by adding MY_PAINT(1,2,3,4) after the animation sequence that restores the GUI.

Edited by wraithdu
Link to comment
Share on other sites

Here is a non-flickering version with consistent repaints, and a few other nitpicky items fixed. The animation still messes with the bkgnd though.

#include <WindowsConstants.au3>
#include <Constants.au3>
#include <GuiConstants.au3>
#include <GUIConstantsEx.au3>
#include <winapi.au3>
#include <GDIPlus.au3>

OnAutoItExitRegister("ended")
HotKeySet("`", "togglequick")
HotKeySet("{ESC}", "fexit")
Global $quickonoff = 1, $view = 1
Global $hImage, $listviewGui

_starting()

Func _starting()
    Global $reqwidth = 1280
    _GDIPlus_Startup()
    Global $hImage1 = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\metal_small.jpg")
    Global $iX1 = _GDIPlus_ImageGetWidth($hImage1)
    Global $iY1 = _GDIPlus_ImageGetHeight($hImage1)
    Global $listviewGui = GUICreate("listviews", $reqwidth, $iY1, 10, @DesktopHeight - 185, $WS_POPUP, $WS_EX_TOOLWINDOW)

    GUISetState()
    ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event
    Global $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($listviewGui) ;Draw to this graphics, $hGraphicGUI, to display on GUI
    Global $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($reqwidth, $iY1, $hGraphicGUI); $hBMPBuff is a bitmap in memory
    Global $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff); Draw to this graphics, $hGraphic, being the graphics of $hBMPBuff

    $num = Int($reqwidth / $iX1)
    For $i = 0 To $num
        _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage1, $i * $iX1, 0, $iX1, $iY1)
    Next
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)

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

While 1
    Sleep(1000)
WEnd


Func togglequick()
    If $quickonoff = 0 Then
        _Win_xPlode($listviewGui, 300, "0x00040008")
        $quickonoff = 1
        MY_PAINT(1,2,3,4)
    Else
        _Win_xPlode($listviewGui, 300, "0x00050004")
        $quickonoff = 0
    EndIf
EndFunc   ;==>togglequick


Func _Win_xPlode($hWnd, $tDel = 600, $ty = "0x00040001")
    DllCall("user32.dll", "int", "AnimateWindow", "hwnd", $hWnd, "int", $tDel, "long", $ty)
EndFunc   ;==>_Win_xPlode

Func MY_PAINT($hWnd, $msg, $wParam, $lParam)
    _WinAPI_RedrawWindow($listviewGui, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>MY_PAINT

Func ended()
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_GraphicsDispose($hGraphicGUI)
    _WinAPI_DeleteObject($hBMPBuff)
    _GDIPlus_Shutdown()
    ConsoleWrite("ended" & @CRLF)
EndFunc   ;==>ended

Func fexit()
    Exit
EndFunc
Link to comment
Share on other sites

Thanks wraithdu.

You made it work, repainting is now consistent. Always repaints after a restore and winanimate effect. I guess I won't be using the winanimate since as you say they don't play well together. It's easy enough to make your own effect anyway.

Thanks for your time on this.

Picea892

Link to comment
Share on other sites

Well I didn't 'say' they don't play well together... more of an observation. I did some more googling after my post, and didn't find any satisfactory solutions to that particular problem, except to learn that WinAnimate seems to create its own buffers for animation. I'm guessing those buffers do not have your GDI+ background, which is why it is blank when sliding. Maybe instead create a disabled pic control as the background to your GUI and paint somehow to that?

Link to comment
Share on other sites

What I found out is that it has something to do with the styles of the GUI. If you set the style and ext. style to default it seems to be working.

Here another way:

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>

OnAutoItExitRegister("ended")
HotKeySet("`","togglequick")
global $quickonoff=1, $view=1
Global $hImage,$listviewGui

_starting()

func _starting()
    Global    $reqwidth=1280
    _GDIPlus_Startup()
    Local $hImage1 = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\metal_small.jpg")
    Local $iX1 = _GDIPlus_ImageGetWidth($hImage1)
    Local $iY1 = _GDIPlus_ImageGetHeight($hImage1)
    Local $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $reqwidth, "int", $iY1, "int", 0, "int",  0x0026200A, "ptr", 0, "int*", 0)
    $hBitmap = $hBitmap[6]
    Local $hCtx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    For $i = 0 To $reqwidth Step $iX1
        _GDIPlus_GraphicsDrawImage($hCtx, $hImage1, $i, 0)
    Next
    Local $hBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _GDIPlus_ImageDispose($hImage1)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hCtx)
    Local $listviewGui = GUICreate("listviews", $reqwidth,$iY1, 10, @DesktopHeight-185);, $WS_POPUP, $WS_EX_TOOLWINDOW)
    Local $Pic = GUICtrlCreatePic("", 0, 0, $reqwidth, $iY1)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()
    Local Const $STM_SETIMAGE = 0x0172
    _WinAPI_DeleteObject(GUICtrlSendMsg($Pic, $STM_SETIMAGE, 0, $hBmp))
    _WinAPI_DeleteObject($hBmp)

EndFunc

while 1
    Sleep (1000)
WEnd


Func togglequick()
if $quickonoff=0 then
    _Win_xPlode(WinGetHandle($listviewGui,""), 300,"0x00040008")
    $quickonoff=1
Else
    _Win_xPlode(WinGetHandle($listviewGui,""), 300,"0x00050004")
    $quickonoff=0
EndIf
EndFunc


Func _Win_xPlode($hWnd, $tDel = 600, $ty="0x00040001")
  DllCall("user32.dll", "int", "AnimateWindow", "hwnd", WinGetHandle($hWnd,""), "int", $tDel, "long", $ty)
    If StringMid($ty,6,1) = 4 Then
      GUISetState(@SW_SHOW, $hWnd)
    Else
      GUISetState(@SW_Hide, $hWnd)
    EndIf
EndFunc   ;==>_Win_Plode


func ended()
    _GDIPlus_Shutdown()
    ConsoleWrite("ended")
EndFunc

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Thanks...so guictlrcreatepic it is. Great example Uez. Thanks all for the help.

Picea892

In case it's of any interest, when you set the bitmap to the Pic using $STM_SETIMAGE the size of the pic is set by the size of the bitmap so setting the initial size of the pic is not necesary. It can prolong the life of several synapses to know that. Also, it means that if the pic has no image initially then you can set the size to 0, 0 and you don't get an unwanted black area waiting untill you set the image from a bitmap.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
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
 Share

  • Recently Browsing   0 members

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