Underdstanding HRESULT in DotNET

  • Thread starter Thread starter Academia
  • Start date Start date
Why would a structure containing an X and Y be a platform dependant
structure ? That does not make sense. The size of a *pointer changes
depending on 32 or 64 bit platforms, but values such as X and Y don't, or at
least not that I have ever encountered. There would be no reason for them
to be paltform dependant unless they themselves were pointers.
 
Bill McCarthy said:
Why would a structure containing an X and Y be a platform dependant
structure ? That does not make sense. The size of a *pointer changes
depending on 32 or 64 bit platforms, but values such as X and Y don't, or
at least not that I have ever encountered. There would be no reason for
them to be paltform dependant unless they themselves were pointers.

That's true. However, 'SendMessage' has a return type of fixed size, and
the 'wParam' and 'lParam' parameters have a fixed size (regardless of the
exact message) too. This size depends on the platform and not of the
content provided in these parameters according to the documentation. If the
meaning of, let's say, 'lParam' is a Boolean value, then it will be stored
in a 64-bit value of 64-bit platforms. If its value is an 'Int32', then it
will be stored in 64 bits on a 64-bit platform too. That's why you have to
type the parameters as 'IntPtr' -- they have to adapt the size of the
platform. By not doing so with 'wParam' and 'lParam', the stack can get
unbalanced.
 
Herfried K. Wagner said:
That's true. However, 'SendMessage' has a return type of fixed size, and
the 'wParam' and 'lParam' parameters have a fixed size (regardless of the
exact message) too. This size depends on the platform and not of the
content provided in these parameters according to the documentation. If
the meaning of, let's say, 'lParam' is a Boolean value, then it will be
stored in a 64-bit value of 64-bit platforms. If its value is an 'Int32',
then it will be stored in 64 bits on a 64-bit platform too. That's why
you have to type the parameters as 'IntPtr' -- they have to adapt the size
of the platform. By not doing so with 'wParam' and 'lParam', the stack
can get unbalanced.

Right, but as to the question I was responding to, if the return value is an
X and Y, he can just declare the return type as the structure.
 
Armin Zingler said:
As you know, Sendmessage is a multi purpose function. The values
passed/returned is not always a pointer, it's a plattform specific
integer, which can be a pointer in one case or any other Integer value in
other cases. If you pass a structure containing fixed sized Integers, it
isn't plattform independet anymore, while an Intptr is. The problem in
VB.Net is that we can not do calculations with Intptrs whereas it can be
possible in other languages. For example see Herfried's declaration of
LONG_PTR: It's an __int64 or a long which can be used for calculations. In
most cases this isn't a problem because often Handles or pointers are
passed. 'Academia' now has the problem that the last two args of
SendMessage are IntPtr but he knows these are X- and Y- values without
knowing there size.

Academia, which message do you send? Is it a known (WM_* etc) or a user
defined message?


Armin

I there is one place where I use a user defined:
Private Const MY_MSG As Integer = WinH.WM_APP + &H230F

Everywhere else they come from some windows API h file.
They are all declared as Integer:
Public Const PFM_OFFSETINDENT As Integer = &H80000000
Maybe the should be defined as something else?

I'll repeate the problem below.
Thanks

Suppose SendMessage ends like this:
..., ByRef wParam As Integer, ByRef lParam As Integer) As IntPtr
and the call ends like this:
...,X,Y) 'X and Y are Integer
Because SendMessage returns X and Y.

If I change SendMessage to IntPtr's,
How do I change the call statement?
 
Herfried K. Wagner said:
That's true. However, 'SendMessage' has a return type of fixed size, and
the 'wParam' and 'lParam' parameters have a fixed size (regardless of the
exact message) too. This size depends on the platform and not of the
content provided in these parameters according to the documentation. If
the meaning of, let's say, 'lParam' is a Boolean value, then it will be
stored in a 64-bit value of 64-bit platforms. If its value is an 'Int32',
then it will be stored in 64 bits on a 64-bit platform too. That's why
you have to

Is the 64 above a typo? Should it be 32 bits?
 
Academia said:
I'll repeate the problem below.
Thanks

Suppose SendMessage ends like this:
..., ByRef wParam As Integer, ByRef lParam As Integer) As IntPtr
and the call ends like this:
...,X,Y) 'X and Y are Integer
Because SendMessage returns X and Y.

If I change SendMessage to IntPtr's,
How do I change the call statement?

Ah, I misread the first time . I thought you meant the function's return
value was the x and y values. I I now see what you mean, you are passing in
the X and Y and get the return values in them. Because you are passing them
in ByRef, you are passing them as a pointer so you don't need to modify the
code at all. ByRef X as Int32 is fine as is on both 32 and 64 bit; the key
is it is ByRef, not ByVal.
 
Bill McCarthy said:
Ah, I misread the first time . I thought you meant the function's return
value was the x and y values. I I now see what you mean, you are passing
in the X and Y and get the return values in them. Because you are passing
them in ByRef, you are passing them as a pointer so you don't need to
modify the code at all. ByRef X as Int32 is fine as is on both 32 and 64
bit; the key is it is ByRef, not ByVal.

Isn't the procedure going to stick 64-bits into my 32-bit variables?
 
Bill McCarthy said:
Why would a structure containing an X and Y be a platform dependant
structure ? That does not make sense. The size of a *pointer
changes depending on 32 or 64 bit platforms, but values such as X
and Y don't, or at least not that I have ever encountered. There
would be no reason for them to be paltform dependant unless they
themselves were pointers.

You're right, I didn't see that the values are passed ByRef. However, if
you have two args, it is not required to put them into a structure
because X and Y don't have to be stored in sequence. The two pointers
can point to wherever. But I see that you can do:

Structure ShortPoint
Public X as Int16
Public Y as Int16
End Structure

dim bla as ShortPoint

sendmessage (....., bla.x, bla.y)

This works. However you can not declare it

declare Sendmessage (... as shortpoint)

because you need two args. Or maybe I misunderstood your declaration

"Declare Function SendMessage Lib ............ As ShortPoint"

Is "As Shortpoint" the function value? I thought X and Y are the last
two arguments.


Armin
 
Academia said:
I there is one place where I use a user defined:
Private Const MY_MSG As Integer = WinH.WM_APP + &H230F

Everywhere else they come from some windows API h file.
They are all declared as Integer:
Public Const PFM_OFFSETINDENT As Integer = &H80000000
Maybe the should be defined as something else?

I'll repeate the problem below.
Thanks

Suppose SendMessage ends like this:
..., ByRef wParam As Integer, ByRef lParam As Integer) As IntPtr
and the call ends like this:
...,X,Y) 'X and Y are Integer
Because SendMessage returns X and Y.

If I change SendMessage to IntPtr's,
How do I change the call statement?


It depends on the documentation of the message. if wParam and lParam are
considered pointers to 32-bit integer values, then "ByRef x As Integer,
ByRef y As Integer" is correct.

If wParam and lparam are considered the values themselves, that means
the values temselves are platform dependent integers, you had to declare
it "ByVal x As IntPtr, ByVal y As IntPtr".


Armin
 
Academia said:
Is the 64 above a typo? Should it be 32 bits?

No, it isn't. The 32 "significant" bits containing the real value are just
padded with 32 additional bits to form a 64-bit value representing the
original value.
 
Herfried K. Wagner said:
No, it isn't. The 32 "significant" bits containing the real value are
just padded with 32 additional bits to form a 64-bit value representing
the original value.
thanks
 
thanks

Armin Zingler said:
It depends on the documentation of the message. if wParam and lParam are
considered pointers to 32-bit integer values, then "ByRef x As Integer,
ByRef y As Integer" is correct.

If wParam and lparam are considered the values themselves, that means the
values temselves are platform dependent integers, you had to declare it
"ByVal x As IntPtr, ByVal y As IntPtr".


Armin
 
Armin Zingler said:
You're right, I didn't see that the values are passed ByRef. However, if
you have two args, it is not required to put them into a structure because
X and Y don't have to be stored in sequence.

As Isaid elsewhere I was assuming he was referring to the return type
The two pointers can point to wherever. But I see that you can do:

Structure ShortPoint
Public X as Int16
Public Y as Int16
End Structure

dim bla as ShortPoint

sendmessage (....., bla.x, bla.y)

This works.


No ! I would avoid that in all situations.

However you can not declare it

declare Sendmessage (... as shortpoint)

because you need two args. Or maybe I misunderstood your declaration

"Declare Function SendMessage Lib ............ As ShortPoint"

Is "As Shortpoint" the function value?

Yep.


I thought X and Y are the last two arguments.

Right. When I first read his code he said "returned" and I presumed he meant
the function return.
 
Back
Top