Scale thumbnail clone to always fit GUI Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Scale thumbnail clone to always fit GUI

19 May 2017, 10:27

I have been finding it very tricky scaling these thumbnails to always fit inside gui. Even when source gets resized. Also trying to keep aspect ratio since source is a TV app. I think coco has a script dealing with this but its very advanced and Im having a hard time to follow what is happening. Perhaps someone out there has experience with this before? The hardest parts with GUI stuff is positioning, no contest about that.

Code: Select all

;this requires the Windows 7 Aero Theme to be enabled
; initializing the script:
#SingleInstance force
#NoEnv
#KeyHistory 0
SetWorkingDir %A_ScriptDir%
;#include C:\Thumbnail.ahk

WinGet, dvbviewer_ID, ID, ahk_class TfrmMain
WinGetPos, RegionX, RegionY, RegionW, RegionH, ahk_class TfrmMain
windowWidth := 450 ; 16:9 aspect ration
windowHeight := 253 ; 16:9 aspect ration

; get the handles:
Gui +LastFound
hDestination := WinExist() ; ... to our GUI...
hSource := WinExist("ahk_exe dvbviewer.exe") ;

; creating the thumbnail:
hThumb := Thumbnail_Create(hDestination, hSource) ; you must get the return value here!

; getting the source window dimensions:
Thumbnail_GetSourceSize(hThumb, width, height)

  ;-- make sure ratio is correct
  CorrectRatio := RegionW / RegionH
  testWidth := windowHeight * CorrectRatio
  if (windowWidth <  testWidth)
  {
     windowHeight := windowWidth / CorrectRatio
  }
  else
  {
     windowWidth := testWidth
  }
  

; then setting its region:
Thumbnail_SetRegion(hThumb, 0, 0 , windowWidth, windowHeight, 0 , 0 ,RegionW, RegionH)



; now some GUI stuff:
Gui +AlwaysOnTop +ToolWindow +Resize 

; Now we can show it:
Thumbnail_Show(hThumb) ; but it is not visible now...
Gui Show, w%windowWidth% h%windowHeight%, Live Thumbnail ; ... until we show the GUI
OnMessage(0x201, "WM_LBUTTONDOWN")
return


GuiSize:
  ;if ErrorLevel = 1  ; The window has been minimized.  No action needed.
  ;  return
  
 Thumbnail_Destroy(thumbID)
  ThumbWidth := A_GuiWidth
  ThumbHeight := A_GuiHeight
 ;thumbID := mainCode(targetName,ThumbWidth,ThumbHeight,start_x,start_y,Rwidth,Rheight)
return

;----------------------------------------------------------------------

GuiClose: ; in case the GUI is closed:
	Thumbnail_Destroy(thumbID) ; free the resources
ExitApp


WM_LBUTTONDOWN(wParam, lParam)
{
    mX := lParam & 0xFFFF
    mY := lParam >> 16
    SendClickThrough(mX,mY)
}

SendClickThrough(mX,mY)
{
  global 
  
  convertedX := Round((mX / ThumbWidth)*Rwidth + start_x)
  convertedY := Round((mY / ThumbHeight)*Rheight + start_y)
  ;msgBox, x%convertedX% y%convertedY%, %targetName%
  ControlClick, x%convertedX% y%convertedY%, %targetName%,,,, NA
;  sleep, 250
;  ControlClick, x%convertedX% y%convertedY%, %targetName%,,,, NA u
}
*/

/**************************************************************************************************************
title: Thumbnail functions
wrapped by maul.esel

Credits:
- skrommel for example how to show a thumbnail (http://www.autohotkey.com/forum/topic34318.html)
- RaptorOne & IsNull for correcting some mistakes in the code

NOTE:
*This requires Windows Vista or Windows7* (tested on Windows 7)
Quick-Tutorial:
To add a thumbnail to a gui, you must know the following:
- the hwnd / id of your gui
- the hwnd / id of the window to show
- the coordinates where to show the thumbnail
- the coordinates of the area to be shown
1. Create a thumbnail with Thumbnail_Create()
2. Set its regions with Thumbnail_SetRegion()
a. optionally query for the source windows width and height before with <Thumbnail_GetSourceSize()>
3. optionally set the opacity with <Thumbnail_SetOpacity()>
4. show the thumbnail with <Thumbnail_Show()>
***************************************************************************************************************
*/


/**************************************************************************************************************
Function: Thumbnail_Create()
creates a thumbnail relationship between two windows

params:
handle hDestination - the window that will show the thumbnail
handle hSource - the window whose thumbnail will be shown
returns:
handle hThumb - thumbnail id on success, false on failure

Remarks:
To get the Hwnds, you could use WinExist()
***************************************************************************************************************
*/
Thumbnail_Create(hDestination, hSource) {

VarSetCapacity(thumbnail, 4, 0)
if DllCall("dwmapi.dll\DwmRegisterThumbnail", "UInt", hDestination, "UInt", hSource, "UInt", &thumbnail)
return false
return NumGet(thumbnail)
}


/**************************************************************************************************************
Function: Thumbnail_SetRegion()
defines dimensions of a previously created thumbnail

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
int xDest - the x-coordinate of the rendered thumbnail inside the destination window
int yDest - the y-coordinate of the rendered thumbnail inside the destination window
int wDest - the width of the rendered thumbnail inside the destination window
int hDest - the height of the rendered thumbnail inside the destination window
int xSource - the x-coordinate of the area that will be shown inside the thumbnail
int ySource - the y-coordinate of the area that will be shown inside the thumbnail
int wSource - the width of the area that will be shown inside the thumbnail
int hSource - the height of the area that will be shown inside the thumbnail
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_SetRegion(hThumb, xDest, yDest, wDest, hDest, xSource, ySource, wSource, hSource) {
dwFlags := 0x00000001 | 0x00000002

VarSetCapacity(dskThumbProps, 45, 0)

NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(xDest, dskThumbProps, 4, "Int")
NumPut(yDest, dskThumbProps, 8, "Int")
NumPut(wDest+xDest, dskThumbProps, 12, "Int")
NumPut(hDest+yDest, dskThumbProps, 16, "Int")

NumPut(xSource, dskThumbProps, 20, "Int")
NumPut(ySource, dskThumbProps, 24, "Int")
NumPut(wSource+xSource, dskThumbProps, 28, "Int")
NumPut(hSource+ySource, dskThumbProps, 32, "Int")

return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}


/**************************************************************************************************************
Function: Thumbnail_Show()
shows a previously created and sized thumbnail

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_Show(hThumb) {
static dwFlags := 0x00000008, fVisible := 1

VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(fVisible, dskThumbProps, 37, "Int")

return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}


/**************************************************************************************************************
Function: Thumbnail_Hide()
hides a thumbnail. It can be shown again without recreating

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_Hide(hThumb) {
static dwFlags := 0x00000008, fVisible := 0

VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "Uint")
NumPut(fVisible, dskThumbProps, 37, "Int")
return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}


/**************************************************************************************************************
Function: Thumbnail_Destroy()
destroys a thumbnail relationship

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_Destroy(hThumb) {
return DllCall("dwmapi.dll\DwmUnregisterThumbnail", "UInt", hThumb) ? false : true
}


/**************************************************************************************************************
Function: Thumbnail_GetSourceSize()
gets the width and height of the source window - can be used with <Thumbnail_SetRegion()>

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
ByRef int width - receives the width of the window
ByRef int height - receives the height of the window
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_GetSourceSize(hThumb, ByRef width, ByRef height) {
VarSetCapacity(Size, 8, 0)
if DllCall("dwmapi.dll\DwmQueryThumbnailSourceSize", "Uint", hThumb, "Uint", &Size)
return false
width := NumGet(&Size + 0, 0, "int")
height := NumGet(&Size + 0, 4, "int")
return true
}


/**************************************************************************************************************
Function: Thumbnail_SetOpacity()
sets the current opacity level

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
int opacity - the opacity level from 0 to 255 (will wrap to the other end if invalid)
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_SetOpacity(hThumb, opacity) {
static dwFlags := 0x00000004

VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(opacity, dskThumbProps, 36, "UChar")
return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "Uint", hThumb, "UInt", &dskThumbProps) ? false : true
}

/**************************************************************************************************************
section: example
This example sctript shows a thumbnail of your desktop in a GUI
(start code)
; initializing the script:
#SingleInstance force
#NoEnv
#KeyHistory 0
SetWorkingDir %A_ScriptDir%
#include Thumbnail.ahk

; get the handles:
Gui +LastFound
hDestination := WinExist() ; ... to our GUI...
hSource := WinExist("ahk_class Progman") ; ... and to the desktop

; creating the thumbnail:
hThumb := Thumbnail_Create(hDestination, hSource) ; you must get the return value here!

; getting the source window dimensions:
Thumbnail_GetSourceSize(hThumb, width, height)

; then setting its region:
Thumbnail_SetRegion(hThumb, 25, 25 ; x and y in the GUI
, 400, 350 ; display dimensions
, 0, 0 ; source area coordinates
, width, height) ; the values from Thumbnail_GetSourceSize()

; now some GUI stuff:
Gui +AlwaysOnTop +ToolWindow
Gui Add, Button, gHideShow x0 y0, Hide / Show

; Now we can show it:
Thumbnail_Show(hThumb) ; but it is not visible now...
Gui Show, w450 h400 ; ... until we show the GUI

; even now we can set the transparency:
Thumbnail_SetOpacity(hThumb, 200)

return

GuiClose: ; in case the GUI is closed:
Thumbnail_Destroy(hThumb) ; free the resources
ExitApp

HideShow: ; in case the button is clicked:
if hidden
Thumbnail_Show(hThumb)
else
Thumbnail_Hide(hThumb)

hidden := !hidden
return
(end)
***************************************************************************************************************
*/
Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: Scale thumbnail clone to always fit GUI

19 May 2017, 12:57

Hi, zcooler.
I'm not really getting the issue, your gui seems to have the same aspect ratio as the source window, do you mean that you want to force resize of gui to keep ratio and still have thumbnail covering the gui?
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Scale thumbnail clone to always fit GUI

19 May 2017, 14:00

Sorry, I was in a hurry writing that :oops:
Helgef wrote:Hi, zcooler.
I'm not really getting the issue, your gui seems to have the same aspect ratio as the source window, do you mean that you want to force resize of gui to keep ratio and still have thumbnail covering the gui?
Exactly spot on what Im after and the only way I can accomplish this effect is with Transparency and Transcolor, but since the thumbnail has clickable features I can not use that method because of the click fall-through. Havent found any working method to toggle that off.
Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: Scale thumbnail clone to always fit GUI

19 May 2017, 14:15

Ok, I don't get the connection to transparency though. I think you have most of what you need, you just need to put it together in the resize routine.
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Scale thumbnail clone to always fit GUI

19 May 2017, 14:28

Helgef wrote:Ok, I don't get the connection to transparency though.
Oh. crap...yeah I was in a hurry as said :oops: This is not my live script, in that im having a text control (to catch the mouse clicks) which im making transparent, which makes resizing the Gui obsolete. Thumb appears perfectly each time but its an illusion of course, which I cant use.
Helgef wrote:I think you have most of what you need, you just need to put it together in the resize routine.
Ok, I will go over it again.
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Scale thumbnail clone to always fit GUI

19 May 2017, 16:40

Helgef wrote:I think you have most of what you need, you just need to put it together in the resize routine.
No, this is simply not possible! I think you will have to bring your A-game solving this. As I see it windowWidth and windowHeight is not the Width and Height for the actual Thumbnail. It is the Width and Height for the Toolwindow. Thumbnail size and Toolwindow size does almost never correlate. I believe I need to be abled to query the thumbnail size in order to size the Toolwindow correctly and accordingly, but query the Thumbnail size is not possible with these thumbnail functions (only source window).

If I am mistaken please would you be so kind to show me how you would go about with it. If Im right an additional function is needed where its possible to Thumbnail_GetTargetSize() (which unfortunately isnt an option reading the MSDN)

Also I will not be using any hotkeys or manual mouse resizing like the base script does (the full version of it). This must work upon first call.
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Scale thumbnail clone to always fit GUI

19 May 2017, 17:47

This is the coco script and he seems to be using ThumbPosGrid() to achive the thumbnail always correlate with toolwindow effect, but I cant get that to work when trying it though.

Code: Select all

; Many thanks to maul.esel for his Thumbnail.ahk library
; Thumbnail.ahk required(http://www.autohotkey.com/community/viewtopic.php?t=70839)

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

SetBatchLines, -1
#SingleInstance force
#NoTrayIcon
;#Include Thumbnail.ahk
DetectHiddenWindows, Off

;~ Config
min_h = 110
min_w = 110
wWorkArea := (A_ScreenWidth + 16)
hWorkArea := (A_ScreenHeight + 16)
s_In = 4
s_Out = 2
bg_Trans = 210
bg_Color = 0
Prev_State = 0

;~ Get Active Window
WinGetTitle, active_Title, A
WinGet, active_Task, ID, A
WinGetPos, x_Active, y_Active,,, A
if active_Title = Program Manager
	ExitApp

;~ GUI
;~ ; Background Window
Gui, Gui:-Caption +ToolWindow +Hwndu_hWin
Gui, Gui:Color, %bg_Color%
Gui, Gui:Show, x0 y0 w%A_ScreenWidth% h%A_ScreenHeight% Hide, uWin

;~ Destination Window
Gui, 2Gui:+OwnerGui -Caption +ToolWindow +HwndhWin
Gui, 2Gui:Color, 383838
Gui, 2Gui:Show, x-8 y-8 w%wWorkArea% h%hWorkArea% Hide, Win
GroupAdd, ExposeWin, uWin
GroupAdd, ExposeWin, Win

; Key Mapping
Hotkey, LButton, Pre_Activation,, IfWinActive, ahk_group ExposeWin
Hotkey, Enter, Pre_Activation,, IfWinActive, ahk_group ExposeWin
Hotkey, RButton, Preview_Window,, IfWinActive, ahk_group ExposeWin

;~ Get list of processes
WinGet, ids, List,,, Program Manager
task_List := Object() ; Create array/object to store ID of tasks/processes
num_Win = 
ExposeMode :=

;~ Store hwnd of tasks in array
Loop, %ids%
{
	task_ID := ids%A_Index%
	WinGetTitle, title, ahk_id %task_ID%
	WinGetPos,,, w, h, ahk_id %task_ID%
	if Window_Hidden()
		continue
	num_Win++ ; Counter to keep track of the number of windows as well as thumbnails
	i++ ; Will use this counter in the thumbnail creation process
	task_List.Insert(task_ID)
}

cols := Ceil(Sqrt(num_Win)), rows := Ceil(Sqrt(num_Win))
If (cols*(rows-1) >= num_Win)
	rows--

; Create Desktop thumbnail
WinGet, desk_ID, ID, ahk_class Program Manager
thumb_Desk := Thumbnail_Create(hWin, desk_ID)
xSource := 0, ySource := 0
Thumbnail_GetSourceSize(thumb_Desk, wSource, hSource)
ThumbPosGrid(thumb_Desk, "1", "1", xDest, yDest, wDest, hDest, "300")
Thumbnail_SetRegion(thumb_Desk, xDest, yDest, wDest, hDest, xSource, ySource, wSource, hSource)
Thumbnail_Show(thumb_Desk)
;~ Thumbnail_Hide(thumb_Desk)

;~ Create Thumbnails | Creation is done in reverse/descending order so that the active window's thumbnail is set on top of the stack. Thumbnail order is the same with z-order of the windows
thumb_List := Object() ; Create array/object to store ID of thumbnails
for k, v in task_List
{
	Source := task_List[i] ; Retrieve window(s) hwnd. Also in reverse order.
	thumb := Thumbnail_Create(hWin, Source)
	thumb_List.Insert(1, thumb) ; Store thumbnail handle in array
	i-- ; Counter starts at n number of tasks/windows going down every iteration
}

;~ Set initial and actual grid position of thumbnails -> for animation purposes
Loop, % num_Win ; Loop through the tasks and the thumbnail(s), then set thumbnail(s) region
{
	task := task_List[A_Index]
	thumb_%A_Index% := thumb_List[A_Index]
	WinGetPos, X%A_Index%, Y%A_Index%,,, ahk_id %task%
	xSource%A_Index% := 0, ySource%A_Index% := 0
	Thumbnail_GetSourceSize(thumb_%A_Index%, wSource%A_Index%, hSource%A_Index%)
	ThumbPosGrid(thumb_%A_Index%, A_Index, num_Win, xDest%A_Index%, yDest%A_Index%, wDest%A_Index%, hDest%A_Index%)
	
	new_xDest%A_Index% := xDest%A_Index%, new_yDest%A_Index% := yDest%A_Index%, new_wDest%A_Index% := wDest%A_Index%, new_hDest%A_Index% := hDest%A_Index% ; Actual position in Grid
	
	old_xDest%A_Index% := X%A_Index%, old_yDest%A_Index% := Y%A_Index%, old_wDest%A_Index% := wSource%A_Index%, old_hDest%A_Index% := hSource%A_Index% ; Position prior animation
	old_xDest%A_Index% := old_xDest%A_Index% + 8, old_yDest%A_Index% := old_yDest%A_Index% + 8 ; adjust offset
	Opacity := 255
	includeNC := True

	Thumbnail_SetRegion(thumb_%A_Index%, old_xDest%A_Index%, old_yDest%A_Index%, old_wDest%A_Index%, old_hDest%A_Index%, xSource%A_Index%, ySource%A_Index%, wSource%A_Index%, hSource%A_Index%) ; Set initial position
	Thumbnail_SetOpacity(thumb_%A_Index%, Opacity)
	Thumbnail_SetIncludeNC(thumb_%A_Index%, includeNC)
	Thumbnail_Show(thumb_%A_Index%)
}
;~ Show GUI
Gui, Gui:Show
WinSet, Transparent, 210, uWin
Gui, 2Gui:Show
WinSet, AlwaysOnTop, On, Win
WinSet, TransColor, 383838, Win
Sleep, 100 ; short delay before animation

;~ Animate
i := ; Counter
Steps := 2
Loop, % num_Win * 11 ; Still need to experiment to come up with a constant number
{
	i++
	action := "-" ; Animation direction: "+" -> Animate out | "-" -> Animate in
	xsteps%i% := round(abs(new_xDest%i% - old_xDest%i%) / Steps), ysteps%i% := round(abs(new_yDest%i% - old_yDest%i%) / Steps)
	wsteps%i% := round(abs(new_wDest%i% - old_wDest%i%) / Steps), hsteps%i% := round(abs(new_hDest%i% - old_hDest%i%) / Steps)
	xDest%i% := (new_xDest%i% > old_xDest%i%) ? (old_xDest%i% += xsteps%i%) : (old_xDest%i% -= xsteps%i%)
	yDest%i% := (new_yDest%i% > old_yDest%i%) ? (old_yDest%i% += ysteps%i%) : (old_yDest%i% -= ysteps%i%)
	if (action = "-")
		wDest%i% := old_wDest%i% -= wsteps%i%, hDest%i% := old_hDest%i% -= hsteps%i%
	else if (action = "+")
		wDest%i% := old_wDest%i% += wsteps%i%, hDest%i% := old_hDest%i% += hsteps%i%
	Thumbnail_SetRegion(thumb_%i%, xDest%i%, yDest%i%, wDest%i%, hDest%i%, xSource%i%, ySource%i%, wSource%i%, hSource%i%) ; Set thumbnail(s) region until actual grid position is reached
	if i = %num_Win% ; Reset counter
	{
		i = 0
		Sleep, 1
	}
}
ExposeMode := "On"
Loop, % num_Win ; Create "number" and "Numpad" hotkeys for window activation		
{
	String2Hotkey(A_Index, "Pre_Activation")
	String2Hotkey(A_Index, "Pre_Activation", "Numpad")
}
hCurs:=DllCall("LoadCursor", "UInt", NULL,"Int", 32649, "UInt") ; IDC_HAND := 32649, IDC_CROSS := 32515
OnMessage(0x200,"WM_MOUSEMOVE")
;PID := DllCall("GetCurrentProcessId")
;EmptyMem(PID)
return

Pre_Activation:
gosub, % (Prev_State = "0") ? "Activate_Window" : "End_Preview"
return

Activate_Window:
if A_ThisHotkey in LButton,Enter ;  Activation via mouse
{
	MouseGetPos, X, Y
	Pos := 1 + X*cols//wWorkArea + Y*rows//hWorkArea * cols
	chosen_Task := task_List[Pos]
	thumb := thumb_List[Pos]
	ThumbPosGrid(thumb, Pos, num_Win, left, top, right, bottom)
	right := (left + right), bottom := (top + bottom)
	if (Pos <= num_Win and X >= left and X <= right and Y >= top and Y <= bottom)
	{
		gosub, Animate_Out
		ID := task_List[Pos]
		WinActivate(ID)
		gosub, Exit
	}
}
else ; activation via hotkey
{
	Pos := A_ThisHotkey
	if Pos contains &,Numpad
		Pos := Digitize(Pos)
	chosen_Task := task_List[Pos]
	gosub, Animate_Out
	ID := task_List[Pos]
	WinActivate(ID)
	ExposeMode := "Off"
	gosub, Exit
}
return

Animate_Out: ; Exit expose mode
chosen_Thumb := Thumbnail_Create(hWin, chosen_Task) ; Create thumbnail copy - this to set the chosen thumbnail on top of the other thumbnails
old_Thumb := thumb_List.Remove(Pos) ; Store handle of copied thumbnail - for destruction purposes
thumb_List.Insert(Pos, chosen_Thumb) ; insert new thumbnail in array

xSource := 0, ySource := 0
Thumbnail_GetSourceSize(chosen_Thumb, wSource, hSource)
ThumbPosGrid(chosen_Thumb, Pos, num_Win, xDest, yDest, wDest, hDest)
Opacity := 255, includeNC := True

Thumbnail_SetRegion(chosen_Thumb, xDest, yDest, wDest, hDest, xSource, ySource, wSource, hSource)
Thumbnail_SetOpacity(chosen_Thumb, Opacity)
Thumbnail_SetIncludeNC(chosen_Thumb, includeNC)
Thumbnail_Show(chosen_Thumb) ; Show the thumbnail copy
Thumbnail_Hide(old_Thumb) ; Hide the original thumbnail

Loop, % num_Win
{
	task := task_List[A_Index]
	thumb_%A_Index% := thumb_List[A_Index]
	WinGetPos, X%A_Index%, Y%A_Index%,,, ahk_id %task%
	xSource%A_Index% := 0, ySource%A_Index% := 0
	Thumbnail_GetSourceSize(thumb_%A_Index%, wSource%A_Index%, hSource%A_Index%)
	ThumbPosGrid(thumb_%A_Index%, A_Index, num_Win, xDest%A_Index%, yDest%A_Index%, wDest%A_Index%, hDest%A_Index%)
	
	old_xDest%A_Index% := xDest%A_Index%, old_yDest%A_Index% := yDest%A_Index%, old_wDest%A_Index% := wDest%A_Index%, old_hDest%A_Index% := hDest%A_Index% ; Position in Grid, position prior animation
	
	new_xDest%A_Index% := X%A_Index%, new_yDest%A_Index% := Y%A_Index%, new_wDest%A_Index% := wSource%A_Index%, new_hDest%A_Index% := hSource%A_Index% ; 
	new_xDest%A_Index% := new_xDest%A_Index% + 8, new_yDest%A_Index% := new_yDest%A_Index% + 8 ; adjust offset
	Opacity := 255
	includeNC := True
}

;~ Animate thumbnails
i := ; Counter
Steps := 2

Loop, % num_Win * 8
{
	i++
	action := "+" ; Animation direction: "+" -> Animate out | "-" -> Animate in
	xsteps%i% := round(abs(new_xDest%i% - old_xDest%i%) / Steps), ysteps%i% := round(abs(new_yDest%i% - old_yDest%i%) / Steps)
	wsteps%i% := round(abs(new_wDest%i% - old_wDest%i%) / Steps), hsteps%i% := round(abs(new_hDest%i% - old_hDest%i%) / Steps)
	xDest%i% := (new_xDest%i% > old_xDest%i%) ? (old_xDest%i% += xsteps%i%) : (old_xDest%i% -= xsteps%i%)
	yDest%i% := (new_yDest%i% > old_yDest%i%) ? (old_yDest%i% += ysteps%i%) : (old_yDest%i% -= ysteps%i%)
	if (action = "-")
		wDest%i% := old_wDest%i% -= wsteps%i%, hDest%i% := old_hDest%i% -= hsteps%i%
	else if (action = "+")
		wDest%i% := old_wDest%i% += wsteps%i%, hDest%i% := old_hDest%i% += hsteps%i%
	Thumbnail_SetRegion(thumb_%i%, xDest%i%, yDest%i%, wDest%i%, hDest%i%, xSource%i%, ySource%i%, wSource%i%, hSource%i%) ; Set thumbnail(s) region until actual grid position is reached
	if i = %num_Win% ; Reset counter
	{
		i = 0
		Sleep, 1 ; Animation delay
	}
}
FadeOut("uWin", "0", "250", "0")
return

Preview_Window:
gosub, % (Prev_State = "0") ? "Start_Preview" : "End_Preview"
return

Start_Preview:
MouseGetPos, X, Y
msgbox
prev_Pos := 1 + X*cols//wWorkArea + Y*rows//hWorkArea * cols
task_Prev := task_List[prev_Pos]
thumb_Hide := thumb_List[prev_Pos] ; Handle of the thumbnail being copied
thumb_Prev := Thumbnail_Create(hWin, task_Prev) ; Create thumbnail copy - this to set the chosen thumbnail on top of the other thumbnails
ThumbPosGrid(thumb_Prev, prev_Pos, num_Win, left, top, right, bottom)
right := (left + right), bottom := (top + bottom)
if (Pos <= num_Win and X >= left and X <= right and Y >= top and Y <= bottom)
{
	xSource := 0, ySource := 0
	Thumbnail_GetSourceSize(thumb_Prev, wSource, hSource)
	ThumbPosGrid(thumb_Prev, "1", "1", xPrev, yPrev, wPrev, hPrev, "0", "Win")
	ThumbPosGrid(thumb_Prev, prev_Pos, num_Win, xDest, yDest, wDest, hDest)
	Opacity := 255, includeNC := True

	Thumbnail_SetRegion(thumb_Prev, xDest, yDest, wDest, hDest, xSource, ySource, wSource, hSource)
	Thumbnail_SetOpacity(thumb_Prev, Opacity)
	Thumbnail_SetIncludeNC(thumb_Prev, includeNC)
	Thumbnail_Show(thumb_Prev) ; Show the thumbnail copy
	Thumbnail_Hide(thumb_%prev_Pos%) ; Hide the original thumbnail

	ThumbAnimate(thumb_Prev, xDest, yDest, wDest, hDest, xPrev, yPrev, wPrev, hPrev, s_Out) ; Function to animate a thumbnail -> single thuumbnail animation only
	Prev_State = 1
}
return

End_Preview:
ThumbPosGrid(thumb_Prev, prev_Pos, num_Win, xDest, yDest, wDest, hDest)
ThumbAnimate(thumb_Prev, xPrev, yPrev, wPrev, hPrev, xDest, yDest, wDest, hDest, s_Out)
Thumbnail_Show(thumb_Hide)
Thumbnail_Destroy(thumb_Prev)
Prev_State = 0
return

Esc::
Loop, % num_Win
{
	String2Hotkey(A_Index, "Pre_Activation",, "Off")
	String2Hotkey(A_Index, "Pre_Activation", "Numpad", "Off")
}
Thumbnail_Destroy(thumb_Desk)
Thumbnail_Destroy(old_Thumb)
Loop, %num_Win%
{
	thumb_%A_Index% := thumb_List[A_Index]
	Thumbnail_Destroy(thumb_%A_Index%)
}
OnMessage(0x200,"") 
DllCall("DestroyCursor","Uint",hCurs)
Gui Gui:Destroy
ExitApp

Exit:
Loop, % num_Win
{
	String2Hotkey(A_Index, "Pre_Activation",, "Off")
	String2Hotkey(A_Index, "Pre_Activation", "Numpad", "Off")
}
Thumbnail_Destroy(thumb_Desk)
Thumbnail_Destroy(old_Thumb)
Loop, %num_Win%
{
	thumb_%A_Index% := thumb_List[A_Index]
	Thumbnail_Destroy(thumb_%A_Index%)
}
OnMessage(0x200,"") 
DllCall("DestroyCursor","Uint",hCurs)
Gui Gui:Destroy
ExitApp

; ====================================================================================
; FUNCTIONS
; ====================================================================================

ThumbPosGrid(hThumb, ItemIndex, ItemCount, ByRef xDest, ByRef yDest, ByRef wDest, ByRef hDest, Spacing="20", Coord="Screen") ; This function sets the position of the thumbnail(s) in a grid
{                                                                                                                            ; It can also retrieve a thumbnail's region/dimension/property.
	cols := Ceil(Sqrt(ItemCount)), rows := Ceil(Sqrt(ItemCount))                                                             ; Specify "Screen" in the "Coord" parameter to postion the
	if (cols*(rows-1) >= ItemCount)                                                                                          ; thumbnail relative to the screen otherwise "Win" to postion it
		rows--                                                                                                               ; relative to the destination window
	if (Coord = "Screen")                                                                                                    
		wGrid :=  A_ScreenWidth / cols, hGrid := A_ScreenHeight / rows
	if (Coord = "Win")
		wGrid :=  (A_ScreenWidth / cols) + (16 / cols), hGrid := (A_ScreenHeight / rows) + (16 / rows)
	Thumbnail_GetSourceSize(hThumb, wSource, hSource)
	area_Ratio := wGrid / hGrid, win_Ratio := wSource / hSource
	if (win_Ratio < area_Ratio)
		hDest := hGrid - Spacing, wDest := round(wSource / hSource * hDest)
	else	
		wDest := wGrid - Spacing, hDest := round(hSource / wSource * wDest)
	if ( wDest > wSource or hDest > hSource )
		hDest := hSource, wDest := wSource
	pos_Cols := ( C := Mod( ItemIndex, cols ) ) ? C : cols, pos_Rows := Ceil( ItemIndex / cols )
	if (Coord = "Screen")
		xDest := (wGrid/2)-(wDest/2) + (wGrid*(pos_Cols-1)) + 8, yDest := (hGrid/2)-(hDest/2) + (hGrid*(pos_Rows-1)) + 8
	if (Coord = "Win")
		xDest := (wGrid/2)-(wDest/2) + (wGrid*(pos_Cols-1)), yDest := (hGrid/2)-(hDest/2) + (hGrid*(pos_Rows-1))
}

ThumbAnimate(hThumb, xOld, yOld, wOld, hOld, xNew, yNew, wNew, hNew, Steps="2") ; Single thumbnail animation only -> used in the Start_Preview, End_Preview subroutine(s)
{
	abs(wNew - wOld) != 0 or abs(hNew - hOld) != 0 ? ((wNew > wOld or hNew > hOld) ? action := "+" : action := "-") : wDest := wOld += abs(wNew - wOld), hDest := hOld += abs(hNew - hOld)
	xSource := 0, ySource := 0, Thumbnail_GetSourceSize(hThumb, wSource, hSource)
	Loop
	{
		xsteps := round(abs(xNew - xOld) / Steps), ysteps := round(abs(yNew - yOld) / Steps)
		if action in +,-
			wsteps := round(abs(wNew - wOld) / Steps), hsteps := round(abs(hNew - hOld) / Steps)
		xDest := (xNew > xOld) ? (xOld += xsteps) : (xOld -= xsteps)
		yDest := (yNew > yOld) ? (yOld += ysteps) : (yOld -= ysteps)
		if (action = "-") 
			wDest := wOld -= wsteps, hDest := hOld -= hsteps
		else if (action = "+")
			wDest := wOld += wsteps, hDest := hOld += hsteps
		Thumbnail_SetRegion(hThumb, xDest, yDest, wDest, hDest, xSource, ySource, wSource, hSource)
		Sleep, 21
	} Until xsteps <= 0 && ysteps <= 0 && wsteps <= 0 && hsteps <= 0
}
; The next two functions were taken from holomind's Real Expose Clone (http://www.autohotkey.com/community/viewtopic.php?t=13001) -> the inspiration for this script
Window_Hidden() { 
   global
   Return w < min_w or h < min_h or title = "" or active_Title = ""
}

WinActivate(ID) 
{
   WinGet, ActiveID, ID, A
   if ActiveID <> ID
       WinActivate ahk_id %ID%
}

Digitize(var) ; Removes non-numerical characters in a string
{
	StringReplace, var, var, %A_Space%,, a
	Loop, Parse, var
    {
		if A_LoopField is not Integer
			StringReplace, var, var, %A_LoopField%,, a
    }
	return var
}

String2Hotkey(String, Label, KeyType="Normal", Options="") ; Converts 2-character string into a hotkey. Useful for the 'Hotkey' command. It just actually inserts " & " in between.
{
	StringReplace, String, String, %A_Space%,, A
	Len := StrLen(String)
	if KeyType = Normal
	{
		Loop, Parse, String
		{
			if A_Index = % Len
				String := A_LoopField
			else
				String := A_LoopField " & "
			Key .= String
		}
	}
	if KeyType = Numpad
	{
		Loop, Parse, String
		{
			String := "Numpad" A_LoopField
			if A_Index = % Len
				String := String
			else
				String := String " & "
			Key .= String
		}
	}
	Hotkey, %Key%, %Label%, %Options%
}

FadeOut(window = "A", end = 0, speed = 10, close = 1) ; http://www.autohotkey.com/community/viewtopic.php?t=71886
{
	WinGet, currentTrans, Transparent, %window%
	If (currentTrans == "")
	{
		WinSet, Trans, 255, %window%
		WinGet, currentTrans, Transparent, %window%
	}
	While, (currentTrans > end)
	{
		Sleep, % speed / 2
		Trans := currentTrans - speed
		WinSet, Trans, %Trans%, %window%
		WinGet, currentTrans, Transparent, %window%
	}
	If (close == 1)
		WinClose, %window%
}

EmptyMem(PIDtoEmpty) ; http://www.autohotkey.com/forum/topic32876.html (first line removed)
{
    h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", PIDtoEmpty)
    DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
    DllCall("CloseHandle", "Int", h)
}

WM_MOUSEMOVE(wParam,lParam) ; http://www.autohotkey.com/community/viewtopic.php?t=9192
{
	Global
	MouseGetPos, X, Y
	Pos := 1 + X*cols//wWorkArea + Y*rows//hWorkArea * cols
	Prev_State <= 0 ? ((Count := num_Win), (Pos := Pos), ThumbPosGrid(thumb_%Pos%, Pos, Count, left, top, right, bottom)) : ((Count := "1"), (Pos := "1"), ThumbPosGrid(thumb_Prev, Pos, Count, left, top, right, bottom, "0", "Win"))
	right := (left + right), bottom := (top + bottom)
	if (Pos <= Count and X >= left and X <= right and Y >= top and Y <= bottom)
		DllCall("SetCursor","UInt",hCurs)
  Return
}

/**************************************************************************************************************
title: Thumbnail functions
wrapped by maul.esel

Credits:
- skrommel for example how to show a thumbnail (http://www.autohotkey.com/forum/topic34318.html)
- RaptorOne & IsNull for correcting some mistakes in the code

NOTE:
*This requires Windows Vista or Windows7* (tested on Windows 7)
Quick-Tutorial:
To add a thumbnail to a gui, you must know the following:
- the hwnd / id of your gui
- the hwnd / id of the window to show
- the coordinates where to show the thumbnail
- the coordinates of the area to be shown
1. Create a thumbnail with Thumbnail_Create()
2. Set its regions with Thumbnail_SetRegion()
a. optionally query for the source windows width and height before with <Thumbnail_GetSourceSize()>
3. optionally set the opacity with <Thumbnail_SetOpacity()>
4. show the thumbnail with <Thumbnail_Show()>
***************************************************************************************************************
*/
/**************************************************************************************************************
Function: Thumbnail_Create()
creates a thumbnail relationship between two windows

params:
handle hDestination - the window that will show the thumbnail
handle hSource - the window whose thumbnail will be shown
returns:
handle hThumb - thumbnail id on success, false on failure

Remarks:
To get the Hwnds, you could use WinExist()
***************************************************************************************************************
*/
Thumbnail_Create(hDestination, hSource) {
VarSetCapacity(thumbnail, 4, 0)
if DllCall("dwmapi.dll\DwmRegisterThumbnail", "UInt", hDestination, "UInt", hSource, "UInt", &thumbnail)
return false
return NumGet(thumbnail)
}
/**************************************************************************************************************
Function: Thumbnail_SetRegion()
defines dimensions of a previously created thumbnail
params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
int xDest - the x-coordinate of the rendered thumbnail inside the destination window
int yDest - the y-coordinate of the rendered thumbnail inside the destination window
int wDest - the width of the rendered thumbnail inside the destination window
int hDest - the height of the rendered thumbnail inside the destination window
int xSource - the x-coordinate of the area that will be shown inside the thumbnail
int ySource - the y-coordinate of the area that will be shown inside the thumbnail
int wSource - the width of the area that will be shown inside the thumbnail
int hSource - the height of the area that will be shown inside the thumbnail
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_SetRegion(hThumb, xDest, yDest, wDest, hDest, xSource, ySource, wSource, hSource) {
dwFlags := 0x00000001 | 0x00000002
VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(xDest, dskThumbProps, 4, "Int")
NumPut(yDest, dskThumbProps, 8, "Int")
NumPut(wDest+xDest, dskThumbProps, 12, "Int")
NumPut(hDest+yDest, dskThumbProps, 16, "Int")
NumPut(xSource, dskThumbProps, 20, "Int")
NumPut(ySource, dskThumbProps, 24, "Int")
NumPut(wSource+xSource, dskThumbProps, 28, "Int")
NumPut(hSource+ySource, dskThumbProps, 32, "Int")
return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}
/**************************************************************************************************************
Function: Thumbnail_Show()
shows a previously created and sized thumbnail

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_Show(hThumb) {
static dwFlags := 0x00000008, fVisible := 1
VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(fVisible, dskThumbProps, 37, "Int")
return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}
/**************************************************************************************************************
Function: Thumbnail_Hide()
hides a thumbnail. It can be shown again without recreating

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_Hide(hThumb) {
static dwFlags := 0x00000008, fVisible := 0

VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "Uint")
NumPut(fVisible, dskThumbProps, 37, "Int")
return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}
/**************************************************************************************************************
Function: Thumbnail_Destroy()
destroys a thumbnail relationship
params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_Destroy(hThumb) {
return DllCall("dwmapi.dll\DwmUnregisterThumbnail", "UInt", hThumb) ? false : true
}
/**************************************************************************************************************
Function: Thumbnail_GetSourceSize()
gets the width and height of the source window - can be used with <Thumbnail_SetRegion()>

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
ByRef int width - receives the width of the window
ByRef int height - receives the height of the window
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_GetSourceSize(hThumb, ByRef width, ByRef height) {
VarSetCapacity(Size, 8, 0)
if DllCall("dwmapi.dll\DwmQueryThumbnailSourceSize", "Uint", hThumb, "Uint", &Size)
return false
width := NumGet(&Size + 0, 0, "int")
height := NumGet(&Size + 0, 4, "int")
return true
}
/**************************************************************************************************************
Function: Thumbnail_SetOpacity()
sets the current opacity level

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
int opacity - the opacity level from 0 to 255 (will wrap to the other end if invalid)
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_SetOpacity(hThumb, opacity) {
static dwFlags := 0x00000004

VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(opacity, dskThumbProps, 36, "UChar")
return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "Uint", hThumb, "UInt", &dskThumbProps) ? false : true
}
/*
Function: Thumbnail_SetIncludeNC()
sets whether the source's non-client area should be included. The default value is true.
Parameters:
	HANDLE hThumb - the thumbnail id returned by <Thumbnail_Create()>
	BOOL include - true to include the non-client area, false to exclude it
Returns:
	BOOL success - true on success, false on failure
*/
Thumbnail_SetIncludeNC(hThumb, include)
{
	static dwFlags := 0x00000010
	_ptr := A_PtrSize ? "UPtr" : "UInt"

	VarSetCapacity(dskThumbProps, 45, 0)

	NumPut(dwFlags,		dskThumbProps,	00,	"UInt")
	NumPut(!include,	dskThumbProps,	42, "UInt")

	return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", _ptr, hThumb, _ptr, &dskThumbProps) >= 0x00
}
Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: Scale thumbnail clone to always fit GUI  Topic is solved

19 May 2017, 17:51

Also I will not be using any hotkeys or manual mouse resizing like the base script does (the full version of it). This must work upon first call.
That just makes it easier I guess. Maybe somthing like this would do it.

Code: Select all

f(){
	global
	Thumbnail_GetSourceSize(hThumb, width, height)
	WinGetPos,,,windowWidth, windowHeight, % "ahk_id " hDestination
	GetClientRect(hDestination,cwindowWidth, cwindowHeight)			; cwindowWidth and cwindowHeight are byref. c is for client
	dw:=windowWidth-cwindowWidth									; difference between window and client size.
	dh:=windowHeight-cwindowHeight	
	; Scale :
	CorrectRatio := width / height									
	testWidth := windowHeight * CorrectRatio						
	if (windowWidth <  testWidth)										
		windowHeight := windowWidth / CorrectRatio					
	else																
		windowWidth := testWidth
	Winmove, % "ahk_id " hDestination,,,, windowWidth+dw, windowHeight+dh					; Move gui to correct size
	Thumbnail_SetRegion(hThumb, 0, 0 , windowWidth, windowHeight, 0 , 0 ,RegionW, RegionH)	; Update thumbnail.
}
GetClientRect(hwnd,ByRef X2, ByRef Y2) {
	VarSetCapacity(rc,16)
	DllCall("GetClientRect", "Uint", hwnd, "Uint", &rc)
	X2:=NumGet(rc,8,"Int")
	Y2:=NumGet(rc,12,"Int")
	return
}
That is, call f() whenever you want to update the thumbnail window.

Edit: I'm not interested enough to look at all that code ;)
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Scale thumbnail clone to always fit GUI

20 May 2017, 02:15

Helgef wrote:Edit: I'm not interested enough to look at all that code ;)
Yes, I figured you didnt test it. FYI
it goes wrong here:

WinGetPos,,, windowWidth, windowHeight, % "ahk_id " hDestination
msgbox % "W= " windowWidth "`nH= " windowHeight


windowWidth and windowHeight are empty and everything fails from there.
Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: Scale thumbnail clone to always fit GUI

20 May 2017, 04:57

If they are empty the handle to the destination window is invalid.
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Scale thumbnail clone to always fit GUI

20 May 2017, 05:18

@Helgef
After more testing I was abled to get it working. Had to apply some more padding to it. However there are still slim lines of Toolwindow showing at left, bottom and right border when resizing source to odd resolutions. Your solution is not perfect, but surley the best one out there so far. Many thanks for the lesson :wave:
Best regards
zcooler

Code: Select all

;this requires the Windows 7 Aero Theme to be enabled
; initializing the script:
#SingleInstance force
#NoEnv
#KeyHistory 0
SetWorkingDir %A_ScriptDir%
;#include C:\Thumbnail.ahk

WinGet, dvbviewer_ID, ID, ahk_class TfrmMain
WinGetPos, RegionX, RegionY, RegionW, RegionH, ahk_class TfrmMain
windowWidth := 450 ; 16:9 aspect ration
windowHeight := 253 ; 16:9 aspect ration

; get the handles:
Gui, Color, 000000
Gui +LastFound ;+hwndhDestination

hDestination := WinExist() ; ... to our GUI...
hSource := WinExist("ahk_exe dvbviewer.exe") ;

; creating the thumbnail:
hThumb := Thumbnail_Create(hDestination, hSource) ; you must get the return value here

; getting the source window dimensions:
Thumbnail_GetSourceSize(hThumb, width, height)

; then setting its region:
Thumbnail_SetRegion(hThumb, 0, 0 , windowWidth, windowHeight, 0 , 0 ,RegionW, RegionH)

; now some GUI stuff:
Gui +AlwaysOnTop +ToolWindow +Resize ;-Caption

; Now we can show it:
Thumbnail_Show(hThumb) ; but it is not visible now...

Gui Show, w%windowWidth% h%windowHeight% Hide, Live Thumbnail ; ... until we show the GUI
DetectHiddenWindows on
f()
Gui Show,, Live Thumbnail ; ... until we show the GUI
DetectHiddenWindows off
OnMessage(0x201, "WM_LBUTTONDOWN")
return
;----------------------------------------------------------------------
GuiClose: ; in case the GUI is closed:
	Thumbnail_Destroy(thumbID) ; free the resources
ExitApp

f(){
	global
	WinGetPos,,,windowWidth, windowHeight, % "ahk_id " hDestination
    GetClientRect(hDestination,cwindowWidth, cwindowHeight)			; cwindowWidth and cwindowHeight are byref. c is for client
	dw:=windowWidth-cwindowWidth-10									; difference between window and client size.
	dh:=windowHeight-cwindowHeight-6	
	; Scale :
	CorrectRatio := width / height									
	testWidth := windowHeight * CorrectRatio						
	if (windowWidth <  testWidth)										
		windowHeight := windowWidth / CorrectRatio					
	else																
		windowWidth := testWidth
	Winmove, % "ahk_id " hDestination,,,, windowWidth+dw, windowHeight+dh					; Move gui to correct size
	Thumbnail_SetRegion(hThumb, -4, 0 , windowWidth, windowHeight, 0 , 0 ,RegionW, RegionH)	; Update thumbnail.
}
GetClientRect(hwnd,ByRef X2, ByRef Y2) {
	VarSetCapacity(rc,16)
	DllCall("GetClientRect", "Uint", hwnd, "Uint", &rc)
	X2:=NumGet(rc,8,"Int")
	Y2:=NumGet(rc,12,"Int")
	return
}
/**************************************************************************************************************
title: Thumbnail functions
wrapped by maul.esel

Credits:
- skrommel for example how to show a thumbnail (http://www.autohotkey.com/forum/topic34318.html)
- RaptorOne & IsNull for correcting some mistakes in the code

NOTE:
*This requires Windows Vista or Windows7* (tested on Windows 7)
Quick-Tutorial:
To add a thumbnail to a gui, you must know the following:
- the hwnd / id of your gui
- the hwnd / id of the window to show
- the coordinates where to show the thumbnail
- the coordinates of the area to be shown
1. Create a thumbnail with Thumbnail_Create()
2. Set its regions with Thumbnail_SetRegion()
a. optionally query for the source windows width and height before with <Thumbnail_GetSourceSize()>
3. optionally set the opacity with <Thumbnail_SetOpacity()>
4. show the thumbnail with <Thumbnail_Show()>
***************************************************************************************************************
*/


/**************************************************************************************************************
Function: Thumbnail_Create()
creates a thumbnail relationship between two windows

params:
handle hDestination - the window that will show the thumbnail
handle hSource - the window whose thumbnail will be shown
returns:
handle hThumb - thumbnail id on success, false on failure

Remarks:
To get the Hwnds, you could use WinExist()
***************************************************************************************************************
*/
Thumbnail_Create(hDestination, hSource) {

VarSetCapacity(thumbnail, 4, 0)
if DllCall("dwmapi.dll\DwmRegisterThumbnail", "UInt", hDestination, "UInt", hSource, "UInt", &thumbnail)
return false
return NumGet(thumbnail)
}


/**************************************************************************************************************
Function: Thumbnail_SetRegion()
defines dimensions of a previously created thumbnail

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
int xDest - the x-coordinate of the rendered thumbnail inside the destination window
int yDest - the y-coordinate of the rendered thumbnail inside the destination window
int wDest - the width of the rendered thumbnail inside the destination window
int hDest - the height of the rendered thumbnail inside the destination window
int xSource - the x-coordinate of the area that will be shown inside the thumbnail
int ySource - the y-coordinate of the area that will be shown inside the thumbnail
int wSource - the width of the area that will be shown inside the thumbnail
int hSource - the height of the area that will be shown inside the thumbnail
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_SetRegion(hThumb, xDest, yDest, wDest, hDest, xSource, ySource, wSource, hSource) {
dwFlags := 0x00000001 | 0x00000002

VarSetCapacity(dskThumbProps, 45, 0)

NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(xDest, dskThumbProps, 4, "Int")
NumPut(yDest, dskThumbProps, 8, "Int")
NumPut(wDest+xDest, dskThumbProps, 12, "Int")
NumPut(hDest+yDest, dskThumbProps, 16, "Int")

NumPut(xSource, dskThumbProps, 20, "Int")
NumPut(ySource, dskThumbProps, 24, "Int")
NumPut(wSource+xSource, dskThumbProps, 28, "Int")
NumPut(hSource+ySource, dskThumbProps, 32, "Int")

return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}


/**************************************************************************************************************
Function: Thumbnail_Show()
shows a previously created and sized thumbnail

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_Show(hThumb) {
static dwFlags := 0x00000008, fVisible := 1

VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(fVisible, dskThumbProps, 37, "Int")

return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}


/**************************************************************************************************************
Function: Thumbnail_Hide()
hides a thumbnail. It can be shown again without recreating

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_Hide(hThumb) {
static dwFlags := 0x00000008, fVisible := 0

VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "Uint")
NumPut(fVisible, dskThumbProps, 37, "Int")
return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}


/**************************************************************************************************************
Function: Thumbnail_Destroy()
destroys a thumbnail relationship

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_Destroy(hThumb) {
return DllCall("dwmapi.dll\DwmUnregisterThumbnail", "UInt", hThumb) ? false : true
}


/**************************************************************************************************************
Function: Thumbnail_GetSourceSize()
gets the width and height of the source window - can be used with <Thumbnail_SetRegion()>

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
ByRef int width - receives the width of the window
ByRef int height - receives the height of the window
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_GetSourceSize(hThumb, ByRef width, ByRef height) {
VarSetCapacity(Size, 8, 0)
if DllCall("dwmapi.dll\DwmQueryThumbnailSourceSize", "Uint", hThumb, "Uint", &Size)
return false
width := NumGet(&Size + 0, 0, "int")
height := NumGet(&Size + 0, 4, "int")
return true
}


/**************************************************************************************************************
Function: Thumbnail_SetOpacity()
sets the current opacity level

params:
handle hThumb - the thumbnail id returned by <Thumbnail_Create()>
int opacity - the opacity level from 0 to 255 (will wrap to the other end if invalid)
returns:
bool success - true on success, false on failure
***************************************************************************************************************
*/
Thumbnail_SetOpacity(hThumb, opacity) {
static dwFlags := 0x00000004

VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(opacity, dskThumbProps, 36, "UChar")
return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "Uint", hThumb, "UInt", &dskThumbProps) ? false : true
}

/**************************************************************************************************************
section: example
This example sctript shows a thumbnail of your desktop in a GUI
(start code)
; initializing the script:
#SingleInstance force
#NoEnv
#KeyHistory 0
SetWorkingDir %A_ScriptDir%
#include Thumbnail.ahk

; get the handles:
Gui +LastFound
hDestination := WinExist() ; ... to our GUI...
hSource := WinExist("ahk_class Progman") ; ... and to the desktop

; creating the thumbnail:
hThumb := Thumbnail_Create(hDestination, hSource) ; you must get the return value here!

; getting the source window dimensions:
Thumbnail_GetSourceSize(hThumb, width, height)

; then setting its region:
Thumbnail_SetRegion(hThumb, 25, 25 ; x and y in the GUI
, 400, 350 ; display dimensions
, 0, 0 ; source area coordinates
, width, height) ; the values from Thumbnail_GetSourceSize()

; now some GUI stuff:
Gui +AlwaysOnTop +ToolWindow
Gui Add, Button, gHideShow x0 y0, Hide / Show

; Now we can show it:
Thumbnail_Show(hThumb) ; but it is not visible now...
Gui Show, w450 h400 ; ... until we show the GUI

; even now we can set the transparency:
Thumbnail_SetOpacity(hThumb, 200)

return

GuiClose: ; in case the GUI is closed:
Thumbnail_Destroy(hThumb) ; free the resources
ExitApp

HideShow: ; in case the button is clicked:
if hidden
Thumbnail_Show(hThumb)
else
Thumbnail_Hide(hThumb)

hidden := !hidden
return
(end)
***************************************************************************************************************
*/
Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: Scale thumbnail clone to always fit GUI

20 May 2017, 13:11

I didn't see any such problems in my brief testing. Do not have that particular software though. One thing you could do, is to only use the client area of the source for the thumbnail. There is a flag to set in some of the functions handling the thumbnail properties, if I recall correctly. It might look better, it might also cause further inconvenience :lol: . You mentiond it being for some video/tv display, the ratio of the window might not be the same as that of the client area, which I would guess is only showing the video. Cheers.
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Scale thumbnail clone to always fit GUI

20 May 2017, 15:31

Helgef wrote:One thing you could do, is to only use the client area of the source for the thumbnail. There is a flag to set in some of the functions handling the thumbnail properties, if I recall correctly. It might look better, it might also cause further inconvenience :lol:
Very interesting lead there :) I applied the fSourceClientAreaOnly flag and removed my paddings and I actually get perfect aligning on the left side, but bottom and right are more spacious compared to before. Hmm...I wonder how I can get it perfect for bottom and right? Are there more fSourceClientAreaOnly NumGet dskThumbProps numbers to set to get it right all around?

Code: Select all

Thumbnail_Show(hThumb) {
static dwFlags := 0x00000008 | 0x00000010, fVisible := 1, fSourceClientAreaOnly := 1

VarSetCapacity(dskThumbProps, 45, 0)
NumPut(dwFlags, dskThumbProps, 0, "UInt")
NumPut(fVisible, dskThumbProps, 37, "Int")
NumPut(fSourceClientAreaOnly, dskThumbProps, 41, "Int")

return DllCall("dwmapi.dll\DwmUpdateThumbnailProperties", "UInt", hThumb, "UInt", &dskThumbProps) ? false : true
}
Helgef wrote:You mentiond it being for some video/tv display, the ratio of the window might not be the same as that of the client area, which I would guess is only showing the video. Cheers.
Yes, the ratio of the TV app window is not the same as client area (when set oddly) but the ratio calculations handles it surpringsingly well. Im trying to keep the source at 16:9 ratio though. No, client area displays whole TV app window with title/statusbar and borders.
Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: Scale thumbnail clone to always fit GUI

20 May 2017, 15:54

No other flags related to that as far as I know. You might want to swap WinGetPos, RegionX, RegionY, RegionW, RegionH, ahk_class TfrmMain for GetClientRect(hSource,RegionW, RegionH) though. And make sure hSource is defined when calling GetClientRect, hSouce is currently assigned after the WinGetPoscall. Note, RegionX/Y aren't used so they can be omitted.
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Scale thumbnail clone to always fit GUI

20 May 2017, 16:49

Helgef wrote:No other flags related to that as far as I know. You might want to swap WinGetPos, RegionX, RegionY, RegionW, RegionH, ahk_class TfrmMain for GetClientRect(hSource,RegionW, RegionH) though. And make sure hSource is defined when calling GetClientRect, hSouce is currently assigned after the WinGetPoscall. Note, RegionX/Y aren't used so they can be omitted.
Oh la la...we are getting close now :mrgreen: These instructions fixed the right aligning which is spot on now. Thanks Helgef :D The remaining problem is the bottom part...much too spacious hmm :?
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Scale thumbnail clone to always fit GUI

20 May 2017, 17:06

Must be something with the ratio calculations. I will go over it tomorrow. Many thanks for your support :wave:
Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: Scale thumbnail clone to always fit GUI

20 May 2017, 17:32

Before I realised you didn't consider the manual (mouse drag) resizing of the gui, I wrote this, I do observe some of the right and bottom missing from the source thumbnail when the gui gets smaller.

Code: Select all

OnMessage(0x0214, "WM_SIZING")
WM_SIZING(wParam,lParam,msg,hwnd){
	global
	Critical, On
	if (hwnd!=hDestination)
		return 1
	x1 := NumGet(lParam+0,0,"Int")
	y1 := NumGet(lParam+0,4,"Int")
	x2 := NumGet(lParam+0,8,"Int")
	y2 := NumGet(lParam+0,12,"Int")
	windowWidth:=x2-x1
	windowHeight:=y2-y1
	CorrectRatio := RegionW / RegionH
	testWidth := windowHeight * CorrectRatio
	if (wParam=1 || wParam=2) {	; Left || Right edge
		windowHeight := windowWidth / CorrectRatio
	} else {
		windowWidth := testWidth
	}
	; Update window size
	if (wParam!=4 && wParam!=7){				; not left corners
		NumPut(windowWidth+x1,lParam+0,8,"Int")
		NumPut(windowHeight+y1,lParam+0,12,"Int")

	} else {									; left corners
		NumPut(x2-windowWidth,lParam+0,0,"Int")
		NumPut(y2-windowHeight,lParam+0,4,"Int")
	}
	Thumbnail_SetRegion(hThumb, 0, 0 , windowWidth, windowHeight, 0 , 0 ,RegionW, RegionH)
	return 1
}
Make sure the OnMessage gets called, then the gui should scale when resized. Note, dw, dh isn't in this one, not sure they should though.

Return to “Ask For Help”

Who is online

Users browsing this forum: AHKStudent, ddt442, RubbeH and 68 guests