Live Windows in Sidebar
Experimenting with DLLCalls and PrintWindow i found a way to make screenshots very fast and from offscreen-windows (behind the active one!).
it looks a little bit like DeskMan.ahk but works completely different in background. no external iview.exe needed any more. a little dllcall does the trick. i guess this only works with windows xp. but with vista in the pipeline i dont care too much about the old windows versions.
i didnt find any similar scripts in AHK forum, so hopefully this is helpfull for others how to do realtime screenshots of even offscreen windows (not visible but not minimized)
Compared to the other version in the first post the screenshots are done in realtime which is nearly fast enough (every 2sec refresh) but i will improve this with buffers again, so if nothing changed no screenshots need to be taken. or the user could define which windows to "watch" in realtime.
my idea is to have some windows "active" like a file-copy dialog or a download window, which you put in backgound, but is updated regularly, and you get a glance whats going on. having this minimized window in your taskbar/dock (sidebar).
Have Fun.
I will merge this with the deskman.ahk script sometime.
Code:
OnExit, handle_exit
Main:
update_period = 2000
; a new window for the dock
Gui, +AlwaysOnTop -Caption +Owner
;Gui, Color, Red
screenleft := a_ScreenWidth - 103
Gui, Show, w100 h%a_ScreenHeight% x%screenleft% y30, LiveWindows
WinGet, hw_frame, id, LiveWindows
;WinSet, Transcolor, Red, ahk_id %hw_frame%
hdc_frame := GetDC( hw_frame )
; buffer
hdc_buffer := CreateCompatibleDC( hdc_frame )
hbm_buffer := CreateCompatibleBitmap( hdc_frame, a_ScreenWidth , a_ScreenHeight )
SelectObject( hdc_buffer, hbm_buffer )
; once
Gosub, update_dock
; start timer in a loop
SetTimer, update_dock, %update_period%
return
handle_exit:
DeleteObject( h_region )
DeleteObject( hbm_buffer )
DeleteDC( hdc_frame )
DeleteDC( hdc_buffer )
ExitApp
CreateCompatibleDC( p_dc )
{
return, DllCall( "gdi32.dll\CreateCompatibleDC", "uint", p_dc )
}
DeleteDC( p_dc )
{
DllCall( "gdi32.dll\DeleteDC", "uint", p_dc )
}
GetDC( p_hw )
{
return, DllCall( "GetDC", "uint", p_hw )
}
DeleteObject( p_object )
{
DllCall( "gdi32.dll\DeleteObject", "uint", p_object )
}
SelectObject( p_dc, p_bitmap )
{
DllCall( "gdi32.dll\SelectObject", "uint", p_dc, "uint", p_bitmap )
}
CreateCompatibleBitmap( p_dc, p_w, p_h )
{
return, DllCall( "gdi32.dll\CreateCompatibleBitmap", "uint", p_dc, "int", p_w, "int", p_h )
}
CreateRectRgn( p_x1, p_y1, p_x2, p_y2 )
{
return, DllCall( "gdi32.dll\CreateRectRgn", "int", p_x1, "int", p_y1, "int", p_x2, "int", p_y2 )
}
update_dock:
SRCCOPY = 0x00CC0020
; thumbnail size or targetsize for bltcopy
p_w = 100
p_h = 100
p_x = 0
p_y = 0
; offset for each thumbnail
ypos=0
; DEBUG: tooltip, "running" w %p_w% h %p_h% x %p_x% y %p_y%
hw_frame_old =
; Loop through all active windows-tasks (processes)
WinGet, ids, list,,, Program Manager
Loop, %ids%
{
StringTrimRight, task_id, ids%a_index%, 0 ; find the id of this window
; perhaps we dont need all this infos
winGetTitle, title , ahk_id %task_id%
WinGetClass, class , ahk_id %task_id% ;get Class-name
WinGetPos, x, y ,w,h, ahk_id %task_id%
; DEBUG: tooltip , %x% %y% %w% %h% %title%
; DEBUG: sleep, 1000
; for now lets use lazy ignore when window is too small of offscreen or has no title
if (title = "")or (w < 300 ) or (x < 0)
{
;
}
else
{
; find the current task
WinGet, hw_frame1, id, ahk_id %task_id%
; DEBUG: tooltip, "now" ids%a_index% "old" %hw_frame_old% "new" %hw_frame1% "id" %task_id%
; HERE IS THE MAGIC! this makes the screenshot (only works with Windows-XP! or gdiplus.dll)
pwin := DllCall("PrintWindow", "UInt", hw_frame1 ,"UInt", hdc_buffer , "UInt", 0)
; now draw the buffer to the Dock-Window, also scaling and moving offset for thumbnails (no antialize yet)
DllCall( "gdi32.dll\StretchBlt", "uint", hdc_frame, "int", 0, "int", ypos, "int", p_w, "int", p_h, "uint", hdc_buffer, "int", p_x, "int", p_y, "int", 400, "int", 400 ,"uint", SRCCOPY )
; DEBUG: sleep, 100
ypos +=100 ; move down to next thumbnail-position
}
}
; resize the window, so we cut of old stuff, pseudo transparent
WinMove , LiveWindows ,, screenleft, 30, 100 , ypos
; DEBUG: sleep , 1000
; DEBUG: tooltip, "now" %ypos%
return