Archive: System::Call


System::Call
  Hi,

I have a question about system plugin.

I added data to a listbox thru SendMessage LB_ADDSTRING and now i want to retrieve it.
Here is the problem, from
http://msdn.microsoft.com/library/en...asp?frame=true
"retrieve parameter:
lParam
Pointer to the buffer that will receive the string; it is type LPTSTR which is subsequently cast to an LPARAM. The buffer must have sufficient space for the string and a terminating null character. An LB_GETTEXTLEN message can be sent before the LB_GETTEXT message to retrieve the length, in TCHARs, of the string."


I cant get the string directly to a nsis variable so i decided to use system plugin, this is the call:
System::Call "user32::SendMessage(i,i,i,*t)i (r1,${LB_GETTEXT},.r2,.r3)"

r1 is the hnwd, r2 is the index and i should get the string in r2 but i got nothing.

Can anyone please help?

Thanks in advance!


Try

System::Call "user32::SendMessage(i,i,i,*t)i (r1,${LB_GETTEXT},.r2,.r3).r4 ?e"
Pop $5
and look at the value of $5. It should have the error code. Then go to this page to find out what this error code means.

Since the lParam is a pointer to a buffer that will hold the text string, you want to allocate it first then pass it to the function. Allocation will depend on the size that is needed. Something like this:
System::Alloc ${NSIS_MAX_STRLEN}
Pop $3
System::Call "user32::SendMessage(i,i,i,i)i (r1,${LB_GETTEXT},.r2,r3).r4"

or maybe generate a small structure that will accept the string and pass it to the call:
System::Call '*(&t${NSIS_MAX_STRLEN})i.r3'
System::Call "user32::SendMessage(i,i,i,i)i (r1,${LB_GETTEXT},.r2,r3).r4"
In both examples I used ${NSIS_MAX_STRLEN} which is most likely a lot more than needed. Usually these functions will tell you how much you need to allocate if the size of the buffer passed to them is too small. My understanding from the page you quote is that you should call the function with any small size and then it will give you in $4 the correct size (you forgot r4 in your code, it is the last parameter)

Hope this helps

CF

I'll do just this:

; if r1 ($1) is the valid handle of the ListBox

>; if r2 ($2) is the valid zero-based index of the ListBox
System::Call 'User32::SendMessage(i r1,i ${LB_GETTEXT},i r2, t .r3) i .r4'

Ok, i got it working. Thanks both!


Hi all,

I have a last question on this example.

I get a numerical value in $r3 back from:

System::Call 'User32::SendMessage(i r1,i ${LB_GETTEXT},i r2, t .r3) i .r4'

The value is like "2110000"...
I am guessing this is probably a pointer?

When I do a "MessageBox" with the value, it keeps it that int...
How do I convert this back to a string?

Thanks!
Scott


I made a dummy example.
And I don't have problems getting the text


Hi Joel,

Thank you.

Ya, I figured it out, it took me awhile to get the "hang" of the System command and its calls.

This worked:

System::Alloc ${NSIS_MAX_STRLEN}
Pop $3
System::Call "user32::SendMessage(i,i,i,i)i (r1,${LB_GETTEXT}, $Index,t.r3).r4"
MessageBox MB_OK "$Index | $3 | $4"
System::Free $3

So much to learn!

Thanks again!
Scott


You don't need to allocate a buffer for that. Simply use `t.r3` and System will handle the allocation. After you Pop $3, it contains the pointer to the buffer anyway. So your command actually ignores that, fills $3 with the data and then frees the wrong memory.


Ah, I see.

So do I need the "System::Free $3" still?

ie, if I let System do the Alloc, is it still expecting
me to Free it?

Or is it just assumed that System will do that for me?

Thanks
Scott


No, no need for Free. In the string parameter case it handles everything internally.