I did the test function below, to help check if the flickering is really gone, how to use it:
Just replace the WinTitle with your current window, i suggest using a video on youtube or something that forces the window to be refreshed so often.
The function will capture the screen of the given WinTitle and paint it into the Gui picture control.
-Topic:
I was debugging the function GDI_SetImageX and i could see that the value of w and h on w := Numget( bm,4 ), h := Numget( bm,8 ) is 0, it shouldnt be the width and height of the WinTitle?
as the hBitmap passed to the function contains the same dimension as the WinTitle window, there's also something wrong with the WM_SETREDRAW lines.
As the function is from a very old topic i think something need to be updated, i dont understand much about Gdip, would like to request help on it.
Also, i could not understand, but sometimes it rarely flicks, and sometimes as seen in the video above it flickes a lot.
.
Code: Select all
;#include gdip.ahk
pToken := Gdip_Startup()
Gui, +Resize +E0x02000000 +E0x00080000
Gui, Color, 0
Gui, Add, Picture, x0 y0 hwndPic 0xE ; <=== Need add 0xE to the control.
Gui, Show, w1200 h600, YetFlickering
WinTitle := "Guns N' Roses - Sweet Child O' Mine (Official Music Video) - YouTube - Opera" ; <== Replace with your window title, i suggest using a browser with a video playing, or any window that refresh very often.
WinGet, Hwnd, Id, %WinTitle%
Loop {
hBm := Gdip_BitmapFromHWND(Hwnd, 1)
GDI_SetImageX(hBM, Pic)
DllCall( "DeleteObject", UInt, hBM )
}
Return
GDI_SetImageX( hBM, hCtrl ) { ; By SKAN Created 10-Nov-2011
; SetImage without flicker : www.autohotkey.com/forum/viewtopic.php?p=488784#488784
hdcSrc := DllCall( "CreateCompatibleDC", UInt,0 )
hdcDst := DllCall( "GetDC", UInt,hCtrl )
VarSetCapacity( bm,24,0 ) ; BITMAP Structure
DllCall( "GetObject", UInt,hbm, UInt,24, UInt,&bm )
w := Numget( bm,4 ), h := Numget( bm,8 )
hbmOld := DllCall( "SelectObject", UInt,hdcSrc, UInt,hBM )
hbmNew := DllCall( "CreateBitmap", Int,w, Int,h, UInt,NumGet( bm,16,"UShort" )
, UInt,NumGet( bm,18,"UShort" ), Int,0 )
hbmOld2 := DllCall( "SelectObject", UInt,hdcDst, UInt,hbmNew )
DllCall( "BitBlt", UInt,hdcDst, Int,0, Int,0, Int,w, Int,h
, UInt,hdcSrc, Int,0, Int,0, UInt,0x00CC0020 )
DllCall( "SelectObject", UInt,hdcSrc, UInt,hbmOld )
DllCall( "DeleteDC", UInt,hdcSrc ), DllCall( "ReleaseDC", UInt,hCtrl, UInt,hdcDst )
;DllCall( "SendMessage", UInt,hCtrl, UInt,0x0B, UInt,0, UInt,0 ) ; WM_SETREDRAW OFF
oBM := DllCall( "SendMessage", UInt,hCtrl, UInt,0x172, UInt,0, UInt,hBM ) ; STM_SETIMAGE
;DllCall( "SendMessage", UInt,hCtrl, UInt,0x0B, UInt,1, UInt,0 ) ; WM_SETREDRAW ON
DllCall( "DeleteObject", UInt,oBM )
}
; ================================================================================
; Adding these two functions in case someone doesn't have it, all other functions can be found in Gdip.Ahk
; ================================================================================
; Function Gdip_BitmapFromHWND
; Description Uses PrintWindow to get a handle to the specified window and return a bitmap from it
;
; hwnd handle to the window to get a bitmap from
; clientOnly capture only the client area of the window, without title bar and border
;
; return If the function succeeds, the return value is a pointer to a gdi+ bitmap
Gdip_BitmapFromHWND(hwnd, Return_hBitmap:=0, clientOnly:=0) {
; Restore the window if minimized! Must be visible for capture.
If DllCall("IsIconic", "ptr", hwnd)
DllCall("ShowWindow", "ptr", hwnd, "int", 4)
Static Ptr := "UPtr"
thisFlag := 0
If (clientOnly=1) {
VarSetCapacity(rc, 16, 0)
DllCall("GetClientRect", "ptr", hwnd, "ptr", &rc)
Width := NumGet(rc, 8, "int")
Height := NumGet(rc, 12, "int")
thisFlag := 1
}
Else
GetWindowRect(hwnd, Width, Height)
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
PrintWindow(hwnd, hdc, 2 + thisFlag)
If (Return_hBitmap) {
SelectObject(hdc, obm)
;DeleteObject(hbm)
DeleteDC(hdc)
Return hbm
}
pBitmap := Gdip_CreateBitmapFromHBITMAP(hbm)
SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc)
return pBitmap
}
; Function PrintWindow
; Description The PrintWindow function copies a visual window into the specified device context (DC), typically a printer DC
;
; hwnd A handle to the window that will be copied
; hdc A handle to the device context
; Flags Drawing options
;
; return If the function succeeds, it returns a nonzero value
;
; PW_CLIENTONLY = 1
PrintWindow(hwnd, hdc, Flags:=2) {
; set Flags to 2, to capture hardware accelerated windows
; this only applies on Windows 8.1 and later versions.
Static Ptr := "UPtr"
return DllCall("PrintWindow", Ptr, hwnd, Ptr, hdc, "uint", Flags)
}