AutoHotkey script for you: File preview (thumbnail) in Total Commander

English support forum

Moderators: white, Hacker, petermad, Stefan2

Fla$her
Power Member
Power Member
Posts: 2295
Joined: 2020-01-18, 04:03 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *Fla$her »

wetware05 wrote: 2023-06-03, 19:54 UTC maybe you have an outdated (or damaged) system .NET Framework library. What operating system do you have?
3.5, XP. I think it's right to check on it first, because it doesn't say anything about restrictions in the header.
After replacing the files, the error disappeared, but the script does not react to the mouse in any way.
Overquoting is evil! 👎
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Download and install last version .NET Framework

Search: "download .net framework fox xp"
Fla$her
Power Member
Power Member
Posts: 2295
Joined: 2020-01-18, 04:03 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *Fla$her »

The maximum is version 4. I don't like the prospect of deploying 500-600 MB for the sake of executing one script, which is quite possible to do without.
I've used programs like WinRefine before, it's fun, but also without a high degree of usefulness.
Overquoting is evil! 👎
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Fla$her I agree with you in differentiating between what is useful and what is adorned. The WinRefine program itself was abandoned by the creator (whatever an .mp3 is heard can be done from this script, videos is more complicated). I made this utility because sometimes I have to search for an image among many and no image manager convinces me, and this method is a fast system. I don't like the thumbnails either.

An essential program, for those of us who know them and know how to drive, is Total Commander. I don't use the desktop, nor the Explorer. Since I turn on the computer I open Total Commander. My "desktop" is a folder open in TCM (for downloads and pending jobs) from which I manage the rest of the computer.
Fla$her
Power Member
Power Member
Posts: 2295
Joined: 2020-01-18, 04:03 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *Fla$her »

2wetware05
So I don't think that your code is useless, otherwise I wouldn't have shown interest. Only it, as it turned out, doesn't work everywhere.
Nevertheless, thumbnails are better suited for search.
I think you should support these requests: 1, 2, maybe 3.
Overquoting is evil! 👎
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Hi.

I have added what was requested. You can disable the Preview not being seen in Total Commander, or disable it so that it is not seen on the desktop and Explorer. And if it is activated for Total commander that only the Preview of the images can be seen by pressing the RCtrl key (Right Control). Three options. The script remembers the last state before closing it, as it saves it in the NewConfig.ini file (you have to delete the NewConfig.ini file that already exists. If you want to keep it, Edit it with notepad and add the text at the end:

Code: Select all

SuspendTCM=1
SuspendDeskTop=1
OnlyKey=0
These options are accessed from the script menu in the icon tray (right-click). When one of the options is activated, the icon will be removed and it will look like a checkmark.

The script maintains the behavior before left-clicking on the icon turns everything off.

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif format.
; You must enable "show file ext name" in explorer.
; You must activate the current screen (click), or when you switch between Explorer, desktop or TCM
; In Total Commander you have to activate (Click) when you change panel.
; You need to check "Show command line" in "configuration", "Layout", in Total Commander
; https://www.autohotkey.com/boards/viewtopic.php?t=90001
;================================================================
; Modified code to add a border to the image, created by Hellbent
; Total Commander support added by WetWare05
; https://www.autohotkey.com/boards/viewtopic.php?p=523384
;================================================================
#Requires AutoHotkey v1.1.33
#Include lib\UIA_Interface.ahk

SetBatchLines, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

CoordMode, Mouse, Screen

maxStr:=200
Global NoW, SetColor, StateC, MaxWidth, MaxHeight, Margin, StateC, Mode, Transp, NameControl, SuspendTCM, SuspendDeskTop, OnlyKey
NoW:=""

If numDisplays=1
 {
 Return
 }
Else
 {
 Loop %numDisplays%
  {
   MultiMon:=1
   SysGet, Mon, Monitor, %A_Index%
   SizeMon[A_Index]:= MonRight
  }
 }

if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 8, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  IniWrite, 230, NewConfig.ini, Preview_TCM, Transp
  IniWrite, Window7, NewConfig.ini, Preview_TCM, NameControl
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 }

If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
If !Transp
 {
  IniRead, Transp, NewConfig.ini, Preview_TCM, Transp
 }
If !NameControl
 {
  IniRead, NameControl, NewConfig.ini, Preview_TCM, NameControl
 }
If !SuspendDeskTop
 {
  IniRead, SuspendDeskTop, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
If !SuspendTCM
 {
  IniRead, SuspendTCM, NewConfig.ini, Preview_TCM, SuspendTCM
 }
 If !OnlyKey
 {
  IniRead, OnlyKey, NewConfig.ini, Preview_TCM, OnlyKey
 }
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth
  
;=========================================================
 Menu, Tray, Icon, Resources\Group_4.ico
 ;Menu, Tray, Icon, shell32.dll, 132 ;Example of icon the DLL Library
 Menu, Tray, Add
 Menu, tray, Add, Suspend Preview in TCM, StanbyTCM
 Menu, tray, Icon, Suspend Preview in TCM, Resources\TCommander.ico
 Menu, tray, Add, Suspend Preview in DeskTop, StanbyDeskTop
 Menu, tray, Icon, Suspend Preview in DeskTop, Resources\Explorer.ico
 Menu, tray, Add, Only Preview with RCtrl Key, OnlyKeyPress
 Menu, tray, Icon, Only Preview with RCtrl Key, Resources\Key.ico
  
 If SuspendTCM=0
  {
   Menu, Tray, ToggleCheck, Suspend Preview in TCM
  }
  
  If SuspendDeskTop=0
  {
   Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
  }
  
  If OnlyKey=0
  {
   Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
  }
 ;Return
 ;==========================================================



SetTimer, preview, 50

init:
; close system file info tip.
RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
pToken := Gdip_Startup()
OnExit, GdipExit
PreviewWindow := CreatePreviewWindow( MaxWidth , MaxHeight )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

preview:
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0) ;<<<--
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt()
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
    }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)  ;<<<--
    }
  }
return

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin
	
	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
			
	Gdip_GraphicsClear( PreviewWindow.G ) ;clear the graphics to start with a fresh canvas to draw on
	Brush := Gdip_BrushCreateSolid( SetColor ) ; create a brush and give it a color (AARRGGBB) 4B7CFA "0x99000000" FFFF00
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin ) ;use the brush to fill a rectangle on the graphics
	Gdip_DeleteBrush( Brush ) ;delete the brush to free the memory ( alt is to have a "Memory Leak" )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height ) ;Draw the resized image on the graphics
	MouseGetPos, x, y ;get the current mouse position
	
	SizeMon := []
	SysGet, numDisplays, MonitorCount

	Loop % numDisplays {
	 SysGet, Mon, Monitor, %A_Index%
	 SizeMon.Push( [Monleft, MonRight, MonTop] )
	StateMon:=1
	}
       			
	ActMon:= MWAGetMonitor()
	Over=0
	NewPos=""
	xOffSet:=16
	yOffSet:=16
	
       If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
	
	TempTop:= SizeMon[ActMon,3]
	TempY:= y-Height
	If (TempY<0 or TempY<TempTop)
	{
	 Over:=1
	 NewPos:=1
	}
	
       Marg:=margin*4 ;5
       xt:= x+Width
       
       if (xt>SizeMon[ActMon,2])
	 {
	  x:= (SizeMon[ActMon,2]-Width)-marg
	  If Over=0
	   {
	    y:= y-50
	   }
	  } 
               	
	If NewPos=1
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , y+yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp ) ;draw the graphics onto the window and reposition it at an offset of the cursor.
	 }
	Else
	UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , (y-Height)-yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
 }

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

^p::
NotifyTrayClick_201:
Pause , Toggle
Return

; https://www.autohotkey.com/boards/viewtopic.php?t=51788
; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%


try if WinActive("ahk_exe TOTALCMD.exe") or WinActive("ahk_exe TOTALCMD64.exe")
 {
  If (WinActive("ahk_exe TOTALCMD.exe") || State=2)
 {
  Gosub, Find_Control
 }

If (WinActive("ahk_exe TOTALCMD64.exe") || State=1)
 {
  Gosub, Find_Control64
 }

If !NoW
 {
  If WinActive("ahk_exe TOTALCMD.exe")
  {
   Gosub, Find_Control
  }
 If WinActive("ahk_exe TOTALCMD64.exe")
  {
   Gosub, Find_Control64
  }
 }
;If OnlyKey=0
If (OnlyKey=0 and SuspendTCM=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
  ret:= UIA_Interface()
 
  ControlGetText sPath, % NoW
  stringRight, RLast, sPath, 1
  sPath:=StrReplace(sPath,">","")
  Element := ret.ElementFromPoint()
  itemName := Element.GetCurrentPropertyValue(30005)
  if (itemName == "")
	itemName := "No 'Name'"

  RegExMatch(itemName, "^[^\t]*", Reg)
  
  FullPath:= sPath Reg
    
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := sPath "\" Reg
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

If (OnlyKey=1 and SuspendTCM=1)
 {
 ret:= UIA_Interface()
 
  ControlGetText sPath, % NoW
  stringRight, RLast, sPath, 1
  sPath:=StrReplace(sPath,">","")
  Element := ret.ElementFromPoint()
  itemName := Element.GetCurrentPropertyValue(30005)
  if (itemName == "")
	itemName := "No 'Name'"

  RegExMatch(itemName, "^[^\t]*", Reg)
    
  FullPath:= sPath Reg
    
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := sPath "\" Reg
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}
Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
  }
  else if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
  }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

NotifyTrayClick(P*) {              ;  v0.41 by SKAN on D39E/D39N @ tiny.cc/notifytrayclick
Static Msg, Fun:="NotifyTrayClick", NM:=OnMessage(0x404,Func(Fun),-1),  Chk,T:=-250,Clk:=1
  If ( (NM := Format(Fun . "_{:03X}", Msg := P[2])) && P.Count()<4 )
     Return ( T := Max(-5000, 0-(P[1] ? Abs(P[1]) : 250)) )
  Critical
  If ( ( Msg<0x201 || Msg>0x209 ) || ( IsFunc(NM) || Islabel(NM) )=0 )
     Return
  Chk := (Fun . "_" . (Msg<=0x203 ? "203" : Msg<=0x206 ? "206" : Msg<=0x209 ? "209" : ""))
  SetTimer, %NM%,  %  (Msg==0x203        || Msg==0x206        || Msg==0x209)
    ? (-1, Clk:=2) : ( Clk=2 ? ("Off", Clk:=1) : ( IsFunc(Chk) || IsLabel(Chk) ? T : -1) )
Return True
}

; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
;	Color Dialog Example script.

^!F8::
stringRight, RSix, SetColor, 6
TColor:="0x" RSix
R:= (TColor&0xFF0000)>>16, G:= (TColor&0x00FF00)>>8, B:= TColor&0xFF

RGBval:=RGB(Rval:= R, Gval:= G, Bval:= B)
;Create Color Dialog GUI
Gui, Add, Text, x0 y10 w40 h20 +Right, Red
Gui, Add, Text, x0 y30 w40 h20 +Right, Green
Gui, Add, Text, x0 y50 w40 h20 +Right, Blue
Gui, Add, Slider, x40 y10 w190 h20 AltSubmit +NoTicks +Range0-255 vsR gSliderSub, %Rval%
Gui, Add, Slider, x40 y30 w190 h20 AltSubmit +NoTicks +Range0-255 vsG gSliderSub, %Gval%
Gui, Add, Slider, x40 y50 w190 h20 AltSubmit +NoTicks +Range0-255 vsB gSliderSub, %Bval%
Gui, Add, Edit, x230 y10 w45 h20 gEditSub veR +Limit3 +Number, %Rval%
Gui, Add, UpDown, Range0-255 vuR gUpDownSub, %Rval%
Gui, Add, Edit, x230 y30 w45 h20 gEditSub veG +Limit3 +Number, %Gval%
Gui, Add, UpDown, Range0-255 vuG gUpDownSub, %Gval%
Gui, Add, Edit, x230 y50 w45 h20 gEditSub veB +Limit3 +Number, %Bval%
Gui, Add, UpDown, Range0-255 vuB gUpDownSub, %Bval%
Gui, Add, Progress, x285 y10 w60 h60 +Border Background%RGBval% vpC
Gui, Add, Text, x285 y10 w60 h60 +Border vtP cWhite +BackgroundTrans, Preview
Gui, Add, Button, x120 y80 w110 h20 vbS gButtonSub, Select Color ;Copy to Clipboard
Gui, Show, w351 h105, Simple Color Dialog
return

EditSub:
	;Get Values
	GuiControlGet,Rval,,eR
	GuiControlGet,Gval,,eG
	GuiControlGet,Bval,,eB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

UpDownSub:
	;Get Values
	GuiControlGet,Rval,,uR
	GuiControlGet,Gval,,uG
	GuiControlGet,Bval,,uB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

SliderSub:
	;Get Values
	GuiControlGet,Rval,,sR
	GuiControlGet,Gval,,sG
	GuiControlGet,Bval,,sB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
return

set:
	;Convert values to Hex
	RGBval:=RGB(Rval,Gval,Bval)
	;Display Tooltip
	ToolTip Red: %Rval%`nGreen: %Gval%`nBlue: %Bval%`nHex: %RGBval%
	;Make tooltip disappear after 375 ms (3/8th of a second)
	SetTimer, RemoveToolTip, 375
	;Apply colour to preview
	GuiControl,+Background%RGBval%,pC
return

RemoveToolTip:
	SetTimer, RemoveToolTip, Off ;Turn timer off
	ToolTip ;Turn off tooltip
return

ButtonSub:
	;Remove '0x' prefix to hex color code, saving it directly to the clipboard
	;StringReplace,Clipboard,RGBval,0x99
	StringReplace,SetColor,RGBval,0x
	SetColor:="0x99" SetColor
	;MsgBox, % SetColor . " " . RGBval
	;Display Last selected values... (these values can later be used), and Notify the user
	;MsgBox,64,Simple Color Dialog,RGB: (%Rval%, %Gval%, %Bval%)`nHex: %RGBval%`nCopied to Clipboard!
	;Skip Directly GuiClose
	Gui, Destroy
	Return

^!s::
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: +HwndGuiID +AlwaysOnTop
Gui, Size: Add, Button, x300 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x300 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x5 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x95 y16 w60 h20 vFmaxW, %TempMaxW%
Gui, Size: Add, Text, x5 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x95 y46 w60 h20 vFmaxH, %TempMaxH%
Gui, Size: Add, Text, x170 y16 w70 h20, Transp.:
Gui, Size: Add, edit, x230 y16 w60 h20 vFtrans , %Transp%
Gui, Size: Add, Text, x170 y46 w70 h20, Margin :
Gui, Size: Add, edit, x230 y46 w60 h20 vFmarg , %margin%
Gui, Size: Show, x%xpos% y%ypos% h80 w370, Image Preview Configuration
Return

#If WinActive("ahk_id " GuiID)
Enter::
NumPadEnter::
NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxWidth:=500
 }
Else 
{
MaxWidth:=FmaxW
IniWrite, %MaxWidth%, NewConfig.ini, Preview_TCM, MaxWidth
}

If !FmaxH
 {
  MaxHeight:=500
 }
Else 
{
MaxHeight:=FmaxH
IniWrite, %MaxHeight%, NewConfig.ini, Preview_TCM, MaxHeight
}

If !Ftrans or Ftrans>256
 {
  Transp:=Transp
 }
Else 
{
Transp:=Ftrans
IniWrite, %Ftrans%, NewConfig.ini, Preview_TCM, Transp
}

If !Fmarg
 {
  Margin:=16
 }
Else 
{
Margin:=Fmarg
IniWrite, %Fmarg%, NewConfig.ini, Preview_TCM, Margin
}
Gui, Size: Destroy
Gosub, Init
Return

Cancel:
Gui, Size: Destroy
Return

;^F8::
Find_Control:
Now:=""
Loop, 30
 {
 NewWin:= "TMyPanel" A_Index
 ControlGetText PPath, % NewWin
 StringRight, RLast, PPath, 1
 If RLast=>
   {
   NoW:= NewWin
   State=1
   Break 
   }
 }
Return

;^F9::
Find_Control64:
Now:=""
Loop, 30
 {
 NewWin:= "Window" A_Index
 ControlGetText PPath, % NewWin
 StringRight, RLast, PPath, 1
 If RLast=>
   {
   NoW:= NewWin
   State=2
   Break 
   }
 }
Return

^Esc::
Exit:
ExitApp
Return

Stanby:
Return

StanbyTCM:
Menu, Tray, ToggleCheck, Suspend Preview in TCM
If SuspendTCM=1 
 {
  SuspendTCM:=0
 ;TrayTip, TCM Image Preview, DISABLED,, 0x1, 0x10, 0x20
 SoundPlay, Resources\State_U.mp3
 IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendTCM
 }
Else
 {
 SuspendTCM:=1
 ;TrayTip, TCM Image Preview, ENABLED,, 0x1, 0x10, 0x20
 IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
 SoundPlay, Resources\State_I.mp3
 }
Return

StanbyDeskTop:
Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
If SuspendDeskTop=1 
 {
  SuspendDeskTop:=0
 ;TrayTip, DeskTop Image Preview, DISABLED,, 0x1, 0x10, 0x20
 IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendDeskTop
 SoundPlay, Resources\State_U.mp3
 }
Else
 {
 SuspendDeskTop:=1
 ;TrayTip, DeskTop Image Preview, ENABLED,, 0x1, 0x10, 0x20
 IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
 SoundPlay, Resources\State_I.mp3
 }
Return

OnlyKeyPress:
Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
If OnlyKey=1 
 {
  OnlyKey:=0
 ;TrayTip, Press Key for View, DISABLED,, 0x1, 0x10, 0x20
 SoundPlay, Resources\State_I.mp3
 IniWrite, 0, NewConfig.ini, Preview_TCM, OnlyKey
 }
Else
 {
 OnlyKey:=1
 ;TrayTip,  Press Key for View, ENABLED,, 0x1, 0x10, 0x20
 IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 SoundPlay, Resources\State_U.mp3
 }
Return

;Function to convert Decimal RGB to Hexadecimal RBG, Note: '0' (zero) padding is unnecessary
RGB(r, g, b) {
	;Shift Numbers
	var:=(r << 16) + (g << 8) + b
	;Save current A_FormatInteger
	OldFormat := A_FormatInteger
	;Set Hex A_FormatInteger mode
	SetFormat, Integer, Hex
	;Force decimal number to Hex number
	var += 0
	;set original A_FormatInteger mode
	SetFormat, Integer, %OldFormat%
	return var
}

; Funtion By Maestr0 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=54557

MWAGetMonitor(Mx := "", My := "")
{
	if  (!Mx or !My) 
	{
		; if Mx or My is empty, revert to the mouse cursor placement
		Coordmode, Mouse, Screen	; use Screen, so we can compare the coords with the sysget information`
		MouseGetPos, Mx, My
	}

	SysGet, MonitorCount, 80	; monitorcount, so we know how many monitors there are, and the number of loops we need to do
	Loop, %MonitorCount%
	{
		SysGet, mon%A_Index%, Monitor, %A_Index%	; "Monitor" will get the total desktop space of the monitor, including taskbars

		if ( Mx >= mon%A_Index%left ) && ( Mx < mon%A_Index%right ) && ( My >= mon%A_Index%top ) && ( My < mon%A_Index%bottom )
		{
			ActiveMon := A_Index
			break
		}
	}
	return ActiveMon
}

#Include <NonNull>
#Include <Gdip_All>
I have changed the default icon and added icons to the menu options. The script beeps when toggling between states. You can send a notice to the inbox, now it is skipped. If you want the warning to appear, edit lines 694, 705 and 712 and delete the semicolon (;) and save.

New download with everything you need:
https://mega.nz/file/Ec4SQDKL#9tKZM7PuZ8hEvcBnWN9wscZMAQt_frghE-KOs8sfCJA
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Hi,

I took a break from the script.

In the new update, the image under the mouse is projected full screen on the second monitor (at the size of the image, and filling the background with the frame color, which can be changed). The full screen image overrides the transparency selected in the setup, if you want to keep the transparency, change in line 363, "Alpha := 255" to "Alpha := Transp". I have totally changed the icon tray menu. Right clicking on the icon tray icon now pauses it and a second click activates the script. Now a small window appears that warns when menu components are activated or deactivated.

The current script has two flaws. 1. When going full screen and displaying some desktop image, when you return to Total Commander, the preview doesn't work. You have to reload the script, from its menu or if it is paused and unpaused, it works (this last behavior is not normal, I have added a line to temporarily reload the script). 2. The script, when opening images, Windows assumes that they are being used by a program, and you cannot rename them or move them to another directory or delete them, because the system assumes that they are in use. You have to close the script to unlock the files. Or it pauses and unpauses and pauses again, because as you reload the script, the system assumes that the images are no longer in use. I've been closing threads and blocking parts of the script, but it doesn't resolve.

There is a new variable in the "NewConfig.ini" file for transparency; if you want to keep your personal "NewConfig.ini" file, add the line "Reflect=0" at the end.

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif format.
; You must enable "show file ext name" in explorer.
; You must activate the current screen (click), or when you switch between Explorer, desktop or TCM
; In Total Commander you have to activate (Click) when you change panel.
; You need to check "Show command line" in "configuration", "Layout", in Total Commander
; https://www.autohotkey.com/boards/viewtopic.php?t=90001
;================================================================
; Modified code to add a border to the image, created by Hellbent
; Total Commander support added by WetWare05
; https://www.autohotkey.com/boards/viewtopic.php?p=523384
;================================================================
#Requires AutoHotkey v1.1.33
#Include lib\UIA_Interface.ahk

SetBatchLines, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
Thread, Interrupt, 0

CoordMode, Mouse, Screen

maxStr:=200
Global NoW, SetColor, StateC, MaxWidth, MaxHeight, Margin, StateC, Mode, Transp, NameControl, SuspendTCM, SuspendDeskTop, OnlyKey, Reflect
NoW:=""

If numDisplays=0
 {
 Return
 }
Else
 {
 Loop %numDisplays%
  {
   MultiMon:=1
   SysGet, Mon, Monitor, %A_Index%
   SizeMon[A_Index]:= MonRight
  }
 }

if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 8, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  IniWrite, 230, NewConfig.ini, Preview_TCM, Transp
  IniWrite, Window7, NewConfig.ini, Preview_TCM, NameControl
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
 }

ReadVar:
If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
If !Transp
 {
  IniRead, Transp, NewConfig.ini, Preview_TCM, Transp
 }
If !NameControl
 {
  IniRead, NameControl, NewConfig.ini, Preview_TCM, NameControl
 }
If !SuspendDeskTop
 {
  IniRead, SuspendDeskTop, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
If !SuspendTCM
 {
  IniRead, SuspendTCM, NewConfig.ini, Preview_TCM, SuspendTCM
 }
 If !OnlyKey
 {
  IniRead, OnlyKey, NewConfig.ini, Preview_TCM, OnlyKey
 }
 If !Reflect
 {
  IniRead, Reflect, NewConfig.ini, Preview_TCM, Reflect
 }
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth
  
;=========================================================
 Menu, Tray, Icon, Resources\Group_4.ico
 ;Menu, Tray, Icon, shell32.dll, 132 ;Example of icon the DLL Library
 Menu, Tray, NoStandard
 Menu, tray, Add, TCM Image Preview, Nothing
 Menu, tray, Icon, TCM Image Preview, Resources\Group_4.ico
 Menu, Tray, Add
 Menu Tray, Add, Open Info, Tray_Open
 Menu Tray, Icon, Open Info, Resources\Info.ico
 Menu, tray, Add, &Reload this Script, Reloaded
 Menu, tray, Icon,&Reload this Script, Resources\2488.ico
 Menu, tray, Add, &Suspend Utility, Stanby
 Menu, tray, Icon,&Suspend Utility, Resources\Group_4_Red.ico
 Menu, Tray, Add
 Menu, tray, Add, Suspend Preview in TCM, StanbyTCM
 Menu, tray, Icon, Suspend Preview in TCM, Resources\TCommander.ico
 Menu, tray, Add, Suspend Preview in DeskTop, StanbyDeskTop
 Menu, tray, Icon, Suspend Preview in DeskTop, Resources\Explorer.ico
 Menu, tray, Add, Only Preview with RCtrl Key, OnlyKeyPress
 Menu, tray, Icon, Only Preview with RCtrl Key, Resources\Key.ico
 Menu, tray, Add, Mirror to Second Monitor, ReflectTwo
 Menu, tray, Icon, Mirror to Second Monitor, Resources\2220.ico
 Menu, Tray, Add
 Menu, tray, Add, Preview Setting, Config
 Menu, tray, Icon, Preview Setting, Resources\130.ico
 Menu, tray, Add, Frame Color, FrameColor
 Menu, tray, Icon, Frame Color, Resources\ColorEdit.ico
 Menu, Tray, Add
 Menu, tray, Add, Exit, Exit
 Menu, tray, Icon, Exit, shell32.dll, 132
   
 If SuspendTCM=0
  {
   Menu, Tray, Check, Suspend Preview in TCM
  }
  
  If SuspendDeskTop=0
  {
   Menu, Tray, Check, Suspend Preview in DeskTop
  }
  
  If OnlyKey=0
  {
   Menu, Tray, Check, Only Preview with RCtrl Key
  }
  
  If Reflect=1
  {
   Menu, Tray, Check, Mirror to Second Monitor
  }
 ;Return
 ;==========================================================

SetTimer, preview, 50

init:

If Reflect=1
 {
  SizeMon := []
  SysGet, numDisplays, 80
  Loop % numDisplays {
  SysGet, Mon, Monitor, %A_Index%
  SizeMon.Push([Monleft, MonRight, MonTop, MonBottom])
 }
 
 ActMon:= MWAGetMonitor()
  
  If ActMon=1
   {
    MaxWidth:= SizeMon[2,2]-SizeMon[1,2]
    MaxHeight:= SizeMon[2,4]
   }
   
  If ActMon=2
   {
    MaxWidth:= SizeMon[1,2]
    MaxHeight:= SizeMon[1,4]
   } 
 }
 
; close system file info tip.
RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
pToken := Gdip_Startup()
OnExit, GdipExit
PreviewWindow := CreatePreviewWindow( MaxWidth , MaxHeight )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Critical
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	try Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

preview:
if A_IsSuspended=0
{
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt()
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
    }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
    }
  }
 }
return

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin
	
	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
			
      If Reflect=0
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin )
	Gdip_DeleteBrush( Brush )
	
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height )
	MouseGetPos, x, y
	ActMon:= MWAGetMonitor() ;<<<<<----------
       }
     
     If Reflect=1
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )
	ActMon:= MWAGetMonitor() ;<<<<<----------
      }	
	
     ;If Reflect=0
      ;{
	SizeMon := []
	SysGet, numDisplays, 80

	Loop % numDisplays {
	 SysGet, Mon, Monitor, %A_Index%
	 SizeMon.Push( [Monleft, MonRight, MonTop, MonBottom] )
	StateMon:=1
	}
      ;}
	
      If Reflect=1
       {
	ActMon:= MWAGetMonitor()
  
        If ActMon=1
         {
	  x:= (SizeMon[1,2]+1)
	  y:= SizeMon[2,3]
	 }
        If ActMon=2
         {
	  x:= SizeMon[1,1]
	  y:= SizeMon[1,3]
	 }      
       }
            
      If Reflect=0
	{
	ActMon:= MWAGetMonitor()
	Over=0
	NewPos=0
	xOffSet:=16
	yOffSet:=16
	
       If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
	
	TempTop:= SizeMon[ActMon,3]
	TempY:= y-Height
	If (TempY<0 or TempY<TempTop)
	{
	 Over:=1
	 NewPos:=1
	}
	
       Marg:=margin*4 ;5
       xt:= x+Width
       
       if (xt>SizeMon[ActMon,2])
	 {
	  x:= (SizeMon[ActMon,2]-Width)-marg
	  If Over=0
	   {
	    y:= y-50
	   }
	  }
       }	  
               	
	If (NewPos=1 && Reflect=0)
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , y+yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	 }
	
	If (Reflect=0 and NewPos=0)
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , (y-Height)-yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	}
	If Reflect=1
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x , y , PreviewWindow.Width , PreviewWindow.Height , Alpha := 255 ) ;Alpha := Transp
	}
  }

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

; https://www.autohotkey.com/boards/viewtopic.php?t=51788
; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925

GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%


try if WinActive("ahk_exe TOTALCMD.exe") or WinActive("ahk_exe TOTALCMD64.exe")
 {
  ActMon:= MWAGetMonitor()
  If (WinActive("ahk_exe TOTALCMD.exe") || State=2)
 {
  Gosub, Find_Control
 }

If (WinActive("ahk_exe TOTALCMD64.exe") || State=1)
 {
  Gosub, Find_Control64
 }

If !NoW
 {
  If WinActive("ahk_exe TOTALCMD.exe")
  {
   Gosub, Find_Control
  }
 If WinActive("ahk_exe TOTALCMD64.exe")
  {
   Gosub, Find_Control64
  }
 }

If (OnlyKey=0 and SuspendTCM=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
  ret:= UIA_Interface()
 
  ControlGetText sPath, % NoW
  stringRight, RLast, sPath, 1
  sPath:=StrReplace(sPath,">","")
  Element := ret.ElementFromPoint()
  itemName := Element.GetCurrentPropertyValue(30005)
  if (itemName == "")
	itemName := "No 'Name'"

  RegExMatch(itemName, "^[^\t]*", Reg)
  
  FullPath:= sPath Reg
    
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := sPath "\" Reg
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

If (OnlyKey=1 and SuspendTCM=1)
 {
 ret:= UIA_Interface()
 
  ControlGetText sPath, % NoW
  stringRight, RLast, sPath, 1
  sPath:=StrReplace(sPath,">","")
  Element := ret.ElementFromPoint()
  itemName := Element.GetCurrentPropertyValue(30005)
  if (itemName == "")
	itemName := "No 'Name'"

  RegExMatch(itemName, "^[^\t]*", Reg)
    
  FullPath:= sPath Reg
    
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := sPath "\" Reg
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}
Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
  }
  else if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
  }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

NotifyTrayClick(P*) {              ;  v0.41 by SKAN on D39E/D39N @ tiny.cc/notifytrayclick
Static Msg, Fun:="NotifyTrayClick", NM:=OnMessage(0x404,Func(Fun),-1),  Chk,T:=-250,Clk:=1
  If ( (NM := Format(Fun . "_{:03X}", Msg := P[2])) && P.Count()<4 )
     Return ( T := Max(-5000, 0-(P[1] ? Abs(P[1]) : 250)) )
  Critical
  If ( ( Msg<0x201 || Msg>0x209 ) || ( IsFunc(NM) || Islabel(NM) )=0 )
     Return
  Chk := (Fun . "_" . (Msg<=0x203 ? "203" : Msg<=0x206 ? "206" : Msg<=0x209 ? "209" : ""))
  SetTimer, %NM%,  %  (Msg==0x203        || Msg==0x206        || Msg==0x209)
    ? (-1, Clk:=2) : ( Clk=2 ? ("Off", Clk:=1) : ( IsFunc(Chk) || IsLabel(Chk) ? T : -1) )
Return True
}

; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
;	Color Dialog Example script.
;^!F8::
FrameColor:
stringRight, RSix, SetColor, 6
TColor:="0x" RSix
R:= (TColor&0xFF0000)>>16, G:= (TColor&0x00FF00)>>8, B:= TColor&0xFF

RGBval:=RGB(Rval:= R, Gval:= G, Bval:= B)
;Create Color Dialog GUI
Gui, Add, Text, x0 y10 w40 h20 +Right, Red
Gui, Add, Text, x0 y30 w40 h20 +Right, Green
Gui, Add, Text, x0 y50 w40 h20 +Right, Blue
Gui, Add, Slider, x40 y10 w190 h20 AltSubmit +NoTicks +Range0-255 vsR gSliderSub, %Rval%
Gui, Add, Slider, x40 y30 w190 h20 AltSubmit +NoTicks +Range0-255 vsG gSliderSub, %Gval%
Gui, Add, Slider, x40 y50 w190 h20 AltSubmit +NoTicks +Range0-255 vsB gSliderSub, %Bval%
Gui, Add, Edit, x230 y10 w45 h20 gEditSub veR +Limit3 +Number, %Rval%
Gui, Add, UpDown, Range0-255 vuR gUpDownSub, %Rval%
Gui, Add, Edit, x230 y30 w45 h20 gEditSub veG +Limit3 +Number, %Gval%
Gui, Add, UpDown, Range0-255 vuG gUpDownSub, %Gval%
Gui, Add, Edit, x230 y50 w45 h20 gEditSub veB +Limit3 +Number, %Bval%
Gui, Add, UpDown, Range0-255 vuB gUpDownSub, %Bval%
Gui, Add, Progress, x285 y10 w60 h60 +Border Background%RGBval% vpC
Gui, Add, Text, x285 y10 w60 h60 +Border vtP cWhite +BackgroundTrans, Preview
Gui, Add, Button, x120 y80 w110 h20 vbS gButtonSub, Select Color ;Copy to Clipboard
Gui, Show, w351 h105, Simple Color Dialog
return

EditSub:
	;Get Values
	GuiControlGet,Rval,,eR
	GuiControlGet,Gval,,eG
	GuiControlGet,Bval,,eB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

UpDownSub:
	;Get Values
	GuiControlGet,Rval,,uR
	GuiControlGet,Gval,,uG
	GuiControlGet,Bval,,uB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

SliderSub:
	;Get Values
	GuiControlGet,Rval,,sR
	GuiControlGet,Gval,,sG
	GuiControlGet,Bval,,sB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
return

set:
	;Convert values to Hex
	RGBval:=RGB(Rval,Gval,Bval)
	;Display Tooltip
	ToolTip Red: %Rval%`nGreen: %Gval%`nBlue: %Bval%`nHex: %RGBval%
	;Make tooltip disappear after 375 ms (3/8th of a second)
	SetTimer, RemoveToolTip, 375
	;Apply colour to preview
	GuiControl,+Background%RGBval%,pC
return

RemoveToolTip:
	SetTimer, RemoveToolTip, Off ;Turn timer off
	ToolTip ;Turn off tooltip
return

ButtonSub:
 ;Remove '0x' prefix to hex color code, saving it directly to the clipboard
 ;StringReplace,Clipboard,RGBval,0x99
 StringReplace,SetColor,RGBval,0x
 SetColor:="0x99" SetColor
 ;MsgBox, % SetColor . " " . RGBval
 ;Display Last selected values... (these values can later be used), and Notify the user
 ;MsgBox,64,Simple Color Dialog,RGB: (%Rval%, %Gval%, %Bval%)`nHex: %RGBval%`nCopied to Clipboard!
 ;Skip Directly GuiClose
 Gui, Destroy
Return

;^!s::
Config:
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: +HwndGuiID +AlwaysOnTop
Gui, Size: Add, Button, x300 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x300 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x5 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x95 y16 w60 h20 vFmaxW, %TempMaxW%
Gui, Size: Add, Text, x5 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x95 y46 w60 h20 vFmaxH, %TempMaxH%
Gui, Size: Add, Text, x170 y16 w70 h20, Transp.:
Gui, Size: Add, edit, x230 y16 w60 h20 vFtrans , %Transp%
Gui, Size: Add, Text, x170 y46 w70 h20, Margin :
Gui, Size: Add, edit, x230 y46 w60 h20 vFmarg , %margin%
Gui, Size: Show, x%xpos% y%ypos% h80 w370, Image Preview Configuration
Return

#If WinActive("ahk_id " GuiID)
Enter::
NumPadEnter::
NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxWidth:=500
 }
Else 
{
MaxWidth:=FmaxW
IniWrite, %MaxWidth%, NewConfig.ini, Preview_TCM, MaxWidth
}

If !FmaxH
 {
  MaxHeight:=500
 }
Else 
{
MaxHeight:=FmaxH
IniWrite, %MaxHeight%, NewConfig.ini, Preview_TCM, MaxHeight
}

If !Ftrans or Ftrans>256
 {
  Transp:=Transp
 }
Else 
{
Transp:=Ftrans
IniWrite, %Ftrans%, NewConfig.ini, Preview_TCM, Transp
}

If !Fmarg
 {
  Margin:=16
 }
Else 
{
Margin:=Fmarg
IniWrite, %Fmarg%, NewConfig.ini, Preview_TCM, Margin
}
Gui, Size: Destroy
Gosub, Init
Return

Cancel:
Gui, Size: Destroy
Return

;^F8::
Find_Control:
Now:=""
Loop, 30
 {
 NewWin:= "TMyPanel" A_Index
 ControlGetText PPath, % NewWin
 StringRight, RLast, PPath, 1
 If RLast=>
   {
   NoW:= NewWin
   State=1
   Break 
   }
 }
Return

;^F9::
Find_Control64:
Now:=""
Loop, 30
 {
 NewWin:= "Window" A_Index
 ControlGetText PPath, % NewWin
 StringRight, RLast, PPath, 1
 If RLast=>
   {
   NoW:= NewWin
   State=2
   Break 
   }
 }
Return

~Esc:: ; *
Gosub, GdipExit
SetTimer, preview, off
Sleep, 1000
SetTimer, preview, On
Return

^Esc::
Exit:
ExitApp
Return

StanbyTCM:
Menu, Tray, ToggleCheck, Suspend Preview in TCM
If SuspendTCM=1 
 {
  SuspendTCM:=0
 ;TrayTip, TCM Image Preview, DISABLED,, 0x1, 0x10, 0x20
  SplashTextOn,200, 80, Notification, Preview in TCM Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendTCM
 }
Else
 {
  SuspendTCM:=1
  SplashTextOn,200, 80, Notification, Preview in TCM
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM  
 }
Return

StanbyDeskTop:
Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
Gosub, GdipExit
If SuspendDeskTop=1 
 {
  SuspendDeskTop:=0
  SplashTextOn,200, 80, Notification, Preview in DeskTop Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Else
 {
  SuspendDeskTop:=1
  SplashTextOn,200, 80, Notification, Preview in DeskTop
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Return

OnlyKeyPress:
Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
If OnlyKey=1 
 {
  OnlyKey:=0
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, OnlyKey
 }
Else
 {
  OnlyKey:=1
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 }
Return

ReflectTwo:
Menu, Tray, ToggleCheck, Mirror to Second Monitor
If Reflect=1 
 {
  SplashTextOn,200, 80, Notification, Mirror to Second Monitor Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  Reflect:=0
  MaxWidth:=""
  MaxHeight:=""
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
 }
Else
 {
 Reflect:=1
 SplashTextOn,200, 80, Notification, Mirror to Second Monitor
 xSplash1 := A_ScreenWidth-206
 ySplash1 := A_ScreenHeight-180
 WinMove, Notification,, xSplash1, ySplash1
 SoundPlay, Resources\State_I.mp3
 Sleep, 1500
 SplashTextOff
 IniWrite, 1, NewConfig.ini, Preview_TCM, Reflect
 Gosub, init
 }
Reload
Return

^p::
NotifyTrayClick_201:
Gosub, Stanby
Return

;^F12::
Stanby:
Suspend:=!Suspend
IfEqual,Suspend,1, Menu,Tray,Icon, Resources\Group_4_Red.ico
IfEqual,Suspend,0, Menu,Tray,Icon, Resources\Group_4.ico
Menu,Tray,Icon,,,1
Suspend,Toggle

if A_IsSuspended=1
 {
  Menu, tray, Check, &Suspend Utility
  SoundPlay, Resources\State_U.mp3 
  SetTimer, preview, off
  SplashTextOn,200, 80, Notification, Application has Been Deactivated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff  
 }
  
if A_IsSuspended=0
 {
  Menu, tray, Uncheck, &Suspend Utility
  SoundPlay, Resources\State_I.mp3
  SetTimer, preview, On
  SplashTextOn,200, 80, Notification, Application has Been Activated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff
  Sleep, 500
  Reload ;<--- Momentary patch to solve problems
 }  
;Gosub, init
Return

Reloaded:
Reload
Return

Tray_Open:
ListLines
return

Nothing:
Return

;Function to convert Decimal RGB to Hexadecimal RBG, Note: '0' (zero) padding is unnecessary
RGB(r, g, b) {
	;Shift Numbers
	var:=(r << 16) + (g << 8) + b
	;Save current A_FormatInteger
	OldFormat := A_FormatInteger
	;Set Hex A_FormatInteger mode
	SetFormat, Integer, Hex
	;Force decimal number to Hex number
	var += 0
	;set original A_FormatInteger mode
	SetFormat, Integer, %OldFormat%
	return var
}

; Funtion By Maestr0 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=54557

MWAGetMonitor(Mx := "", My := "")
{
	if  (!Mx or !My) 
	{
		; if Mx or My is empty, revert to the mouse cursor placement
		Coordmode, Mouse, Screen	; use Screen, so we can compare the coords with the sysget information`
		MouseGetPos, Mx, My
	}

	SysGet, MonitorCount, 80	; monitorcount, so we know how many monitors there are, and the number of loops we need to do
	Loop, %MonitorCount%
	{
		SysGet, mon%A_Index%, Monitor, %A_Index%	; "Monitor" will get the total desktop space of the monitor, including taskbars

		if ( Mx >= mon%A_Index%left ) && ( Mx < mon%A_Index%right ) && ( My >= mon%A_Index%top ) && ( My < mon%A_Index%bottom )
		{
			ActiveMon := A_Index
			break
		}
	}
	return ActiveMon
}

#Include <NonNull>
#Include <Gdip_All>
Demo video: https://www.youtube.com/watch?v=wk3wLfi3SW0

New download, with the new icons: https://mega.nz/file/gY5V1QiS#uaCDnDGaF58HzrndORAiTlWkNz4LOYUyMNwRn4kWWCk
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Hi.

Fixed the error of changing the screen and that the previews of the images did not come out, when the projection to the second monitor is activated.

Optimized the file path lookup in Total Commander, thanks to "Hacker" input at viewtopic.php?t=52539 this optimization, and others, has made the script almost 100 lines smaller. Now the name search is done through ACC, so you can delete the UIA libraries (UIA_Browser.ahk, UIA_Constants.ahk and UIA_Interface.ahk), if you don't need them for another script.

Cannot resolve Windows detecting that files are being used. It is the same effect as if the image were opened by a graphics editing program. Windows will not allow the file to be deleted or renamed until the graphics editing program (or a viewer) is closed.

The download from the previous post is still valid, only you have to use this script, instead of Preview TCM 1b.ahk (Delete its content and paste the present script).

(For people who didn't get the previous scripts working, try this one, see if you get lucky.)

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif format.
; You must enable "show file ext name" in explorer.
; You must activate the current screen (click), or when you switch between Explorer, desktop or TCM
; In Total Commander you have to activate (Click) when you change panel.
; You need to check "Show command line" in "configuration", "Layout", in Total Commander
; https://www.autohotkey.com/boards/viewtopic.php?t=90001
;================================================================
; Modified code to add a border to the image, created by Hellbent
; Total Commander support added by WetWare05
; https://www.autohotkey.com/boards/viewtopic.php?p=523384
;================================================================
#Requires AutoHotkey v1.1.33

SetBatchLines, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
Thread, Interrupt, 0

CoordMode, Mouse, Screen

maxStr:=200
Global NoW, SetColor, MaxWidth, MaxHeight, Margin, Transp, SuspendTCM, SuspendDeskTop, OnlyKey, Reflect
NoW:=""

;=========================================================
 Menu, Tray, Icon, Resources\Group_4.ico
 ;Menu, Tray, Icon, shell32.dll, 132 ;Example of icon the DLL Library
 Menu, Tray, NoStandard
 Menu, tray, Add, TCM Image Preview, Nothing
 Menu, tray, Icon, TCM Image Preview, Resources\Group_4.ico
 Menu, Tray, Add
 Menu Tray, Add, Open Info, Tray_Open
 Menu Tray, Icon, Open Info, Resources\Info.ico
 Menu, tray, Add, &Reload this Script, Reloaded
 Menu, tray, Icon,&Reload this Script, Resources\2488.ico
 Menu, tray, Add, &Suspend Utility, Stanby
 Menu, tray, Icon,&Suspend Utility, Resources\Group_4_Red.ico
 Menu, Tray, Add
 Menu, tray, Add, Suspend Preview in TCM, StanbyTCM
 Menu, tray, Icon, Suspend Preview in TCM, Resources\TCommander.ico
 Menu, tray, Add, Suspend Preview in DeskTop, StanbyDeskTop
 Menu, tray, Icon, Suspend Preview in DeskTop, Resources\Explorer.ico
 Menu, tray, Add, Only Preview with RCtrl Key, OnlyKeyPress
 Menu, tray, Icon, Only Preview with RCtrl Key, Resources\Key.ico
 Menu, tray, Add, Mirror to Second Monitor, ReflectTwo
 Menu, tray, Icon, Mirror to Second Monitor, Resources\2220.ico
 Menu, Tray, Add
 Menu, tray, Add, Preview Setting, Config
 Menu, tray, Icon, Preview Setting, Resources\130.ico
 Menu, tray, Add, Frame Color, FrameColor
 Menu, tray, Icon, Frame Color, Resources\ColorEdit.ico
 Menu, Tray, Add
 Menu, tray, Add, Exit, Exit
 Menu, tray, Icon, Exit, shell32.dll, 132
 
if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 8, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  IniWrite, 230, NewConfig.ini, Preview_TCM, Transp
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
 }

ReadVar:
If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
If !Transp
 {
  IniRead, Transp, NewConfig.ini, Preview_TCM, Transp
 }
If !SuspendDeskTop
 {
  IniRead, SuspendDeskTop, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
If !SuspendTCM
 {
  IniRead, SuspendTCM, NewConfig.ini, Preview_TCM, SuspendTCM
 }
 If !OnlyKey
 {
  IniRead, OnlyKey, NewConfig.ini, Preview_TCM, OnlyKey
 }
 If !Reflect
 {
  IniRead, Reflect, NewConfig.ini, Preview_TCM, Reflect
 }
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth
   
 If SuspendTCM=0
  {
   Menu, Tray, Check, Suspend Preview in TCM
  }
  
  If SuspendDeskTop=0
  {
   Menu, Tray, Check, Suspend Preview in DeskTop
  }
  
  If OnlyKey=0
  {
   Menu, Tray, Check, Only Preview with RCtrl Key
  }
  
  If Reflect=1
  {
   Menu, Tray, Check, Mirror to Second Monitor
  }

 ;==========================================================

SetTimer, preview, 50

init:
SizeMon := []
SysGet, numDisplays, 80
Loop % numDisplays {
  SysGet, Mon, Monitor, %A_Index%
  SizeMon.Push([Monleft, MonRight, MonTop, MonBottom])
 }
  
 If Reflect=1
 {
 ActMon:= MWAGetMonitor()
  
  If ActMon=1
   {
    MaxWidth:= SizeMon[2,2]-SizeMon[1,2]
    MaxHeight:= SizeMon[2,4]
   }
   
  If ActMon=2
   {
    MaxWidth:= SizeMon[1,2]
    MaxHeight:= SizeMon[1,4]
   } 
 }
 
; close system file info tip.
RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
pToken := Gdip_Startup()
OnExit, GdipExit
PreviewWindow := CreatePreviewWindow( MaxWidth , MaxHeight )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Critical
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	try Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

preview:
if A_IsSuspended=0
{
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt()
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
    }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
    }
  }
 }
return

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin
	
	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
			
      If Reflect=0
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin )
	Gdip_DeleteBrush( Brush )
	
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height )
	MouseGetPos, x, y	
       }
     
     If Reflect=1
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )	
      }	
	
     	SizeMon := []
	SysGet, numDisplays, 80

	Loop % numDisplays {
	 SysGet, Mon, Monitor, %A_Index%
	 SizeMon.Push( [Monleft, MonRight, MonTop, MonBottom] )
	StateMon:=1
	}
	
      If Reflect=1
       {
	ActMon:= MWAGetMonitor()
  
        If ActMon=1
         {
	  x:= (SizeMon[1,2]+1)
	  y:= SizeMon[2,3]
	 }
        If ActMon=2
         {
	  x:= SizeMon[1,1]
	  y:= SizeMon[1,3]
	 }      
       }
            
      If Reflect=0
	{
	ActMon:= MWAGetMonitor()
	Over=0
	NewPos=0
	xOffSet:=16
	yOffSet:=16
	
       If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
	
	TempTop:= SizeMon[ActMon,3]
	TempY:= y-Height
	If (TempY<0 or TempY<TempTop)
	{
	 Over:=1
	 NewPos:=1
	}
	
       Marg:=margin*4 ;5
       xt:= x+Width
       
       if (xt>SizeMon[ActMon,2])
	 {
	  x:= (SizeMon[ActMon,2]-Width)-marg
	  If Over=0
	   {
	    y:= y-50
	   }
	  }
       }	  
               	
	If (NewPos=1 && Reflect=0)
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , y+yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	 }
	
	If (Reflect=0 and NewPos=0)
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , (y-Height)-yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	}
	If Reflect=1
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x , y , PreviewWindow.Width , PreviewWindow.Height , Alpha := 255 ) ;Alpha := Transp
	}
  }

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925 and https://www.autohotkey.com/boards/viewtopic.php?t=51788
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%

try if (WinClass = "TTOTAL_CMD" && CtrlClass = "LCLListBox1" or CtrlClass = "LCLListBox2" or CtrlClass = "TMyListBox1" or CtrlClass = "TMyListBox2")
{
SendMessage, 1074, 1000, , , ahk_class TTOTAL_CMD
SendMessage, 1074, 8 + ErrorLevel, , , ahk_class TTOTAL_CMD
ControlGetText, TargetPath, , ahk_id %ErrorLevel%
sPath := SubStr(TargetPath, 1, InStr(TargetPath, "\", , 0) - 1)

If (OnlyKey=0 and SuspendTCM=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif)", reg)
   
  FullPath:= sPath Reg
      
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := sPath "\" Reg
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

If (OnlyKey=1 and SuspendTCM=1)
 {
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif)", reg)
    
  FullPath:= sPath Reg
     
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := sPath "\" Reg
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}
;Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
  }
  ;else 
  if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
  }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

NotifyTrayClick(P*) {              ;  v0.41 by SKAN on D39E/D39N @ tiny.cc/notifytrayclick
Static Msg, Fun:="NotifyTrayClick", NM:=OnMessage(0x404,Func(Fun),-1),  Chk,T:=-250,Clk:=1
  If ( (NM := Format(Fun . "_{:03X}", Msg := P[2])) && P.Count()<4 )
     Return ( T := Max(-5000, 0-(P[1] ? Abs(P[1]) : 250)) )
  Critical
  If ( ( Msg<0x201 || Msg>0x209 ) || ( IsFunc(NM) || Islabel(NM) )=0 )
     Return
  Chk := (Fun . "_" . (Msg<=0x203 ? "203" : Msg<=0x206 ? "206" : Msg<=0x209 ? "209" : ""))
  SetTimer, %NM%,  %  (Msg==0x203        || Msg==0x206        || Msg==0x209)
    ? (-1, Clk:=2) : ( Clk=2 ? ("Off", Clk:=1) : ( IsFunc(Chk) || IsLabel(Chk) ? T : -1) )
Return True
}

; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
;	Color Dialog Example script.
;^!F8::
FrameColor:
stringRight, RSix, SetColor, 6
TColor:="0x" RSix
R:= (TColor&0xFF0000)>>16, G:= (TColor&0x00FF00)>>8, B:= TColor&0xFF

RGBval:=RGB(Rval:= R, Gval:= G, Bval:= B)
;Create Color Dialog GUI
Gui, Add, Text, x0 y10 w40 h20 +Right, Red
Gui, Add, Text, x0 y30 w40 h20 +Right, Green
Gui, Add, Text, x0 y50 w40 h20 +Right, Blue
Gui, Add, Slider, x40 y10 w190 h20 AltSubmit +NoTicks +Range0-255 vsR gSliderSub, %Rval%
Gui, Add, Slider, x40 y30 w190 h20 AltSubmit +NoTicks +Range0-255 vsG gSliderSub, %Gval%
Gui, Add, Slider, x40 y50 w190 h20 AltSubmit +NoTicks +Range0-255 vsB gSliderSub, %Bval%
Gui, Add, Edit, x230 y10 w45 h20 gEditSub veR +Limit3 +Number, %Rval%
Gui, Add, UpDown, Range0-255 vuR gUpDownSub, %Rval%
Gui, Add, Edit, x230 y30 w45 h20 gEditSub veG +Limit3 +Number, %Gval%
Gui, Add, UpDown, Range0-255 vuG gUpDownSub, %Gval%
Gui, Add, Edit, x230 y50 w45 h20 gEditSub veB +Limit3 +Number, %Bval%
Gui, Add, UpDown, Range0-255 vuB gUpDownSub, %Bval%
Gui, Add, Progress, x285 y10 w60 h60 +Border Background%RGBval% vpC
Gui, Add, Text, x285 y10 w60 h60 +Border vtP cWhite +BackgroundTrans, Preview
Gui, Add, Button, x120 y80 w110 h20 vbS gButtonSub, Select Color ;Copy to Clipboard
Gui, Show, w351 h105, Simple Color Dialog
return

EditSub:
	;Get Values
	GuiControlGet,Rval,,eR
	GuiControlGet,Gval,,eG
	GuiControlGet,Bval,,eB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

UpDownSub:
	;Get Values
	GuiControlGet,Rval,,uR
	GuiControlGet,Gval,,uG
	GuiControlGet,Bval,,uB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

SliderSub:
	;Get Values
	GuiControlGet,Rval,,sR
	GuiControlGet,Gval,,sG
	GuiControlGet,Bval,,sB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
return

set:
	;Convert values to Hex
	RGBval:=RGB(Rval,Gval,Bval)
	;Display Tooltip
	ToolTip Red: %Rval%`nGreen: %Gval%`nBlue: %Bval%`nHex: %RGBval%
	;Make tooltip disappear after 375 ms (3/8th of a second)
	SetTimer, RemoveToolTip, 375
	;Apply colour to preview
	GuiControl,+Background%RGBval%,pC
return

RemoveToolTip:
	SetTimer, RemoveToolTip, Off ;Turn timer off
	ToolTip ;Turn off tooltip
return

ButtonSub:
 ;Remove '0x' prefix to hex color code, saving it directly to the clipboard
 ;StringReplace,Clipboard,RGBval,0x99
 StringReplace,SetColor,RGBval,0x
 SetColor:="0x99" SetColor
 ;MsgBox, % SetColor . " " . RGBval
 ;Display Last selected values... (these values can later be used), and Notify the user
 ;MsgBox,64,Simple Color Dialog,RGB: (%Rval%, %Gval%, %Bval%)`nHex: %RGBval%`nCopied to Clipboard!
 ;Skip Directly GuiClose
 Gui, Destroy
Return

;^!s::
Config:
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: +HwndGuiID +AlwaysOnTop
Gui, Size: Add, Button, x300 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x300 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x5 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x95 y16 w60 h20 vFmaxW, %TempMaxW%
Gui, Size: Add, Text, x5 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x95 y46 w60 h20 vFmaxH, %TempMaxH%
Gui, Size: Add, Text, x170 y16 w70 h20, Transp.:
Gui, Size: Add, edit, x230 y16 w60 h20 vFtrans , %Transp%
Gui, Size: Add, Text, x170 y46 w70 h20, Margin :
Gui, Size: Add, edit, x230 y46 w60 h20 vFmarg , %margin%
Gui, Size: Show, x%xpos% y%ypos% h80 w370, Image Preview Configuration
Return

#If WinActive("ahk_id " GuiID)
Enter::
NumPadEnter::
NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxWidth:=500
 }
Else 
{
MaxWidth:=FmaxW
IniWrite, %MaxWidth%, NewConfig.ini, Preview_TCM, MaxWidth
}

If !FmaxH
 {
  MaxHeight:=500
 }
Else 
{
MaxHeight:=FmaxH
IniWrite, %MaxHeight%, NewConfig.ini, Preview_TCM, MaxHeight
}

If !Ftrans or Ftrans>256
 {
  Transp:=Transp
 }
Else 
{
Transp:=Ftrans
IniWrite, %Ftrans%, NewConfig.ini, Preview_TCM, Transp
}

If !Fmarg
 {
  Margin:=16
 }
Else 
{
Margin:=Fmarg
IniWrite, %Fmarg%, NewConfig.ini, Preview_TCM, Margin
}
Gui, Size: Destroy
Gosub, Init
Return

Cancel:
Gui, Size: Destroy
Return

~Esc:: ; *
Gosub, GdipExit
SetTimer, preview, off
Sleep, 1000
SetTimer, preview, On
Return

^Esc::
Exit:
ExitApp
Return

StanbyTCM:
Menu, Tray, ToggleCheck, Suspend Preview in TCM
If SuspendTCM=1 
 {
  SuspendTCM:=0
 ;TrayTip, TCM Image Preview, DISABLED,, 0x1, 0x10, 0x20
  SplashTextOn,200, 80, Notification, Preview in TCM Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendTCM
 }
Else
 {
  SuspendTCM:=1
  SplashTextOn,200, 80, Notification, Preview in TCM
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM  
 }
Return

StanbyDeskTop:
Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
Gosub, GdipExit
If SuspendDeskTop=1 
 {
  SuspendDeskTop:=0
  SplashTextOn,200, 80, Notification, Preview in DeskTop Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Else
 {
  SuspendDeskTop:=1
  SplashTextOn,200, 80, Notification, Preview in DeskTop
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Return

OnlyKeyPress:
Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
If OnlyKey=1 
 {
  OnlyKey:=0
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, OnlyKey
 }
Else
 {
  OnlyKey:=1
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 }
Return

ReflectTwo:
Menu, Tray, ToggleCheck, Mirror to Second Monitor
If Reflect=1 
 {
  SplashTextOn,200, 80, Notification, Mirror to Second Monitor Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  Reflect:=0
  MaxWidth:=""
  MaxHeight:=""
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
  MaxWidth:=""
  MaxHeight:=""  
  Gosub, ReadVar
 }
Else
 {
 Reflect:=1
 SplashTextOn,200, 80, Notification, Mirror to Second Monitor
 xSplash1 := A_ScreenWidth-206
 ySplash1 := A_ScreenHeight-180
 WinMove, Notification,, xSplash1, ySplash1
 SoundPlay, Resources\State_I.mp3
 Sleep, 1500
 SplashTextOff
 IniWrite, 1, NewConfig.ini, Preview_TCM, Reflect
 
 MaxWidth:=""
 MaxHeight:="" 
 Gosub, ReadVar 
 }
Return

^p::
NotifyTrayClick_201:
Gosub, Stanby
Return

;^F12::
Stanby:
Suspend:=!Suspend
IfEqual,Suspend,1, Menu,Tray,Icon, Resources\Group_4_Red.ico
IfEqual,Suspend,0, Menu,Tray,Icon, Resources\Group_4.ico
Menu,Tray,Icon,,,1
Suspend,Toggle

if A_IsSuspended=1
 {
  Menu, tray, Check, &Suspend Utility
  SoundPlay, Resources\State_U.mp3 
  SetTimer, preview, off
  SplashTextOn,200, 80, Notification, Application has Been Deactivated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff  
 }
  
if A_IsSuspended=0
 {
  Menu, tray, Uncheck, &Suspend Utility
  SoundPlay, Resources\State_I.mp3
  SetTimer, preview, On
  SplashTextOn,200, 80, Notification, Application has Been Activated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff
  Sleep, 500  
 }  
Return

Reloaded:
Reload
Return

Tray_Open:
ListLines
return

Nothing:
Return
 
;Function to convert Decimal RGB to Hexadecimal RBG, Note: '0' (zero) padding is unnecessary
RGB(r, g, b) {
	;Shift Numbers
	var:=(r << 16) + (g << 8) + b
	;Save current A_FormatInteger
	OldFormat := A_FormatInteger
	;Set Hex A_FormatInteger mode
	SetFormat, Integer, Hex
	;Force decimal number to Hex number
	var += 0
	;set original A_FormatInteger mode
	SetFormat, Integer, %OldFormat%
	return var
}

; Funtion By Maestr0 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=54557

MWAGetMonitor(Mx := "", My := "")
{
	if  (!Mx or !My) 
	{
		; if Mx or My is empty, revert to the mouse cursor placement
		Coordmode, Mouse, Screen	; use Screen, so we can compare the coords with the sysget information`
		MouseGetPos, Mx, My
	}

	SysGet, MonitorCount, 80	; monitorcount, so we know how many monitors there are, and the number of loops we need to do
	Loop, %MonitorCount%
	{
		SysGet, mon%A_Index%, Monitor, %A_Index%	; "Monitor" will get the total desktop space of the monitor, including taskbars

		if ( Mx >= mon%A_Index%left ) && ( Mx < mon%A_Index%right ) && ( My >= mon%A_Index%top ) && ( My < mon%A_Index%bottom )
		{
			ActiveMon := A_Index
			break
		}
	}
	return ActiveMon
}

#Include <NonNull>
#Include <Gdip_All>
Reissued on 06-21. Image size was not reset when switching from mirror to second monitor to normal state. Fixed.
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Hi.

The preview did not work if you did a file search in one of the panels and the "add to list" option was activated. Fixed.

The download above is still valid. Replace the script with the current one.

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif format.
; You must enable "show file ext name" in explorer.
; You must activate the current screen (click), or when you switch between Explorer, desktop or TCM
; In Total Commander you have to activate (Click) when you change panel.
; You need to check "Show command line" in "configuration", "Layout", in Total Commander
; https://www.autohotkey.com/boards/viewtopic.php?t=90001
;================================================================
; Modified code to add a border to the image, created by Hellbent
; Total Commander support added by WetWare05
; https://www.autohotkey.com/boards/viewtopic.php?p=523384
;================================================================
#Requires AutoHotkey v1.1.33

SetBatchLines, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
Thread, Interrupt, 0

CoordMode, Mouse, Screen

maxStr:=200
Global NoW, SetColor, MaxWidth, MaxHeight, Margin, Transp, SuspendTCM, SuspendDeskTop, OnlyKey, Reflect
NoW:=""

;=========================================================
 Menu, Tray, Icon, Resources\Group_4.ico
 ;Menu, Tray, Icon, shell32.dll, 132 ;Example of icon the DLL Library
 Menu, Tray, NoStandard
 Menu, tray, Add, TCM Image Preview, Nothing
 Menu, tray, Icon, TCM Image Preview, Resources\Group_4.ico
 Menu, Tray, Add
 Menu Tray, Add, Open Info, Tray_Open
 Menu Tray, Icon, Open Info, Resources\Info.ico
 Menu, tray, Add, &Reload this Script, Reloaded
 Menu, tray, Icon,&Reload this Script, Resources\2488.ico
 Menu, tray, Add, &Suspend Utility, Stanby
 Menu, tray, Icon,&Suspend Utility, Resources\Group_4_Red.ico
 Menu, Tray, Add
 Menu, tray, Add, Suspend Preview in TCM, StanbyTCM
 Menu, tray, Icon, Suspend Preview in TCM, Resources\TCommander.ico
 Menu, tray, Add, Suspend Preview in DeskTop, StanbyDeskTop
 Menu, tray, Icon, Suspend Preview in DeskTop, Resources\Explorer.ico
 Menu, tray, Add, Only Preview with RCtrl Key, OnlyKeyPress
 Menu, tray, Icon, Only Preview with RCtrl Key, Resources\Key.ico
 Menu, tray, Add, Mirror to Second Monitor, ReflectTwo
 Menu, tray, Icon, Mirror to Second Monitor, Resources\2220.ico
 Menu, Tray, Add
 Menu, tray, Add, Preview Setting, Config
 Menu, tray, Icon, Preview Setting, Resources\130.ico
 Menu, tray, Add, Frame Color, FrameColor
 Menu, tray, Icon, Frame Color, Resources\ColorEdit.ico
 Menu, Tray, Add
 Menu, tray, Add, Exit, Exit
 Menu, tray, Icon, Exit, shell32.dll, 132
 
if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 8, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  IniWrite, 230, NewConfig.ini, Preview_TCM, Transp
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
 }

ReadVar:
If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
If !Transp
 {
  IniRead, Transp, NewConfig.ini, Preview_TCM, Transp
 }
If !SuspendDeskTop
 {
  IniRead, SuspendDeskTop, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
If !SuspendTCM
 {
  IniRead, SuspendTCM, NewConfig.ini, Preview_TCM, SuspendTCM
 }
 If !OnlyKey
 {
  IniRead, OnlyKey, NewConfig.ini, Preview_TCM, OnlyKey
 }
 If !Reflect
 {
  IniRead, Reflect, NewConfig.ini, Preview_TCM, Reflect
 }
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth
   
 If SuspendTCM=0
  {
   Menu, Tray, Check, Suspend Preview in TCM
  }
  
  If SuspendDeskTop=0
  {
   Menu, Tray, Check, Suspend Preview in DeskTop
  }
  
  If OnlyKey=0
  {
   Menu, Tray, Check, Only Preview with RCtrl Key
  }
  
  If Reflect=1
  {
   Menu, Tray, Check, Mirror to Second Monitor
  }

 ;==========================================================

SetTimer, preview, 50

init:
SizeMon := []
SysGet, numDisplays, 80
Loop % numDisplays {
  SysGet, Mon, Monitor, %A_Index%
  SizeMon.Push([Monleft, MonRight, MonTop, MonBottom])
 }
  
 If Reflect=1
 {
 ActMon:= MWAGetMonitor()
  
  If ActMon=1
   {
    MaxWidth:= SizeMon[2,2]-SizeMon[1,2]
    MaxHeight:= SizeMon[2,4]
   }
   
  If ActMon=2
   {
    MaxWidth:= SizeMon[1,2]
    MaxHeight:= SizeMon[1,4]
   } 
 }
 
; close system file info tip.
RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
pToken := Gdip_Startup()
OnExit, GdipExit
PreviewWindow := CreatePreviewWindow( MaxWidth , MaxHeight )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Critical
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	try Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

preview:
if A_IsSuspended=0
{
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt()
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
    }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
    }
  }
 }
return

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin
	
	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
			
      If Reflect=0
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin )
	Gdip_DeleteBrush( Brush )
	
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height )
	MouseGetPos, x, y	
       }
     
     If Reflect=1
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )	
      }	
	
     	SizeMon := []
	SysGet, numDisplays, 80

	Loop % numDisplays {
	 SysGet, Mon, Monitor, %A_Index%
	 SizeMon.Push( [Monleft, MonRight, MonTop, MonBottom] )
	StateMon:=1
	}
	
      If Reflect=1
       {
	ActMon:= MWAGetMonitor()
  
        If ActMon=1
         {
	  x:= (SizeMon[1,2]+1)
	  y:= SizeMon[2,3]
	 }
        If ActMon=2
         {
	  x:= SizeMon[1,1]
	  y:= SizeMon[1,3]
	 }      
       }
            
      If Reflect=0
	{
	ActMon:= MWAGetMonitor()
	Over=0
	NewPos=0
	xOffSet:=16
	yOffSet:=16
	
       If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
	
	TempTop:= SizeMon[ActMon,3]
	TempY:= y-Height
	If (TempY<0 or TempY<TempTop)
	{
	 Over:=1
	 NewPos:=1
	}
	
       Marg:=margin*4 ;5
       xt:= x+Width
       
       if (xt>SizeMon[ActMon,2])
	 {
	  x:= (SizeMon[ActMon,2]-Width)-marg
	  If Over=0
	   {
	    y:= y-50
	   }
	  }
       }	  
               	
	If (NewPos=1 && Reflect=0)
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , y+yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	 }
	
	If (Reflect=0 and NewPos=0)
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , (y-Height)-yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	}
	If Reflect=1
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x , y , PreviewWindow.Width , PreviewWindow.Height , Alpha := 255 ) ;Alpha := Transp
	}
  }

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925 and https://www.autohotkey.com/boards/viewtopic.php?t=51788
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%

try if (WinClass = "TTOTAL_CMD" && CtrlClass = "LCLListBox1" or CtrlClass = "LCLListBox2" or CtrlClass = "TMyListBox1" or CtrlClass = "TMyListBox2")
 {
  SendMessage, 1074, 1000, , , ahk_class TTOTAL_CMD
  SendMessage, 1074, 8 + ErrorLevel, , , ahk_class TTOTAL_CMD
  ControlGetText, TargetPath, , ahk_id %ErrorLevel%
  sPath := SubStr(TargetPath, 1, InStr(TargetPath, "\", , 0) - 1)

If (OnlyKey=0 and SuspendTCM=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif)", reg)

   Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

If (OnlyKey=1 and SuspendTCM=1)
 {
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif)", reg)
    
  Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}
;Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
  }
  ;else 
  if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
  }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

NotifyTrayClick(P*) {              ;  v0.41 by SKAN on D39E/D39N @ tiny.cc/notifytrayclick
Static Msg, Fun:="NotifyTrayClick", NM:=OnMessage(0x404,Func(Fun),-1),  Chk,T:=-250,Clk:=1
  If ( (NM := Format(Fun . "_{:03X}", Msg := P[2])) && P.Count()<4 )
     Return ( T := Max(-5000, 0-(P[1] ? Abs(P[1]) : 250)) )
  Critical
  If ( ( Msg<0x201 || Msg>0x209 ) || ( IsFunc(NM) || Islabel(NM) )=0 )
     Return
  Chk := (Fun . "_" . (Msg<=0x203 ? "203" : Msg<=0x206 ? "206" : Msg<=0x209 ? "209" : ""))
  SetTimer, %NM%,  %  (Msg==0x203        || Msg==0x206        || Msg==0x209)
    ? (-1, Clk:=2) : ( Clk=2 ? ("Off", Clk:=1) : ( IsFunc(Chk) || IsLabel(Chk) ? T : -1) )
Return True
}

; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
;	Color Dialog Example script.
;^!F8::
FrameColor:
stringRight, RSix, SetColor, 6
TColor:="0x" RSix
R:= (TColor&0xFF0000)>>16, G:= (TColor&0x00FF00)>>8, B:= TColor&0xFF

RGBval:=RGB(Rval:= R, Gval:= G, Bval:= B)
;Create Color Dialog GUI
Gui, Add, Text, x0 y10 w40 h20 +Right, Red
Gui, Add, Text, x0 y30 w40 h20 +Right, Green
Gui, Add, Text, x0 y50 w40 h20 +Right, Blue
Gui, Add, Slider, x40 y10 w190 h20 AltSubmit +NoTicks +Range0-255 vsR gSliderSub, %Rval%
Gui, Add, Slider, x40 y30 w190 h20 AltSubmit +NoTicks +Range0-255 vsG gSliderSub, %Gval%
Gui, Add, Slider, x40 y50 w190 h20 AltSubmit +NoTicks +Range0-255 vsB gSliderSub, %Bval%
Gui, Add, Edit, x230 y10 w45 h20 gEditSub veR +Limit3 +Number, %Rval%
Gui, Add, UpDown, Range0-255 vuR gUpDownSub, %Rval%
Gui, Add, Edit, x230 y30 w45 h20 gEditSub veG +Limit3 +Number, %Gval%
Gui, Add, UpDown, Range0-255 vuG gUpDownSub, %Gval%
Gui, Add, Edit, x230 y50 w45 h20 gEditSub veB +Limit3 +Number, %Bval%
Gui, Add, UpDown, Range0-255 vuB gUpDownSub, %Bval%
Gui, Add, Progress, x285 y10 w60 h60 +Border Background%RGBval% vpC
Gui, Add, Text, x285 y10 w60 h60 +Border vtP cWhite +BackgroundTrans, Preview
Gui, Add, Button, x120 y80 w110 h20 vbS gButtonSub, Select Color ;Copy to Clipboard
Gui, Show, w351 h105, Simple Color Dialog
return

EditSub:
	;Get Values
	GuiControlGet,Rval,,eR
	GuiControlGet,Gval,,eG
	GuiControlGet,Bval,,eB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

UpDownSub:
	;Get Values
	GuiControlGet,Rval,,uR
	GuiControlGet,Gval,,uG
	GuiControlGet,Bval,,uB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

SliderSub:
	;Get Values
	GuiControlGet,Rval,,sR
	GuiControlGet,Gval,,sG
	GuiControlGet,Bval,,sB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
return

set:
	;Convert values to Hex
	RGBval:=RGB(Rval,Gval,Bval)
	;Display Tooltip
	ToolTip Red: %Rval%`nGreen: %Gval%`nBlue: %Bval%`nHex: %RGBval%
	;Make tooltip disappear after 375 ms (3/8th of a second)
	SetTimer, RemoveToolTip, 375
	;Apply colour to preview
	GuiControl,+Background%RGBval%,pC
return

RemoveToolTip:
	SetTimer, RemoveToolTip, Off ;Turn timer off
	ToolTip ;Turn off tooltip
return

ButtonSub:
 ;Remove '0x' prefix to hex color code, saving it directly to the clipboard
 ;StringReplace,Clipboard,RGBval,0x99
 StringReplace,SetColor,RGBval,0x
 SetColor:="0x99" SetColor
 ;MsgBox, % SetColor . " " . RGBval
 ;Display Last selected values... (these values can later be used), and Notify the user
 ;MsgBox,64,Simple Color Dialog,RGB: (%Rval%, %Gval%, %Bval%)`nHex: %RGBval%`nCopied to Clipboard!
 ;Skip Directly GuiClose
 Gui, Destroy
Return

;^!s::
Config:
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: +HwndGuiID +AlwaysOnTop
Gui, Size: Add, Button, x300 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x300 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x5 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x95 y16 w60 h20 vFmaxW, %TempMaxW%
Gui, Size: Add, Text, x5 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x95 y46 w60 h20 vFmaxH, %TempMaxH%
Gui, Size: Add, Text, x170 y16 w70 h20, Transp.:
Gui, Size: Add, edit, x230 y16 w60 h20 vFtrans , %Transp%
Gui, Size: Add, Text, x170 y46 w70 h20, Margin :
Gui, Size: Add, edit, x230 y46 w60 h20 vFmarg , %margin%
Gui, Size: Show, x%xpos% y%ypos% h80 w370, Image Preview Configuration
Return

#If WinActive("ahk_id " GuiID)
Enter::
NumPadEnter::
NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxWidth:=500
 }
Else 
{
MaxWidth:=FmaxW
IniWrite, %MaxWidth%, NewConfig.ini, Preview_TCM, MaxWidth
}

If !FmaxH
 {
  MaxHeight:=500
 }
Else 
{
MaxHeight:=FmaxH
IniWrite, %MaxHeight%, NewConfig.ini, Preview_TCM, MaxHeight
}

If !Ftrans or Ftrans>256
 {
  Transp:=Transp
 }
Else 
{
Transp:=Ftrans
IniWrite, %Ftrans%, NewConfig.ini, Preview_TCM, Transp
}

If !Fmarg
 {
  Margin:=16
 }
Else 
{
Margin:=Fmarg
IniWrite, %Fmarg%, NewConfig.ini, Preview_TCM, Margin
}
Gui, Size: Destroy
Gosub, Init
Return

Cancel:
Gui, Size: Destroy
Return

~Esc:: ; *
Gosub, GdipExit
SetTimer, preview, off
Sleep, 1000
SetTimer, preview, On
Return

^Esc::
Exit:
ExitApp
Return

StanbyTCM:
Menu, Tray, ToggleCheck, Suspend Preview in TCM
If SuspendTCM=1 
 {
  SuspendTCM:=0
 ;TrayTip, TCM Image Preview, DISABLED,, 0x1, 0x10, 0x20
  SplashTextOn,200, 80, Notification, Preview in TCM Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendTCM
 }
Else
 {
  SuspendTCM:=1
  SplashTextOn,200, 80, Notification, Preview in TCM
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM  
 }
Return

StanbyDeskTop:
Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
Gosub, GdipExit
If SuspendDeskTop=1 
 {
  SuspendDeskTop:=0
  SplashTextOn,200, 80, Notification, Preview in DeskTop Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Else
 {
  SuspendDeskTop:=1
  SplashTextOn,200, 80, Notification, Preview in DeskTop
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Return

OnlyKeyPress:
Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
If OnlyKey=1 
 {
  OnlyKey:=0
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, OnlyKey
 }
Else
 {
  OnlyKey:=1
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 }
Return

ReflectTwo:
Menu, Tray, ToggleCheck, Mirror to Second Monitor
If Reflect=1 
 {
  SplashTextOn,200, 80, Notification, Mirror to Second Monitor Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  Reflect:=0
  MaxWidth:=""
  MaxHeight:=""
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
  MaxWidth:=""
  MaxHeight:=""  
  Gosub, ReadVar
 }
Else
 {
 Reflect:=1
 SplashTextOn,200, 80, Notification, Mirror to Second Monitor
 xSplash1 := A_ScreenWidth-206
 ySplash1 := A_ScreenHeight-180
 WinMove, Notification,, xSplash1, ySplash1
 SoundPlay, Resources\State_I.mp3
 Sleep, 1500
 SplashTextOff
 IniWrite, 1, NewConfig.ini, Preview_TCM, Reflect
 
 MaxWidth:=""
 MaxHeight:="" 
 Gosub, ReadVar 
 }
Return

^p::
NotifyTrayClick_201:
Gosub, Stanby
Return

;^F12::
Stanby:
Suspend:=!Suspend
IfEqual,Suspend,1, Menu,Tray,Icon, Resources\Group_4_Red.ico
IfEqual,Suspend,0, Menu,Tray,Icon, Resources\Group_4.ico
Menu,Tray,Icon,,,1
Suspend,Toggle

if A_IsSuspended=1
 {
  Menu, tray, Check, &Suspend Utility
  SoundPlay, Resources\State_U.mp3 
  SetTimer, preview, off
  SplashTextOn,200, 80, Notification, Application has Been Deactivated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff  
 }
  
if A_IsSuspended=0
 {
  Menu, tray, Uncheck, &Suspend Utility
  SoundPlay, Resources\State_I.mp3
  SetTimer, preview, On
  SplashTextOn,200, 80, Notification, Application has Been Activated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff
  Sleep, 500  
 }  
Return

Reloaded:
Reload
Return

Tray_Open:
ListLines
return

Nothing:
Return
 
;Function to convert Decimal RGB to Hexadecimal RBG, Note: '0' (zero) padding is unnecessary
RGB(r, g, b) {
	;Shift Numbers
	var:=(r << 16) + (g << 8) + b
	;Save current A_FormatInteger
	OldFormat := A_FormatInteger
	;Set Hex A_FormatInteger mode
	SetFormat, Integer, Hex
	;Force decimal number to Hex number
	var += 0
	;set original A_FormatInteger mode
	SetFormat, Integer, %OldFormat%
	return var
}

; Funtion By Maestr0 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=54557

MWAGetMonitor(Mx := "", My := "")
{
	if  (!Mx or !My) 
	{
		; if Mx or My is empty, revert to the mouse cursor placement
		Coordmode, Mouse, Screen	; use Screen, so we can compare the coords with the sysget information`
		MouseGetPos, Mx, My
	}

	SysGet, MonitorCount, 80	; monitorcount, so we know how many monitors there are, and the number of loops we need to do
	Loop, %MonitorCount%
	{
		SysGet, mon%A_Index%, Monitor, %A_Index%	; "Monitor" will get the total desktop space of the monitor, including taskbars

		if ( Mx >= mon%A_Index%left ) && ( Mx < mon%A_Index%right ) && ( My >= mon%A_Index%top ) && ( My < mon%A_Index%bottom )
		{
			ActiveMon := A_Index
			break
		}
	}
	return ActiveMon
}

#Include <NonNull>
#Include <Gdip_All>
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Hi. :wink:

I'm trying to include the ability to see a preview of the videos. The shared script is a development version. Use the program mpv.exe https://mpv.io, change the location of the player to the script on line 214. As I'm testing, it only shows .mp4, to see more extensions, add them on lines 205, 386 and 420.

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif,mp4 format.
; You must enable "show file ext name" in explorer.
; You must activate the current screen (click), or when you switch between Explorer, desktop or TCM
; In Total Commander you have to activate (Click) when you change panel.
; You need to check "Show command line" in "configuration", "Layout", in Total Commander
; https://www.autohotkey.com/boards/viewtopic.php?t=90001
;================================================================
; Modified code to add a border to the image, created by Hellbent
; Total Commander support added by WetWare05
; https://www.autohotkey.com/boards/viewtopic.php?p=523384
;================================================================
#Requires AutoHotkey v1.1.33

SetBatchLines, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
Thread, Interrupt, 0

CoordMode, Mouse, Screen

maxStr:=200
Global NoW, SetColor, MaxWidth, MaxHeight, Margin, Transp, SuspendTCM, SuspendDeskTop, OnlyKey, Reflect
NoW:=""

;=========================================================
 Menu, Tray, Icon, Resources\Group_4.ico
 ;Menu, Tray, Icon, shell32.dll, 132 ;Example of icon the DLL Library
 Menu, Tray, NoStandard
 Menu, tray, Add, TCM Image Preview, Nothing
 Menu, tray, Icon, TCM Image Preview, Resources\Group_4.ico
 Menu, Tray, Add
 Menu Tray, Add, Open Info, Tray_Open
 Menu Tray, Icon, Open Info, Resources\Info.ico
 Menu, tray, Add, &Reload this Script, Reloaded
 Menu, tray, Icon,&Reload this Script, Resources\2488.ico
 Menu, tray, Add, &Suspend Utility, Stanby
 Menu, tray, Icon,&Suspend Utility, Resources\Group_4_Red.ico
 Menu, Tray, Add
 Menu, tray, Add, Suspend Preview in TCM, StanbyTCM
 Menu, tray, Icon, Suspend Preview in TCM, Resources\TCommander.ico
 Menu, tray, Add, Suspend Preview in DeskTop, StanbyDeskTop
 Menu, tray, Icon, Suspend Preview in DeskTop, Resources\Explorer.ico
 Menu, tray, Add, Only Preview with RCtrl Key, OnlyKeyPress
 Menu, tray, Icon, Only Preview with RCtrl Key, Resources\Key.ico
 Menu, tray, Add, Mirror to Second Monitor, ReflectTwo
 Menu, tray, Icon, Mirror to Second Monitor, Resources\2220.ico
 Menu, Tray, Add
 Menu, tray, Add, Preview Setting, Config
 Menu, tray, Icon, Preview Setting, Resources\130.ico
 Menu, tray, Add, Frame Color, FrameColor
 Menu, tray, Icon, Frame Color, Resources\ColorEdit.ico
 Menu, Tray, Add
 Menu, tray, Add, Exit, Exit
 Menu, tray, Icon, Exit, shell32.dll, 132
 
if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 8, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  IniWrite, 230, NewConfig.ini, Preview_TCM, Transp
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
 }

ReadVar:
If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
If !Transp
 {
  IniRead, Transp, NewConfig.ini, Preview_TCM, Transp
 }
If !SuspendDeskTop
 {
  IniRead, SuspendDeskTop, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
If !SuspendTCM
 {
  IniRead, SuspendTCM, NewConfig.ini, Preview_TCM, SuspendTCM
 }
 If !OnlyKey
 {
  IniRead, OnlyKey, NewConfig.ini, Preview_TCM, OnlyKey
 }
 If !Reflect
 {
  IniRead, Reflect, NewConfig.ini, Preview_TCM, Reflect
 }
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth
   
 If SuspendTCM=0
  {
   Menu, Tray, Check, Suspend Preview in TCM
  }
  
  If SuspendDeskTop=0
  {
   Menu, Tray, Check, Suspend Preview in DeskTop
  }
  
  If OnlyKey=0
  {
   Menu, Tray, Check, Only Preview with RCtrl Key
  }
  
  If Reflect=1
  {
   Menu, Tray, Check, Mirror to Second Monitor
  }

 ;==========================================================

SetTimer, preview, 50

init:
SizeMon := []
SysGet, numDisplays, 80
Loop % numDisplays {
  SysGet, Mon, Monitor, %A_Index%
  SizeMon.Push([Monleft, MonRight, MonTop, MonBottom])
 }
  
 If Reflect=1
 {
 ActMon:= MWAGetMonitor()
  
  If ActMon=1
   {
    MaxWidth:= SizeMon[2,2]-SizeMon[1,2]
    MaxHeight:= SizeMon[2,4]
   }
   
  If ActMon=2
   {
    MaxWidth:= SizeMon[1,2]
    MaxHeight:= SizeMon[1,4]
   } 
 }
 
; close system file info tip.
RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
pToken := Gdip_Startup()
OnExit, GdipExit
PreviewWindow := CreatePreviewWindow( MaxWidth , MaxHeight )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Critical
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	try Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

preview:
if A_IsSuspended=0
{
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
     {
      btt()
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
     }
    Else if Ext=mp4
     {
      Path:= % Current.Path
      MouseGetPos, xMov, yMov
      xMov:= xMov+10
      yMov:= yMov-285
     ;yMov:= yMov+50
      Process, Close, mpv.exe
      ;Run, mpv.exe --loop --ontop --geometry="%xMov%":"%yMov%" --window-scale=0.5 "%Path%"
      Run, d:\Utilidades\MPV Player\mpv.exe --loop --ontop --window-scale=1.5 --geometry="%xMov%":"%yMov%" "%Path%" ; Change Scale example-> --window-scale=0.5 or delete option 
      Path:=""      
     }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
    }
  }
 }
return

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin
	
	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
			
      If Reflect=0
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin )
	Gdip_DeleteBrush( Brush )
	
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height )
	MouseGetPos, x, y	
       }
     
     If Reflect=1
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )	
      }	
	
     	SizeMon := []
	SysGet, numDisplays, 80

	Loop % numDisplays {
	 SysGet, Mon, Monitor, %A_Index%
	 SizeMon.Push( [Monleft, MonRight, MonTop, MonBottom] )
	StateMon:=1
	}
	
      If Reflect=1
       {
	ActMon:= MWAGetMonitor()
  
        If ActMon=1
         {
	  x:= (SizeMon[1,2]+1)
	  y:= SizeMon[2,3]
	 }
        If ActMon=2
         {
	  x:= SizeMon[1,1]
	  y:= SizeMon[1,3]
	 }      
       }
            
      If Reflect=0
	{
	ActMon:= MWAGetMonitor()
	Over=0
	NewPos=0
	xOffSet:=16
	yOffSet:=16
	
       If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
	
	TempTop:= SizeMon[ActMon,3]
	TempY:= y-Height
	If (TempY<0 or TempY<TempTop)
	{
	 Over:=1
	 NewPos:=1
	}
	
       Marg:=margin*4 ;5
       xt:= x+Width
       
       if (xt>SizeMon[ActMon,2])
	 {
	  x:= (SizeMon[ActMon,2]-Width)-marg
	  If Over=0
	   {
	    y:= y-50
	   }
	  }
       }	  
               	
	If (NewPos=1 && Reflect=0)
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , y+yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	 }
	
	If (Reflect=0 and NewPos=0)
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , (y-Height)-yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	}
	If Reflect=1
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x , y , PreviewWindow.Width , PreviewWindow.Height , Alpha := 255 ) ;Alpha := Transp
	}
  }

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925 and https://www.autohotkey.com/boards/viewtopic.php?t=51788
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%

try if (WinClass = "TTOTAL_CMD" && CtrlClass = "LCLListBox1" or CtrlClass = "LCLListBox2" or CtrlClass = "TMyListBox1" or CtrlClass = "TMyListBox2")
 {
  SendMessage, 1074, 1000, , , ahk_class TTOTAL_CMD
  SendMessage, 1074, 8 + ErrorLevel, , , ahk_class TTOTAL_CMD
  ControlGetText, TargetPath, , ahk_id %ErrorLevel%
  sPath := SubStr(TargetPath, 1, InStr(TargetPath, "\", , 0) - 1)

If (OnlyKey=0 and SuspendTCM=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4)", reg)

   Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

If (OnlyKey=1 and SuspendTCM=1)
 {
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4)", reg)
    
  Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}
;Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
  }
  ;else 
  if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
  }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

NotifyTrayClick(P*) {              ;  v0.41 by SKAN on D39E/D39N @ tiny.cc/notifytrayclick
Static Msg, Fun:="NotifyTrayClick", NM:=OnMessage(0x404,Func(Fun),-1),  Chk,T:=-250,Clk:=1
  If ( (NM := Format(Fun . "_{:03X}", Msg := P[2])) && P.Count()<4 )
     Return ( T := Max(-5000, 0-(P[1] ? Abs(P[1]) : 250)) )
  Critical
  If ( ( Msg<0x201 || Msg>0x209 ) || ( IsFunc(NM) || Islabel(NM) )=0 )
     Return
  Chk := (Fun . "_" . (Msg<=0x203 ? "203" : Msg<=0x206 ? "206" : Msg<=0x209 ? "209" : ""))
  SetTimer, %NM%,  %  (Msg==0x203        || Msg==0x206        || Msg==0x209)
    ? (-1, Clk:=2) : ( Clk=2 ? ("Off", Clk:=1) : ( IsFunc(Chk) || IsLabel(Chk) ? T : -1) )
Return True
}

; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
;	Color Dialog Example script.
;^!F8::
FrameColor:
stringRight, RSix, SetColor, 6
TColor:="0x" RSix
R:= (TColor&0xFF0000)>>16, G:= (TColor&0x00FF00)>>8, B:= TColor&0xFF

RGBval:=RGB(Rval:= R, Gval:= G, Bval:= B)
;Create Color Dialog GUI
Gui, Add, Text, x0 y10 w40 h20 +Right, Red
Gui, Add, Text, x0 y30 w40 h20 +Right, Green
Gui, Add, Text, x0 y50 w40 h20 +Right, Blue
Gui, Add, Slider, x40 y10 w190 h20 AltSubmit +NoTicks +Range0-255 vsR gSliderSub, %Rval%
Gui, Add, Slider, x40 y30 w190 h20 AltSubmit +NoTicks +Range0-255 vsG gSliderSub, %Gval%
Gui, Add, Slider, x40 y50 w190 h20 AltSubmit +NoTicks +Range0-255 vsB gSliderSub, %Bval%
Gui, Add, Edit, x230 y10 w45 h20 gEditSub veR +Limit3 +Number, %Rval%
Gui, Add, UpDown, Range0-255 vuR gUpDownSub, %Rval%
Gui, Add, Edit, x230 y30 w45 h20 gEditSub veG +Limit3 +Number, %Gval%
Gui, Add, UpDown, Range0-255 vuG gUpDownSub, %Gval%
Gui, Add, Edit, x230 y50 w45 h20 gEditSub veB +Limit3 +Number, %Bval%
Gui, Add, UpDown, Range0-255 vuB gUpDownSub, %Bval%
Gui, Add, Progress, x285 y10 w60 h60 +Border Background%RGBval% vpC
Gui, Add, Text, x285 y10 w60 h60 +Border vtP cWhite +BackgroundTrans, Preview
Gui, Add, Button, x120 y80 w110 h20 vbS gButtonSub, Select Color ;Copy to Clipboard
Gui, Show, w351 h105, Simple Color Dialog
return

EditSub:
	;Get Values
	GuiControlGet,Rval,,eR
	GuiControlGet,Gval,,eG
	GuiControlGet,Bval,,eB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

UpDownSub:
	;Get Values
	GuiControlGet,Rval,,uR
	GuiControlGet,Gval,,uG
	GuiControlGet,Bval,,uB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

SliderSub:
	;Get Values
	GuiControlGet,Rval,,sR
	GuiControlGet,Gval,,sG
	GuiControlGet,Bval,,sB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
return

set:
	;Convert values to Hex
	RGBval:=RGB(Rval,Gval,Bval)
	;Display Tooltip
	ToolTip Red: %Rval%`nGreen: %Gval%`nBlue: %Bval%`nHex: %RGBval%
	;Make tooltip disappear after 375 ms (3/8th of a second)
	SetTimer, RemoveToolTip, 375
	;Apply colour to preview
	GuiControl,+Background%RGBval%,pC
return

RemoveToolTip:
	SetTimer, RemoveToolTip, Off ;Turn timer off
	ToolTip ;Turn off tooltip
return

ButtonSub:
 ;Remove '0x' prefix to hex color code, saving it directly to the clipboard
 ;StringReplace,Clipboard,RGBval,0x99
 StringReplace,SetColor,RGBval,0x
 SetColor:="0x99" SetColor
 ;MsgBox, % SetColor . " " . RGBval
 ;Display Last selected values... (these values can later be used), and Notify the user
 ;MsgBox,64,Simple Color Dialog,RGB: (%Rval%, %Gval%, %Bval%)`nHex: %RGBval%`nCopied to Clipboard!
 ;Skip Directly GuiClose
 Gui, Destroy
Return

;^!s::
Config:
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: +HwndGuiID +AlwaysOnTop
Gui, Size: Add, Button, x300 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x300 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x5 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x95 y16 w60 h20 vFmaxW, %TempMaxW%
Gui, Size: Add, Text, x5 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x95 y46 w60 h20 vFmaxH, %TempMaxH%
Gui, Size: Add, Text, x170 y16 w70 h20, Transp.:
Gui, Size: Add, edit, x230 y16 w60 h20 vFtrans , %Transp%
Gui, Size: Add, Text, x170 y46 w70 h20, Margin :
Gui, Size: Add, edit, x230 y46 w60 h20 vFmarg , %margin%
Gui, Size: Show, x%xpos% y%ypos% h80 w370, Image Preview Configuration
Return

#If WinActive("ahk_id " GuiID)
Enter::
NumPadEnter::
NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxWidth:=500
 }
Else 
{
MaxWidth:=FmaxW
IniWrite, %MaxWidth%, NewConfig.ini, Preview_TCM, MaxWidth
}

If !FmaxH
 {
  MaxHeight:=500
 }
Else 
{
MaxHeight:=FmaxH
IniWrite, %MaxHeight%, NewConfig.ini, Preview_TCM, MaxHeight
}

If !Ftrans or Ftrans>256
 {
  Transp:=Transp
 }
Else 
{
Transp:=Ftrans
IniWrite, %Ftrans%, NewConfig.ini, Preview_TCM, Transp
}

If !Fmarg
 {
  Margin:=16
 }
Else 
{
Margin:=Fmarg
IniWrite, %Fmarg%, NewConfig.ini, Preview_TCM, Margin
}
Gui, Size: Destroy
Gosub, Init
Return

Cancel:
Gui, Size: Destroy
Return

~Esc:: ; *
Gosub, GdipExit
SetTimer, preview, off
Sleep, 1000
SetTimer, preview, On
Return

^Esc::
Exit:
ExitApp
Return

StanbyTCM:
Menu, Tray, ToggleCheck, Suspend Preview in TCM
If SuspendTCM=1 
 {
  SuspendTCM:=0
 ;TrayTip, TCM Image Preview, DISABLED,, 0x1, 0x10, 0x20
  SplashTextOn,200, 80, Notification, Preview in TCM Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendTCM
 }
Else
 {
  SuspendTCM:=1
  SplashTextOn,200, 80, Notification, Preview in TCM
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM  
 }
Return

StanbyDeskTop:
Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
Gosub, GdipExit
If SuspendDeskTop=1 
 {
  SuspendDeskTop:=0
  SplashTextOn,200, 80, Notification, Preview in DeskTop Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Else
 {
  SuspendDeskTop:=1
  SplashTextOn,200, 80, Notification, Preview in DeskTop
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Return

OnlyKeyPress:
Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
If OnlyKey=1 
 {
  OnlyKey:=0
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, OnlyKey
 }
Else
 {
  OnlyKey:=1
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 }
Return

ReflectTwo:
Menu, Tray, ToggleCheck, Mirror to Second Monitor
If Reflect=1 
 {
  SplashTextOn,200, 80, Notification, Mirror to Second Monitor Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  Reflect:=0
  MaxWidth:=""
  MaxHeight:=""
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
  MaxWidth:=""
  MaxHeight:=""  
  Gosub, ReadVar
 }
Else
 {
 Reflect:=1
 SplashTextOn,200, 80, Notification, Mirror to Second Monitor
 xSplash1 := A_ScreenWidth-206
 ySplash1 := A_ScreenHeight-180
 WinMove, Notification,, xSplash1, ySplash1
 SoundPlay, Resources\State_I.mp3
 Sleep, 1500
 SplashTextOff
 IniWrite, 1, NewConfig.ini, Preview_TCM, Reflect
 
 MaxWidth:=""
 MaxHeight:="" 
 Gosub, ReadVar 
 }
Return

^p::
NotifyTrayClick_201:
Gosub, Stanby
Return

;^F12::
Stanby:
Suspend:=!Suspend
IfEqual,Suspend,1, Menu,Tray,Icon, Resources\Group_4_Red.ico
IfEqual,Suspend,0, Menu,Tray,Icon, Resources\Group_4.ico
Menu,Tray,Icon,,,1
Suspend,Toggle

if A_IsSuspended=1
 {
  Menu, tray, Check, &Suspend Utility
  SoundPlay, Resources\State_U.mp3 
  SetTimer, preview, off
  SplashTextOn,200, 80, Notification, Application has Been Deactivated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff  
 }
  
if A_IsSuspended=0
 {
  Menu, tray, Uncheck, &Suspend Utility
  SoundPlay, Resources\State_I.mp3
  SetTimer, preview, On
  SplashTextOn,200, 80, Notification, Application has Been Activated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff
  Sleep, 500  
 }  
Return

Reloaded:
Reload
Return

Tray_Open:
ListLines
return

Nothing:
Return
 
;Function to convert Decimal RGB to Hexadecimal RBG, Note: '0' (zero) padding is unnecessary
RGB(r, g, b) {
	;Shift Numbers
	var:=(r << 16) + (g << 8) + b
	;Save current A_FormatInteger
	OldFormat := A_FormatInteger
	;Set Hex A_FormatInteger mode
	SetFormat, Integer, Hex
	;Force decimal number to Hex number
	var += 0
	;set original A_FormatInteger mode
	SetFormat, Integer, %OldFormat%
	return var
}

; Funtion By Maestr0 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=54557

MWAGetMonitor(Mx := "", My := "")
{
	if  (!Mx or !My) 
	{
		; if Mx or My is empty, revert to the mouse cursor placement
		Coordmode, Mouse, Screen	; use Screen, so we can compare the coords with the sysget information`
		MouseGetPos, Mx, My
	}

	SysGet, MonitorCount, 80	; monitorcount, so we know how many monitors there are, and the number of loops we need to do
	Loop, %MonitorCount%
	{
		SysGet, mon%A_Index%, Monitor, %A_Index%	; "Monitor" will get the total desktop space of the monitor, including taskbars

		if ( Mx >= mon%A_Index%left ) && ( Mx < mon%A_Index%right ) && ( My >= mon%A_Index%top ) && ( My < mon%A_Index%bottom )
		{
			ActiveMon := A_Index
			break
		}
	}
	return ActiveMon
}

#Include <NonNull>
#Include <Gdip_All>
My idea is that the viewer does not show the video, but a copy stored in a directory, which contains a video-preview of the original video. Problem? What to do one by one. This script —of its own production— makes preview videos (it makes five 2/3-second cuts in different parts of the video), but for the moment it only saves it in the same directory where the script is located. (Use the ffmpeg.exe libraries and the libx265.dll which are free to use).

Code: Select all

FileDelete, Tiempo.txt
MP4:=""
FileSelectFile, MP4, 3, , Open a file

If !MP4
 {
  MsgBox, No file selected!!
  ExitApp
 }

Runwait,  %comspec% /c ffprobe -i "%mp4%" -show_entries format=duration -v quiet -of csv="p=0" > Time.txt,, hide
FileReadLine, TimeS, Time.txt, 1

TimeS1:= Round(TimeS/6)

Loop, 5
{
If A_Index=1
   {
    Time1:="00:00:25"
    Time2:="00:00:27"
   }
  Else
   {
    TimeSer:=Round((TimeS1*A_Index)/60)
    If TimeSer>60
     {
      TimeSer:=Round(TimeSer/60, 2)
      StringReplace, TimeSer, TimeSer, ., :,
      RegExMatch(TimeSer, "\d{2}$", Result)
      If Result>60
       {
        Result:= Result-60
        RegExMatch(TimeSer, "^\d{2}", TimeSez)
        TimeSez++
        TimeSez:= TimeSez ":" Result
        Time1:= TimeSez ":00"
        Time2:= TimeSez ":02"
       }
   Else
    {
     Time1:= TimeSer ":00"
     Time2:= TimeSer ":02"
    }
  }
 Else
 {
  Time1:="00:" TimeSer ":00"
  Time2:="00:" TimeSer ":02"
 }
}
Clipss:= "Clip0" A_Index ".ts"
Runwait, %comspec% /c ffmpeg -i "%mp4%" -ss "%Time1%" -to "%Time2%" -y -an -t 4 -vcodec libx265 -crf 30 -vf scale=320:-1 "%Clipss%",, Hide ; (-crf 20 better quality, bigger size) (-crf 40 worse quality, smaller size)
}

If Not MP4=""
 {
  SplitPath, MP4, , , , OutNameNoExt
  ClipName:= OutNameNoExt "_Mini.mp4"
  Run, %comspec% /c ffmpeg -i "concat:Clip01.ts|Clip02.ts|Clip03.ts|Clip04.ts|Clip05.ts" -c copy "%ClipName%",, Hide
  FileDelete, *.ts
 }
The videos generated by the video-preview generator script are at 320. In the preview script you can change the size of the video-preview on line 214. I have increased it to 1.5 (for 4K monitor). If you want to see a very large video preview, you have to change to a smaller size, such as 0.5 or 0.2.

https://www.youtube.com/watch?v=fF9aOQbKQ40

Another alternative would be for a video player to show parts of the video, but I haven't found one that does this (if anyone knows of a player, let me know). The player mpv.exe can be asked to display the video from start to finish and loop, but it doesn't jump to multiple parts like the script above does.

(I'm also adding to support animated gifs, but I think it can be simplified to play with the first script by adding the gif extension to the above lines.)
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

I'm stuck.

I have followed two lines of development. The first development is to have "video preview" generated all together, created with the second script of the previous Post, in a single directory for that use: "g:\Video_Preview\" . When the long path of a video is retrieved, "i:\Torrent\Magnolia (1999)\Magnolia (1999) 720p Final.mp4", the script is left with the file name "Magnolia (1999) 720p Final.mp4" and look in the directory where the "video previews" are, adding that path: "g:\Video_Preview\Magnolia (1999) 720p Final.mp4". If the file does not exist, it shows a 30 second preview of the video in a loop.

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif,mp4 format.
; You must enable "show file ext name" in explorer.
; You must activate the current screen (click), or when you switch between Explorer, desktop or TCM
; In Total Commander you have to activate (Click) when you change panel.
; You need to check "Show command line" in "configuration", "Layout", in Total Commander
; https://www.autohotkey.com/boards/viewtopic.php?t=90001
;================================================================
; Modified code to add a border to the image, created by Hellbent
; Total Commander support added by WetWare05
; https://www.autohotkey.com/boards/viewtopic.php?p=523384
;================================================================
#Requires AutoHotkey v1.1.33

SetBatchLines, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
Thread, Interrupt, 0

CoordMode, Mouse, Screen

maxStr:=200
Global NoW, SetColor, MaxWidth, MaxHeight, Margin, Transp, SuspendTCM, SuspendDeskTop, OnlyKey, Reflect
NoW:=""

;=========================================================
 Menu, Tray, Icon, Resources\Group_4.ico
 ;Menu, Tray, Icon, shell32.dll, 132 ;Example of icon the DLL Library
 Menu, Tray, NoStandard
 Menu, tray, Add, TCM Image Preview, Nothing
 Menu, tray, Icon, TCM Image Preview, Resources\Group_4.ico
 Menu, Tray, Add
 Menu Tray, Add, Open Info, Tray_Open
 Menu Tray, Icon, Open Info, Resources\Info.ico
 Menu, tray, Add, &Reload this Script, Reloaded
 Menu, tray, Icon,&Reload this Script, Resources\2488.ico
 Menu, tray, Add, &Suspend Utility, Stanby
 Menu, tray, Icon,&Suspend Utility, Resources\Group_4_Red.ico
 Menu, Tray, Add
 Menu, tray, Add, Suspend Preview in TCM, StanbyTCM
 Menu, tray, Icon, Suspend Preview in TCM, Resources\TCommander.ico
 Menu, tray, Add, Suspend Preview in DeskTop, StanbyDeskTop
 Menu, tray, Icon, Suspend Preview in DeskTop, Resources\Explorer.ico
 Menu, tray, Add, Only Preview with RCtrl Key, OnlyKeyPress
 Menu, tray, Icon, Only Preview with RCtrl Key, Resources\Key.ico
 Menu, tray, Add, Mirror to Second Monitor, ReflectTwo
 Menu, tray, Icon, Mirror to Second Monitor, Resources\2220.ico
 Menu, Tray, Add
 Menu, tray, Add, Preview Setting, Config
 Menu, tray, Icon, Preview Setting, Resources\130.ico
 Menu, tray, Add, Frame Color, FrameColor
 Menu, tray, Icon, Frame Color, Resources\ColorEdit.ico
 Menu, Tray, Add
 Menu, tray, Add, Exit, Exit
 Menu, tray, Icon, Exit, shell32.dll, 132
 
if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 8, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  IniWrite, 230, NewConfig.ini, Preview_TCM, Transp
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
 }

ReadVar:
If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
If !Transp
 {
  IniRead, Transp, NewConfig.ini, Preview_TCM, Transp
 }
If !SuspendDeskTop
 {
  IniRead, SuspendDeskTop, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
If !SuspendTCM
 {
  IniRead, SuspendTCM, NewConfig.ini, Preview_TCM, SuspendTCM
 }
 If !OnlyKey
 {
  IniRead, OnlyKey, NewConfig.ini, Preview_TCM, OnlyKey
 }
 If !Reflect
 {
  IniRead, Reflect, NewConfig.ini, Preview_TCM, Reflect
 }
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth
   
 If SuspendTCM=0
  {
   Menu, Tray, Check, Suspend Preview in TCM
  }
  
  If SuspendDeskTop=0
  {
   Menu, Tray, Check, Suspend Preview in DeskTop
  }
  
  If OnlyKey=0
  {
   Menu, Tray, Check, Only Preview with RCtrl Key
  }
  
  If Reflect=1
  {
   Menu, Tray, Check, Mirror to Second Monitor
  }

 ;==========================================================

SetTimer, preview, 50

init:
SizeMon := []
SysGet, numDisplays, 80
Loop % numDisplays {
  SysGet, Mon, Monitor, %A_Index%
  SizeMon.Push([Monleft, MonRight, MonTop, MonBottom])
 }
  
 If Reflect=1
 {
 ActMon:= MWAGetMonitor()
  
  If ActMon=1
   {
    MaxWidth:= SizeMon[2,2]-SizeMon[1,2]
    MaxHeight:= SizeMon[2,4]
   }
   
  If ActMon=2
   {
    MaxWidth:= SizeMon[1,2]
    MaxHeight:= SizeMon[1,4]
   } 
 }
 
; close system file info tip.
RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
pToken := Gdip_Startup()
OnExit, GdipExit
PreviewWindow := CreatePreviewWindow( MaxWidth , MaxHeight )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Critical
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	try Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

preview:
if A_IsSuspended=0
{
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
     {
      btt()
      Process, Close, mpv.exe
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
     }
    Else if Ext=mp4
     {
      ;Gosub, GdipExit
      Path:= % Current.Path
      SplitPath, Path, NewName
      PrePath:= "g:\Video_Preview\" NewName
      MouseGetPos, xMov, yMov
      xMov:= xMov+10
      yMov:= yMov-285 
      Process, Close, mpv.exe
      if !FileExist("%PrePath%")
       {
	Run, d:\Utilidades\MPV Player\mpv.exe --loop --start=01:45 --end=02:15 --ontop --window-scale=0.3 --geometry="%xMov%":"%yMov%" "%Path%"	
       }
      Else
       {
        Run, d:\Utilidades\MPV Player\mpv.exe --loop --ontop --window-scale=1.5 --geometry="%xMov%":"%yMov%" "%PrePath%" ; Change Scale example-> --window-scale=0.5 or delete option
       }
      Path:=""
      PrePath:=""    
     }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
    }
  }
 }
return

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin
	
	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
			
      If Reflect=0
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin )
	Gdip_DeleteBrush( Brush )
	
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height )
	MouseGetPos, x, y	
       }
     
     If Reflect=1
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )	
      }	
	
     	SizeMon := []
	SysGet, numDisplays, 80

	Loop % numDisplays {
	 SysGet, Mon, Monitor, %A_Index%
	 SizeMon.Push( [Monleft, MonRight, MonTop, MonBottom] )
	StateMon:=1
	}
	
      If Reflect=1
       {
	ActMon:= MWAGetMonitor()
  
        If ActMon=1
         {
	  x:= (SizeMon[1,2]+1)
	  y:= SizeMon[2,3]
	 }
        If ActMon=2
         {
	  x:= SizeMon[1,1]
	  y:= SizeMon[1,3]
	 }      
       }
            
      If Reflect=0
	{
	ActMon:= MWAGetMonitor()
	Over=0
	NewPos=0
	xOffSet:=16
	yOffSet:=16
	
       If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
	
	TempTop:= SizeMon[ActMon,3]
	TempY:= y-Height
	If (TempY<0 or TempY<TempTop)
	{
	 Over:=1
	 NewPos:=1
	}
	
       Marg:=margin*4 ;5
       xt:= x+Width
       
       if (xt>SizeMon[ActMon,2])
	 {
	  x:= (SizeMon[ActMon,2]-Width)-marg
	  If Over=0
	   {
	    y:= y-50
	   }
	  }
       }	  
               	
	If (NewPos=1 && Reflect=0)
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , y+yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	 }
	
	If (Reflect=0 and NewPos=0)
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , (y-Height)-yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	}
	If Reflect=1
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x , y , PreviewWindow.Width , PreviewWindow.Height , Alpha := 255 ) ;Alpha := Transp
	}
  }

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925 and https://www.autohotkey.com/boards/viewtopic.php?t=51788
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%

try if (WinClass = "TTOTAL_CMD" && CtrlClass = "LCLListBox1" or CtrlClass = "LCLListBox2" or CtrlClass = "TMyListBox1" or CtrlClass = "TMyListBox2")
 {
  SendMessage, 1074, 1000, , , ahk_class TTOTAL_CMD
  SendMessage, 1074, 8 + ErrorLevel, , , ahk_class TTOTAL_CMD
  ControlGetText, TargetPath, , ahk_id %ErrorLevel%
  sPath := SubStr(TargetPath, 1, InStr(TargetPath, "\", , 0) - 1)

If (OnlyKey=0 and SuspendTCM=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4)", reg)

   Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret	
  }
}

If (OnlyKey=1 and SuspendTCM=1)
 {
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4)", reg)
    
  Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}
;Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
  }
  ;else 
  if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
  }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

NotifyTrayClick(P*) {              ;  v0.41 by SKAN on D39E/D39N @ tiny.cc/notifytrayclick
Static Msg, Fun:="NotifyTrayClick", NM:=OnMessage(0x404,Func(Fun),-1),  Chk,T:=-250,Clk:=1
  If ( (NM := Format(Fun . "_{:03X}", Msg := P[2])) && P.Count()<4 )
     Return ( T := Max(-5000, 0-(P[1] ? Abs(P[1]) : 250)) )
  Critical
  If ( ( Msg<0x201 || Msg>0x209 ) || ( IsFunc(NM) || Islabel(NM) )=0 )
     Return
  Chk := (Fun . "_" . (Msg<=0x203 ? "203" : Msg<=0x206 ? "206" : Msg<=0x209 ? "209" : ""))
  SetTimer, %NM%,  %  (Msg==0x203        || Msg==0x206        || Msg==0x209)
    ? (-1, Clk:=2) : ( Clk=2 ? ("Off", Clk:=1) : ( IsFunc(Chk) || IsLabel(Chk) ? T : -1) )
Return True
}

; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
;	Color Dialog Example script.
;^!F8::
FrameColor:
stringRight, RSix, SetColor, 6
TColor:="0x" RSix
R:= (TColor&0xFF0000)>>16, G:= (TColor&0x00FF00)>>8, B:= TColor&0xFF

RGBval:=RGB(Rval:= R, Gval:= G, Bval:= B)
;Create Color Dialog GUI
Gui, Add, Text, x0 y10 w40 h20 +Right, Red
Gui, Add, Text, x0 y30 w40 h20 +Right, Green
Gui, Add, Text, x0 y50 w40 h20 +Right, Blue
Gui, Add, Slider, x40 y10 w190 h20 AltSubmit +NoTicks +Range0-255 vsR gSliderSub, %Rval%
Gui, Add, Slider, x40 y30 w190 h20 AltSubmit +NoTicks +Range0-255 vsG gSliderSub, %Gval%
Gui, Add, Slider, x40 y50 w190 h20 AltSubmit +NoTicks +Range0-255 vsB gSliderSub, %Bval%
Gui, Add, Edit, x230 y10 w45 h20 gEditSub veR +Limit3 +Number, %Rval%
Gui, Add, UpDown, Range0-255 vuR gUpDownSub, %Rval%
Gui, Add, Edit, x230 y30 w45 h20 gEditSub veG +Limit3 +Number, %Gval%
Gui, Add, UpDown, Range0-255 vuG gUpDownSub, %Gval%
Gui, Add, Edit, x230 y50 w45 h20 gEditSub veB +Limit3 +Number, %Bval%
Gui, Add, UpDown, Range0-255 vuB gUpDownSub, %Bval%
Gui, Add, Progress, x285 y10 w60 h60 +Border Background%RGBval% vpC
Gui, Add, Text, x285 y10 w60 h60 +Border vtP cWhite +BackgroundTrans, Preview
Gui, Add, Button, x120 y80 w110 h20 vbS gButtonSub, Select Color ;Copy to Clipboard
Gui, Show, w351 h105, Simple Color Dialog
return

EditSub:
	;Get Values
	GuiControlGet,Rval,,eR
	GuiControlGet,Gval,,eG
	GuiControlGet,Bval,,eB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

UpDownSub:
	;Get Values
	GuiControlGet,Rval,,uR
	GuiControlGet,Gval,,uG
	GuiControlGet,Bval,,uB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

SliderSub:
	;Get Values
	GuiControlGet,Rval,,sR
	GuiControlGet,Gval,,sG
	GuiControlGet,Bval,,sB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
return

set:
	;Convert values to Hex
	RGBval:=RGB(Rval,Gval,Bval)
	;Display Tooltip
	ToolTip Red: %Rval%`nGreen: %Gval%`nBlue: %Bval%`nHex: %RGBval%
	;Make tooltip disappear after 375 ms (3/8th of a second)
	SetTimer, RemoveToolTip, 375
	;Apply colour to preview
	GuiControl,+Background%RGBval%,pC
return

RemoveToolTip:
	SetTimer, RemoveToolTip, Off ;Turn timer off
	ToolTip ;Turn off tooltip
return

ButtonSub:
 ;Remove '0x' prefix to hex color code, saving it directly to the clipboard
 ;StringReplace,Clipboard,RGBval,0x99
 StringReplace,SetColor,RGBval,0x
 SetColor:="0x99" SetColor
 ;MsgBox, % SetColor . " " . RGBval
 ;Display Last selected values... (these values can later be used), and Notify the user
 ;MsgBox,64,Simple Color Dialog,RGB: (%Rval%, %Gval%, %Bval%)`nHex: %RGBval%`nCopied to Clipboard!
 ;Skip Directly GuiClose
 Gui, Destroy
Return

;^!s::
Config:
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: +HwndGuiID +AlwaysOnTop
Gui, Size: Add, Button, x300 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x300 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x5 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x95 y16 w60 h20 vFmaxW, %TempMaxW%
Gui, Size: Add, Text, x5 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x95 y46 w60 h20 vFmaxH, %TempMaxH%
Gui, Size: Add, Text, x170 y16 w70 h20, Transp.:
Gui, Size: Add, edit, x230 y16 w60 h20 vFtrans , %Transp%
Gui, Size: Add, Text, x170 y46 w70 h20, Margin :
Gui, Size: Add, edit, x230 y46 w60 h20 vFmarg , %margin%
Gui, Size: Show, x%xpos% y%ypos% h80 w370, Image Preview Configuration
Return

#If WinActive("ahk_id " GuiID)
Enter::
NumPadEnter::
NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxWidth:=500
 }
Else 
{
MaxWidth:=FmaxW
IniWrite, %MaxWidth%, NewConfig.ini, Preview_TCM, MaxWidth
}

If !FmaxH
 {
  MaxHeight:=500
 }
Else 
{
MaxHeight:=FmaxH
IniWrite, %MaxHeight%, NewConfig.ini, Preview_TCM, MaxHeight
}

If !Ftrans or Ftrans>256
 {
  Transp:=Transp
 }
Else 
{
Transp:=Ftrans
IniWrite, %Ftrans%, NewConfig.ini, Preview_TCM, Transp
}

If !Fmarg
 {
  Margin:=16
 }
Else 
{
Margin:=Fmarg
IniWrite, %Fmarg%, NewConfig.ini, Preview_TCM, Margin
}
Gui, Size: Destroy
Gosub, Init
Return

Cancel:
Gui, Size: Destroy
Return

~Esc:: ; *
Gosub, GdipExit
SetTimer, preview, off
Sleep, 1000
SetTimer, preview, On
Return

^Esc::
Exit:
ExitApp
Return

StanbyTCM:
Menu, Tray, ToggleCheck, Suspend Preview in TCM
If SuspendTCM=1 
 {
  SuspendTCM:=0
 ;TrayTip, TCM Image Preview, DISABLED,, 0x1, 0x10, 0x20
  SplashTextOn,200, 80, Notification, Preview in TCM Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendTCM
 }
Else
 {
  SuspendTCM:=1
  SplashTextOn,200, 80, Notification, Preview in TCM
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM  
 }
Return

StanbyDeskTop:
Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
Gosub, GdipExit
If SuspendDeskTop=1 
 {
  SuspendDeskTop:=0
  SplashTextOn,200, 80, Notification, Preview in DeskTop Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Else
 {
  SuspendDeskTop:=1
  SplashTextOn,200, 80, Notification, Preview in DeskTop
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Return

OnlyKeyPress:
Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
If OnlyKey=1 
 {
  OnlyKey:=0
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, OnlyKey
 }
Else
 {
  OnlyKey:=1
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 }
Return

ReflectTwo:
Menu, Tray, ToggleCheck, Mirror to Second Monitor
If Reflect=1 
 {
  SplashTextOn,200, 80, Notification, Mirror to Second Monitor Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  Reflect:=0
  MaxWidth:=""
  MaxHeight:=""
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
  MaxWidth:=""
  MaxHeight:=""  
  Gosub, ReadVar
 }
Else
 {
 Reflect:=1
 SplashTextOn,200, 80, Notification, Mirror to Second Monitor
 xSplash1 := A_ScreenWidth-206
 ySplash1 := A_ScreenHeight-180
 WinMove, Notification,, xSplash1, ySplash1
 SoundPlay, Resources\State_I.mp3
 Sleep, 1500
 SplashTextOff
 IniWrite, 1, NewConfig.ini, Preview_TCM, Reflect
 
 MaxWidth:=""
 MaxHeight:="" 
 Gosub, ReadVar 
 }
Return

^p::
NotifyTrayClick_201:
Gosub, Stanby
Return

;^F12::
Stanby:
Suspend:=!Suspend
IfEqual,Suspend,1, Menu,Tray,Icon, Resources\Group_4_Red.ico
IfEqual,Suspend,0, Menu,Tray,Icon, Resources\Group_4.ico
Menu,Tray,Icon,,,1
Suspend,Toggle

if A_IsSuspended=1
 {
  Menu, tray, Check, &Suspend Utility
  SoundPlay, Resources\State_U.mp3 
  SetTimer, preview, off
  SplashTextOn,200, 80, Notification, Application has Been Deactivated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff  
 }
  
if A_IsSuspended=0
 {
  Menu, tray, Uncheck, &Suspend Utility
  SoundPlay, Resources\State_I.mp3
  SetTimer, preview, On
  SplashTextOn,200, 80, Notification, Application has Been Activated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff
  Sleep, 500  
 }  
Return

Reloaded:
Reload
Return

Tray_Open:
ListLines
return

Nothing:
Return
 
;Function to convert Decimal RGB to Hexadecimal RBG, Note: '0' (zero) padding is unnecessary
RGB(r, g, b) {
	;Shift Numbers
	var:=(r << 16) + (g << 8) + b
	;Save current A_FormatInteger
	OldFormat := A_FormatInteger
	;Set Hex A_FormatInteger mode
	SetFormat, Integer, Hex
	;Force decimal number to Hex number
	var += 0
	;set original A_FormatInteger mode
	SetFormat, Integer, %OldFormat%
	return var
}

; Funtion By Maestr0 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=54557

MWAGetMonitor(Mx := "", My := "")
{
	if  (!Mx or !My) 
	{
		; if Mx or My is empty, revert to the mouse cursor placement
		Coordmode, Mouse, Screen	; use Screen, so we can compare the coords with the sysget information`
		MouseGetPos, Mx, My
	}

	SysGet, MonitorCount, 80	; monitorcount, so we know how many monitors there are, and the number of loops we need to do
	Loop, %MonitorCount%
	{
		SysGet, mon%A_Index%, Monitor, %A_Index%	; "Monitor" will get the total desktop space of the monitor, including taskbars

		if ( Mx >= mon%A_Index%left ) && ( Mx < mon%A_Index%right ) && ( My >= mon%A_Index%top ) && ( My < mon%A_Index%bottom )
		{
			ActiveMon := A_Index
			break
		}
	}
	return ActiveMon
}

#Include <NonNull>
#Include <Gdip_All>
The second development has been from discovering that it is possible to execute a preview with mpv.exe, with several jumps and in a loop. The run line in CMD looks like this:

Code: Select all

mpv --loop edl://"Magnolia (1999) 720p Final.mp4",length=5,start=120;"Magnolia (1999) 720p Final.mp4",length=2,start=135;"Magnolia (1999) ) 720p Final.mp4",length=2,start=235;"Magnolia (1999) 720p Final.mp4",length=2,start=445
But adding everything that is needed in the script, it looks like this:

Code: Select all

d:\Utilities\MPV Player\mpv.exe --loop --ontop --window-scale=0.5 --geometry=300:200 edl://"i:\Torrent\Magnolia (1999)\Magnolia (1999) 720p Final.mp4",length=2,start=1488;"i:\Torrent\Magnolia (1999)\Magnolia (1999) 720p Final.mp4",length=2,start=2976;"i:\Torrent\Magnolia (1999)\Magnolia (1999) 720p Final.mp4",length=2,start=4464;"i:\Torrent\Magnolia (1999)\Magnolia (1999) 720p Final.mp4",length=2,start=5952 ;"i:\Torrent\Magnolia (1999)\Magnolia (1999) 720p Final.mp4",length=2,start=7440
(Yes, you have to repeat the video name each time. This is because you can mix multiple parts from multiple videos. This process creates a virtual video.)

So it's a real hassle to create such a line to work in the autohotkey script (for having disallowed symbols, giving errors, eg: the semicolon is for adding comments). If someone helps me I appreciate it.

An "old dog" trick is to have such a line saved to a .bat file and run the bat file. This is script with this trick. The player mpv.exe, and its necessary files, have to be in the same directory as the script. This script takes a little longer than the previous one, because it has to do several processes: calculate the time of the video, divide the time into sections, generate the complex line written above, save it to a .bat file, and execute it. Depending on how fast the computer is, it will make it faster. On a slow computer, the process may fail.

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif,mp4 format.
; You must enable "show file ext name" in explorer.
; You must activate the current screen (click), or when you switch between Explorer, desktop or TCM
; In Total Commander you have to activate (Click) when you change panel.
; You need to check "Show command line" in "configuration", "Layout", in Total Commander
; https://www.autohotkey.com/boards/viewtopic.php?t=90001
;================================================================
; Modified code to add a border to the image, created by Hellbent
; Total Commander support added by WetWare05
; https://www.autohotkey.com/boards/viewtopic.php?p=523384
;================================================================
#Requires AutoHotkey v1.1.33

SetBatchLines, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
Thread, Interrupt, 0

CoordMode, Mouse, Screen

maxStr:=200
Global NoW, SetColor, MaxWidth, MaxHeight, Margin, Transp, SuspendTCM, SuspendDeskTop, OnlyKey, Reflect
NoW:=""

;=========================================================
 Menu, Tray, Icon, Resources\Group_4.ico
 ;Menu, Tray, Icon, shell32.dll, 132 ;Example of icon the DLL Library
 Menu, Tray, NoStandard
 Menu, tray, Add, TCM Image Preview, Nothing
 Menu, tray, Icon, TCM Image Preview, Resources\Group_4.ico
 Menu, Tray, Add
 Menu Tray, Add, Open Info, Tray_Open
 Menu Tray, Icon, Open Info, Resources\Info.ico
 Menu, tray, Add, &Reload this Script, Reloaded
 Menu, tray, Icon,&Reload this Script, Resources\2488.ico
 Menu, tray, Add, &Suspend Utility, Stanby
 Menu, tray, Icon,&Suspend Utility, Resources\Group_4_Red.ico
 Menu, Tray, Add
 Menu, tray, Add, Suspend Preview in TCM, StanbyTCM
 Menu, tray, Icon, Suspend Preview in TCM, Resources\TCommander.ico
 Menu, tray, Add, Suspend Preview in DeskTop, StanbyDeskTop
 Menu, tray, Icon, Suspend Preview in DeskTop, Resources\Explorer.ico
 Menu, tray, Add, Only Preview with RCtrl Key, OnlyKeyPress
 Menu, tray, Icon, Only Preview with RCtrl Key, Resources\Key.ico
 Menu, tray, Add, Mirror to Second Monitor, ReflectTwo
 Menu, tray, Icon, Mirror to Second Monitor, Resources\2220.ico
 Menu, Tray, Add
 Menu, tray, Add, Preview Setting, Config
 Menu, tray, Icon, Preview Setting, Resources\130.ico
 Menu, tray, Add, Frame Color, FrameColor
 Menu, tray, Icon, Frame Color, Resources\ColorEdit.ico
 Menu, Tray, Add
 Menu, tray, Add, Exit, Exit
 Menu, tray, Icon, Exit, shell32.dll, 132
 
if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 8, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  IniWrite, 230, NewConfig.ini, Preview_TCM, Transp
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
 }

ReadVar:
If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
If !Transp
 {
  IniRead, Transp, NewConfig.ini, Preview_TCM, Transp
 }
If !SuspendDeskTop
 {
  IniRead, SuspendDeskTop, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
If !SuspendTCM
 {
  IniRead, SuspendTCM, NewConfig.ini, Preview_TCM, SuspendTCM
 }
 If !OnlyKey
 {
  IniRead, OnlyKey, NewConfig.ini, Preview_TCM, OnlyKey
 }
 If !Reflect
 {
  IniRead, Reflect, NewConfig.ini, Preview_TCM, Reflect
 }
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth
   
 If SuspendTCM=0
  {
   Menu, Tray, Check, Suspend Preview in TCM
  }
  
  If SuspendDeskTop=0
  {
   Menu, Tray, Check, Suspend Preview in DeskTop
  }
  
  If OnlyKey=0
  {
   Menu, Tray, Check, Only Preview with RCtrl Key
  }
  
  If Reflect=1
  {
   Menu, Tray, Check, Mirror to Second Monitor
  }

 ;==========================================================

SetTimer, preview, 50

init:
SizeMon := []
SysGet, numDisplays, 80
Loop % numDisplays {
  SysGet, Mon, Monitor, %A_Index%
  SizeMon.Push([Monleft, MonRight, MonTop, MonBottom])
 }
  
 If Reflect=1
 {
 ActMon:= MWAGetMonitor()
  
  If ActMon=1
   {
    MaxWidth:= SizeMon[2,2]-SizeMon[1,2]
    MaxHeight:= SizeMon[2,4]
   }
   
  If ActMon=2
   {
    MaxWidth:= SizeMon[1,2]
    MaxHeight:= SizeMon[1,4]
   } 
 }
 
; close system file info tip.
RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
pToken := Gdip_Startup()
OnExit, GdipExit
PreviewWindow := CreatePreviewWindow( MaxWidth , MaxHeight )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Critical
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	try Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

preview:
if A_IsSuspended=0
{
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt()
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
    }
    
    Else if Ext=mp4
    {
      FileDelete, Time.txt
      FileDelete, d:\Utilidades\MPV Player\Player.bat
      Path:= % Current.Path
      MouseGetPos, xMov, yMov
      xMov:= xMov+10
      yMov:= yMov-285
      Process, Close, mpv.exe
      Runwait,  %comspec% /c d:\Utilidades\AutoHotkey\Scripts\YouTube-DL\ffprobe.exe -i "%Path%" -show_entries format=duration -v quiet -of csv="p=0" > Time.txt,, hide
      FileReadLine, TimeS, Time.txt, 1
      TimeS1:= Round(TimeS/6)
      CountT:=[]

      Loop, 5
       {
        If A_Index=1
       {
       CountT.Push(TimeS1)
       }
      Else
       {
        SumD:=TimeS1*A_Index
	CountT.Push(SumD)
       }
      }

      Count1:= CountT[1]
      Count2:= CountT[2]
      Count3:= CountT[3]
      Count4:= CountT[4]
      Count5:= CountT[5]
      
      FilmPath= `"%Path%`"
      longBat:= "mpv --loop --ontop --window-scale=0.5 --geometry=" xMov ":" yMov " edl://" FilmPath ",length=2,start=" Count1 ";" FilmPath ",length=2,start=" Count2 ";" FilmPath ",length=2,start=" Count3 ";" FilmPath ",length=2,start=" Count4 ";" FilmPath ",length=2,start=" Count5
      FileAppend, %longBat%, Player.bat
      Run, Player.bat,, hide      
      Path:=""      
     }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
    }
  }
 }
return

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin
	
	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
			
      If Reflect=0
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin )
	Gdip_DeleteBrush( Brush )
	
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height )
	MouseGetPos, x, y	
       }
     
     If Reflect=1
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )	
      }	
	
     	SizeMon := []
	SysGet, numDisplays, 80

	Loop % numDisplays {
	 SysGet, Mon, Monitor, %A_Index%
	 SizeMon.Push( [Monleft, MonRight, MonTop, MonBottom] )
	StateMon:=1
	}
	
      If Reflect=1
       {
	ActMon:= MWAGetMonitor()
  
        If ActMon=1
         {
	  x:= (SizeMon[1,2]+1)
	  y:= SizeMon[2,3]
	 }
        If ActMon=2
         {
	  x:= SizeMon[1,1]
	  y:= SizeMon[1,3]
	 }      
       }
            
      If Reflect=0
	{
	ActMon:= MWAGetMonitor()
	Over=0
	NewPos=0
	xOffSet:=16
	yOffSet:=16
	
       If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
	
	TempTop:= SizeMon[ActMon,3]
	TempY:= y-Height
	If (TempY<0 or TempY<TempTop)
	{
	 Over:=1
	 NewPos:=1
	}
	
       Marg:=margin*4 ;5
       xt:= x+Width
       
       if (xt>SizeMon[ActMon,2])
	 {
	  x:= (SizeMon[ActMon,2]-Width)-marg
	  If Over=0
	   {
	    y:= y-50
	   }
	  }
       }	  
               	
	If (NewPos=1 && Reflect=0)
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , y+yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	 }
	
	If (Reflect=0 and NewPos=0)
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , (y-Height)-yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	}
	If Reflect=1
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x , y , PreviewWindow.Width , PreviewWindow.Height , Alpha := 255 ) ;Alpha := Transp
	}
  }

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925 and https://www.autohotkey.com/boards/viewtopic.php?t=51788
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%

try if (WinClass = "TTOTAL_CMD" && CtrlClass = "LCLListBox1" or CtrlClass = "LCLListBox2" or CtrlClass = "TMyListBox1" or CtrlClass = "TMyListBox2")
 {
  SendMessage, 1074, 1000, , , ahk_class TTOTAL_CMD
  SendMessage, 1074, 8 + ErrorLevel, , , ahk_class TTOTAL_CMD
  ControlGetText, TargetPath, , ahk_id %ErrorLevel%
  sPath := SubStr(TargetPath, 1, InStr(TargetPath, "\", , 0) - 1)

If (OnlyKey=0 and SuspendTCM=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4)", reg)

   Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

If (OnlyKey=1 and SuspendTCM=1)
 {
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4)", reg)
    
  Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}
;Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
  }
  ;else 
  if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    If SuspendDeskTop=0
   {
    Return
   }
  Else
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
  }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

NotifyTrayClick(P*) {              ;  v0.41 by SKAN on D39E/D39N @ tiny.cc/notifytrayclick
Static Msg, Fun:="NotifyTrayClick", NM:=OnMessage(0x404,Func(Fun),-1),  Chk,T:=-250,Clk:=1
  If ( (NM := Format(Fun . "_{:03X}", Msg := P[2])) && P.Count()<4 )
     Return ( T := Max(-5000, 0-(P[1] ? Abs(P[1]) : 250)) )
  Critical
  If ( ( Msg<0x201 || Msg>0x209 ) || ( IsFunc(NM) || Islabel(NM) )=0 )
     Return
  Chk := (Fun . "_" . (Msg<=0x203 ? "203" : Msg<=0x206 ? "206" : Msg<=0x209 ? "209" : ""))
  SetTimer, %NM%,  %  (Msg==0x203        || Msg==0x206        || Msg==0x209)
    ? (-1, Clk:=2) : ( Clk=2 ? ("Off", Clk:=1) : ( IsFunc(Chk) || IsLabel(Chk) ? T : -1) )
Return True
}

; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
;	Color Dialog Example script.
;^!F8::
FrameColor:
stringRight, RSix, SetColor, 6
TColor:="0x" RSix
R:= (TColor&0xFF0000)>>16, G:= (TColor&0x00FF00)>>8, B:= TColor&0xFF

RGBval:=RGB(Rval:= R, Gval:= G, Bval:= B)
;Create Color Dialog GUI
Gui, Add, Text, x0 y10 w40 h20 +Right, Red
Gui, Add, Text, x0 y30 w40 h20 +Right, Green
Gui, Add, Text, x0 y50 w40 h20 +Right, Blue
Gui, Add, Slider, x40 y10 w190 h20 AltSubmit +NoTicks +Range0-255 vsR gSliderSub, %Rval%
Gui, Add, Slider, x40 y30 w190 h20 AltSubmit +NoTicks +Range0-255 vsG gSliderSub, %Gval%
Gui, Add, Slider, x40 y50 w190 h20 AltSubmit +NoTicks +Range0-255 vsB gSliderSub, %Bval%
Gui, Add, Edit, x230 y10 w45 h20 gEditSub veR +Limit3 +Number, %Rval%
Gui, Add, UpDown, Range0-255 vuR gUpDownSub, %Rval%
Gui, Add, Edit, x230 y30 w45 h20 gEditSub veG +Limit3 +Number, %Gval%
Gui, Add, UpDown, Range0-255 vuG gUpDownSub, %Gval%
Gui, Add, Edit, x230 y50 w45 h20 gEditSub veB +Limit3 +Number, %Bval%
Gui, Add, UpDown, Range0-255 vuB gUpDownSub, %Bval%
Gui, Add, Progress, x285 y10 w60 h60 +Border Background%RGBval% vpC
Gui, Add, Text, x285 y10 w60 h60 +Border vtP cWhite +BackgroundTrans, Preview
Gui, Add, Button, x120 y80 w110 h20 vbS gButtonSub, Select Color ;Copy to Clipboard
Gui, Show, w351 h105, Simple Color Dialog
return

EditSub:
	;Get Values
	GuiControlGet,Rval,,eR
	GuiControlGet,Gval,,eG
	GuiControlGet,Bval,,eB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

UpDownSub:
	;Get Values
	GuiControlGet,Rval,,uR
	GuiControlGet,Gval,,uG
	GuiControlGet,Bval,,uB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

SliderSub:
	;Get Values
	GuiControlGet,Rval,,sR
	GuiControlGet,Gval,,sG
	GuiControlGet,Bval,,sB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
return

set:
	;Convert values to Hex
	RGBval:=RGB(Rval,Gval,Bval)
	;Display Tooltip
	ToolTip Red: %Rval%`nGreen: %Gval%`nBlue: %Bval%`nHex: %RGBval%
	;Make tooltip disappear after 375 ms (3/8th of a second)
	SetTimer, RemoveToolTip, 375
	;Apply colour to preview
	GuiControl,+Background%RGBval%,pC
return

RemoveToolTip:
	SetTimer, RemoveToolTip, Off ;Turn timer off
	ToolTip ;Turn off tooltip
return

ButtonSub:
 ;Remove '0x' prefix to hex color code, saving it directly to the clipboard
 ;StringReplace,Clipboard,RGBval,0x99
 StringReplace,SetColor,RGBval,0x
 SetColor:="0x99" SetColor
 ;MsgBox, % SetColor . " " . RGBval
 ;Display Last selected values... (these values can later be used), and Notify the user
 ;MsgBox,64,Simple Color Dialog,RGB: (%Rval%, %Gval%, %Bval%)`nHex: %RGBval%`nCopied to Clipboard!
 ;Skip Directly GuiClose
 Gui, Destroy
Return

;^!s::
Config:
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: +HwndGuiID +AlwaysOnTop
Gui, Size: Add, Button, x300 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x300 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x5 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x95 y16 w60 h20 vFmaxW, %TempMaxW%
Gui, Size: Add, Text, x5 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x95 y46 w60 h20 vFmaxH, %TempMaxH%
Gui, Size: Add, Text, x170 y16 w70 h20, Transp.:
Gui, Size: Add, edit, x230 y16 w60 h20 vFtrans , %Transp%
Gui, Size: Add, Text, x170 y46 w70 h20, Margin :
Gui, Size: Add, edit, x230 y46 w60 h20 vFmarg , %margin%
Gui, Size: Show, x%xpos% y%ypos% h80 w370, Image Preview Configuration
Return

#If WinActive("ahk_id " GuiID)
Enter::
NumPadEnter::
NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxWidth:=500
 }
Else 
{
MaxWidth:=FmaxW
IniWrite, %MaxWidth%, NewConfig.ini, Preview_TCM, MaxWidth
}

If !FmaxH
 {
  MaxHeight:=500
 }
Else 
{
MaxHeight:=FmaxH
IniWrite, %MaxHeight%, NewConfig.ini, Preview_TCM, MaxHeight
}

If !Ftrans or Ftrans>256
 {
  Transp:=Transp
 }
Else 
{
Transp:=Ftrans
IniWrite, %Ftrans%, NewConfig.ini, Preview_TCM, Transp
}

If !Fmarg
 {
  Margin:=16
 }
Else 
{
Margin:=Fmarg
IniWrite, %Fmarg%, NewConfig.ini, Preview_TCM, Margin
}
Gui, Size: Destroy
Gosub, Init
Return

Cancel:
Gui, Size: Destroy
Return

~Esc:: ; *
Gosub, GdipExit
SetTimer, preview, off
Sleep, 1000
SetTimer, preview, On
Return

^Esc::
Exit:
ExitApp
Return

StanbyTCM:
Menu, Tray, ToggleCheck, Suspend Preview in TCM
If SuspendTCM=1 
 {
  SuspendTCM:=0
 ;TrayTip, TCM Image Preview, DISABLED,, 0x1, 0x10, 0x20
  SplashTextOn,200, 80, Notification, Preview in TCM Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendTCM
 }
Else
 {
  SuspendTCM:=1
  SplashTextOn,200, 80, Notification, Preview in TCM
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM  
 }
Return

StanbyDeskTop:
Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
Gosub, GdipExit
If SuspendDeskTop=1 
 {
  SuspendDeskTop:=0
  SplashTextOn,200, 80, Notification, Preview in DeskTop Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Else
 {
  SuspendDeskTop:=1
  SplashTextOn,200, 80, Notification, Preview in DeskTop
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Return

OnlyKeyPress:
Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
If OnlyKey=1 
 {
  OnlyKey:=0
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, OnlyKey
 }
Else
 {
  OnlyKey:=1
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 }
Return

ReflectTwo:
Menu, Tray, ToggleCheck, Mirror to Second Monitor
If Reflect=1 
 {
  SplashTextOn,200, 80, Notification, Mirror to Second Monitor Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  Reflect:=0
  MaxWidth:=""
  MaxHeight:=""
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
  MaxWidth:=""
  MaxHeight:=""  
  Gosub, ReadVar
 }
Else
 {
 Reflect:=1
 SplashTextOn,200, 80, Notification, Mirror to Second Monitor
 xSplash1 := A_ScreenWidth-206
 ySplash1 := A_ScreenHeight-180
 WinMove, Notification,, xSplash1, ySplash1
 SoundPlay, Resources\State_I.mp3
 Sleep, 1500
 SplashTextOff
 IniWrite, 1, NewConfig.ini, Preview_TCM, Reflect
 
 MaxWidth:=""
 MaxHeight:="" 
 Gosub, ReadVar 
 }
Return

^p::
NotifyTrayClick_201:
Gosub, Stanby
Return

;^F12::
Stanby:
Suspend:=!Suspend
IfEqual,Suspend,1, Menu,Tray,Icon, Resources\Group_4_Red.ico
IfEqual,Suspend,0, Menu,Tray,Icon, Resources\Group_4.ico
Menu,Tray,Icon,,,1
Suspend,Toggle

if A_IsSuspended=1
 {
  Menu, tray, Check, &Suspend Utility
  SoundPlay, Resources\State_U.mp3 
  SetTimer, preview, off
  SplashTextOn,200, 80, Notification, Application has Been Deactivated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff  
 }
  
if A_IsSuspended=0
 {
  Menu, tray, Uncheck, &Suspend Utility
  SoundPlay, Resources\State_I.mp3
  SetTimer, preview, On
  SplashTextOn,200, 80, Notification, Application has Been Activated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff
  Sleep, 500  
 }  
Return

Reloaded:
Reload
Return

Tray_Open:
ListLines
return

Nothing:
Return
 
;Function to convert Decimal RGB to Hexadecimal RBG, Note: '0' (zero) padding is unnecessary
RGB(r, g, b) {
	;Shift Numbers
	var:=(r << 16) + (g << 8) + b
	;Save current A_FormatInteger
	OldFormat := A_FormatInteger
	;Set Hex A_FormatInteger mode
	SetFormat, Integer, Hex
	;Force decimal number to Hex number
	var += 0
	;set original A_FormatInteger mode
	SetFormat, Integer, %OldFormat%
	return var
}

; Funtion By Maestr0 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=54557

MWAGetMonitor(Mx := "", My := "")
{
	if  (!Mx or !My) 
	{
		; if Mx or My is empty, revert to the mouse cursor placement
		Coordmode, Mouse, Screen	; use Screen, so we can compare the coords with the sysget information`
		MouseGetPos, Mx, My
	}

	SysGet, MonitorCount, 80	; monitorcount, so we know how many monitors there are, and the number of loops we need to do
	Loop, %MonitorCount%
	{
		SysGet, mon%A_Index%, Monitor, %A_Index%	; "Monitor" will get the total desktop space of the monitor, including taskbars

		if ( Mx >= mon%A_Index%left ) && ( Mx < mon%A_Index%right ) && ( My >= mon%A_Index%top ) && ( My < mon%A_Index%bottom )
		{
			ActiveMon := A_Index
			break
		}
	}
	return ActiveMon
}

#Include <NonNull>
#Include <Gdip_All>
The second one is not really working... I've changed something, I have to check it.

(OffTopic: since there can be images and videos in the same directory, displaying images and video is a bit confusing. It is better to have activated the ability to view videos and images by holding down the right "control" key, which is done from the icon tray menu.)

—You can tell I'm very bored :o :lol:
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Hi.

In the second script, change the routine between lines 206 and 245, to the following lines (it works a little better, but sometimes some types of videos, due to their encoding, give problems):

Code: Select all

Else if Ext=mp4
    {
      FileDelete, Time.txt
      FileDelete, Player.bat
      Path:= % Current.Path
      MouseGetPos, xMov, yMov
      xMov:= xMov+10
      yMov:= yMov-285
      Process, Close, mpv.exe
      Runwait,  %comspec% /c ffprobe "%Path%" -show_entries format=duration -of compact=p=0:nk=1 -v 0 > Time.txt,, hide
      FileReadLine, TimeS, Time.txt, 1
      TimeS1:= Round(TimeS/6)
      
      Count1:= TimeS1
      Count2:= TimeS1*2
      Count3:= TimeS1*3
      Count4:= TimeS1*4
      Count5:= TimeS1*5
      
      FilmPath= `"%Path%`"
      longBat:= "mpv --loop --ontop --window-scale=0.5 --geometry=" xMov ":" yMov " edl://" FilmPath ",length=2,start=" Count1 ";" FilmPath ",length=2,start=" Count2 ";" FilmPath ",length=2,start=" Count3 ";" FilmPath ",length=2,start=" Count4 ";" FilmPath ",length=2,start=" Count5
      FileAppend, %longBat%, Player.bat
      Run, Player.bat,, hide      
      Path:=""      
     }
    else
It works best if all —the necessary files mpv.exe and ffprobe.exe necessary files—are in the same directory.

The problem is caused by taking time to calculate the duration of the video, I've tried MediaInfo and others, but I'm having trouble retrieving the information for the AutoHotkey script.

(Try setting all the "length" fields to 1. Maybe it's better. If you want more cuts, Move up the 6 n "TimeS1:= Round(TimeS/6)" and add more lines "Count5:= TimeS1*6" "Count5:= TimeS1*7" and add them to the line "longBat:= ...")
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

A more polished script.

I managed to run mpv.exe from the script itself, without resorting to creating a .bat file. Now the duration of the video is calculated by the mediainfo.exe utility (I have left the ffprobe line, which also calculates the duration, in case you want to change or test. The videos are played in 5 different parts, for a second (in the standard on the web pages) and in loop. To prevent the window from being left open, I have added a routine that makes it close at 9 and a half seconds. If you do not want this option, put a semicolon in front of line 240 (SetTimer, MediaOff, 9500), if you want to keep more time up or down, change the number 9500 (the time is in milliseconds: 1 second is 1000 milliseconds).

Now both on TCM, as on the desktop and the Explorer works the option "only see when the right control button is pressed." How it works best is by dropping and clicking on each file, instead of holding the key down all the time (a matter of getting used to it).

Known bugs, if you see an image and then a video, you may not close the image. The script is intended to work with Gdip windows, but the videos are viewed with mpv.exe, so the close function does not work with the videos. It does work well to watch several videos, as it closes them when it opens the next one. Switching to an image also works well and closes the video. The second problem is that video viewing is done by decreasing the size by half, in video granes is fine, but in small ones, no. Also the position of the video I have calculated for myself, because almost all the videos are at 1280x720 and it is my best option. But it won't work well for other people and other video sizes. This issue is easy to resolve. You can ask mpv.exe to display all videos at a specific size (I think it's with the --autofit=320x-1 option, where you tell the width and the length adapts it; if you choose this option, you must delete --window-scale=0.5 in line 237).

Ah, another problem is that mediaInfo (or ffprobe) do not calculate the time in videos with x265 encoding (and others with a high compression rate), and that is why they do not open, because the possibility of calculating the time cuts has not been created.

Now visualize git. It now also works in the "thumbnail view" window in TCM, but its behavior is somewhat more erratic.

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif,mp4,gif format.
; You must enable "show file ext name" in explorer.
; You must activate the current screen (click), or when you switch between Explorer, desktop or TCM
; In Total Commander you have to activate (Click) when you change panel.
; You need to check "Show command line" in "configuration", "Layout", in Total Commander
; https://www.autohotkey.com/boards/viewtopic.php?t=90001
;================================================================
; Modified code to add a border to the image, created by Hellbent
; Total Commander support added by WetWare05
; https://www.autohotkey.com/boards/viewtopic.php?p=523384
;================================================================
#Requires AutoHotkey v1.1.33

SetBatchLines, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
Thread, Interrupt, 0

CoordMode, Mouse, Screen

maxStr:=200
Global NoW, SetColor, MaxWidth, MaxHeight, Margin, Transp, SuspendTCM, SuspendDeskTop, OnlyKey, Reflect
NoW:=""

;=========================================================
 Menu, Tray, Icon, Resources\Group_4.ico
 ;Menu, Tray, Icon, shell32.dll, 132 ;Example of icon the DLL Library
 Menu, Tray, NoStandard
 Menu, tray, Add, TCM Image Preview, Nothing
 Menu, tray, Icon, TCM Image Preview, Resources\Group_4.ico
 Menu, Tray, Add
 Menu Tray, Add, Open Info, Tray_Open
 Menu Tray, Icon, Open Info, Resources\Info.ico
 Menu, tray, Add, &Reload this Script, Reloaded
 Menu, tray, Icon,&Reload this Script, Resources\2488.ico
 Menu, tray, Add, &Suspend Utility, Stanby
 Menu, tray, Icon,&Suspend Utility, Resources\Group_4_Red.ico
 Menu, Tray, Add
 Menu, tray, Add, Suspend Preview in TCM, StanbyTCM
 Menu, tray, Icon, Suspend Preview in TCM, Resources\TCommander.ico
 Menu, tray, Add, Suspend Preview in DeskTop, StanbyDeskTop
 Menu, tray, Icon, Suspend Preview in DeskTop, Resources\Explorer.ico
 Menu, tray, Add, Only Preview with RCtrl Key, OnlyKeyPress
 Menu, tray, Icon, Only Preview with RCtrl Key, Resources\Key.ico
 Menu, tray, Add, Mirror to Second Monitor, ReflectTwo
 Menu, tray, Icon, Mirror to Second Monitor, Resources\2220.ico
 Menu, Tray, Add
 Menu, tray, Add, Preview Setting, Config
 Menu, tray, Icon, Preview Setting, Resources\130.ico
 Menu, tray, Add, Frame Color, FrameColor
 Menu, tray, Icon, Frame Color, Resources\ColorEdit.ico
 Menu, Tray, Add
 Menu, tray, Add, Exit, Exit
 Menu, tray, Icon, Exit, shell32.dll, 132
 
if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 8, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  IniWrite, 230, NewConfig.ini, Preview_TCM, Transp
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
 }

ReadVar:
If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
If !Transp
 {
  IniRead, Transp, NewConfig.ini, Preview_TCM, Transp
 }
If !SuspendDeskTop
 {
  IniRead, SuspendDeskTop, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
If !SuspendTCM
 {
  IniRead, SuspendTCM, NewConfig.ini, Preview_TCM, SuspendTCM
 }
 If !OnlyKey
 {
  IniRead, OnlyKey, NewConfig.ini, Preview_TCM, OnlyKey
 }
 If !Reflect
 {
  IniRead, Reflect, NewConfig.ini, Preview_TCM, Reflect
 }
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth
   
 If SuspendTCM=0
  {
   Menu, Tray, Check, Suspend Preview in TCM
  }
  
  If SuspendDeskTop=0
  {
   Menu, Tray, Check, Suspend Preview in DeskTop
  }
  
  If OnlyKey=0
  {
   Menu, Tray, Check, Only Preview with RCtrl Key
  }
  
  If Reflect=1
  {
   Menu, Tray, Check, Mirror to Second Monitor
  }

 ;==========================================================

SetTimer, preview, 50

init:
SizeMon := []
SysGet, numDisplays, 80
Loop % numDisplays {
  SysGet, Mon, Monitor, %A_Index%
  SizeMon.Push([Monleft, MonRight, MonTop, MonBottom])
 }
  
 If Reflect=1
 {
 ActMon:= MWAGetMonitor()
  
  If ActMon=1
   {
    MaxWidth:= SizeMon[2,2]-SizeMon[1,2]
    MaxHeight:= SizeMon[2,4]
   }
   
  If ActMon=2
   {
    MaxWidth:= SizeMon[1,2]
    MaxHeight:= SizeMon[1,4]
   } 
 }
 
; close system file info tip.
RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
pToken := Gdip_Startup()
OnExit, GdipExit
PreviewWindow := CreatePreviewWindow( MaxWidth , MaxHeight )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Critical
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	try Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

preview:
if A_IsSuspended=0
{
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt()
      Process, Close, mpv.exe
      ShowPreview( Current.Path , PreviewWindow ) ;<<<<<----------
    }
    
    ;Else if Ext=mp4
    Else if Ext in mp4,gif
    {
      FileDelete, longBat.txt
      FileDelete, Time.txt
      FileDelete, Player.bat
      Path:= % Current.Path
      MouseGetPos, xMov, yMov
      xMov:= xMov+10
      ;yMov:= yMov-285
      yMov:= yMov-560
      Process, Close, mpv.exe      
      Duration:= "Video;%Duration%"      
      runwait, %comspec% /c MediaInfo --Inform="%Duration%" "%Path%" > Time.txt ,,Hide
      ;Runwait,  %comspec% /c ffprobe "%Path%" -show_entries format=duration -of compact=p=0:nk=1 -v 0 > Time.txt,, hide
      FileReadLine, TimeS, Time.txt, 1
      MiliSeg:=Round(TimeS*0.001)
      TimeS1:= Round(MiliSeg/6)
            
      FilmPath= `";%Path%`"
      Count1:= TimeS1
      Count1:= FilmPath ",length=1,start=" Count1
      Count2:= TimeS1*2
      Count2:= FilmPath ",length=1,start=" Count2
      Count3:= TimeS1*3
      Count3:= FilmPath ",length=1,start=" Count3
      Count4:= TimeS1*4
      Count4:= FilmPath ",length=1,start=" Count4
      Count5:= TimeS1*5
      Count5:= FilmPath ",length=1,start=" Count5
      Total:= "--loop --ontop --window-scale=0.5 --no-audio --geometry=" xMov ":" yMov " edl://" Count1 Count2 Count3 Count4 Count5
      run, %comspec% /c mpv %Total% ,, Hide
           
      SetTimer, MediaOff, 9500
      Path:=""      
     }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
    }
  }
 }
return

MediaOff:
Process, Close, mpv.exe
Return

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin
	
	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
			
      If Reflect=0
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin )
	Gdip_DeleteBrush( Brush )
	
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height )
	MouseGetPos, x, y	
       }
     
     If Reflect=1
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )	
      }	
	
     	SizeMon := []
	SysGet, numDisplays, 80

	Loop % numDisplays {
	 SysGet, Mon, Monitor, %A_Index%
	 SizeMon.Push( [Monleft, MonRight, MonTop, MonBottom] )
	StateMon:=1
	}
	
      If Reflect=1
       {
	ActMon:= MWAGetMonitor()
  
        If ActMon=1
         {
	  x:= (SizeMon[1,2]+1)
	  y:= SizeMon[2,3]
	 }
        If ActMon=2
         {
	  x:= SizeMon[1,1]
	  y:= SizeMon[1,3]
	 }      
       }
            
      If Reflect=0
	{
	ActMon:= MWAGetMonitor()
	Over=0
	NewPos=0
	xOffSet:=16
	yOffSet:=16
	
       If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
	
	TempTop:= SizeMon[ActMon,3]
	TempY:= y-Height
	If (TempY<0 or TempY<TempTop)
	{
	 Over:=1
	 NewPos:=1
	}
	
       Marg:=margin*4 ;5
       xt:= x+Width
       
       if (xt>SizeMon[ActMon,2])
	 {
	  x:= (SizeMon[ActMon,2]-Width)-marg
	  If Over=0
	   {
	    y:= y-50
	   }
	  }
       }	  
               	
	If (NewPos=1 && Reflect=0)
	 {
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , y+yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	 }
	
	If (Reflect=0 and NewPos=0)
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , (y-Height)-yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	}
	If Reflect=1
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x , y , PreviewWindow.Width , PreviewWindow.Height , Alpha := 255 ) ;Alpha := Transp
	}
  }

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925 and https://www.autohotkey.com/boards/viewtopic.php?t=51788
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%

try if (WinClass = "TTOTAL_CMD" && CtrlClass = "LCLListBox1" or CtrlClass = "LCLListBox2" or CtrlClass = "TMyListBox1" or CtrlClass = "TMyListBox2" or CtrlClass = "LCLListBox")
 {
  SendMessage, 1074, 1000, , , ahk_class TTOTAL_CMD
  SendMessage, 1074, 8 + ErrorLevel, , , ahk_class TTOTAL_CMD
  ControlGetText, TargetPath, , ahk_id %ErrorLevel%
  sPath := SubStr(TargetPath, 1, InStr(TargetPath, "\", , 0) - 1)

If (OnlyKey=0 and SuspendTCM=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4|gif)", reg)

   Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

If (OnlyKey=1 and SuspendTCM=1)
 {
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4|gif)", reg)
    
  Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    If SuspendDeskTop=0
   {
    Return
   }
   
  If (OnlyKey=0 and SuspendDeskTop=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
    }
   }
  If (OnlyKey=1 and SuspendDeskTop=1)
  {
  oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
     }
   }
  }
     
  if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    If SuspendDeskTop=0
   {
    Return
   }
   
  If (OnlyKey=0 and SuspendDeskTop=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
   }
  }
 }
If (OnlyKey=1 and SuspendDeskTop=1)
{
oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
 }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

NotifyTrayClick(P*) {              ;  v0.41 by SKAN on D39E/D39N @ tiny.cc/notifytrayclick
Static Msg, Fun:="NotifyTrayClick", NM:=OnMessage(0x404,Func(Fun),-1),  Chk,T:=-250,Clk:=1
  If ( (NM := Format(Fun . "_{:03X}", Msg := P[2])) && P.Count()<4 )
     Return ( T := Max(-5000, 0-(P[1] ? Abs(P[1]) : 250)) )
  Critical
  If ( ( Msg<0x201 || Msg>0x209 ) || ( IsFunc(NM) || Islabel(NM) )=0 )
     Return
  Chk := (Fun . "_" . (Msg<=0x203 ? "203" : Msg<=0x206 ? "206" : Msg<=0x209 ? "209" : ""))
  SetTimer, %NM%,  %  (Msg==0x203        || Msg==0x206        || Msg==0x209)
    ? (-1, Clk:=2) : ( Clk=2 ? ("Off", Clk:=1) : ( IsFunc(Chk) || IsLabel(Chk) ? T : -1) )
Return True
}

; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
;	Color Dialog Example script.
;^!F8::
FrameColor:
stringRight, RSix, SetColor, 6
TColor:="0x" RSix
R:= (TColor&0xFF0000)>>16, G:= (TColor&0x00FF00)>>8, B:= TColor&0xFF

RGBval:=RGB(Rval:= R, Gval:= G, Bval:= B)
;Create Color Dialog GUI
Gui, Add, Text, x0 y10 w40 h20 +Right, Red
Gui, Add, Text, x0 y30 w40 h20 +Right, Green
Gui, Add, Text, x0 y50 w40 h20 +Right, Blue
Gui, Add, Slider, x40 y10 w190 h20 AltSubmit +NoTicks +Range0-255 vsR gSliderSub, %Rval%
Gui, Add, Slider, x40 y30 w190 h20 AltSubmit +NoTicks +Range0-255 vsG gSliderSub, %Gval%
Gui, Add, Slider, x40 y50 w190 h20 AltSubmit +NoTicks +Range0-255 vsB gSliderSub, %Bval%
Gui, Add, Edit, x230 y10 w45 h20 gEditSub veR +Limit3 +Number, %Rval%
Gui, Add, UpDown, Range0-255 vuR gUpDownSub, %Rval%
Gui, Add, Edit, x230 y30 w45 h20 gEditSub veG +Limit3 +Number, %Gval%
Gui, Add, UpDown, Range0-255 vuG gUpDownSub, %Gval%
Gui, Add, Edit, x230 y50 w45 h20 gEditSub veB +Limit3 +Number, %Bval%
Gui, Add, UpDown, Range0-255 vuB gUpDownSub, %Bval%
Gui, Add, Progress, x285 y10 w60 h60 +Border Background%RGBval% vpC
Gui, Add, Text, x285 y10 w60 h60 +Border vtP cWhite +BackgroundTrans, Preview
Gui, Add, Button, x120 y80 w110 h20 vbS gButtonSub, Select Color ;Copy to Clipboard
Gui, Show, w351 h105, Simple Color Dialog
return

EditSub:
	;Get Values
	GuiControlGet,Rval,,eR
	GuiControlGet,Gval,,eG
	GuiControlGet,Bval,,eB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

UpDownSub:
	;Get Values
	GuiControlGet,Rval,,uR
	GuiControlGet,Gval,,uG
	GuiControlGet,Bval,,uB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

SliderSub:
	;Get Values
	GuiControlGet,Rval,,sR
	GuiControlGet,Gval,,sG
	GuiControlGet,Bval,,sB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
return

set:
	;Convert values to Hex
	RGBval:=RGB(Rval,Gval,Bval)
	;Display Tooltip
	ToolTip Red: %Rval%`nGreen: %Gval%`nBlue: %Bval%`nHex: %RGBval%
	;Make tooltip disappear after 375 ms (3/8th of a second)
	SetTimer, RemoveToolTip, 375
	;Apply colour to preview
	GuiControl,+Background%RGBval%,pC
return

RemoveToolTip:
	SetTimer, RemoveToolTip, Off ;Turn timer off
	ToolTip ;Turn off tooltip
return

ButtonSub:
 ;Remove '0x' prefix to hex color code, saving it directly to the clipboard
 ;StringReplace,Clipboard,RGBval,0x99
 StringReplace,SetColor,RGBval,0x
 SetColor:="0x99" SetColor
 ;MsgBox, % SetColor . " " . RGBval
 ;Display Last selected values... (these values can later be used), and Notify the user
 ;MsgBox,64,Simple Color Dialog,RGB: (%Rval%, %Gval%, %Bval%)`nHex: %RGBval%`nCopied to Clipboard!
 ;Skip Directly GuiClose
 Gui, Destroy
Return

;^!s::
Config:
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: +HwndGuiID +AlwaysOnTop
Gui, Size: Add, Button, x300 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x300 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x5 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x95 y16 w60 h20 vFmaxW, %TempMaxW%
Gui, Size: Add, Text, x5 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x95 y46 w60 h20 vFmaxH, %TempMaxH%
Gui, Size: Add, Text, x170 y16 w70 h20, Transp.:
Gui, Size: Add, edit, x230 y16 w60 h20 vFtrans , %Transp%
Gui, Size: Add, Text, x170 y46 w70 h20, Margin :
Gui, Size: Add, edit, x230 y46 w60 h20 vFmarg , %margin%
Gui, Size: Show, x%xpos% y%ypos% h80 w370, Image Preview Configuration
Return

#If WinActive("ahk_id " GuiID)
Enter::
NumPadEnter::
NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxWidth:=500
 }
Else 
{
MaxWidth:=FmaxW
IniWrite, %MaxWidth%, NewConfig.ini, Preview_TCM, MaxWidth
}

If !FmaxH
 {
  MaxHeight:=500
 }
Else 
{
MaxHeight:=FmaxH
IniWrite, %MaxHeight%, NewConfig.ini, Preview_TCM, MaxHeight
}

If !Ftrans or Ftrans>256
 {
  Transp:=Transp
 }
Else 
{
Transp:=Ftrans
IniWrite, %Ftrans%, NewConfig.ini, Preview_TCM, Transp
}

If !Fmarg
 {
  Margin:=16
 }
Else 
{
Margin:=Fmarg
IniWrite, %Fmarg%, NewConfig.ini, Preview_TCM, Margin
}
Gui, Size: Destroy
Gosub, Init
Return

Cancel:
Gui, Size: Destroy
Return

~Esc:: ; *
Gosub, GdipExit
SetTimer, preview, off
Sleep, 1000
SetTimer, preview, On
Return

^Esc::
Exit:
ExitApp
Return

StanbyTCM:
Menu, Tray, ToggleCheck, Suspend Preview in TCM
If SuspendTCM=1 
 {
  SuspendTCM:=0
 ;TrayTip, TCM Image Preview, DISABLED,, 0x1, 0x10, 0x20
  SplashTextOn,200, 80, Notification, Preview in TCM Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendTCM
 }
Else
 {
  SuspendTCM:=1
  SplashTextOn,200, 80, Notification, Preview in TCM
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM  
 }
Return

StanbyDeskTop:
Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
Gosub, GdipExit
If SuspendDeskTop=1 
 {
  SuspendDeskTop:=0
  SplashTextOn,200, 80, Notification, Preview in DeskTop Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Else
 {
  SuspendDeskTop:=1
  SplashTextOn,200, 80, Notification, Preview in DeskTop
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Return

OnlyKeyPress:
Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
If OnlyKey=1 
 {
  OnlyKey:=0
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, OnlyKey
 }
Else
 {
  OnlyKey:=1
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 }
Return

ReflectTwo:
Menu, Tray, ToggleCheck, Mirror to Second Monitor
If Reflect=1 
 {
  SplashTextOn,200, 80, Notification, Mirror to Second Monitor Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  Reflect:=0
  MaxWidth:=""
  MaxHeight:=""
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
  MaxWidth:=""
  MaxHeight:=""  
  Gosub, ReadVar
 }
Else
 {
 Reflect:=1
 SplashTextOn,200, 80, Notification, Mirror to Second Monitor
 xSplash1 := A_ScreenWidth-206
 ySplash1 := A_ScreenHeight-180
 WinMove, Notification,, xSplash1, ySplash1
 SoundPlay, Resources\State_I.mp3
 Sleep, 1500
 SplashTextOff
 IniWrite, 1, NewConfig.ini, Preview_TCM, Reflect
 
 MaxWidth:=""
 MaxHeight:="" 
 Gosub, ReadVar 
 }
Return

^p::
NotifyTrayClick_201:
Gosub, Stanby
Return

;^F12::
Stanby:
Suspend:=!Suspend
IfEqual,Suspend,1, Menu,Tray,Icon, Resources\Group_4_Red.ico
IfEqual,Suspend,0, Menu,Tray,Icon, Resources\Group_4.ico
Menu,Tray,Icon,,,1
Suspend,Toggle

if A_IsSuspended=1
 {
  Menu, tray, Check, &Suspend Utility
  SoundPlay, Resources\State_U.mp3 
  SetTimer, preview, off
  SplashTextOn,200, 80, Notification, Application has Been Deactivated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff  
 }
  
if A_IsSuspended=0
 {
  Menu, tray, Uncheck, &Suspend Utility
  SoundPlay, Resources\State_I.mp3
  SetTimer, preview, On
  SplashTextOn,200, 80, Notification, Application has Been Activated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff
  Sleep, 500  
 }  
Return

Reloaded:
Reload
Return

Tray_Open:
ListLines
return

Nothing:
Return
 
;Function to convert Decimal RGB to Hexadecimal RBG, Note: '0' (zero) padding is unnecessary
RGB(r, g, b) {
	;Shift Numbers
	var:=(r << 16) + (g << 8) + b
	;Save current A_FormatInteger
	OldFormat := A_FormatInteger
	;Set Hex A_FormatInteger mode
	SetFormat, Integer, Hex
	;Force decimal number to Hex number
	var += 0
	;set original A_FormatInteger mode
	SetFormat, Integer, %OldFormat%
	return var
}

; Funtion By Maestr0 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=54557

MWAGetMonitor(Mx := "", My := "")
{
	if  (!Mx or !My) 
	{
		; if Mx or My is empty, revert to the mouse cursor placement
		Coordmode, Mouse, Screen	; use Screen, so we can compare the coords with the sysget information`
		MouseGetPos, Mx, My
	}

	SysGet, MonitorCount, 80	; monitorcount, so we know how many monitors there are, and the number of loops we need to do
	Loop, %MonitorCount%
	{
		SysGet, mon%A_Index%, Monitor, %A_Index%	; "Monitor" will get the total desktop space of the monitor, including taskbars

		if ( Mx >= mon%A_Index%left ) && ( Mx < mon%A_Index%right ) && ( My >= mon%A_Index%top ) && ( My < mon%A_Index%bottom )
		{
			ActiveMon := A_Index
			break
		}
	}
	return ActiveMon
}

#Include <NonNull>
#Include <Gdip_All>
(Attentión!! I was without headphones and I had not noticed the sound issue, in the above script I have added the option --no-audio in line 237, so that it plays without sound (it is less crazy). That change is not in the download.)

Example video: https://www.youtube.com/watch?v=JRSgHsVw7vQ
I am using an old version of MediaInfo, so I have decided to pack everything necessary for it to work, which also has to be all in the same directory, so that it works better. (The file is large because of mpv.exe and ffprobe.exe, as they are large in size.) https://mega.nz/file/ldRVhCTZ#ZiQFLdB15yal624M2BpYolotwNXP0H0413kj33YgwHc
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: AutoHotkey script for you: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Hi.

Changed the routine to know the time of the video. It no longer goes to the command line and writes a file, and then reads it. Now works with ffprobe and a function (it's at the end of the script) written and shared by jeeswg at https://www.autohotkey.com/boards/viewtopic.php?t=61925

You don't save time, but you avoid writing and deleting a file on the hard drive. :?

(Read the comments on lines 212 and 234 in case you want to make changes to the appearance and position of the video.)

Code: Select all

; Mouse over to the file to preview the content without clicking. Support ahk,txt,ini,jpg,jpeg,png,bmp,tif,mp4,gif,avi,ts,mkv format.
; You must enable "show file ext name" in explorer.
; You must activate the current screen (click), or when you switch between Explorer, desktop or TCM
; In Total Commander you have to activate (Click) when you change panel.
; You need to check "Show command line" in "configuration", "Layout", in Total Commander
; https://www.autohotkey.com/boards/viewtopic.php?t=90001
;================================================================
; Modified code to add a border to the image, created by Hellbent
; Total Commander support added by WetWare05
; https://www.autohotkey.com/boards/viewtopic.php?p=523384
;================================================================
#Requires AutoHotkey v1.1.33

SetBatchLines, -1
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
Thread, Interrupt, 0

CoordMode, Mouse, Screen

maxStr:=200
Global NoW, SetColor, MaxWidth, MaxHeight, Margin, Transp, SuspendTCM, SuspendDeskTop, OnlyKey, Reflect
NoW:=""

;=========================================================
 Menu, Tray, Icon, Resources\Group_4.ico
 ;Menu, Tray, Icon, shell32.dll, 132 ;Example of icon the DLL Library
 Menu, Tray, NoStandard
 Menu, tray, Add, TCM Image Preview, Nothing
 Menu, tray, Icon, TCM Image Preview, Resources\Group_4.ico
 Menu, Tray, Add
 Menu Tray, Add, Open Info, Tray_Open
 Menu Tray, Icon, Open Info, Resources\Info.ico
 Menu, tray, Add, &Reload this Script, Reloaded
 Menu, tray, Icon,&Reload this Script, Resources\2488.ico
 Menu, tray, Add, &Suspend Utility, Stanby
 Menu, tray, Icon,&Suspend Utility, Resources\Group_4_Red.ico
 Menu, Tray, Add
 Menu, tray, Add, Suspend Preview in TCM, StanbyTCM
 Menu, tray, Icon, Suspend Preview in TCM, Resources\TCommander.ico
 Menu, tray, Add, Suspend Preview in DeskTop, StanbyDeskTop
 Menu, tray, Icon, Suspend Preview in DeskTop, Resources\Explorer.ico
 Menu, tray, Add, Only Preview with RCtrl Key, OnlyKeyPress
 Menu, tray, Icon, Only Preview with RCtrl Key, Resources\Key.ico
 Menu, tray, Add, Mirror to Second Monitor, ReflectTwo
 Menu, tray, Icon, Mirror to Second Monitor, Resources\2220.ico
 Menu, Tray, Add
 Menu, tray, Add, Preview Setting, Config
 Menu, tray, Icon, Preview Setting, Resources\130.ico
 Menu, tray, Add, Frame Color, FrameColor
 Menu, tray, Icon, Frame Color, Resources\ColorEdit.ico
 Menu, Tray, Add
 Menu, tray, Add, Exit, Exit
 Menu, tray, Icon, Exit, shell32.dll, 132
 
if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 8, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  IniWrite, 230, NewConfig.ini, Preview_TCM, Transp
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
 }

ReadVar:
If !MaxWidth
 {
  IniRead, MaxWidth, NewConfig.ini, Preview_TCM, MaxWidth
 }
If !MaxHeight
 {
  IniRead, MaxHeight, NewConfig.ini, Preview_TCM, MaxHeight
 }
 If !Margin
 {
  IniRead, Margin, NewConfig.ini, Preview_TCM, Margin
 }
If !SetColor
 {
  IniRead, SetColor, NewConfig.ini, Preview_TCM, SetColor
 }
If !Transp
 {
  IniRead, Transp, NewConfig.ini, Preview_TCM, Transp
 }
If !SuspendDeskTop
 {
  IniRead, SuspendDeskTop, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
If !SuspendTCM
 {
  IniRead, SuspendTCM, NewConfig.ini, Preview_TCM, SuspendTCM
 }
 If !OnlyKey
 {
  IniRead, OnlyKey, NewConfig.ini, Preview_TCM, OnlyKey
 }
 If !Reflect
 {
  IniRead, Reflect, NewConfig.ini, Preview_TCM, Reflect
 }
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth
   
 If SuspendTCM=0
  {
   Menu, Tray, Check, Suspend Preview in TCM
  }
  
  If SuspendDeskTop=0
  {
   Menu, Tray, Check, Suspend Preview in DeskTop
  }
  
  If OnlyKey=0
  {
   Menu, Tray, Check, Only Preview with RCtrl Key
  }
  
  If Reflect=1
  {
   Menu, Tray, Check, Mirror to Second Monitor
  }

 ;==========================================================

SetTimer, preview, 50

init:
SizeMon := []
SysGet, numDisplays, 80
Loop % numDisplays {
  SysGet, Mon, Monitor, %A_Index%
  SizeMon.Push([Monleft, MonRight, MonTop, MonBottom])
 }
  
 If Reflect=1
 {
 ActMon:= MWAGetMonitor()
  
  If ActMon=1
   {
    MaxWidth:= SizeMon[2,2]-SizeMon[1,2]
    MaxHeight:= SizeMon[2,4]
   }
   
  If ActMon=2
   {
    MaxWidth:= SizeMon[1,2]
    MaxHeight:= SizeMon[1,4]
   } 
 }
 
; close system file info tip.
RegRead, ShowInfoTip, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip
RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, 0
pToken := Gdip_Startup()
OnExit, GdipExit
PreviewWindow := CreatePreviewWindow( MaxWidth , MaxHeight )
return

CreatePreviewWindow( Width , Height ){
	local Obj := {}
	Critical
	Gui, New, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
	Obj.Hwnd := hPreview
	try Gui, Show, NA
	Obj.Width := Width
	Obj.Height := Height
	Obj.hbm  := CreateDIBSection( Obj.Width , Obj.Height )
	Obj.hdc  := CreateCompatibleDC()
	Obj.obm  := SelectObject( Obj.hdc , Obj.hbm )
	Obj.G    := Gdip_GraphicsFromHDC( Obj.hdc )
	Gdip_SetInterpolationMode( Obj.G , 0)
	
	return obj
}

preview:
if A_IsSuspended=0
{
 Current := GetFileUnderMouse()

  if (Displayed != Current.Path)
  {
    Displayed := Current.Path
    Ext       := Current.Ext
    if Ext in ahk,txt,ini
    {
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
      File := FileOpen(Current.Path, "r")
      btt(File.Read(maxStr),,,,"Style5")
      File.Close()
    }
    else if Ext in jpg,jpeg,png,bmp,tif
    {
      btt()
      Process, Close, mpv.exe
      ShowPreview( Current.Path , PreviewWindow )
    }      
    Else if Ext in mp4,gif,avi,ts,mkv
    {
      Path:= % Current.Path
      MouseGetPos, xMov, yMov
      xMov:= xMov+10
      ;yMov:= yMov-285
      yMov:= yMov-560 ; Reduce this number if the display is less than 970
      Process, Close, mpv.exe      
      Duration:= "Video;%Duration%"      
      vGblPathFFprobe := "ffprobe.exe"
      vProperty := "format=duration"
      vTarget := Chr(34) vGblPathFFprobe Chr(34) " -v error -show_entries " vProperty " -of default=noprint_wrappers=1:nokey=1 " Chr(34) Path Chr(34)
      FullTime:= RTrim(JEE_RunGetStdOut(vTarget))
      CutTime:= Round(FullTime)
      TimeS1:= Round(CutTime/6)      
            
      FilmPath= `";%Path%`"
      Count1:= TimeS1
      Count1:= FilmPath ",length=1,start=" Count1
      Count2:= TimeS1*2
      Count2:= FilmPath ",length=1,start=" Count2
      Count3:= TimeS1*3
      Count3:= FilmPath ",length=1,start=" Count3
      Count4:= TimeS1*4
      Count4:= FilmPath ",length=1,start=" Count4
      Count5:= TimeS1*5
      Count5:= FilmPath ",length=1,start=" Count5
      ;Total:= "--loop --ontop --window-scale=0.5 --no-audio --geometry=" xMov ":" yMov " edl://" Count1 Count2 Count3 Count4 Count5
      Total:= "--loop --ontop --autofit=970x-1 --no-audio --geometry=" xMov ":" yMov " edl://" Count1 Count2 Count3 Count4 Count5 ;command --autofit=970x-1 sets the width of the video window, to reduce, go down from 970 to 720, 640 or 320
      run, %comspec% /c mpv %Total% ,, Hide            
           
      SetTimer, MediaOff, 9500
      Path:=""      
     }
    else
    {
      btt()
      UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc, , , , , 0)
    }
  }
 }
return

MediaOff:
Process, Close, mpv.exe
Return

ShowPreview( Path , PreviewWindow ){
	
	pBitmap := Gdip_CreateBitmapFromFile( path )
	Bwidth := Gdip_GetImageWidth( pBitmap )
	Bheight := Gdip_GetImageHeight( pBitmap )
	
	MaxWidth := PreviewWindow.Width - 2 * Margin
	MaxHeight := PreviewWindow.Height - 2 * Margin
	
	if( BWidth > MaxWidth ){
		Width := MaxWidth
		Height := MaxWidth * ( BHeight / BWidth )
		
		if( Height > MaxHeight ){
			Height := MaxHeight
			Width := MaxHeight * ( BWidth / BHeight )
		}
		
	}else if( BHeight > MaxHeight ){
		Height := MaxHeight
		Width := MaxHeight * ( BWidth / BHeight )

	}else{
		Width := BWidth
		Height := BHeight
	}
			
      If Reflect=0
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 2 * Margin , height + 2 * Margin )
	Gdip_DeleteBrush( Brush )
	
	Gdip_DrawImage( PreviewWindow.G , pBitmap , Margin , Margin , width , height )
	MouseGetPos, x, y	
       }
     
     If Reflect=1
       {
	Gdip_GraphicsClear( PreviewWindow.G )
	Brush := Gdip_BrushCreateSolid( SetColor )
	GDIP_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , PreviewWindow.Width , PreviewWindow.Height )
	Gdip_DeleteBrush( Brush )
	Gdip_DrawImage( PreviewWindow.G , pBitmap , ( PreviewWindow.Width - width ) / 2 , ( PreviewWindow.Height - height ) / 2 , width , height )	
      }	
	
     	SizeMon := []
	SysGet, numDisplays, 80

	Loop % numDisplays {
	 SysGet, Mon, Monitor, %A_Index%
	 SizeMon.Push( [Monleft, MonRight, MonTop, MonBottom] )
	StateMon:=1
	}
	
      If Reflect=1
       {
	ActMon:= MWAGetMonitor()
  
        If ActMon=1
         {
	  x:= (SizeMon[1,2]+1)
	  y:= SizeMon[2,3]
	 }
        If ActMon=2
         {
	  x:= SizeMon[1,1]
	  y:= SizeMon[1,3]
	 }      
       }
            
      If Reflect=0
	{
	ActMon:= MWAGetMonitor()
	Over=0
	NewPos=0
	xOffSet:=16
	yOffSet:=16
	
       If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
	
	TempTop:= SizeMon[ActMon,3]
	TempY:= y-Height
	If (TempY<0 or TempY<TempTop)
	{
	 Over:=1
	 NewPos:=1
	}
	
       Marg:=margin*4 ;5
       xt:= x+Width
       
       if (xt>SizeMon[ActMon,2])
	 {
	  x:= (SizeMon[ActMon,2]-Width)-marg
	  If Over=0
	   {
	    y:= y-50
	   }
	  }
       }	  
               	
	If (NewPos=1 && Reflect=0)
	 {	  
	  UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , y+yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	 }
	
	If (Reflect=0 and NewPos=0)
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x+xOffSet , (y-Height)-yOffSet , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp )
	}
	If Reflect=1
	{
	 UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x , y , PreviewWindow.Width , PreviewWindow.Height , Alpha := 255 ) ;Alpha := Transp
	}
  }

GdipExit:
  RegWrite, REG_DWORD, HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced, ShowInfoTip, %ShowInfoTip%
  Gdip_DisposeImage(pBitmap)
  Gdip_DeleteGraphics(G)
  SelectObject(hdc, obm)
  DeleteDC(hdc)
  DeleteObject(hbm)
	Gdip_Shutdown(pToken)
	ExitApp
return

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=69925 and https://www.autohotkey.com/boards/viewtopic.php?t=51788
GetFileUnderMouse()
{
  static Windows:=ComObjCreate("Shell.Application").Windows

  MouseGetPos, , , hwnd, CtrlClass
  WinGetClass, WinClass, ahk_id %hwnd%

try if (WinClass = "TTOTAL_CMD" && CtrlClass = "LCLListBox1" or CtrlClass = "LCLListBox2" or CtrlClass = "TMyListBox1" or CtrlClass = "TMyListBox2" or CtrlClass = "LCLListBox") ; or CtrlClass = "SysListView321" or CtrlClass = "SysListView32"
 {
  SendMessage, 1074, 1000, , , ahk_class TTOTAL_CMD
  SendMessage, 1074, 8 + ErrorLevel, , , ahk_class TTOTAL_CMD
  ControlGetText, TargetPath, , ahk_id %ErrorLevel%
  sPath := SubStr(TargetPath, 1, InStr(TargetPath, "\", , 0) - 1)

If (OnlyKey=0 and SuspendTCM=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4|gif|avi|ts|mkv)", reg)

   Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

If (OnlyKey=1 and SuspendTCM=1)
 {
 oAcc := Acc_ObjectFromPoint(ChildID)
 Name := ChildID ? oAcc.accName(ChildID) : ""
 RegExMatch(Name, "^(.*)\.(jpg|jpeg|png|bmp|tif|mp4|gif|avi|ts|mkv)", reg)
    
  Test:=RegExMatch(Name, "^[a-zA-Z]:\\")

       If Test=0
	{
	 FullPath:= sPath Reg
	}

       If Test=1
	{
	 FullPath:= Reg
	}
  
        SplitPath, FullPath, , , OutExtension, OutNameNoExt
        ret := {}
        If Test=0
	 {
	  ret.Path := sPath "\" Reg
	 }
	If Test=1
	 {	
	  ret.Path := Reg  
	 }	
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt
        return, ret
  }
}

  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    If SuspendDeskTop=0
   {
    Return
   }
   
  If (OnlyKey=0 and SuspendDeskTop=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
    oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
      }
    }
   }
  If (OnlyKey=1 and SuspendDeskTop=1)
  {
  oAcc := Acc_ObjectFromPoint()
    Name := Acc_Parent(oAcc).accValue(0)
    NonNull(Name, oAcc.accValue(0))

    if (Name="")
      return

    for window in Windows
      if (window.hwnd = hwnd)
      {
        FolderPath := RegExReplace(window.Document.Folder.Self.Path, "(\w+?\:)\\$", "$1") ; “d:\” 转换为 “d:” — “d:\” convertido a “d:”

        SplitPath, Name, , , OutExtension, OutNameNoExt
        ret := {}
        ret.Path := FolderPath "\" Name
        ret.Ext  := OutExtension
        ret.Name := OutNameNoExt

        return, ret
     }
   }
  }
     
  if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    If SuspendDeskTop=0
   {
    Return
   }
   
  If (OnlyKey=0 and SuspendDeskTop=1)
 {
GetKeyState, state, RCtrl
if (state = "D")
{
    oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
   }
  }
 }
If (OnlyKey=1 and SuspendDeskTop=1)
{
oAcc := Acc_ObjectFromPoint(ChildID)
    Name := ChildID ? oAcc.accName(ChildID) : ""

    if (Name="")
      return

    SplitPath, Name, , , OutExtension, OutNameNoExt
    ret := {}
    ret.Path := A_Desktop "\" Name
    ret.Ext  := OutExtension
    ret.Name := OutNameNoExt

    return, ret
 }
}

Acc_Init() {
	Static h
	If Not h
		h:=DllCall("LoadLibrary","Str","oleacc","Ptr")
}
Acc_ObjectFromPoint(ByRef _idChild_ = "", x = "", y = "") {
	Acc_Init()
	If	DllCall("oleacc\AccessibleObjectFromPoint", "Int64", x==""||y==""?0*DllCall("GetCursorPos","Int64*",pt)+pt:x&0xFFFFFFFF|y<<32, "Ptr*", pacc, "Ptr", VarSetCapacity(varChild,8+2*A_PtrSize,0)*0+&varChild)=0
	Return ComObjEnwrap(9,pacc,1), _idChild_:=NumGet(varChild,8,"UInt")
}
Acc_Parent(Acc) { 
	try parent:=Acc.accParent
	return parent?Acc_Query(parent):
}
Acc_Query(Acc) { ; thanks Lexikos - www.autohotkey.com/forum/viewtopic.php?t=81731&p=509530#509530
	try return ComObj(9, ComObjQuery(Acc,"{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}

NotifyTrayClick(P*) {              ;  v0.41 by SKAN on D39E/D39N @ tiny.cc/notifytrayclick
Static Msg, Fun:="NotifyTrayClick", NM:=OnMessage(0x404,Func(Fun),-1),  Chk,T:=-250,Clk:=1
  If ( (NM := Format(Fun . "_{:03X}", Msg := P[2])) && P.Count()<4 )
     Return ( T := Max(-5000, 0-(P[1] ? Abs(P[1]) : 250)) )
  Critical
  If ( ( Msg<0x201 || Msg>0x209 ) || ( IsFunc(NM) || Islabel(NM) )=0 )
     Return
  Chk := (Fun . "_" . (Msg<=0x203 ? "203" : Msg<=0x206 ? "206" : Msg<=0x209 ? "209" : ""))
  SetTimer, %NM%,  %  (Msg==0x203        || Msg==0x206        || Msg==0x209)
    ? (-1, Clk:=2) : ( Clk=2 ? ("Off", Clk:=1) : ( IsFunc(Chk) || IsLabel(Chk) ? T : -1) )
Return True
}

; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
;	Color Dialog Example script.
;^!F8::
FrameColor:
stringRight, RSix, SetColor, 6
TColor:="0x" RSix
R:= (TColor&0xFF0000)>>16, G:= (TColor&0x00FF00)>>8, B:= TColor&0xFF

RGBval:=RGB(Rval:= R, Gval:= G, Bval:= B)
;Create Color Dialog GUI
Gui, Add, Text, x0 y10 w40 h20 +Right, Red
Gui, Add, Text, x0 y30 w40 h20 +Right, Green
Gui, Add, Text, x0 y50 w40 h20 +Right, Blue
Gui, Add, Slider, x40 y10 w190 h20 AltSubmit +NoTicks +Range0-255 vsR gSliderSub, %Rval%
Gui, Add, Slider, x40 y30 w190 h20 AltSubmit +NoTicks +Range0-255 vsG gSliderSub, %Gval%
Gui, Add, Slider, x40 y50 w190 h20 AltSubmit +NoTicks +Range0-255 vsB gSliderSub, %Bval%
Gui, Add, Edit, x230 y10 w45 h20 gEditSub veR +Limit3 +Number, %Rval%
Gui, Add, UpDown, Range0-255 vuR gUpDownSub, %Rval%
Gui, Add, Edit, x230 y30 w45 h20 gEditSub veG +Limit3 +Number, %Gval%
Gui, Add, UpDown, Range0-255 vuG gUpDownSub, %Gval%
Gui, Add, Edit, x230 y50 w45 h20 gEditSub veB +Limit3 +Number, %Bval%
Gui, Add, UpDown, Range0-255 vuB gUpDownSub, %Bval%
Gui, Add, Progress, x285 y10 w60 h60 +Border Background%RGBval% vpC
Gui, Add, Text, x285 y10 w60 h60 +Border vtP cWhite +BackgroundTrans, Preview
Gui, Add, Button, x120 y80 w110 h20 vbS gButtonSub, Select Color ;Copy to Clipboard
Gui, Show, w351 h105, Simple Color Dialog
return

EditSub:
	;Get Values
	GuiControlGet,Rval,,eR
	GuiControlGet,Gval,,eG
	GuiControlGet,Bval,,eB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

UpDownSub:
	;Get Values
	GuiControlGet,Rval,,uR
	GuiControlGet,Gval,,uG
	GuiControlGet,Bval,,uB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,sR,%Rval%
	GuiControl,,sG,%Gval%
	GuiControl,,sB,%Bval%
return

SliderSub:
	;Get Values
	GuiControlGet,Rval,,sR
	GuiControlGet,Gval,,sG
	GuiControlGet,Bval,,sB
	;Set preview
	gosub set
	;Make Everything else aware
	GuiControl,,eR,%Rval%
	GuiControl,,eG,%Gval%
	GuiControl,,eB,%Bval%
	GuiControl,,uR,%Rval%
	GuiControl,,uG,%Gval%
	GuiControl,,uB,%Bval%
return

set:
	;Convert values to Hex
	RGBval:=RGB(Rval,Gval,Bval)
	;Display Tooltip
	ToolTip Red: %Rval%`nGreen: %Gval%`nBlue: %Bval%`nHex: %RGBval%
	;Make tooltip disappear after 375 ms (3/8th of a second)
	SetTimer, RemoveToolTip, 375
	;Apply colour to preview
	GuiControl,+Background%RGBval%,pC
return

RemoveToolTip:
	SetTimer, RemoveToolTip, Off ;Turn timer off
	ToolTip ;Turn off tooltip
return

ButtonSub:
 ;Remove '0x' prefix to hex color code, saving it directly to the clipboard
 ;StringReplace,Clipboard,RGBval,0x99
 StringReplace,SetColor,RGBval,0x
 SetColor:="0x99" SetColor
 ;MsgBox, % SetColor . " " . RGBval
 ;Display Last selected values... (these values can later be used), and Notify the user
 ;MsgBox,64,Simple Color Dialog,RGB: (%Rval%, %Gval%, %Bval%)`nHex: %RGBval%`nCopied to Clipboard!
 ;Skip Directly GuiClose
 Gui, Destroy
Return

;^!s::
Config:
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: +HwndGuiID +AlwaysOnTop
Gui, Size: Add, Button, x300 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x300 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x5 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x95 y16 w60 h20 vFmaxW, %TempMaxW%
Gui, Size: Add, Text, x5 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x95 y46 w60 h20 vFmaxH, %TempMaxH%
Gui, Size: Add, Text, x170 y16 w70 h20, Transp.:
Gui, Size: Add, edit, x230 y16 w60 h20 vFtrans , %Transp%
Gui, Size: Add, Text, x170 y46 w70 h20, Margin :
Gui, Size: Add, edit, x230 y46 w60 h20 vFmarg , %margin%
Gui, Size: Show, x%xpos% y%ypos% h80 w370, Image Preview Configuration
Return

#If WinActive("ahk_id " GuiID)
Enter::
NumPadEnter::
NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxWidth:=500
 }
Else 
{
MaxWidth:=FmaxW
IniWrite, %MaxWidth%, NewConfig.ini, Preview_TCM, MaxWidth
}

If !FmaxH
 {
  MaxHeight:=500
 }
Else 
{
MaxHeight:=FmaxH
IniWrite, %MaxHeight%, NewConfig.ini, Preview_TCM, MaxHeight
}

If !Ftrans or Ftrans>256
 {
  Transp:=Transp
 }
Else 
{
Transp:=Ftrans
IniWrite, %Ftrans%, NewConfig.ini, Preview_TCM, Transp
}

If !Fmarg
 {
  Margin:=16
 }
Else 
{
Margin:=Fmarg
IniWrite, %Fmarg%, NewConfig.ini, Preview_TCM, Margin
}
Gui, Size: Destroy
Gosub, Init
Return

Cancel:
Gui, Size: Destroy
Return

~Esc:: ; *
Gosub, GdipExit
SetTimer, preview, off
Sleep, 1000
SetTimer, preview, On
Return

^Esc::
Exit:
ExitApp
Return

StanbyTCM:
Menu, Tray, ToggleCheck, Suspend Preview in TCM
If SuspendTCM=1 
 {
  SuspendTCM:=0
 ;TrayTip, TCM Image Preview, DISABLED,, 0x1, 0x10, 0x20
  SplashTextOn,200, 80, Notification, Preview in TCM Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendTCM
 }
Else
 {
  SuspendTCM:=1
  SplashTextOn,200, 80, Notification, Preview in TCM
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendTCM  
 }
Return

StanbyDeskTop:
Menu, Tray, ToggleCheck, Suspend Preview in DeskTop
Gosub, GdipExit
If SuspendDeskTop=1 
 {
  SuspendDeskTop:=0
  SplashTextOn,200, 80, Notification, Preview in DeskTop Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Else
 {
  SuspendDeskTop:=1
  SplashTextOn,200, 80, Notification, Preview in DeskTop
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, SuspendDeskTop
 }
Return

OnlyKeyPress:
Menu, Tray, ToggleCheck, Only Preview with RCtrl Key
If OnlyKey=1 
 {
  OnlyKey:=0
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_I.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 0, NewConfig.ini, Preview_TCM, OnlyKey
 }
Else
 {
  OnlyKey:=1
  SplashTextOn,200, 80, Notification, Only Preview with RCtrl Key Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  IniWrite, 1, NewConfig.ini, Preview_TCM, OnlyKey
 }
Return

ReflectTwo:
Menu, Tray, ToggleCheck, Mirror to Second Monitor
If Reflect=1 
 {
  SplashTextOn,200, 80, Notification, Mirror to Second Monitor Off
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  SoundPlay, Resources\State_U.mp3
  Sleep, 1500
  SplashTextOff
  Reflect:=0
  MaxWidth:=""
  MaxHeight:=""
  IniWrite, 0, NewConfig.ini, Preview_TCM, Reflect
  MaxWidth:=""
  MaxHeight:=""  
  Gosub, ReadVar
 }
Else
 {
 Reflect:=1
 SplashTextOn,200, 80, Notification, Mirror to Second Monitor
 xSplash1 := A_ScreenWidth-206
 ySplash1 := A_ScreenHeight-180
 WinMove, Notification,, xSplash1, ySplash1
 SoundPlay, Resources\State_I.mp3
 Sleep, 1500
 SplashTextOff
 IniWrite, 1, NewConfig.ini, Preview_TCM, Reflect
 
 MaxWidth:=""
 MaxHeight:="" 
 Gosub, ReadVar 
 }
Return

^p::
NotifyTrayClick_201:
Gosub, Stanby
Return

;^F12::
Stanby:
Suspend:=!Suspend
IfEqual,Suspend,1, Menu,Tray,Icon, Resources\Group_4_Red.ico
IfEqual,Suspend,0, Menu,Tray,Icon, Resources\Group_4.ico
Menu,Tray,Icon,,,1
Suspend,Toggle

if A_IsSuspended=1
 {
  Menu, tray, Check, &Suspend Utility
  SoundPlay, Resources\State_U.mp3 
  SetTimer, preview, off
  SplashTextOn,200, 80, Notification, Application has Been Deactivated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff  
 }
  
if A_IsSuspended=0
 {
  Menu, tray, Uncheck, &Suspend Utility
  SoundPlay, Resources\State_I.mp3
  SetTimer, preview, On
  SplashTextOn,200, 80, Notification, Application has Been Activated
  xSplash1 := A_ScreenWidth-206
  ySplash1 := A_ScreenHeight-180
  WinMove, Notification,, xSplash1, ySplash1
  Sleep, 1500
  SplashTextOff
  Sleep, 500  
 }  
Return

Reloaded:
Reload
Return

Tray_Open:
ListLines
return

Nothing:
Return
 
;Function to convert Decimal RGB to Hexadecimal RBG, Note: '0' (zero) padding is unnecessary
RGB(r, g, b) {
	;Shift Numbers
	var:=(r << 16) + (g << 8) + b
	;Save current A_FormatInteger
	OldFormat := A_FormatInteger
	;Set Hex A_FormatInteger mode
	SetFormat, Integer, Hex
	;Force decimal number to Hex number
	var += 0
	;set original A_FormatInteger mode
	SetFormat, Integer, %OldFormat%
	return var
}

; Funtion By Maestr0 https://www.autohotkey.com/boards/viewtopic.php?f=6&t=54557

MWAGetMonitor(Mx := "", My := "")
{
	if  (!Mx or !My) 
	{
		; if Mx or My is empty, revert to the mouse cursor placement
		Coordmode, Mouse, Screen	; use Screen, so we can compare the coords with the sysget information`
		MouseGetPos, Mx, My
	}

	SysGet, MonitorCount, 80	; monitorcount, so we know how many monitors there are, and the number of loops we need to do
	Loop, %MonitorCount%
	{
		SysGet, mon%A_Index%, Monitor, %A_Index%	; "Monitor" will get the total desktop space of the monitor, including taskbars

		if ( Mx >= mon%A_Index%left ) && ( Mx < mon%A_Index%right ) && ( My >= mon%A_Index%top ) && ( My < mon%A_Index%bottom )
		{
			ActiveMon := A_Index
			break
		}
	}
	return ActiveMon
}

;By jeeswg -> https://www.autohotkey.com/boards/viewtopic.php?t=61925
JEE_RunGetStdOut(vTarget, vSize:="")
{
	local
	static vComSpec := A_ComSpec ? A_ComSpec : ComSpec
	DetectHiddenWindows, On
	Run, % vComSpec,, Hide, vPID
	WinWait, % "ahk_pid " vPID
	DllCall("kernel32\AttachConsole", UInt,vPID)
	oShell := ComObjCreate("WScript.Shell")
	oExec := oShell.Exec(vTarget)
	vStdOut := ""
	if !(vSize = "")
		VarSetCapacity(vStdOut, vSize)
	while !oExec.StdOut.AtEndOfStream
		vStdOut := oExec.StdOut.ReadAll()
	DllCall("kernel32\FreeConsole")
	Process, Close, % vPID
	return vStdOut
}

#Include <NonNull>
#Include <Gdip_All>
Post Reply