Call SendMessage WinAPI to get item_rect for tree control

M

Maxim Ap

Hi everyone!

I am trying to write lib for windows application GUI testing.The problem
that I see now it is how to call SendMessage WinAPI for tree control to
get tree item rect.Code Commctrl.h for this looks like:

#define TVM_GETITEMRECT (TV_FIRST + 4)
#define TreeView_GetItemRect(hwnd, hitem, prc, code) \
(*(HTREEITEM *)prc = (hitem), (BOOL)SNDMSG((hwnd), TVM_GETITEMRECT,
(WPARAM)(code), (LPARAM)(RECT *)(prc)))

And I don't know what is *(HTREEITEM *)prc = (hitem) and how to do this
on Ruby.

For example my Ruby code for GetRoot looks like:

def send_message(hwnd,msg,wParam,lParam )
send_message = user32 'SendMessage' , ['L' , 'L' , 'L' , 'P' ], 'L'
send_message.call hwnd, msg, wParam, lParam
end

def get_tree_root_item(htree)
send_message(htree,0x1100+10,TVGN_ROOT,0 )
end

and this works for me.

Commctrl.h for this looks:
#define TreeView_GetRoot(hwnd) TreeView_GetNextItem(hwnd, NULL,
TVGN_ROOT)

#define TVM_GETNEXTITEM (TV_FIRST + 10)
#define TreeView_GetNextItem(hwnd, hitem, code) \
(HTREEITEM)SNDMSG((hwnd), TVM_GETNEXTITEM, (WPARAM)(code),
(LPARAM)(HTREEITEM)(hitem))

It would be greate if someone can explain what is *(HTREEITEM *)prc =
(hitem) and how to do this in Ruby.

Thanks,
Maxim
 
S

Su Zhang

You need to pass a buffer to SendMessage to store the rectangle's
information. You can pass the API a Ruby string, and Win32API will pass
the actual address of the string to the API. The API then mutate the
string content so that it stores the rectangle information. The string
itself is like a primitive structure containing different fields, and
later on you can use String#unpack to retrieve every single field.

Suppose you already have the handle to the controls and the message's
internal integer representation defined:

buf = [handle_tree_item, 0, 0, 0].pack('l*')
send_message = Win32API.new('user32', 'SendMessage' , ['L' , 'L' , 'L' ,
'P' ], 'L')
sned_message.call(handle_tree_view, TVM_GETITEMRECT, 0, buf)
rect = buf.unpack('l*')

rect[0] # left
rect[1] # top
rect[2] # right
rect[3] # bottom
And I don't know what is *(HTREEITEM *)prc = (hitem) and how to do this
on Ruby.

This is basically a dereference operation on the pointer prc, which
cannot be done in Ruby in the language level. You can use RtlMoveMemory
supplied by kernel32.dll to achieve the same thing in an ugly manner.
 
M

Maxim Ap

Eric wrote in post #978925:
Did you ever figure this out? I am trying to do something similar

I found more flexible solution to work with Windows applications. I
integrate AutoIT.dll with Ruby.It works great and meet all my
requirements.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top