Jump to content

Desktop Icon Caption Names Not Matching Progman Coords


Go to solution Solved by ioa747,

Recommended Posts

Posted

I was trying to match up the desktop's icon coords with their names and there are few posts but it seems something changed with X64.

This creates a desktop sized gui with red dots marking the icons location and supposed text of what the icon caption should be.  Any ideas so that the coords match the icon names?

 

 

Opt("MustDeclareVars", 1)

#include <GDIPlus.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

Global $oShell = ObjCreate("Shell.Application")
Global $oDesktop = $oShell.Namespace(0).Items
Global Const $SC_DRAGMOVE = 0xF012

HotKeySet("{ESC}", _Exit)

_GDIPlus_Startup()
Local $aCoordsOfIcons = _DisplayIconPositions()
CreateGUIwMarks($aCoordsOfIcons)

Func CreateGUIwMarks($aCoords)
        Global $myWidth = @DesktopWidth
        Global $myHeight = @DesktopHeight
        Global $hGUI = GUICreate('', $myWidth, $myHeight, 0, 0, $WS_POPUP, $WS_EX_LAYERED)
        GUISetState()

        ;-- Setup Shape (Small Circle)
        Global $hBitmap = _GDIPlus_BitmapCreateFromScan0($myWidth, $myHeight)
        Global $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBrushShape = _GDIPlus_BrushCreateSolid(0xFFFF0000)
        Global $hBrushText = _GDIPlus_BrushCreateSolid(0xFF000000)
        ;Global $hPen = _GDIPlus_PenCreate(0xFFFF0000, 4) ; Red pen color
        ;_GDIPlus_GraphicsDrawEllipse($hGraphic, 130, 100, 140, 70, $hPen)
        ;_GDIPlus_GraphicsFillEllipse($hGraphic, 0, 0, 10, 10, $hBrushShape)
        ;_GDIPlus_GraphicsFillEllipse($hGraphic, 980, 980, 10, 10, $hBrushShape)

        ;-- Setup String
        Global $hFormat = _GDIPlus_StringFormatCreate()
        Global $hFamily = _GDIPlus_FontFamilyCreate("Calibri")
        Global $hFont = _GDIPlus_FontCreate($hFamily, 9, 0)
      _GDIPlus_GraphicsSetTextRenderingHint($hBuffer, 4)
      _GDIPlus_GraphicsSetSmoothingMode($hBuffer, 4)

        For $aa = 0 To UBound($aCoords) - 1
            ;-- Add Shape
            _GDIPlus_GraphicsFillEllipse($hGraphic, $aCoords[$aa][0], $aCoords[$aa][1], 10, 10, $hBrushShape)

            ;-- Add String
            Global $tLayout = _GDIPlus_RectFCreate($aCoords[$aa][0]+7, $aCoords[$aa][1], 75, 15) ; x,y,w,h (orig w:0/h:0 for unlimited)
            _GDIPlus_GraphicsDrawStringEx($hGraphic, $aCoords[$aa][2], $hFont, $tLayout, $hFormat, $hBrushText)
        Next


        _GDIPlus_GraphicsDispose($hGraphic)
        Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap, $hGUI, 255)
        GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

        While 1
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    _Exit()
            EndSwitch
        WEnd
EndFunc

Func _DisplayIconPositions()
    Local $hListView = _GetDesktopListView()
    If $hListView = 0 Then
        MsgBox(0, "Error", "Unable to get desktop ListView handle.")
        Exit
    EndIf

    Local $iCount = _GUICtrlListView_GetItemCount($hListView)
    Local $sOutput = ""
    Local $sName, $aPos

    Local $aCoords[0][3]
    For $i = 0 To $iCount - 1
        $sName = _GetDesktopItemName($i)
        $aPos = _GUICtrlListView_GetItemPosition($hListView, $i)
        $sOutput &= "Icon Name: " & $sName & " - Position: (" & $aPos[0] & ", " & $aPos[1] & ")" & @CRLF
         _ArrayAdd($aCoords, $aPos[0]  & "|" & $aPos[1] & "|" & $sName)
    Next

    MsgBox(0, "Icon Positions: " & $iCount, $sOutput)
    Return $aCoords
EndFunc

Func _GetDesktopListView()
    Local $hProgman = WinGetHandle("[CLASS:Progman]")
    Local $hWorkerW = 0
    Local $hSHELLDLL_DefView = _GetSHELLDLL_DefView($hProgman)
    Local $hListView = 0

    If $hSHELLDLL_DefView <> 0 Then
        $hListView = ControlGetHandle($hSHELLDLL_DefView, "", "[CLASS:SysListView32; INSTANCE:1]")
    EndIf

    ; If failed to get handle from Progman, try WorkerW
    If $hListView = 0 Then
        $hWorkerW = WinGetHandle("[CLASS:WorkerW]")
        $hSHELLDLL_DefView = _GetSHELLDLL_DefView($hWorkerW)
        If $hSHELLDLL_DefView <> 0 Then
            $hListView = ControlGetHandle($hSHELLDLL_DefView, "", "[CLASS:SysListView32; INSTANCE:1]")
        EndIf
    EndIf

    If $hListView = 0 Then
        MsgBox(0, "Error", "Failed to get Desktop ListView handle.")
    Else
        ;MsgBox(0, "Success", "ListView handle obtained successfully: " & $hListView)
    EndIf

    Return $hListView
EndFunc

Func _GetSHELLDLL_DefView($hParent)
    Local $hSHELLDLL_DefView = 0
    Local $aWin = _WinAPI_EnumChildWindows($hParent, 0)

    For $i = 1 To $aWin[0][0]
        If _WinAPI_GetClassName($aWin[$i][0]) = "SHELLDLL_DefView" Then
            $hSHELLDLL_DefView = $aWin[$i][0]
            ExitLoop
        EndIf
    Next

    Return $hSHELLDLL_DefView
EndFunc

Func _GetDesktopItemName($index)
    If $index < $oDesktop.Count Then
        Return $oDesktop.Item($index).Name
    Else
        Return "[No Name]"
    EndIf
EndFunc

Func _EnumChildWindows($hWndParent, $iMaxDepth, $iDepth, ByRef $aArray, ByRef $iCount)
    Local $hChild = _WinAPI_GetWindow($hWndParent, $GW_CHILD)

    While $hChild <> 0
        $iCount += 1
        ReDim $aArray[$iCount + 1][2]
        $aArray[$iCount][0] = $hChild
        $aArray[$iCount][1] = _WinAPI_GetClassName($hChild)

        If $iDepth < $iMaxDepth Then
            _EnumChildWindows($hChild, $iMaxDepth, $iDepth + 1, $aArray, $iCount)
        EndIf

        $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT)
    Wend

    $aArray[0][0] = $iCount
EndFunc

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc

Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
EndFunc   ;==>_WM_LBUTTONDOWN

Func _Exit()
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
    Exit
EndFunc

 

Posted (edited)

Thanks @ioa747 but I couldn’t make heads or tails with where I could match up the coordinates with the icon names from that code and if that code really even extracts the icon names or just sorts them by position 

Edited by NassauSky
Posted (edited)

me with win10 when I run the script, it gives me an error :
(124) : ==> Subscript used on non-accessible variable.:
For $i = 1 To $aWin[0][0]
For $i = 1 To $aWin^ ERROR

which is due to the inability to find the correct Desktop Handle

Edit:

that's how it worked

; https://www.autoitscript.com/forum/topic/211931-desktop-icon-caption-names-not-matching-progman-coords/?do=findComment&comment=1534232

Opt("MustDeclareVars", 1)

#include <GDIPlus.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

Global $oShell = ObjCreate("Shell.Application")
Global $oDesktop = $oShell.Namespace(0).Items
Global Const $SC_DRAGMOVE = 0xF012

HotKeySet("{ESC}", _Exit)

_GDIPlus_Startup()
Local $aCoordsOfIcons = _DisplayIconPositions()
CreateGUIwMarks($aCoordsOfIcons)

Func CreateGUIwMarks($aCoords)
        Global $myWidth = @DesktopWidth
        Global $myHeight = @DesktopHeight
        Global $hGUI = GUICreate('', $myWidth, $myHeight, 0, 0, $WS_POPUP, $WS_EX_LAYERED)
        GUISetState()

        ;-- Setup Shape (Small Circle)
        Global $hBitmap = _GDIPlus_BitmapCreateFromScan0($myWidth, $myHeight)
        Global $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBrushShape = _GDIPlus_BrushCreateSolid(0xFFFF0000)
        Global $hBrushText = _GDIPlus_BrushCreateSolid(0xFF000000)
        ;Global $hPen = _GDIPlus_PenCreate(0xFFFF0000, 4) ; Red pen color
        ;_GDIPlus_GraphicsDrawEllipse($hGraphic, 130, 100, 140, 70, $hPen)
        ;_GDIPlus_GraphicsFillEllipse($hGraphic, 0, 0, 10, 10, $hBrushShape)
        ;_GDIPlus_GraphicsFillEllipse($hGraphic, 980, 980, 10, 10, $hBrushShape)

        ;-- Setup String
        Global $hFormat = _GDIPlus_StringFormatCreate()
        Global $hFamily = _GDIPlus_FontFamilyCreate("Calibri")
        Global $hFont = _GDIPlus_FontCreate($hFamily, 9, 0)
      _GDIPlus_GraphicsSetTextRenderingHint($hBuffer, 4)
      _GDIPlus_GraphicsSetSmoothingMode($hBuffer, 4)

        For $aa = 0 To UBound($aCoords) - 1
            ;-- Add Shape
            _GDIPlus_GraphicsFillEllipse($hGraphic, $aCoords[$aa][0], $aCoords[$aa][1], 10, 10, $hBrushShape)

            ;-- Add String
            Global $tLayout = _GDIPlus_RectFCreate($aCoords[$aa][0]+7, $aCoords[$aa][1], 75, 15) ; x,y,w,h (orig w:0/h:0 for unlimited)
            _GDIPlus_GraphicsDrawStringEx($hGraphic, $aCoords[$aa][2], $hFont, $tLayout, $hFormat, $hBrushText)
        Next


        _GDIPlus_GraphicsDispose($hGraphic)
        Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap, $hGUI, 255)
        GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

        While 1
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    _Exit()
            EndSwitch
        WEnd
EndFunc

Func _DisplayIconPositions()
    Local $hListView = _GetDesktopListView()
    If $hListView = 0 Then
        MsgBox(0, "Error", "Unable to get desktop ListView handle.")
        Exit
    EndIf

    Local $iCount = _GUICtrlListView_GetItemCount($hListView)
    Local $sOutput = ""
    Local $sName, $aPos

    Local $aCoords[0][3]
    For $i = 0 To $iCount - 1
        $sName = _GetDesktopItemName($i)
        $aPos = _GUICtrlListView_GetItemPosition($hListView, $i)
        $sOutput &= "Icon Name: " & $sName & " - Position: (" & $aPos[0] & ", " & $aPos[1] & ")" & @CRLF
         _ArrayAdd($aCoords, $aPos[0]  & "|" & $aPos[1] & "|" & $sName)
    Next

    MsgBox(0, "Icon Positions: " & $iCount, $sOutput)
    Return $aCoords
EndFunc

Func _GetDesktopListView()
    Local $hDesktop = _WinGetDesktopHandle()
    Local $hListView = ControlGetHandle($hDesktop, "", "[CLASS:SysListView32;INSTANCE:1]")
    Return $hListView
EndFunc

Func _GetDesktopItemName($index)
    If $index < $oDesktop.Count Then
        Return $oDesktop.Item($index).Name
    Else
        Return "[No Name]"
    EndIf
EndFunc

Func _EnumChildWindows($hWndParent, $iMaxDepth, $iDepth, ByRef $aArray, ByRef $iCount)
    Local $hChild = _WinAPI_GetWindow($hWndParent, $GW_CHILD)

    While $hChild <> 0
        $iCount += 1
        ReDim $aArray[$iCount + 1][2]
        $aArray[$iCount][0] = $hChild
        $aArray[$iCount][1] = _WinAPI_GetClassName($hChild)

        If $iDepth < $iMaxDepth Then
            _EnumChildWindows($hChild, $iMaxDepth, $iDepth + 1, $aArray, $iCount)
        EndIf

        $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT)
    Wend

    $aArray[0][0] = $iCount
EndFunc

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc

Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
EndFunc   ;==>_WM_LBUTTONDOWN

Func _Exit()
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
    Exit
EndFunc

;----------------------------------------------------------------------------------------
;  https://www.autoitscript.com/forum/topic/119783-desktop-class-workerw/#comment-903081
; <_WinGetDesktopHandle.au3>
; Function to get the Windows' Desktop Handle.
;   Since this is no longer a simple '[CLASS:Progman]' on Aero-enabled desktops, this method uses a slightly
;   more involved method to find the correct Desktop Handle.
;
; Author: Ascend4nt, credits to Valik for pointing out the Parent->Child relationship: Desktop->'SHELLDLL_DefView'
;----------------------------------------------------------------------------------------
Func _WinGetDesktopHandle()
    Local $i, $hDeskWin, $hSHELLDLL_DefView, $h_Listview_Configs, $aWinList
    ; The traditional Windows Classname for the Desktop, not always so on newer O/S's
    $hDeskWin = WinGetHandle("[CLASS:Progman]")
    ; Parent->Child relationship: Desktop->SHELLDLL_DefView
    $hSHELLDLL_DefView = ControlGetHandle($hDeskWin, '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]')
    ; No luck with finding the Desktop and/or child?
    If $hDeskWin = '' Or $hSHELLDLL_DefView = '' Then
        ; Look through a list of WorkerW windows - one will be the Desktop on Windows 7+ O/S's
        $aWinList = WinList("[CLASS:WorkerW]")
        For $i = 1 To $aWinList[0][0]
            $hSHELLDLL_DefView = ControlGetHandle($aWinList[$i][1], '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]')
            If $hSHELLDLL_DefView <> '' Then
                $hDeskWin = $aWinList[$i][1]
                ExitLoop
            EndIf
        Next
    EndIf
    ; Parent->Child relationship: Desktop->SHELDLL_DefView->SysListView32
    $h_Listview_Configs = ControlGetHandle($hSHELLDLL_DefView, '', '[CLASS:SysListView32; INSTANCE:1]')
    If $h_Listview_Configs = '' Then Return SetError(-1, 0, '')
    Return SetExtended($h_Listview_Configs, $hDeskWin)
EndFunc   ;==>_WinGetDesktopHandle
;----------------------------------------------------------------------------------------

 

Edited by ioa747

I know that I know nothing

Posted

Not sure what the issue truly is.  First there is way too much useless code in OP based on the thread title.  Second I feel the way you are trying to solve the issue is disconnected with the real problem.  Maybe refocussing on the strict minimum code would help to find a solution,.. But good luck to you anyway.

Posted

@ioa747 thanks for the sample code. It seems to be functioning the same as mine. The icon text isn't matching what's at the coords.

 

@Nine Yes I'm going to skim the code a bit. The visualization was to clearly see that the text is not matching the coordinates. 😕

 

Thanks for the tips so far

  • Solution
Posted (edited)
1 hour ago, NassauSky said:

The icon text isn't matching what's at the coords

 

; https://www.autoitscript.com/forum/topic/211931-desktop-icon-caption-names-not-matching-progman-coords/?do=findComment&comment=1534232
#AutoIt3Wrapper_UseX64=y

Opt("MustDeclareVars", 1)

#include <GDIPlus.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

;~ Global $oShell = ObjCreate("Shell.Application")
;~ Global $oDesktop = $oShell.Namespace(0).Items
Global Const $SC_DRAGMOVE = 0xF012

HotKeySet("{ESC}", _Exit)

_GDIPlus_Startup()

Local $aCoordsOfIcons = _DisplayIconPositions()
;~ _ArrayDisplay($aCoordsOfIcons)

CreateGUIwMarks($aCoordsOfIcons)

Func CreateGUIwMarks($aCoords)
        Global $myWidth = @DesktopWidth
        Global $myHeight = @DesktopHeight
        Global $hGUI = GUICreate('', $myWidth, $myHeight, 0, 0, $WS_POPUP, $WS_EX_LAYERED)
        GUISetState()

        ;-- Setup Shape (Small Circle)
        Global $hBitmap = _GDIPlus_BitmapCreateFromScan0($myWidth, $myHeight)
        Global $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBrushShape = _GDIPlus_BrushCreateSolid(0xFFFF0000)
        Global $hBrushText = _GDIPlus_BrushCreateSolid(0xFF000000)
        ;Global $hPen = _GDIPlus_PenCreate(0xFFFF0000, 4) ; Red pen color
        ;_GDIPlus_GraphicsDrawEllipse($hGraphic, 130, 100, 140, 70, $hPen)
        ;_GDIPlus_GraphicsFillEllipse($hGraphic, 0, 0, 10, 10, $hBrushShape)
        ;_GDIPlus_GraphicsFillEllipse($hGraphic, 980, 980, 10, 10, $hBrushShape)

        ;-- Setup String
        Global $hFormat = _GDIPlus_StringFormatCreate()
        Global $hFamily = _GDIPlus_FontFamilyCreate("Calibri")
        Global $hFont = _GDIPlus_FontCreate($hFamily, 9, 0)
      _GDIPlus_GraphicsSetTextRenderingHint($hBuffer, 4)
      _GDIPlus_GraphicsSetSmoothingMode($hBuffer, 4)

        For $aa = 0 To UBound($aCoords) - 1
            ;-- Add Shape
            _GDIPlus_GraphicsFillEllipse($hGraphic, $aCoords[$aa][0], $aCoords[$aa][1], 10, 10, $hBrushShape)

            ;-- Add String
            Global $tLayout = _GDIPlus_RectFCreate($aCoords[$aa][0]+7, $aCoords[$aa][1], 75, 15) ; x,y,w,h (orig w:0/h:0 for unlimited)
            _GDIPlus_GraphicsDrawStringEx($hGraphic, $aCoords[$aa][2], $hFont, $tLayout, $hFormat, $hBrushText)
        Next


        _GDIPlus_GraphicsDispose($hGraphic)
        Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap, $hGUI, 255)
        GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

        While 1
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    _Exit()
            EndSwitch
        WEnd
EndFunc

Func _DisplayIconPositions()
    Local $hListView = _GetDesktopListView()
    If $hListView = 0 Then
        MsgBox(0, "Error", "Unable to get desktop ListView handle.")
        Exit
    EndIf

    Local $iCount = _GUICtrlListView_GetItemCount($hListView)
    Local $sOutput = ""
    Local $sName, $aPos

    Local $aCoords[0][3]
    For $i = 0 To $iCount - 1
        $sName = _GUICtrlListView_GetItemText($hListView, $i)
        $aPos = _GUICtrlListView_GetItemPosition($hListView, $i)
        $sOutput &= "Icon Name: " & $sName & " - Position: (" & $aPos[0] & ", " & $aPos[1] & ")" & @CRLF
         _ArrayAdd($aCoords, $aPos[0]  & "|" & $aPos[1] & "|" & $sName)
    Next

    Return $aCoords
EndFunc

Func _GetDesktopListView()
    Local $hDesktop = _WinGetDesktopHandle()
    Local $hListView = ControlGetHandle($hDesktop, "", "[CLASS:SysListView32;INSTANCE:1]")
    Return $hListView
EndFunc

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc

Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
EndFunc   ;==>_WM_LBUTTONDOWN

Func _Exit()
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
    Exit
EndFunc

;----------------------------------------------------------------------------------------
;  https://www.autoitscript.com/forum/topic/119783-desktop-class-workerw/#comment-903081
; <_WinGetDesktopHandle.au3>
; Function to get the Windows' Desktop Handle.
;   Since this is no longer a simple '[CLASS:Progman]' on Aero-enabled desktops, this method uses a slightly
;   more involved method to find the correct Desktop Handle.
;
; Author: Ascend4nt, credits to Valik for pointing out the Parent->Child relationship: Desktop->'SHELLDLL_DefView'
;----------------------------------------------------------------------------------------
Func _WinGetDesktopHandle()
    Local $i, $hDeskWin, $hSHELLDLL_DefView, $h_Listview_Configs, $aWinList
    ; The traditional Windows Classname for the Desktop, not always so on newer O/S's
    $hDeskWin = WinGetHandle("[CLASS:Progman]")
    ; Parent->Child relationship: Desktop->SHELLDLL_DefView
    $hSHELLDLL_DefView = ControlGetHandle($hDeskWin, '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]')
    ; No luck with finding the Desktop and/or child?
    If $hDeskWin = '' Or $hSHELLDLL_DefView = '' Then
        ; Look through a list of WorkerW windows - one will be the Desktop on Windows 7+ O/S's
        $aWinList = WinList("[CLASS:WorkerW]")
        For $i = 1 To $aWinList[0][0]
            $hSHELLDLL_DefView = ControlGetHandle($aWinList[$i][1], '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]')
            If $hSHELLDLL_DefView <> '' Then
                $hDeskWin = $aWinList[$i][1]
                ExitLoop
            EndIf
        Next
    EndIf
    ; Parent->Child relationship: Desktop->SHELDLL_DefView->SysListView32
    $h_Listview_Configs = ControlGetHandle($hSHELLDLL_DefView, '', '[CLASS:SysListView32; INSTANCE:1]')
    If $h_Listview_Configs = '' Then Return SetError(-1, 0, '')
    Return SetExtended($h_Listview_Configs, $hDeskWin)
EndFunc   ;==>_WinGetDesktopHandle
;----------------------------------------------------------------------------------------

 

 

Edited by ioa747

I know that I know nothing

Posted (edited)

@ioa747 yep that's the code I used to position the red markers over each icon.  That's not the problem. Those coordinate markers match the positions on the screen of each icon. I am more concerned about getting the icon caption for each position. I can't find any working examples.

I'm still trying to figure it out why the below code is matching the coords with the text incorrectly on 2 PC's I've tested so far. Both PC's have over 30 icons mixed with network links, URL's, folders apps etc.

This is the closest I got without the GUI (since the GUI is just to confirm the icon text matches the coords)

Opt("MustDeclareVars", 1)

#include <Array.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <MsgBoxConstants.au3>
#include <File.au3>

Global $oShell = ObjCreate("Shell.Application")
Global $oDesktop = $oShell.Namespace(0).Items

_DisplayIconPositions()

Func _DisplayIconPositions()
    Local $hListView = _GetDesktopListView()
    If $hListView = 0 Then
        MsgBox(0, "Error", "Unable to get desktop ListView handle.")
        Exit
    EndIf

    Local $iCount = _GUICtrlListView_GetItemCount($hListView)
    Local $sOutput = ""
    Local $sName, $aPos

    Local $sDesktopPath = ObjCreate("WScript.Shell").SpecialFolders("Desktop")
    Local $aFiles = _FileListToArray($sDesktopPath, "*.*", 1)

    If @error Then
        MsgBox($MB_SYSTEMMODAL, "", "Error: No files/directories matched the search pattern.")
        Exit
    EndIf

    For $i = 1 To $aFiles[0]
        $sName = $aFiles[$i]
        $aPos = _GUICtrlListView_GetItemPosition($hListView, $i - 1)
        If Not IsArray($aPos) Then
            ContinueLoop
        EndIf
        $sOutput &= "Icon Name: " & $sName & " - Position: (" & $aPos[0] & ", " & $aPos[1] & ")" & @CRLF
    Next

    MsgBox(0, "Icon Positions", $sOutput)
EndFunc

Func _GetDesktopListView()
    Local $hProgman = WinGetHandle("[CLASS:Progman]")
    Local $hWorkerW = 0
    Local $hSHELLDLL_DefView = _GetSHELLDLL_DefView($hProgman)
    Local $hListView = 0

    If $hSHELLDLL_DefView <> 0 Then
        $hListView = ControlGetHandle($hSHELLDLL_DefView, "", "[CLASS:SysListView32; INSTANCE:1]")
    EndIf

    ; If failed to get handle from Progman, try WorkerW
    If $hListView = 0 Then
        $hWorkerW = WinGetHandle("[CLASS:WorkerW]")
        $hSHELLDLL_DefView = _GetSHELLDLL_DefView($hWorkerW)
        If $hSHELLDLL_DefView <> 0 Then
            $hListView = ControlGetHandle($hSHELLDLL_DefView, "", "[CLASS:SysListView32; INSTANCE:1]")
        EndIf
    EndIf

    Return $hListView
EndFunc

Func _GetSHELLDLL_DefView($hParent)
    Local $hSHELLDLL_DefView = 0
    Local $aWin = _WinAPI_EnumChildWindows($hParent, 0)

    For $i = 1 To $aWin[0][0]
        If _WinAPI_GetClassName($aWin[$i][0]) = "SHELLDLL_DefView" Then
            $hSHELLDLL_DefView = $aWin[$i][0]
            ExitLoop
        EndIf
    Next

    Return $hSHELLDLL_DefView
EndFunc

 

Edited by NassauSky
Posted (edited)

You could also use UIAutomation :

#include "Includes\CUIAutomation2.au3"

Opt("MustDeclareVars", True)

; Create UI Automation object
Local $oUIAutomation = ObjCreateInterface($sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation)
If Not IsObj($oUIAutomation) Then Exit ConsoleWrite("$oUIAutomation ERR" & @CRLF)
;ConsoleWrite("$oUIAutomation OK" & @CRLF)

; Get Desktop element
Local $pDesktop, $oDesktop
$oUIAutomation.GetRootElement($pDesktop)
$oDesktop = ObjCreateInterface($pDesktop, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
If Not IsObj($oDesktop) Then Exit ConsoleWrite("$oDesktop ERR" & @CRLF)
;ConsoleWrite("$oDesktop OK" & @CRLF)

; Get Shell
Local $pCondition, $pShell, $oShell
$oUIAutomation.CreatePropertyCondition($UIA_ClassNamePropertyId, "Progman", $pCondition)
$oDesktop.FindFirst($TreeScope_Children, $pCondition, $pShell)
$oShell = ObjCreateInterface($pShell, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
If Not IsObj($oShell) Then Exit ConsoleWrite("$oShell ERR" & @CRLF)
;ConsoleWrite("$oShell OK" & @CRLF)

; Get all icons
Local $pElementArray, $oElementArray, $iElements, $pElement, $oElement
$oUIAutomation.CreatePropertyCondition($UIA_ControlTypePropertyId, $UIA_ListItemControlTypeId, $pCondition)
$oShell.FindAll($TreeScope_Descendants, $pCondition, $pElementArray)
$oElementArray = ObjCreateInterface($pElementArray, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray)
If Not IsObj($oElementArray) Then Exit ConsoleWrite("$oElementArray ERR" & @CRLF)
$oElementArray.Length($iElements)
;ConsoleWrite("$oElementArray OK" & @CRLF)
;ConsoleWrite($iElements & @CRLF)

Local $sValue, $tRect = DllStructCreate("long Left;long Top;long Right;long Bottom")
For $i = 0 To $iElements - 1
  $oElementArray.GetElement($i, $pElement)
  $oElement = ObjCreateInterface($pElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)

  $oElement.GetCurrentPropertyValue($UIA_NamePropertyId, $sValue)
  ConsoleWrite("Name: " & $sValue)
  $oElement.CurrentBoundingRectangle($tRect)
  ConsoleWrite(" -- L:" & $tRect.Left & " T:" & $tRect.Top & " R:" & $tRect.Right & " B:" & $tRect.Bottom & @CRLF)
Next

 

Edited by Nine
Posted (edited)

@Nine, I did a quick test and that looks like it hit the jackpot. Thanks 😁 I'll work on that now.

@DennisFong222 I apologize what did I say that made you think I didn't research newer X64 options?  If you thought there was such an option specifically to extract Names w/Coords I'll be more than happy to study and test it out.

@ioa747 I apologize if I wasn't clear but I wasn't seeing the error "Subscript used on non-accessible variable" you saw when I tested it on my home and work PC's but then I did see the error on a 3rd PC. I also wasn't successful running the nice code that you provided and I provided a Screenshot1 below to display it was not showing icon names just the red marker positions.  After I modified it adding back the shell object thinking I can extract the icon names I was semi-successful in Screenshot2 below but that didn't sync up with the actual icon names when you compare the text at the top and bottom of the icons.

Good news is I have a plan to play with the UIA option which requires a large UDF but it so far is looking like the most reliable solution so far.

Test-Ioa.pngScreenshot 2 from Ioa747 suggestion adding shell object enum

Edited by NassauSky
Posted (edited)

So far looking real good. Thanks all and @Nine for the UIA solution.  This demo circles all the icon locations and displays the name above each icon to confirm the coords match the name.

Update 1: Just as I marked it as a solution since it was working perfect on my work PC, I logged into another user on the same PC and it's showing 0.  I'll have to debug this more...

Update 2: This is a second solution that does work but I had to make sure the x64 directive was running correctly by updating my Scite to the full version. I haven't tested but it will probably work also if it is just compiled as 64 bit.

 

#AutoIt3Wrapper_UseX64=Y
#include "Includes\CUIAutomation2.au3"
Opt("MustDeclareVars", True)



#include <GDIPlus.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <File.au3>


Global Const $SC_DRAGMOVE = 0xF012

HotKeySet("{ESC}", _Exit)

_GDIPlus_Startup()
Local $aCoordsOfIcons = UIA_GetIconInfo()
CreateGUIwMarks($aCoordsOfIcons)


Func UIA_GetIconInfo()

        ; Create UI Automation object
        Local $oUIAutomation = ObjCreateInterface($sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation)
        If Not IsObj($oUIAutomation) Then Exit ConsoleWrite("$oUIAutomation ERR" & @CRLF)
        ;ConsoleWrite("$oUIAutomation OK" & @CRLF)

        ; Get Desktop element
        Local $pDesktop, $oDesktop
        $oUIAutomation.GetRootElement($pDesktop)
        $oDesktop = ObjCreateInterface($pDesktop, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
        If Not IsObj($oDesktop) Then Exit ConsoleWrite("$oDesktop ERR" & @CRLF)
        ;ConsoleWrite("$oDesktop OK" & @CRLF)

        ; Get Shell
        Local $pCondition, $pShell, $oShell
        $oUIAutomation.CreatePropertyCondition($UIA_ClassNamePropertyId, "Progman", $pCondition)
        $oDesktop.FindFirst($TreeScope_Children, $pCondition, $pShell)
        $oShell = ObjCreateInterface($pShell, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
        If Not IsObj($oShell) Then Exit ConsoleWrite("$oShell ERR" & @CRLF)
        ;ConsoleWrite("$oShell OK" & @CRLF)

        ; Get all icons
        Local $pElementArray, $oElementArray, $iElements, $pElement, $oElement
        $oUIAutomation.CreatePropertyCondition($UIA_ControlTypePropertyId, $UIA_ListItemControlTypeId, $pCondition)
        $oShell.FindAll($TreeScope_Descendants, $pCondition, $pElementArray)
        $oElementArray = ObjCreateInterface($pElementArray, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray)
        If Not IsObj($oElementArray) Then Exit ConsoleWrite("$oElementArray ERR" & @CRLF)
        $oElementArray.Length($iElements)
        ;ConsoleWrite("$oElementArray OK" & @CRLF)
        ;ConsoleWrite($iElements & @CRLF)

        Local $aCoords[0][3] ; Collect Icon Info to Array
        Local $sValue, $tRect = DllStructCreate("long Left;long Top;long Right;long Bottom")
        For $i = 0 To $iElements - 1
          $oElementArray.GetElement($i, $pElement)
          $oElement = ObjCreateInterface($pElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)

          $oElement.GetCurrentPropertyValue($UIA_NamePropertyId, $sValue)
          ConsoleWrite("Name: " & $sValue)
          $oElement.CurrentBoundingRectangle($tRect)
          ConsoleWrite(" -- L:" & $tRect.Left & " T:" & $tRect.Top & " R:" & $tRect.Right & " B:" & $tRect.Bottom & @CRLF)
          _ArrayAdd($aCoords, $tRect.Left & "|" &$tRect.Top & "|" & $sValue)
        Next
        MsgBox(0, "Desktop Icon Count: ", $iElements)
        Return $aCoords
EndFunc ;==>UIA_GetIconInfo



Func CreateGUIwMarks($aCoords)
        Global $myWidth = @DesktopWidth
        Global $myHeight = @DesktopHeight
        Global $hGUI = GUICreate('', $myWidth, $myHeight, 0, 0, $WS_POPUP, $WS_EX_LAYERED)
        GUISetState()

        ;-- Setup Shape (Small Circle)
        Global $hBitmap = _GDIPlus_BitmapCreateFromScan0($myWidth, $myHeight)
        Global $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBrushShape = _GDIPlus_BrushCreateSolid(0xFFFF0000)
        Global $hBrushText = _GDIPlus_BrushCreateSolid(0xFF000000)
        Global $hPen = _GDIPlus_PenCreate(0xFFFF0000, 4) ; Red pen color
        ;_GDIPlus_GraphicsDrawEllipse($hGraphic, 130, 100, 140, 70, $hPen)
        ;_GDIPlus_GraphicsFillEllipse($hGraphic, 0, 0, 10, 10, $hBrushShape)
        ;_GDIPlus_GraphicsFillEllipse($hGraphic, 980, 980, 10, 10, $hBrushShape)

        ;-- Setup String
        Global $hFormat = _GDIPlus_StringFormatCreate()
        Global $hFamily = _GDIPlus_FontFamilyCreate("Calibri")
        Global $hFont = _GDIPlus_FontCreate($hFamily, 9, 0)
      _GDIPlus_GraphicsSetTextRenderingHint($hBuffer, 4)
      _GDIPlus_GraphicsSetSmoothingMode($hBuffer, 4)

        For $aa = 0 To UBound($aCoords) - 1
            ;-- Add Shape
            ;_GDIPlus_GraphicsFillEllipse($hGraphic, $aCoords[$aa][0], $aCoords[$aa][1], 10, 10, $hBrushShape)
            _GDIPlus_GraphicsDrawEllipse($hGraphic, $aCoords[$aa][0], $aCoords[$aa][1], 75, 60, $hPen)


            ;-- Add String
            Global $tLayout = _GDIPlus_RectFCreate($aCoords[$aa][0]+7, $aCoords[$aa][1], 75, 15) ; x,y,w,h (orig w:0/h:0 for unlimited)
            _GDIPlus_GraphicsDrawStringEx($hGraphic, $aCoords[$aa][2], $hFont, $tLayout, $hFormat, $hBrushText)
        Next


        _GDIPlus_GraphicsDispose($hGraphic)
        Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap, $hGUI, 255)
        GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

        While 1
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    _Exit()
            EndSwitch
        WEnd
EndFunc

Test-Nine.thumb.png.725524d3f77c91a325361e4a7c2391db.png

Edited by NassauSky
Posted

now that I saw the screenshots you posted,
it is probably the fault that you have the lite version and not the full version of scite

which means that the script did not run on 64 even though it had the directive  #AutoIt3Wrapper_UseX64=y
 

even though you found a tip with your script I would suggest you to upgrade to full  (which you find here SciTE4AutoIt3.exe)

I know that I know nothing

Posted

Thanks @ioa747 now that is working!  Interesting how the Scite lite didn't recognize that directive.

Sorry @Nine I got it to work on 3 PC's after I updated my Scite to the full version.

Both solutions seem nice for their specific uses. I am keeping a couple apps size down and will opt with the @ioa747 native solution for now not needed to add the extra UIA UDF libraries.

Thanks again!!

  • 5 weeks later...
Posted

I figured I'd paste the full code here since when I needed to use it again the code I provided earlier used UIA and wasn't working properly:

 

; https://www.autoitscript.com/forum/topic/211931-desktop-icon-caption-names-not-matching-progman-coords/?do=findComment&comment=1534232
#AutoIt3Wrapper_UseX64=y
If NOT @AutoItX64 Then
    MsgBox(0, "Script Mode", "Running in 32-bit mode" & @CRLF & "You need to run it in Scite Full or Compile it 64bit")
EndIf

#include <GDIPlus.au3>
#include <Array.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>

Opt("MustDeclareVars", 1)
Global Const $SC_DRAGMOVE = 0xF012
HotKeySet("{ESC}", _Exit)

_GDIPlus_Startup()
Local $aCoordsOfIcons = _DisplayIconPositions()
_ArrayDisplay($aCoordsOfIcons)

CreateGUIwCircles($aCoordsOfIcons)

Func CreateGUIwCircles($aCoords)
        Global $myWidth = @DesktopWidth
        Global $myHeight = @DesktopHeight
        Global $hGUI = GUICreate('', $myWidth, $myHeight, 0, 0, $WS_POPUP, $WS_EX_LAYERED)
        GUISetState()

        ;-- Setup Shape (Small Circle)
        Global $hBitmap = _GDIPlus_BitmapCreateFromScan0($myWidth, $myHeight)
        Global $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
        Global $hBrushShape = _GDIPlus_BrushCreateSolid(0xFFFF0000)
        Global $hBrushText = _GDIPlus_BrushCreateSolid(0xFF000000)
        Global $hPen = _GDIPlus_PenCreate(0xFFFF0000, 4) ; Red pen color

        ;-- Setup String
        Global $hFormat = _GDIPlus_StringFormatCreate()
        Global $hFamily = _GDIPlus_FontFamilyCreate("Calibri")
        Global $hFont = _GDIPlus_FontCreate($hFamily, 9, 0)
      _GDIPlus_GraphicsSetTextRenderingHint($hBuffer, 4)
      _GDIPlus_GraphicsSetSmoothingMode($hBuffer, 4)

        For $aa = 0 To UBound($aCoords) - 1
            ;-- Add Shape
            _GDIPlus_GraphicsDrawEllipse($hGraphic, $aCoords[$aa][0], $aCoords[$aa][1], 75, 60, $hPen)

            ;-- Add String
            Global $tLayout = _GDIPlus_RectFCreate($aCoords[$aa][0]+7, $aCoords[$aa][1], 75, 15) ; x,y,w,h (orig w:0/h:0 for unlimited)
            _GDIPlus_GraphicsDrawStringEx($hGraphic, $aCoords[$aa][2], $hFont, $tLayout, $hFormat, $hBrushText)
        Next

        _GDIPlus_GraphicsDispose($hGraphic)
        Global $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
        _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap, $hGUI, 255)
        GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")

        While 1
            Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                    _Exit()
            EndSwitch
        WEnd
EndFunc

Func _DisplayIconPositions()
    Local $hListView = _GetDesktopListView()
    If $hListView = 0 Then
        MsgBox(0, "Error", "Unable to get desktop ListView handle.")
        Exit
    EndIf

    Local $iCount = _GUICtrlListView_GetItemCount($hListView)
    Local $sOutput = ""
    Local $sName, $aPos

    Local $aCoords[0][3]
    For $i = 0 To $iCount - 1
        $sName = _GUICtrlListView_GetItemText($hListView, $i)
        $aPos = _GUICtrlListView_GetItemPosition($hListView, $i)
        $sOutput &= "Icon Name: " & $sName & " - Position: (" & $aPos[0] & ", " & $aPos[1] & ")" & @CRLF
         _ArrayAdd($aCoords, $aPos[0]  & "|" & $aPos[1] & "|" & $sName)
    Next

    Return $aCoords
EndFunc

Func _GetDesktopListView()
    Local $hDesktop = _WinGetDesktopHandle()
    Local $hListView = ControlGetHandle($hDesktop, "", "[CLASS:SysListView32;INSTANCE:1]")
    Return $hListView
EndFunc

Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $bReleaseGDI = True)
    If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0)
    Local $tDim = DllStructCreate($tagBITMAP)
    If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0)
    Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION)
    Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap)
    $tSize.X = $tDim.bmWidth
    $tSize.Y = $tDim.bmHeight
    $tBlend.Alpha = $iOpacity
    $tBlend.Format = 1
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteDC($hMemDC)
    If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap)
    Return True
EndFunc

Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0)
EndFunc   ;==>_WM_LBUTTONDOWN

Func _Exit()
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
    Exit
EndFunc

Func _WinGetDesktopHandle()
;----------------------------------------------------------------------------------------
;  https://www.autoitscript.com/forum/topic/119783-desktop-class-workerw/#comment-903081
; <_WinGetDesktopHandle.au3>
; Function to get the Windows' Desktop Handle.
;   Since this is no longer a simple '[CLASS:Progman]' on Aero-enabled desktops, this method uses a slightly
;   more involved method to find the correct Desktop Handle.
;
; Author: Ascend4nt, credits to Valik for pointing out the Parent->Child relationship: Desktop->'SHELLDLL_DefView'
;----------------------------------------------------------------------------------------

    Local $i, $hDeskWin, $hSHELLDLL_DefView, $h_Listview_Configs, $aWinList
    ; The traditional Windows Classname for the Desktop, not always so on newer O/S's
    $hDeskWin = WinGetHandle("[CLASS:Progman]")
    ; Parent->Child relationship: Desktop->SHELLDLL_DefView
    $hSHELLDLL_DefView = ControlGetHandle($hDeskWin, '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]')
    ; No luck with finding the Desktop and/or child?
    If $hDeskWin = '' Or $hSHELLDLL_DefView = '' Then
        ; Look through a list of WorkerW windows - one will be the Desktop on Windows 7+ O/S's
        $aWinList = WinList("[CLASS:WorkerW]")
        For $i = 1 To $aWinList[0][0]
            $hSHELLDLL_DefView = ControlGetHandle($aWinList[$i][1], '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]')
            If $hSHELLDLL_DefView <> '' Then
                $hDeskWin = $aWinList[$i][1]
                ExitLoop
            EndIf
        Next
    EndIf
    ; Parent->Child relationship: Desktop->SHELDLL_DefView->SysListView32
    $h_Listview_Configs = ControlGetHandle($hSHELLDLL_DefView, '', '[CLASS:SysListView32; INSTANCE:1]')
    If $h_Listview_Configs = '' Then Return SetError(-1, 0, '')
    Return SetExtended($h_Listview_Configs, $hDeskWin)
EndFunc   ;==>_WinGetDesktopHandle

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...