By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,989 Members | 2,392 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,989 IT Pros & Developers. It's quick & easy.

Hex question

P: n/a
I wrote a control in which I overrode WndProc to implement a custom
MouseMove. I caught the MouseMove message and passed it to a function which
raises a custom event. In this function I get the x and y from the LParam of
the message; x being the low order word, y being the high order word. I use
two functions to get the LoWord and HiWord from the LParam

Private Shared Function HiWord(ByVal Number As Integer) As Integer
Return ((Number >> 16) And &HFFFF)
End Function

Private Shared Function LoWord(ByVal Number As Integer) As Integer
Return (Number And &HFFFF)
End Function

This gets me x and y correctly except when x or y is negative.
Example:

LParam.ToInt32: 5636101 (&H00560005)
x: 5 (&H0005)
y: 86 (&H0056)

LParam.ToInt32: 5636100 (&H00560004)
x: 4 (&H0004)
y: 86 (&H0056)

LParam.ToInt32: 5636099 (&H00560003)
x: 3 (&H0003)
y: 86 (&H0056)

LParam.ToInt32: 5570562 (&H00550002)
x: 2 (&H0002)
y: 85 (&H0055)

LParam.ToInt32: 5570561 (&H00550001)
x: 1 (&H0001)
y: 85 (&H0055)

LParam.ToInt32: 5570560 (&H00550000)
x: 0 (&H0000)
y: 85 (&H0055)

LParam.ToInt32: 5636095(&H0055FFFF)
x: 65535 (&HFFFF) <-- This should be -1!!!!
y: 85 (&H0055)

If this were VB6, &HFFFF would produce -1 and &HFFFF& would produce 65535.
In VB.Net &HFFFF and &HFFFF& are the same, both producing 65535. Negative 1
is represented by &HFFFFFFFF. How can I make my calculation aware that
&HFFFF is like vb6, using a 2-byte integer instead of a 4-byte integer.

By the way, I used Lutz Roeder's Reflector to see how Controls handle this
by default. I understand that it is not a perfect decompiler already,
because it works backwards from MSIL. It would seem that Controls get x and
y like this:

x = CType(m.LParam.ToInt32, Short)
y = (m.LParam.ToInt32) >> 16)

If I were to try this, I would get an OverflowException when LParam.ToInt32
equaled 5636095 (way more than a Short can hold)

How can I extract x and y properly?

--

Any help is appreciated.
Thanks in advance.

Hong Kong Phooey
Nov 21 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a

"Hong Kong Phooey" <NO****@NOSPAM.com> wrote in message
news:eZ**************@TK2MSFTNGP15.phx.gbl...
I wrote a control in which I overrode WndProc to implement a custom
MouseMove. I caught the MouseMove message and passed it to a function
which
raises a custom event. In this function I get the x and y from the LParam
of
the message; x being the low order word, y being the high order word. I
use
two functions to get the LoWord and HiWord from the LParam

Private Shared Function HiWord(ByVal Number As Integer) As Integer
Return ((Number >> 16) And &HFFFF)
End Function

Private Shared Function LoWord(ByVal Number As Integer) As Integer
Return (Number And &HFFFF)
End Function


That code is only correct for unsigned integers. For signed integers the
sign bit gets shifted to the high order bit of the low order word by the
HiWord function. The clearest and simplest way to do this in VB.NET is to
use the BitConverter. When you want to extract types embedded in some
opaque byte structure, use BitConverter.

Private Shared Function HiWord(ByVal Number As Int32) As Int16
Return BitConverter.ToInt16(BitConverter.GetBytes(Number) , 0)
End Function
Private Shared Function LoWord(ByVal Number As Int32) As Int16
Return BitConverter.ToInt16(BitConverter.GetBytes(Number) , 2)
End Function

If you need to optimize this:

Private Sub ExtractWords(ByVal Number As Int32, ByRef HiWord As Int16, ByRef
LoWord As Int16)
Dim b As Byte() = BitConverter.GetBytes(Number)
HiWord = BitConverter.ToInt16(b, 0)
LoWord = BitConverter.ToInt16(b, 2)
End Sub

To do this with bit shifting, you would need to pull off the sign bit, do
the shifting, and replace the sign bit in its original location. Which is
more bit twiddling than I usually care to do.

David
Nov 21 '05 #2

P: n/a
Hi,
LParam.ToInt32: 5636095(&H0055FFFF)
x: 65535 (&HFFFF) <-- This should be -1!!!!
y: 85 (&H0055)
This is because your functions return Integer values. &HFFFF is an
Integer literal so it is actually 0000FFFF and thus 65535. You want to
get Short values, so you can either use the following functions:

~
Private Function HiWord(ByVal Number As Integer) As Short
Return CShort(Number >> 16)
End Function

Private Function LoWord(ByVal Number As Integer) As Short
Return CShort(Number And 65535)
End Function
~

which will require to remove integer overflow checks (Project -> <Name>
Properties... -> Configuration Properties -> Optimizations -> Remove
integer overflow checks) or use BitConverter approach suggested by
David.
If this were VB6, &HFFFF would produce -1 and &HFFFF& would produce 65535. In VB.Net &HFFFF and &HFFFF& are the same, both producing 65535.


Well, they are not the same.

&HFFFF and &HFFFF% and &HFFFFI are Integer literals. They equal 0000FFFF
or 65535 (Integer value).
&HFFFF& and &HFFFFL are Long literals. They equal 000000000000FFFF or
65535 (Long value).

The one you are looking for is &HFFFFS which is Short literal. It equals
FFFF or -1 (Short value).

I hope this helps to clarify the situation.
Roman
Nov 21 '05 #3

P: n/a
Coolness. I'll use the BitConverter class.
Thanks

Hong Kong Phooey

"David Browne" <davidbaxterbrowne no potted me**@hotmail.com> wrote in
message news:OR**************@TK2MSFTNGP14.phx.gbl...

"Hong Kong Phooey" <NO****@NOSPAM.com> wrote in message
news:eZ**************@TK2MSFTNGP15.phx.gbl...
I wrote a control in which I overrode WndProc to implement a custom
MouseMove. I caught the MouseMove message and passed it to a function
which
raises a custom event. In this function I get the x and y from the LParam of
the message; x being the low order word, y being the high order word. I
use
two functions to get the LoWord and HiWord from the LParam

Private Shared Function HiWord(ByVal Number As Integer) As Integer
Return ((Number >> 16) And &HFFFF)
End Function

Private Shared Function LoWord(ByVal Number As Integer) As Integer
Return (Number And &HFFFF)
End Function

That code is only correct for unsigned integers. For signed integers the
sign bit gets shifted to the high order bit of the low order word by the
HiWord function. The clearest and simplest way to do this in VB.NET is to
use the BitConverter. When you want to extract types embedded in some
opaque byte structure, use BitConverter.

Private Shared Function HiWord(ByVal Number As Int32) As Int16
Return BitConverter.ToInt16(BitConverter.GetBytes(Number) , 0)
End Function
Private Shared Function LoWord(ByVal Number As Int32) As Int16
Return BitConverter.ToInt16(BitConverter.GetBytes(Number) , 2)
End Function

If you need to optimize this:

Private Sub ExtractWords(ByVal Number As Int32, ByRef HiWord As Int16,

ByRef LoWord As Int16)
Dim b As Byte() = BitConverter.GetBytes(Number)
HiWord = BitConverter.ToInt16(b, 0)
LoWord = BitConverter.ToInt16(b, 2)
End Sub

To do this with bit shifting, you would need to pull off the sign bit, do
the shifting, and replace the sign bit in its original location. Which is
more bit twiddling than I usually care to do.

David

Nov 21 '05 #4

P: n/a
Damn, I didn't know that about the Hex literals; that you could append
something other than a (&) to the end. Where did you ever find that
information? I've never seen that before.

Thanks
Hong Kong Phooey

"Dragon" <no@spam.please> wrote in message
news:%2***************@TK2MSFTNGP15.phx.gbl...
Hi,
LParam.ToInt32: 5636095(&H0055FFFF)
x: 65535 (&HFFFF) <-- This should be -1!!!!
y: 85 (&H0055)


This is because your functions return Integer values. &HFFFF is an
Integer literal so it is actually 0000FFFF and thus 65535. You want to
get Short values, so you can either use the following functions:

~
Private Function HiWord(ByVal Number As Integer) As Short
Return CShort(Number >> 16)
End Function

Private Function LoWord(ByVal Number As Integer) As Short
Return CShort(Number And 65535)
End Function
~

which will require to remove integer overflow checks (Project -> <Name>
Properties... -> Configuration Properties -> Optimizations -> Remove
integer overflow checks) or use BitConverter approach suggested by
David.
If this were VB6, &HFFFF would produce -1 and &HFFFF& would produce

65535.
In VB.Net &HFFFF and &HFFFF& are the same, both producing 65535.


Well, they are not the same.

&HFFFF and &HFFFF% and &HFFFFI are Integer literals. They equal 0000FFFF
or 65535 (Integer value).
&HFFFF& and &HFFFFL are Long literals. They equal 000000000000FFFF or
65535 (Long value).

The one you are looking for is &HFFFFS which is Short literal. It equals
FFFF or -1 (Short value).

I hope this helps to clarify the situation.
Roman

Nov 21 '05 #5

P: n/a

"Hong Kong Phooey" <NO****@NOSPAM.com> сообщил/сообщила в новостях
следующее: news:#c**************@TK2MSFTNGP09.phx.gbl...
Damn, I didn't know that about the Hex literals; that you could append
something other than a (&) to the end. Where did you ever find that
information? I've never seen that before.

Thanks
Hong Kong Phooey


He he, there are much more 8=]

% & @ ! # $ are type characters. Not all of them can belong to
hexademical literals, though.

See
http://msdn.microsoft.com/library/en...BSpec2_2_1.asp
for info on them.

S I L F R D C don't have a specific name AFAIK. You can find info on
them scattered around Literals chapter in VB language specification:

http://msdn.microsoft.com/library/en...fVBSpec2_4.asp

Read about integer literals here:

http://msdn.microsoft.com/library/en...BSpec2_4_2.asp

Roman
Nov 21 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.