AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

row height in list views?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
RobOtter



Joined: 30 Jan 2005
Posts: 125
Location: Darmstadt, Germany

PostPosted: Thu Mar 23, 2006 4:42 pm    Post subject: row height in list views? Reply with quote

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 Crying or Very sad
Back to top
View user's profile Send private message
evl



Joined: 24 Aug 2005
Posts: 1238

PostPosted: Thu Mar 23, 2006 4:58 pm    Post subject: Reply with quote

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
Back to top
View user's profile Send private message
RobOtter



Joined: 30 Jan 2005
Posts: 125
Location: Darmstadt, Germany

PostPosted: Thu Mar 23, 2006 5:36 pm    Post subject: Reply with quote

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?
Back to top
View user's profile Send private message
evl



Joined: 24 Aug 2005
Posts: 1238

PostPosted: Thu Mar 23, 2006 6:06 pm    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
Guest






PostPosted: Thu Mar 23, 2006 8:34 pm    Post subject: Reply with quote

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 Sad

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
Back to top
evl



Joined: 24 Aug 2005
Posts: 1238

PostPosted: Thu Mar 23, 2006 8:49 pm    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Thu Mar 23, 2006 10:11 pm    Post subject: Reply with quote

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 Wed Mar 29, 2006 4:55 pm; edited 2 times in total
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10467

PostPosted: Thu Mar 23, 2006 11:52 pm    Post subject: Reply with quote

Nice and compact, and it's a great resource for similar questions in the future. Thanks for sharing it.
Back to top
View user's profile Send private message Send e-mail
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Fri Mar 24, 2006 4:05 am    Post subject: Reply with quote

Chris wrote:
Thanks for sharing it.


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

Just something I resurrected from the forum.
Back to top
View user's profile Send private message
RobOtter



Joined: 30 Jan 2005
Posts: 125
Location: Darmstadt, Germany

PostPosted: Fri Mar 24, 2006 7:04 am    Post subject: Reply with quote

Thank you, shimanov! I would never have found that myself, itīs too sophisticated for me Rolling Eyes

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...
Back to top
View user's profile Send private message
Chris
Site Admin


Joined: 02 Mar 2004
Posts: 10467

PostPosted: Sun Mar 26, 2006 4:09 am    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message Send e-mail
Tekl



Joined: 24 Sep 2004
Posts: 813
Location: Germany

PostPosted: Wed Mar 29, 2006 12:58 am    Post subject: Reply with quote

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
Back to top
View user's profile Send private message Visit poster's website
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Wed Mar 29, 2006 1:56 am    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
PhiLho



Joined: 27 Dec 2005
Posts: 6721
Location: France (near Paris)

PostPosted: Wed Mar 29, 2006 6:49 am    Post subject: Reply with quote

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).
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")
Back to top
View user's profile Send private message Visit poster's website
RobOtter



Joined: 30 Jan 2005
Posts: 125
Location: Darmstadt, Germany

PostPosted: Wed Mar 29, 2006 7:51 am    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group