443,989 Members | 2,392 Online
+ 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
5 Replies

 P: n/a "Hong Kong Phooey" 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 -> 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" wrote in message news:OR**************@TK2MSFTNGP14.phx.gbl... "Hong Kong Phooey" 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" 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 -> 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" сообщил/сообщила в новостях следующее: 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.