Jump to content

Getting desktops listview handle


Recommended Posts

I had this figured out, but the code for it is on my computer which is not accessible right now. Anybody know how to do this? I need this to work on Windows 7. I'm always getting 0, but I definitely have more than 0 items on my desktop.

#include <GUIListView.au3>

$handle = ControlGetHandle("[CLASS:Progman]", "", "SysListView321")

$count = _GUICtrlListView_GetItemCount($handle)
Msgbox(0, '', $count)
My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]
Link to comment
Share on other sites

Check out ICU, remember that to access a SysListView the script needs to be compiled in line with @OSArch.

I'm not quite sure what you mean by "in line with @OSArch"... I modified my code to this:

#include <GUIListView.au3>

If Not @Compiled Then MsgBox(64, "ICU Info", "ICU needs to be compiled for full functionality")
If @OSArch = "X64" And @AutoItX64 = 0 Then
    MsgBox(16, "ICU Error", "This version of ICU is 32-bit compiled" & @CRLF & _
            "and will not run correctly with a 64-bit OS" & @CRLF & @CRLF & _
            "Please recompile as a 64-bit executable")
    Exit
EndIf

$handle = ControlGetHandle("Program Manager", "", "SysListView321")

$count = _GUICtrlListView_GetItemCount($handle)
Msgbox(0, '', $count)

When I compiled that and ran it I still got 0. I could have sworn I had figured out how to do it without needing to compile... I might just have to go dig up my other computer...

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]
Link to comment
Share on other sites

Compiling is not the key (thats needed for other ICU features). If this does not pop-up the msgbox, the handle should be obtained, works for me.

#include <GUIListView.au3>

If @OSArch = "X64" And @AutoItX64 = 0 Then
    MsgBox(16, "ICU Error", "This version of ICU is 32-bit compiled" & @CRLF & _
            "and will not run correctly with a 64-bit OS" & @CRLF & @CRLF & _
            "Please recompile as a 64-bit executable")
    Exit
EndIf

$handle = ControlGetHandle("Program Manager", "", "SysListView321")

$count = _GUICtrlListView_GetItemCount($handle)
Msgbox(0, '', $count)

Edit: From the Help-File: "Some commands may fail when using a 32-bit AutoIt process to read from a 64-bit process. Likewise commands may fail when using a 64-bit AutoIt process to read from a 32-bit process."

Edited by KaFu
Link to comment
Share on other sites

Compiling is not the key (thats needed for other ICU features). If this does not pop-up the msgbox, the handle should be obtained, works for me.

#include <GUIListView.au3>

If @OSArch = "X64" And @AutoItX64 = 0 Then
    MsgBox(16, "ICU Error", "This version of ICU is 32-bit compiled" & @CRLF & _
            "and will not run correctly with a 64-bit OS" & @CRLF & @CRLF & _
            "Please recompile as a 64-bit executable")
    Exit
EndIf

$handle = ControlGetHandle("Program Manager", "", "SysListView321")

$count = _GUICtrlListView_GetItemCount($handle)
Msgbox(0, '', $count)

Edit: From the Help-File: "Some commands may fail when using a 32-bit AutoIt process to read from a 64-bit process. Likewise commands may fail when using a 64-bit AutoIt process to read from a 32-bit process."

No message box about the warning, but I still get 0 for the count.

I'm running 32bit Windows 7... I don't see where I would have a 64-bit process going for anything... Also, using 3.3.6.1 autoit if that matters at all

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]
Link to comment
Share on other sites

#include <GUIListView.au3>
$handle = ControlGetHandle("Program Manager", "", "SysListView321")
$count = _GUICtrlListView_GetItemCount($handle)
Msgbox(0, '', IsHWnd($handle) & @crlf & WinGetTitle($handle) & @crlf & $count)

This returns "True, Folderview, 39" for me. 64bit can't be an issue for you, and I'm also running on Win7... don't know whats wrong :mellow:

Link to comment
Share on other sites

#include <GUIListView.au3>
$handle = ControlGetHandle("Program Manager", "", "SysListView321")
$count = _GUICtrlListView_GetItemCount($handle)
Msgbox(0, '', IsHWnd($handle) & @crlf & WinGetTitle($handle) & @crlf & $count)

This returns "True, Folderview, 39" for me. 64bit can't be an issue for you, and I'm also running on Win7... don't know whats wrong :mellow:

Returns "False, scite window (because it's topmost), 0"... hmm, you sure 64bit can't be a issue? Your sig says your running 64bit while I'm running 32.. My system is english so that's not an issue..

Is this what you get when you desktop is active with the AutoIt v3 Window Info?

>>>> Control <<<<

Class: SysListView32

Instance: 1

ClassnameNN: SysListView321

Name:

Advanced (Class): [CLASS:SysListView32; INSTANCE:1]

ID: 1

Text: FolderView

Position: 0, 0

Size: 1440, 900

ControlClick Coords: 873, 58

Style: 0x56003A40

ExStyle: 0x00000000

Handle: 0x000100DC

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]
Link to comment
Share on other sites

  • Moderators

My OS: Win7 x64

- The class for the my desktop listview parent is "[CLASS:WorkerW]", not Progman

- Even running in 32 bit mode I get my item counts.

- The only time I've found you need to worry about x64 vs. x86, is when you're trying to access the controls memory ( eg. _GUICtrlListView_GetItemText() (Which I just found a bug for 3.3.6.1, but it won't effect any listview that is unicode )).

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

This version inspired by Ascend4nts EnumChildWindows UDF returns a valid handle on my Win7-64bit and XP-VM.

#include <winapi.au3>
#include <Constants.au3>
#include <GuiListView.au3>

Global $h_Desktop_SysListView32
_GetDesktopHandle()
MsgBox(0, "", WinGetTitle($h_Desktop_SysListView32) & @crlf & _GUICtrlListView_GetItemCount($h_Desktop_SysListView32))

Func _GetDesktopHandle()
    Local $aRet_Dll
    $h_Desktop_SysListView32 = 0
    $hCBReg = DllCallbackRegister("_GetDesktopHandle_EnumChildWinProc", "hwnd", "hwnd;lparam")
    If $hCBReg = 0 Then Return SetError(2)
    $aRet_Dll = DllCall("user32.dll", "int", "EnumChildWindows", "hwnd", _WinAPI_GetDesktopWindow(), "ptr", DllCallbackGetPtr($hCBReg), "lparam", 101)
    $iErr = @error
    DllCallbackFree($hCBReg)
    If $iErr Then Return SetError(3,$iErr,"")
    Return $h_Desktop_SysListView32
EndFunc   ;==>_GetDesktopHandle

Func _GetDesktopHandle_EnumChildWinProc($hWnd,$lParam)
    if _WinAPI_GetClassName($hWnd) = "SysListView32" and _WinAPI_GetWindowLong($hWnd, $GWL_ID) = 1 then $h_Desktop_SysListView32 = $hWnd
    Return 1
EndFunc
Edited by KaFu
Link to comment
Share on other sites

Well, still no luck.

SmOke_N, when running 32 bit is the name of your desktop listview the same?

KaFu, that code still gets 0 0..

Later today (after the World Cup matches) I'll try to get my 64bit Win7 desktop set up and see if I can find any differences that explain why I'm getting 0 for everything I try..

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]
Link to comment
Share on other sites

Link to comment
Share on other sites

Hmmm :mellow:, strange. That one works on my Win7/64bit and XP-VM/32bit...

Maybe there's something wrong with your au install? Try this compiled version:

_GetDesktopHandle.zip

The link you sent me worked.. so I reinstalled AutoIt and now the code you gave me works:

#include <winapi.au3>
#include <Constants.au3>
#include <GuiListView.au3>

Global $h_Desktop_SysListView32
_GetDesktopHandle()
MsgBox(0, "", WinGetTitle($h_Desktop_SysListView32) & @crlf & _GUICtrlListView_GetItemCount($h_Desktop_SysListView32))

Func _GetDesktopHandle()
    Local $aRet_Dll
    $h_Desktop_SysListView32 = 0
    $hCBReg = DllCallbackRegister("_GetDesktopHandle_EnumChildWinProc", "hwnd", "hwnd;lparam")
    If $hCBReg = 0 Then Return SetError(2)
    $aRet_Dll = DllCall("user32.dll", "int", "EnumChildWindows", "hwnd", _WinAPI_GetDesktopWindow(), "ptr", DllCallbackGetPtr($hCBReg), "lparam", 101)
    $iErr = @error
    DllCallbackFree($hCBReg)
    If $iErr Then Return SetError(3,$iErr,"")
    Return $h_Desktop_SysListView32
EndFunc   ;==>_GetDesktopHandle

Func _GetDesktopHandle_EnumChildWinProc($hWnd,$lParam)
    if _WinAPI_GetClassName($hWnd) = "SysListView32" and _WinAPI_GetWindowLong($hWnd, $GWL_ID) = 1 then $h_Desktop_SysListView32 = $hWnd
    Return 1
EndFunc

None of the other code samples work though, but I guess I could just use this.. seems a bit more complicated than I would like for something that should be so simple, but whatever.. Thanks a lot for your help in figuring this out

Edited by Achilles
My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]
Link to comment
Share on other sites

None of the other code samples work though, but I guess I could just use this.. seems a bit more complicated than I would like for something that should be so simple, but whatever.. Thanks a lot for your help in figuring this out

Great :mellow:... the reason I was so eager is because this is one of the basics for ICU. Like SmOke_N stated above

The class for the my desktop listview parent is "[CLASS:WorkerW]", not Progman

and the Progman method is the main method floating around this board to obtain the Desktop handle... but it is not Win7 save, only valid on XP... I wonder why sometimes it even works on Win7, but it is definitely not reliable (like the function above should be :P).

The only time I've found you need to worry about x64 vs. x86, is when you're trying to access the controls memory

So if you do try to access the listview text (like I do in ICU), don't forget to compile in-line with @OSArch.
Link to comment
Share on other sites

  • Moderators

Great :mellow:... the reason I was so eager is because this is one of the basics for ICU. Like SmOke_N stated above

and the Progman method is the main method floating around this board to obtain the Desktop handle... but it is not Win7 save, only valid on XP... I wonder why sometimes it even works on Win7, but it is definitely not reliable (like the function above should be :P).

I wasn't speaking of reliability. I see what you've done, and it is interesting indeed. In fact, I actually never have seen the GWL_ID in use before your example. That could to prove handy for other things.

So if you do try to access the listview text (like I do in ICU), don't forget to compile in-line with @OSArch.

I would probably use a 32bit/64bit wrapper and IPC if I found the need really necessary.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I wasn't speaking of reliability.

I know, but I was :mellow: ...

I would probably use a 32bit/64bit wrapper and IPC if I found the need really necessary.

I would be interested in which approach you would take for a wrapper. And what's IPC? Google didn't give any obvious clue on a glance. Edited by KaFu
Link to comment
Share on other sites

  • Moderators

I know, but I was :mellow: ...

Ok, but you used my quote. The way you replied to my partial quote, was like putting words in my mouth.

I would be interested in which approach you would take for a wrapper. And what's IPC? Google didn't give any obvious clue on a glance.

IPC - http://msdn.microsoft.com/en-us/library/aa365574(VS.85).aspx

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

  • 5 years later...

This is another method that I wrote but it is slower then KaFu method:

Func _GetDesktopHandle2()
    Local $ExplorerPids = ProcessList('explorer.exe')
    If @error Or $ExplorerPids[0][0] = 0 Then Return SetError(1,0,0)
    Local $tmp1 = WinList('','FolderView'),$tmp2,$tmp3
    If @error Or $tmp1[0][0] = 0 Then Return SetError(2,0,0)
    For $a = 1 To $tmp1[0][0]
        $tmp2 = WinGetProcess($tmp1[$a][1])
        If @error Or _ArraySearch($ExplorerPids,$tmp2,1,0,0,0,1,1) <= 0 Then ContinueLoop
        $tmp2 = _WinAPI_EnumChildWindows($tmp1[$a][1],0)
        If @error Then ContinueLoop
        $tmp3 = _ArraySearch($tmp2,'SysListView32',1,0,0,0,1,1)
        If $tmp3 > 0 Then Return $tmp2[$tmp3][0]
    Next
    Return SetError(3,0,0)
EndFunc

It take 80 ms. 

 KaFu method takes abut 20 - 25 ms.

Anyway I posted it here in case that my method is more stable. If so then I would like to know about it :)

 

Edit:
From easy look I guess that what done in KaFu method is about the same thing that done in my code inside _WinAPI_EnumChildWindows 
so I guess that KaFu method should be stable

 

 

EDIT:

OK, This code I worte is faster then KaFu code:

#include <WinAPISys.au3>
Func _GetDesktopHandle3()
    Local $tmp1 = _WinAPI_EnumChildWindows(_WinAPI_GetDesktopWindow(),1)
    If @error Or $tmp1[0][0] = 0 Then Return SetError(1,0,0)
    For $a = 1 To $tmp1[0][0]
        If $tmp1[$a][1] = 'SysListView32' And _WinAPI_GetWindowLong($tmp1[$a][0], $GWL_ID) = 1 Then Return $tmp1[$a][0]
    Next
    Return SetError(2,0,0)
EndFunc

 

It takes 18 ms and also works in 32 bit

Edited by Guest
Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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