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

English support forum

Moderators: white, Hacker, petermad, Stefan2

wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

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

Post by *wetware05 »

Hi.

I have adapted an AutoHotkey script, by user "tuzi", shared here: https://www.autohotkey.com/boards/viewtopic.php?t=90001 to be able to see previews in TCM.

limits or problems. Since the file path is taken from a Total Commander control, panel 1 or 2 must be activated for it to work. The cursor has to move over the file name, not in the empty spaces of the horizontal line of the file. Since the route is taken from a TCM check (on line 109), it can vary for each person. Using Autohotkey's "window Spy" utility, you have to choose the name of the control (text) that is next to the "command line", which is the one that shows the path of the active panel. In both Explorer and Total Commander, you must have enabled to see the file extensions.

It makes use of different libraries, everything you need is downloaded in this file: https://mega.nz/file/5RAUhCTR#GNZ7-6tbjYXVTIQoGc_4oepQIbQtNysO5IaAyVBihTo

With this other script you don't see the previews, unless you are pressing the control key (change if necessary on line 109). If you want some larger or smaller previews, it is changed in line 9.

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.
; 鼠标移动到文件上面,不用点击即可预览内容。支持 ahk,txt,ini,jpg,jpeg,png,bmp,tif 格式。
; 需要在 资源管理器-显示 中勾选 “文件扩展名” 选项。
;https://www.autohotkey.com/boards/viewtopic.php?t=90001

SetBatchLines, -1
CoordMode, Mouse, Screen
maxStr:=200, maxW:=500, maxH:=500

gosub, init
SetTimer, preview, 50

return

preview:
  Current := GetFileUnderMouse()

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

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

  Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
  Gui, Show, NA

  pToken := Gdip_Startup()
  OnExit, GdipExit

  hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)
  Gdip_SetInterpolationMode(G, 0)
return

displaypic:
  pBitmap := Gdip_CreateBitmapFromFile(Current.Path)
  Width   := Gdip_GetImageWidth(pBitmap)
  Height  := Gdip_GetImageHeight(pBitmap)
  ratio   := Width/Height

  if (ratio>=1)
  {
    dw:=maxW
    dh:=dw/ratio
  }
  else
  {
    dh:=maxH
    dw:=ratio*dh
  }

  Gdip_DrawImage(G, pBitmap, 0, 0, dw, dh)
  Gdip_DisposeImage(pBitmap)
  MouseGetPos, OutputVarX, OutputVarY
  UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, OutputVarY+16, dw, dh)
return

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::
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 TOTALCMD64.exe"){
GetKeyState, state, Ctrl
if (state = "D")
{
  ret:= UIA_Interface()
  ControlGetText sPath, Window7
  ;sPath:=StrReplace(sPath,">","\")
  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 = "DirectUIHWND3")
  {
    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:”

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

        return, ret
      }
  }
  else if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    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)
}

#Include <NonNull>
#Include <Gdip_All>
Example video.https://www.youtube.com/watch?v=YnHfgA3MERo
wetware05
Junior Member
Junior Member
Posts: 64
Joined: 2023-05-15, 16:10 UTC

Re: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Hi, emmafrost1, I'll take your suggestions into account. :wink:

I had the problem that control name changed in TCM. The following script keeps the name of the control in a variable. It adapts to each person and if TCM has changed the name of the control on the same computer (for it to work, in configuration, "show command line" must be activated).

(Lines 9 or 10 can be alternated (or to suit each one) to determine the size of the images to display.)

I have noticed that it has the error that if a graph with alpha channel (transparency) is displayed, it shows the previous graph behind it. Since I don't know how to handle the Gdip library, I don't know how to solve it.

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.
; 鼠标移动到文件上面,不用点击即可预览内容。支持 ahk,txt,ini,jpg,jpeg,png,bmp,tif 格式。
; 需要在 资源管理器-显示 中勾选 “文件扩展名” 选项。
;https://www.autohotkey.com/boards/viewtopic.php?t=90001

SetBatchLines, -1
CoordMode, Mouse, Screen
maxStr:=200, maxW:=1500, maxH:=1500
;maxStr:=200, maxW:=500, maxH:=500
Global NoW
NoW=""

gosub, init
SetTimer, preview, 50

return

preview:
  Current := GetFileUnderMouse()

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

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

  Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
  Gui, Show, NA

  pToken := Gdip_Startup()
  OnExit, GdipExit

  hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)
  Gdip_SetInterpolationMode(G, 0)
return

displaypic:
  pBitmap := Gdip_CreateBitmapFromFile(Current.Path)
  Width   := Gdip_GetImageWidth(pBitmap)
  Height  := Gdip_GetImageHeight(pBitmap)
  ratio   := Width/Height

  if (ratio>=1)
  {
    dw:=maxW
    dh:=dw/ratio
  }
  else
  {
    dh:=maxH
    dw:=ratio*dh
  }

  Gdip_DrawImage(G, pBitmap, 0, 0, dw, dh)
  Gdip_DisposeImage(pBitmap)
  MouseGetPos, OutputVarX, OutputVarY
  UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, OutputVarY+16, dw, dh)
return

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::
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 TOTALCMD64.exe")
{
If NoW=""
 {
Loop, 30
 {
 NewWin:= "Window" A_Index
 ControlGetText PPath, % NewWin
 StringRight, RLast, PPath, 1
  If RLast=>
   {
   NoW:= NewWin
   Break 
   }
  }
 }
 
GetKeyState, state, Ctrl
 if (state = "D")
 {
  ret:= UIA_Interface()
 
  ControlGetText sPath, % NoW
  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 = "DirectUIHWND3")
  {
    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:”

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

        return, ret
      }
  }
  else if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    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)
}

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

Re: File preview (thumbnail) in Total Commander

Post by *wetware05 »

Hi :wink:

I have made changes to the script. Now the image preview does not go outside the monitor. On desktop it works fine with a single monitor (I have to check to work with multiple monitors, now it fails).

I have added to be able to change the previous size of the image. With the keyboard shortcut Ctrl+Alt+s a small screen will appear to change the maximum size of height and width.

This change will be written to a Config.ini file and read from it each time the Script is started. The name of the control is saved in the same way.

When it is started for the first time it will create the Config.ini file with the values ​​found between lines 17 to 19. Change the values ​​of those lines if you want to change the size or if you know that the name of the control is something else. The next times it will read the Config.ini file.

If you want to change the keyboard shortcut, go to line 264. Symbols used by AutoHotkey:

# = Windows key
^ = Control key
! = Alt key
+ = Shift key

Example: ^F3:: (Ctrl+F3) — +f:: (Shift+f) It is now ^!s:: (Ctrl+Alt+s)

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.
; 鼠标移动到文件上面,不用点击即可预览内容。支持 ahk,txt,ini,jpg,jpeg,png,bmp,tif 格式。
; 需要在 资源管理器-显示 中勾选 “文件扩展名” 选项。
;https://www.autohotkey.com/boards/viewtopic.php?t=90001
SetBatchLines, -1
CoordMode, Mouse, Screen
maxStr:=200 ;, maxW:=1500, maxH:=1500
;maxStr:=200, maxW:=500, maxH:=500
XSize:= A_ScreenWidth
YSize:= A_ScreenHeight
Global NoW
NoW=""

if !FileExist("Config.ini")
  {
  IniWrite, 500, Config.ini, Preview_TCM, maxW
  IniWrite, 500, Config.ini, Preview_TCM, maxH
  IniWrite, Window7, Config.ini, Preview_TCM, NoW
  }

If !maxW
 {
  IniRead, maxW, Config.ini, Preview_TCM, maxW
 }
If !maxH
 {
  IniRead, maxH, Config.ini, Preview_TCM, maxH
 }

gosub, init
SetTimer, preview, 50
return

preview:
  Current := GetFileUnderMouse()

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

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

  Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
  Gui, Show, NA

  pToken := Gdip_Startup()
  OnExit, GdipExit

  hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)
  Gdip_SetInterpolationMode(G, 0)
return

displaypic:
  pBitmap := Gdip_CreateBitmapFromFile(Current.Path)
  Width   := Gdip_GetImageWidth(pBitmap)
  Height  := Gdip_GetImageHeight(pBitmap)
  ratio   := Round(Width/Height)

  if (ratio>=1)
  {
    dw:=Round(maxW)
    dh:=Round(dw/ratio)
  }
  else
  {
    dh:=Round(MaxH)
    dw:=Round(ratio*dh)
  }

  Gdip_DrawImage(G, pBitmap, 0, 0, dw, dh)
  Gdip_DisposeImage(pBitmap)
  MouseGetPos, OutputVarX, OutputVarY
  
  NewPos:=0
  
  PosY:= OutputVarY-dh
    If PosY < 0
    {
     ;StringTrimLeft, NPosY, PosY, 1
     ;OutPutVarY:= OutPutVarY+NPosY
     NewPos:=1
    }
  
  PosX:= OutputVarx+dw
    
    If PosX > %XSize%
    {
     NPosX:= PosX-XSize
     OutPutVarX:= OutPutVarX-NPosX
     ;NewPos:=1
    }
    
  If NewPos=0
   {
   UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, (OutputVarY-dh)-16, dw, dh)
   ;UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, (OutputVarY-dh)-6, dw, dh)
   }
  If NewPos=1
   {
   UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, OutputVarY+16, dw, dh)
   }
return

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::
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 TOTALCMD64.exe")
{

If NoW=""
 {
IniRead, Now, Config.ini, Preview_TCM, Now
ControlGetText PPath, % NoW

If !PPath
{
 Loop, 30
 {
 NewWin:= "Window" A_Index
 ControlGetText PPath, % NewWin
 StringRight, RLast, PPath, 1
  If RLast=>
   {
   NoW:= NewWin
   IniWrite, %NoW%, Config.ini, Preview_TCM, NoW
   Break 
   }
  }
 }
}
;Else NoW:= NewWin

GetKeyState, state, Ctrl
 if (state = "D")
 {
  ret:= UIA_Interface()
 
  ControlGetText sPath, % NoW
  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 = "DirectUIHWND3")
  {
    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:”

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

        return, ret
      }
  }
  else if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    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)
}

^!s::
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
;Gui, Search:+HwndGuiID	
Gui, Size: Add, Button, x225 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x225 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x10 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x100 y16 w100 h20 vFmaxW
Gui, Size: Add, Text, x10 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x100 y46 w100 h20 vFmaxH
Gui, Size: Show, x%xpos% y%ypos% h80 w300, Size_P
Return

Cancel:
Gui, Size: Destroy
Return

NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxW:=500
 }
Else MaxW:=FmaxW
IniWrite, %MaxW%, Config.ini, Preview_TCM, maxW

MaxW:=FmaxW
If !FmaxH
 {
  MaxH:=500
 }
Else MaxH:=FmaxH
IniWrite, %MaxH%, Config.ini, Preview_TCM, maxH
Gui, Size: Destroy
Return

#Include <NonNull>
#Include <Gdip_All>
On desktop the image preview is shown when you hover over the images, but in Total Commander you have to hold down the Control button. This key can be changed on line 181.

For it to work you have to download the libraries attached in the first post.
User avatar
Sir_SiLvA
Power Member
Power Member
Posts: 3278
Joined: 2003-05-06, 11:46 UTC

Re: File preview (thumbnail) in Total Commander

Post by *Sir_SiLvA »

wetware05 wrote: 2023-05-23, 23:50 UTC Hi :wink:
I have made changes to the script.For it to work you have to download the libraries attached in the first post.
I cant get this script to work :?:

My Setup:
AHK [folder]
- AHOld4Icons.exe - 64bit Exe, Version 1.1.34.4
- AutoHotkey32.exe - 32bit Exe, Version 2.0.2.0
- AutoHotkey64.exe - 64bit Exe, Version 2.0.2.0
- UX [folder]
- - Lib [folder] with the files from OP in it
- - Mouse over the file to preview.ahk the script

AutoHotkey32.exe & AutoHotkey64.exe break right away with an Error:

Code: Select all

Error: Function calls require a space or "(".  Use comma only between parameters.
Text:	SetBatchLines, -1
Line:	4
File:	T:\TotalCmd\Tools\SmallTools\AHK\ux\Mouse over the file (do not need click) to preview the contents.ahk
The program will exit.
AHOld4Icons.exe runs the file and I can call the size dialog with Ctrl+Alt+s but I got no hover over preview?

EDITH:
Okay script only works with old AutoHotkey and TC64 *facepalm* out of the box....
I changed try if WinActive( "ahk_exe TOTALCMD64.exe") to
try if WinActive( "ahk_exe TOTALCMD64.exe") || WinActive( "ahk_exe TOTALCMD.exe")
but even if I change NewWin:= "Window" A_Index to NewWin:= "TMyPanel" A_Index cant get it
to work for tc32.

Besides - sorry to say so - the whole scipt seems rather pointless in TC as activating thumbnails
with STRG+SHIFT+F1 (one hand), viewing files in quickview CTRL+Q (one hand) or even viewing the file
with F3 (one hand) is faster then having to press CTRL and moving the mouse (2 hands) :roll:

But its probably just me who dont understand the use of it :?:
Hoecker sie sind raus!
User avatar
white
Power Member
Power Member
Posts: 4594
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

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

Post by *white »

Moderator message from: white » 2023-05-25, 00:44 UTC

The post in this thread by emmafrost1 was an AI generated post. There were spamlinks in the signature and the user posted spamlinks in another post later.

I banned the account and deleted the posts.
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, Sir_SiLvA

I don't use the script. It was just a challenge (i'm not trying to sell anything). The original script is not mine, it is from an AutoHotkey user (tuzi). I challenged myself to make it work in Total Commander. (You have to try to feel like you are doing something useful, but the truth is that the whole existence is pretty useless.)

I don't use TCM preview either, I use Google's old Picasa image viewer, which they retired, but as a viewer I find it the best - simple, fast, elegant) and still downloadable.

It can be used without pressing the control key. But then the function would be annoying for everyday tasks with TCM, and that's why I added that option.

"Show command line" must be active for it to work. To its left TCM shows the path of the focused panel. If the panel is changed, it must be activated (click), so that the route changes and the script correctly acquires the new route. You could extract the path from the panel header, but then you would have to complicate the script to find out if you have panel 1 or 2 active and find which control corresponds to which panel. The basic problem is that TCM randomly assigns the name of the controls (except panels 1 and 2 which are called LCLListBox1 and LCLListBox2). For each person, the names of the controls change, depending on their configuration on the screen (from their personalized interface). The script automatically looks for control of the route. It has the error that in the first cycle it does not correctly return the name of the control and therefore the first time it does not show the image (I am looking for the reason).

(The cursor has to go through the name of the file, not its row)

You also have to have "view file extensions" enabled, as the script tries to filter files that are images (it also previews .txt and .ahk, I imagine it can be expanded to other file types).

Now I am trying to put a margin to the images (to isolate them from the background, it will be black or a color to choose, the width can also be chosen). But I only do it for entertainment.

(The script, as I shared it in its first version, was created for people with knowledge of TCM and AutoHotkey, so that they themselves would make the necessary changes. Now I am adapting it for less experienced people, but there will come a time when I will get bored and I will abandon it. The user of the original script himself abandoned that project. It is the "norm" in the new societies that he has not touched to live. Ghisler, the author of TMC is still in his fight to improve his product. Although it is possible that the new ones generations do not use it. I am an old person, I come from the time when I used Norton Commander from MS-Dos. Norton made the mistake of adapting his utility to Windows, but to the "old users" of the "Dos" version, we didn't like it and that's where Total Commander was born —first keeping the old name—)
User avatar
Sir_SiLvA
Power Member
Power Member
Posts: 3278
Joined: 2003-05-06, 11:46 UTC

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

Post by *Sir_SiLvA »

wetware05 wrote: 2023-05-25, 11:44 UTC I don't use the script. It was just a challenge (i'm not trying to sell anything). The original script is not mine, it is from an AutoHotkey user (tuzi). I challenged myself to make it work in AutoHotkey. (You have to try to feel like you are doing something useful, but the truth is that the whole existence is pretty useless.)
I didnt wanted to offend you.

Just tried to point out the downsides AND make it work for
a) AHK 2.0 no idea how, but I know we have some AHK guys in this forum you can hopefully make the according changes

b) TC64 and TC32
that is why I suggest to change
try if WinActive( "ahk_exe TOTALCMD64.exe")
to
try if WinActive( "ahk_exe TOTALCMD64.exe") || WinActive( "ahk_exe TOTALCMD.exe")
but I have no clue how to include Window7 = tc64 and TMyPanel3 = tc32
as
NewWin:= "Window" A_Index || "TMyPanel" A_Index
does not work. :?:
Hoecker sie sind raus!
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, Sir_SiLvA

Don't worry, I haven't been offended.

Now I understand what you mean. The non-X64 Total commander gives a different name to the control from which I extract the route (as you say, it is TMyPanelX). I have to do a different routine for when that possibility occurs. Maybe I'll have it figured out today.

The advice being given now, regarding Autohotkey, is to install version 1.1.36.02 and then version 2.0.2 (uninstalled previous versions). That way version 2 evaluates the script and makes it run with one kind of version or another. If it does not detect it, a dialog window appears to ask the user. It is also convenient to put in the script what version it is for, to avoid the process of detecting it.
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 »

Sir_SiLvA

There is a real mess in the script, I have to implement some error handling.

For now, in your case, you can solve it by opening the Config.ini file and if the line NoW=Window7 does not exist, add a new line: Now=TMyPanel3. If it exists, change it.
User avatar
Sir_SiLvA
Power Member
Power Member
Posts: 3278
Joined: 2003-05-06, 11:46 UTC

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

Post by *Sir_SiLvA »

wetware05 wrote: 2023-05-25, 15:24 UTC For now, in your case, you can solve it by opening the Config.ini file and if the line NoW=Window7
does not exist, add a new line: Now=TMyPanel3. If it exists, change it.
Thanks, I admit I am a AHK noob, but I read that :D My point was to make the script
a) Work with AHK 2 and b) work with TC32 and 64 both running at the same time
so that when someone see this thread in 10 years he can still use it :D
Hoecker sie sind raus!
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 »

Sir_SiLvA, how optimistic that a script, a utility or a program will work within 10 years. By then all the programs implied in the script will have changed and it will no longer work.

I have changed the way the script behaves. If both the X64 and X32 versions of Total Commander are used on the same computer, the script will work on both. It is very conflictive to save the path control name in the Config.ini file. It gives many problems when being able to use the two versions of TCM.

This script only works for version 1 of AutoHotkey. Adapting it to version 2 would take a lot of work and headaches, because the libraries used are for version 1 and adapting them would imply making the script almost from scratch. The optimum is to have both versions of AutoHotkey. The process goes through uninstalling all versions; install version 1 and then version 2. The end result is that all scripts from both versions will work.

Now it gives problems when working with two monitors, because of the changes I made to control that the images go off the monitor. I'm going to solve it.

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.
; 鼠标移动到文件上面,不用点击即可预览内容。支持 ahk,txt,ini,jpg,jpeg,png,bmp,tif 格式。
; 需要在 资源管理器-显示 中勾选 “文件扩展名” 选项。
;https://www.autohotkey.com/boards/viewtopic.php?t=90001
#Requires AutoHotkey v1.1.33
SetBatchLines, -1
CoordMode, Mouse, Screen
maxStr:=200 ;, maxW:=1500, maxH:=1500
;maxStr:=200, maxW:=500, maxH:=500
XSize:= A_ScreenWidth
YSize:= A_ScreenHeight
Global NoW
NoW:=""


if !FileExist("Config.ini")
  {
  IniWrite, 500, Config.ini, Preview_TCM, maxW
  IniWrite, 500, Config.ini, Preview_TCM, maxH
  ;IniWrite, Window7, Config.ini, Preview_TCM, NoW
  }

If !maxW
 {
  IniRead, maxW, Config.ini, Preview_TCM, maxW
 }
If !maxH
 {
  IniRead, maxH, Config.ini, Preview_TCM, maxH
 }

gosub, init
SetTimer, preview, 50
return

preview:
  Current := GetFileUnderMouse()

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

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
  
  Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HwndhPreview
  Gui, Show, NA

  pToken := Gdip_Startup()
  OnExit, GdipExit

  hbm  := CreateDIBSection(maxW, maxH)
  hdc  := CreateCompatibleDC()
  obm  := SelectObject(hdc, hbm)
  G    := Gdip_GraphicsFromHDC(hdc)
  Gdip_SetInterpolationMode(G, 0)
return

displaypic:
  pBitmap := Gdip_CreateBitmapFromFile(Current.Path)
  Width   := Gdip_GetImageWidth(pBitmap)
  Height  := Gdip_GetImageHeight(pBitmap)
  ratio   := Round(Width/Height)

  if (ratio>=1)
  {
    dw:=Round(maxW)
    dh:=Round(dw/ratio)
  }
  else
  {
    dh:=Round(MaxH)
    dw:=Round(ratio*dh)
  }

  Gdip_DrawImage(G, pBitmap, 0, 0, dw, dh)
  Gdip_DisposeImage(pBitmap)
  MouseGetPos, OutputVarX, OutputVarY
  
  NewPos:=0
  
  PosY:= OutputVarY-dh
    If PosY < 0
    {
     ;StringTrimLeft, NPosY, PosY, 1
     ;OutPutVarY:= OutPutVarY+NPosY
     NewPos:=1
    }
  
  PosX:= OutputVarx+dw
    
    If PosX > %XSize%
    {
     NPosX:= PosX-XSize
     OutPutVarX:= OutPutVarX-NPosX
     ;NewPos:=1
    }
    
  If NewPos=0
   {
   UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, (OutputVarY-dh)-16, dw, dh)
   ;UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, (OutputVarY-dh)-6, dw, dh)
   }
  If NewPos=1
   {
   UpdateLayeredWindow(hPreview, hdc, OutputVarX+16, OutputVarY+16, dw, dh)
   }
return

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::
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
  }
 }

GetKeyState, state, Ctrl
 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
  }
}
Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    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:”

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

        return, ret
      }
  }
  else if (WinClass = "Progman" || WinClass = "WorkerW")
  {
    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)
}

^!s::
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
;Gui, Search:+HwndGuiID	
Gui, Size: Add, Button, x225 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x225 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x10 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x100 y16 w100 h20 vFmaxW
Gui, Size: Add, Text, x10 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x100 y46 w100 h20 vFmaxH
Gui, Size: Show, x%xpos% y%ypos% h80 w300, Size_P
Return

Cancel:
Gui, Size: Destroy
Return

NewSize:
Gui, Size: Submit
If !FmaxW
 {
  MaxW:=500
 }
Else MaxW:=FmaxW
IniWrite, %MaxW%, Config.ini, Preview_TCM, maxW

MaxW:=FmaxW
If !FmaxH
 {
  MaxH:=500
 }
Else MaxH:=FmaxH
IniWrite, %MaxH%, Config.ini, Preview_TCM, maxH
Gui, Size: Destroy
Return

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

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

#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:

Changes I have made. A border has been added to the preview image. Added a dialog to change the border. Now the preview image has transparency. Now you no longer need to press the control key. But to make it easy to disable this utility, clicking on the dash icon will disable it.

It remains to include the ability to change the width of the border and the level of transparency. Due to issues with the new changes, images will fall off the screen if they are on the edge. Pending to resolve.

I share what I have so far from the script. All the more complex work is from Hellbent https://www.autohotkey.com/boards/viewtopic.php?f=76&t=117630modifying tuzi script https://www.autohotkey.com/boards/viewtopic.php?t=90001. My part is to have adapted it for Total Commander and to have created routine code.

I wanted to have created a DropDownList (or DDL) to select the color, but I found a GUI with slide controls to select a color, credit to joedf https://www.autohotkey.com/boards/viewtopic.php?t=65.

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.
; 鼠标移动到文件上面,不用点击即可预览内容。支持 ahk,txt,ini,jpg,jpeg,png,bmp,tif 格式。
; 需要在 资源管理器-显示 中勾选 “文件扩展名” 选项。
;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.

CoordMode, Mouse, Screen

maxStr:=200
XSize:= A_ScreenWidth
YSize:= A_ScreenHeight
;SetColor:= 0x99FFFF00
Global NoW, SetColor, MaxWidth, MaxHeight, Margin, XSize, YSize
NoW:=""

if !FileExist("NewConfig.ini")
  {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 16, NewConfig.ini, Preview_TCM, Margin
  IniWrite, 0x99FFFF00, NewConfig.ini, Preview_TCM, SetColor
  ;IniWrite, Window7, NewConfig.ini, Preview_TCM, NoW
  }

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
 }
 

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 := 500 , MaxHeight := 500 )
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() ;<<--No idea what this does
      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 )
	
	;Margin := 16
	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_FillRectangle( PreviewWindow.G , Brush , 0 , 0 , width + 5 * Margin , height + 5 * 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
	
	UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height , Alpha := 230) ;draw the graphics onto the window and reposition it at an offset of the cursor.
	Gdip_DisposeImage( pBitmap ) ;delete the bitmap to free memory.
}

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
  }
 }

;GetKeyState, state, Ctrl
 ;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
  }
;}
Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    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")
  {
    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
}

^!s::
Xpos:= Floor((A_ScreenWidth/2)-450)
Ypos:= Floor((A_ScreenHeight/2)-200)
Gui, Size: Add, Button, x225 y16 w65 h20 GNewSize, OK
Gui, Size: Add, Button, x225 y46 w65 h20 gCancel, Cancel
Gui, Size: Font, S9 Bold, Verdana
Gui, Size: Add, Text, x10 y16 w90 h20, Max. Width:
Gui, Size: Add, edit, x100 y16 w100 h20 vFmaxW
Gui, Size: Add, Text, x10 y46 w90 h20, Max.   High:
Gui, Size: Add, edit, x100 y46 w100 h20 vFmaxH
Gui, Size: Show, x%xpos% y%ypos% h80 w300, Size_P
Return

Cancel:
Gui, Size: Destroy
Return

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
}
Gui, Size: Destroy
Gosub, Init
Return

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

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

;
; AutoHotkey Version: 1.1.12.00
; Language:       English
; Dev Platform:   Windows 7 Home Premium x64
; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
; Date:           August 20th, 2013
;
; Script Function:
;	Color Dialog Example script.
;
;<<<<<<<<  HEADER END  >>>>>>>>>

;Set starting default value to RGB(44,197,89), Just a random colour
RGBval:=RGB(Rval:=44,Gval:=197,Bval:=89)

^!F8::
;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

;GuiClose:
	;Exit This Example script
;	ExitApp

;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
}

#Include <NonNull>
#Include <Gdip_All>
Demonstration of use:
[urlhttps://www.youtube.com/watch?v=npIccPN93KI[/url]

The necessary libraries are shared above.
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.

Added in the configuration Gui the possibility to change the level of transparency (0=transparent 256=opaque) and the width of the border. Now the GUI of the color selection appears with the current color (I don't know if this utility works well, since if you slide all the controls to the left, the result is not a black border, but a non-existent one, for black you have to bring the controls—together—a third of the way down the slider).

Changed so that image previews don't go off screen (on single screen computers; pending review for multiple monitors).

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.
; 鼠标移动到文件上面,不用点击即可预览内容。支持 ahk,txt,ini,jpg,jpeg,png,bmp,tif 格式。
; 需要在 资源管理器-显示 中勾选 “文件扩展名” 选项。
;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.

CoordMode, Mouse, Screen

maxStr:=200
XSize:= A_ScreenWidth
YSize:= A_ScreenHeight
Global NoW, SetColor, StateC, MaxWidth, MaxHeight, Margin, XSize, YSize, StateC, Mode, Transp, NameControl, ChangeN
NoW:=""

if !FileExist("NewConfig.ini")
 {
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxWidth
  IniWrite, 500, NewConfig.ini, Preview_TCM, MaxHeight
  IniWrite, 16, 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
 }

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
 } 
 
 TempMaxH:= MaxHeight
 TempMaxW:= MaxWidth 

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
	
	Over=0
	NewPos=""
	xOffSet:=16
	yOffSet:=16
	
	If Margin => 15
	{
	 yOffSet:=35
	}
	
	If Margin > 30
	{
	 yOffSet:=70
	}
		
	Py:= y
	TempY:= y - Height
	If TempY < 0
	{
	 Over:=1
	 NewPos:=1
	}
	
	Marg:=margin*4 ;5
	xt:= x+Width
	If xt > %XSize%
	 {
	  NPosX:= xt-XSize
	  x:= (x-NPosX)-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 )
	
	;UpdateLayeredWindow( PreviewWindow.Hwnd , PreviewWindow.hdc , x + 16 , y + 16 , PreviewWindow.Width , PreviewWindow.Height , Alpha := Transp ) ;draw the graphics onto the window and reposition it at an offset of the cursor.
	;Gdip_DisposeImage( pBitmap ) ;delete the bitmap to free memory.
}

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
  }
 }

;GetKeyState, state, Ctrl
 ;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
  }
;}
Else
  try if (WinClass = "CabinetWClass" && CtrlClass = "DirectUIHWND2")
  {
    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")
  {
    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
}
;
; AutoHotkey Version: 1.1.12.00
; Language:       English
; Dev Platform:   Windows 7 Home Premium x64
; Author:         Joe DF  |  http://joedf.co.nr  |  joedf@users.sourceforge.net
; Date:           August 20th, 2013
;
; Script Function:
;	Color Dialog Example script.
;
;<<<<<<<<  HEADER END  >>>>>>>>>

;Set starting default value to RGB(44,197,89), Just a random colour
;RGBval:=RGB(Rval:=44,Gval:=197,Bval:=89)

^!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

;GuiClose:
	;Exit This Example script
;	ExitApp

;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
}

#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 »

Adapted the script so that it works with several monitors, and that the previews of the images do not leave the margins of the current monitor.

I am considering making the image under the mouse full screen on the second monitor. Another option is to show all image thumbnails, from the current panel, on the second monitor.

———New file with everything you need—————
Last edited by wetware05 on 2023-06-03, 10:14 UTC, edited 1 time in total.
User avatar
white
Power Member
Power Member
Posts: 4594
Joined: 2003-11-19, 08:16 UTC
Location: Netherlands

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

Post by *white »

2wetware05
I don't know if you know this but on this board, you can always edit the first post of a thread you started. So if you wish to do so, you can update the script in the first post rather than to post each new version of your script in a new post.
Post Reply