AutoHotkey Community

It is currently May 27th, 2012, 7:14 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: March 23rd, 2006, 4:42 pm 
Offline

Joined: January 30th, 2005, 11:18 pm
Posts: 133
Location: Darmstadt, Germany
Hi,

is there a way to find out the height of a row in list view (and also the height of the header)?
I´ve already found how to tell the width of a column (via SendMessage) but it seems like there is no equivalent for the height :cry:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 23rd, 2006, 4:58 pm 
Offline

Joined: August 24th, 2005, 5:17 pm
Posts: 1237
Shimanov showed me how to automatically re-size the height of a listview which gets the height of a row as part of that - take a look here:
http://www.autohotkey.com/forum/viewtopic.php?t=7060


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 23rd, 2006, 5:36 pm 
Offline

Joined: January 30th, 2005, 11:18 pm
Posts: 133
Location: Darmstadt, Germany
Thanks!

I get the header height with no problems, but getting the row height fails. This is because "rect" seems to be empty.
I must admit I haven´t tried the script as it is but put the needed portions in my script to get information about Windows Explorers detailed file view.
Is their anything special with the SysListView321 of Explorer that I have to take care about?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 23rd, 2006, 6:06 pm 
Offline

Joined: August 24th, 2005, 5:17 pm
Posts: 1237
Did you remember to include the line:
Code:
VarSetCapacity( rect, 16, 0 )


I've not used the script with anything other than my own listview in a gui. Try posting some code if you can't get it working.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 23rd, 2006, 8:34 pm 
Yes, I had that line in my code.
By the time I´ve tried shimanov´s original script and it´s working fine!
So maybe the problem is with the list view object of the Explorer.
I have tried the code on Explorer´s detailed view and thought it might cause the problem. But I´ve also tried it on every other view mode and it´s not working there either :(

Here´s a small sample code. Try hitting Alt-y in an Explorer window:
Code:
; Test on Windows Explorer detailed file list mode
; In the end, this should bring out the height of a row

#y::
WINGETCLASS, windowType, A
IF (windowType = "CabinetWClass" OR windowType = "ExploreWClass")
{
   ; LVM_GETITEMRECT
   ;   LVIR_BOUNDS
   VarSetCapacity( rect, 16, 0 )
   SendMessage, 0x1000+14, 0, &rect, SysListView321, A
   y1 := 0
   y2 := 0
   loop, 4
   {
      y1 += *( &rect+3+A_Index )
      y2 += *( &rect+11+A_Index )
      MsgBox, Loop: %A_Index% rect: %rect%
   }
   lv_row_h := y2-y1
      MsgBox, lv_row_h: %lv_row_h% y1: %y1% y2: %y2%
}
RETURN


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: March 23rd, 2006, 8:49 pm 
Offline

Joined: August 24th, 2005, 5:17 pm
Posts: 1237
CAUTION!! Testing that script actually crashed explorer for me.

I guess that method seems unlikely to work with explorer, unless Shimanov can shed any light on it.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 23rd, 2006, 10:11 pm 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
The message in question is considered local from the perspective of the responding process. It is necessary to use remote process access (RPA) methods in order to complete message handling successfully.

Code:
!y::
WinGet, hw_target, ID, A
WINGETCLASS, windowType, ahk_id %hw_target%
IF (windowType = "CabinetWClass" OR windowType = "ExploreWClass")
{
   WinGet, pid_target, PID, ahk_id %hw_target%
   
   hp_explorer := DllCall( "OpenProcess"
                        , "uint", 0x18                           ; PROCESS_VM_OPERATION|PROCESS_VM_READ
                        , "int", false
                        , "uint", pid_target )
   
   remote_buffer := DllCall( "VirtualAllocEx"
                        , "uint", hp_explorer
                        , "uint", 0
                        , "uint", 0x1000
                        , "uint", 0x1000                        ; MEM_COMMIT
                        , "uint", 0x4 )                           ; PAGE_READWRITE

   ; LVM_GETITEMRECT
   ;   LVIR_BOUNDS
   SendMessage, 0x1000+14, 0, remote_buffer, SysListView321, ahk_id %hw_target%

   VarSetCapacity( rect, 16, 0 )
   result := DllCall( "ReadProcessMemory"
                  , "uint", hp_explorer
                  , "uint", remote_buffer
                  , "uint", &rect
                  , "uint", 16
                  , "uint", 0 )

   result := DllCall( "VirtualFreeEx"
                     , "uint", hp_explorer
                     , "uint", remote_buffer
                     , "uint", 0
                     , "uint", 0x8000 )                           ; MEM_RELEASE
   
   result := DllCall( "CloseHandle", "uint", hp_explorer )

   y1 := DecodeInteger( "int4", &rect, 4 )
   y2 := DecodeInteger( "int4", &rect, 12 )

   lv_row_h := y2-y1
      MsgBox, lv_row_h: %lv_row_h% y1: %y1% y2: %y2%
}
RETURN

DecodeInteger( p_type, p_address, p_offset, p_hex=true )
{
   old_FormatInteger := A_FormatInteger

   if ( p_hex )
      SetFormat, Integer, hex
   else
      SetFormat, Integer, dec
      
   sign := InStr( p_type, "u", false )^1
   
   StringRight, size, p_type, 1
   
   loop, %size%
      value += ( *( ( p_address+p_offset )+( A_Index-1 ) ) << ( 8*( A_Index-1 ) ) )
      
   if ( sign and size <= 4 and *( p_address+p_offset+( size-1 ) ) & 0x80 )
      value := -( ( ~value+1 ) & ( ( 2**( 8*size ) )-1 ) )
      
   SetFormat, Integer, %old_FormatInteger%

   return, value
}


Last edited by shimanov on March 29th, 2006, 4:55 pm, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 23rd, 2006, 11:52 pm 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Nice and compact, and it's a great resource for similar questions in the future. Thanks for sharing it.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 24th, 2006, 4:05 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
Chris wrote:
Thanks for sharing it.


Hi Chris. It's been a while. Still enjoying AHk.

Just something I resurrected from the forum.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 24th, 2006, 7:04 am 
Offline

Joined: January 30th, 2005, 11:18 pm
Posts: 133
Location: Darmstadt, Germany
Thank you, shimanov! I would never have found that myself, it´s too sophisticated for me :roll:

Chris, do you think it is possible to wrap a nice AHK command around this? It would be great if we users would not have to dig so deep in the dirt of Windows internals...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 26th, 2006, 4:09 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
The ControlGet List command uses the above VirtualAllocEx method to get text from ListViews. Although there is a plan to add a similar capability for TreeViews and possibly other controls, adding a more general-purpose feature seems like something that should be implemented as #include function(s) rather than a built-in feature. This is because such a feature seems like it would be used by fewer than 1% of users.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 29th, 2006, 12:58 am 
Offline

Joined: September 24th, 2004, 3:00 pm
Posts: 814
Location: Germany
Hi,

I tried to get the size of the bounding rectangle around all list-items with LVM_GETVIEWRECT. I changed the code to the following and I don't know if I did a mistake or windows is causing the strange results.

Code:
 
...
...
  ; LVM_GETVIEWRECT
   ;   LVIR_BOUNDS
   SendMessage, 0x1000+34, 0, remote_buffer, SysListView321, ahk_id %explorer_ID%

   VarSetCapacity( rect, 16, 0 )
   result := DllCall( "ReadProcessMemory"
                  , "uint", hp_explorer
                  , "uint", remote_buffer
                  , "uint", &rect
                  , "uint", 16
                  , "uint", 0 )

   result := DllCall( "VirtualFreeEx"
                     , "uint", hp_explorer
                     , "uint", remote_buffer
                     , "uint", 0
                     , "uint", 0x8000 )                           ; MEM_RELEASE

   result := DllCall( "CloseHandle", "uint", hp_explorer )

   x1 := 0
   x2 := 0
   y1 := 0
   y2 := 0
   loop, 4
   {
      x1 += *( &rect+0+A_Index-1 )
      x2 += *( &rect+8+A_Index-1 )
      y1 += *( &rect+4+A_Index-1 )
      y2 += *( &rect+12+A_Index-1 )
   }


My changes are the Messagecode and the code for x1,x2,y1 and y2. As I don't really understand what there happens it could be, I did it the wrong way.

_________________
Tekl


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 29th, 2006, 1:56 am 
Offline

Joined: September 25th, 2005, 4:31 pm
Posts: 610
Could this be an issue?

MSDN wrote:
LVM_GETVIEWRECT
...
The list view must be in icon or small icon view.


Also check ErrorLevel:

MSDN wrote:
Returns TRUE if successful, or FALSE otherwise.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 29th, 2006, 6:49 am 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
Chris wrote:
This is because such a feature seems like it would be used by fewer than 1% of users.

Well, it looks like a natural extension of SendMessage: a good number of these messages use wParam or lParam as a pointer to a buffer where the target window writes information. This information isn't available for a foreign application, unless using shimanov's trick. I was bitten by this undocumented problem too...
This feature is "advanced" in the form given by shimanov, but if integrated to SendMessage, it would be more accessible and popular.
And don't forget that such advanced features are hard to write, but can be used by many users once the base trick is released.
That's in the same spirit that it would be nice to have GetChildHWND built in AHK (often used, we have to include the function each time).

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 29th, 2006, 7:51 am 
Offline

Joined: January 30th, 2005, 11:18 pm
Posts: 133
Location: Darmstadt, Germany
Chris,
I agree with PhiLho. The easier a functionality can be accessed, the more often users would use it. In addition, it is imho comparable to other functions one can apply on ListViews, so adding it would be a step to a complete support of ListViews in AHK.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 25 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Exabot [Bot], Leef_me, sjc1000 and 71 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group