[VB .NET] Read Line from Paltalk 10

You can talk about VB programming here

[VB .NET] Read Line from Paltalk 10

Postby autopilot » Mon Aug 15, 2011 2:10 pm


Since Paltalk 10 switched to the RichEdit20W control for room chat, a lot of people have struggled to retrieve incoming chat text. Here is a function I put together to return text from a given line:
Code: Select all
Code Removed
See post below for new code.

Note:
I don't know why, but just like before, the line index is still index - 2.
So to read the 5th line, the index would be (5 - 2).
Last edited by autopilot on Mon Aug 15, 2011 6:46 pm, edited 1 time in total.
User avatar
autopilot
Forum Moderator
Forum Moderator
 
Posts: 358
Joined: Sat Sep 23, 2006 7:19 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby String » Mon Aug 15, 2011 3:07 pm

Well done, Autopilot.
-= Please ask your questions in the forum, not in pm.
String
imFiles Senior
imFiles Senior
 
Posts: 313
Joined: Mon Mar 10, 2008 7:06 am
Location: IDE

Re: [VB .NET] Read Line from Paltalk 10

Postby autopilot » Mon Aug 15, 2011 3:41 pm

i could probably make the default much lower for the MaxBuffer, but I just set it ridiculously high to make sure it always picked up the whole line.
User avatar
autopilot
Forum Moderator
Forum Moderator
 
Posts: 358
Joined: Sat Sep 23, 2006 7:19 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby Chike » Mon Aug 15, 2011 4:06 pm

EM_GETLINE needs the available length as a WORD(2 bytes) at the beginning and that definately not what there with the loop.
baText(0) = iCount
baText(1) = iCount / 256
This would be good for CPUs that use little endian byte order.

It shouldn't matter if the text is ANSI or Unicode as the SendMessageA/SendMessageW should convert. How do you see the array in debugger as byte or unicode charachters?
Image
Chike
imFiles Master
imFiles Master
 
Posts: 583
Joined: Sun May 13, 2007 6:20 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby autopilot » Mon Aug 15, 2011 4:35 pm

Chike wrote:baText(0) = iCount
baText(1) = iCount / 256
This would be good for CPUs that use little endian byte order.

First, baText(0) would fail to get set and throw an exception any time iCount is larger then 255, and second, I would rather see a method that is CPU independent.

My function above may not be perfect, but has worked without fail in all of my testing situations so far.
User avatar
autopilot
Forum Moderator
Forum Moderator
 
Posts: 358
Joined: Sat Sep 23, 2006 7:19 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby autopilot » Mon Aug 15, 2011 4:43 pm

Chike wrote:EM_GETLINE needs the available length as a WORD(2 bytes) at the beginning and that definately not what there with the loop.

So are you saying that the longest line EM_GETLINE can return is a length as WORD = FFFF?
I have not tested with anything to see if and what the max is, but until I get problems with my function posted above, it is what I will be using.
User avatar
autopilot
Forum Moderator
Forum Moderator
 
Posts: 358
Joined: Sat Sep 23, 2006 7:19 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby Chike » Mon Aug 15, 2011 5:22 pm

Yes, longest possible text is 65535 charachters.
Use bSize whatever that is, basically you fill the array with zeros when using default.
Send the function max buffer smaller than actual line length(10, 100) and see what you get.
It is not about perfection it's about writing code without bugs.
I am not familiar with pointer casting in .NET, little endian should be good enough for paltalk.
Image
Chike
imFiles Master
imFiles Master
 
Posts: 583
Joined: Sun May 13, 2007 6:20 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby autopilot » Mon Aug 15, 2011 6:36 pm

After doing some investigation, my BitConverter.GetBytes was returning a 4 byte array = {1, 16, 0, 0}
The integer passed to BitConverter.GetBytes was 4097.
I am not sure why the BitConverter.GetBytes is returning a 4 bite array, but {1, 16} is correct for LittleEndian, so (if I understand it correctly) i need to reverse it to pass WORD {16, 1}. Therefore, I have removed the loop and changed it to:
Code: Select all
CODE REMOVED
Updated code in post below


Note:
I have tested with many MaxBuffer values and passing the reversed first 2 bytes are always correct for the (MaxBuffer * 2) + 1 value as long as the value is less then 65535. Any time it gets a value greater then 65535, it will then cause problems, so I set a cap of 32767.

I also added an If statement to handle a case if the MaxBuffer value was too low (smaller then line length).
Last edited by autopilot on Tue Aug 16, 2011 10:20 am, edited 1 time in total.
User avatar
autopilot
Forum Moderator
Forum Moderator
 
Posts: 358
Joined: Sat Sep 23, 2006 7:19 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby Chike » Mon Aug 15, 2011 8:02 pm

It returns a 4 byte result because it is sent a 32bit value.
You don't need to reverse anything, and it's still not going to be good for big endian machines which would need baText(0) = bSize(2) and baText(1) = bSize(3)
Unlike the x86 which converting from word to byte or double word is trivial, big endian machines need special instructions to do so.
I wouldn't worry about endianness. Apart from mobile which this code wont work on anyway i am not aware of any other machines that run paltalk other then x86 or x64.
Image
Chike
imFiles Master
imFiles Master
 
Posts: 583
Joined: Sun May 13, 2007 6:20 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby Chike » Tue Aug 16, 2011 3:13 am

The result of EM_GETLINE is the number of TCHARs copied, no need for any checking,, it will never be greater than erquested.

The word is the required TCHARs not the size of the buffer in bytes so no need to limit it to 32767, and it's valu should be just MaxBuffer.
Image
Chike
imFiles Master
imFiles Master
 
Posts: 583
Joined: Sun May 13, 2007 6:20 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby autopilot » Tue Aug 16, 2011 10:17 am

Thank you Chike for the clarifications. I still dont know why the first byte of the WORD value is the lower half of the WORD, but after removing the byte reversal, my iRetval is never more then my buffer.

So here is the code after making the changes that Chike pointed out:
Code: Select all
    Private Function ReadLine(ByVal hwnd As IntPtr, ByVal iLine As Integer, Optional ByVal MaxBuffer As Integer = 500) As String
        Dim iRetval As Integer
        Dim sAnswer As String = Nothing
        Dim baText() As Byte
        ' Cap MaxBuffer so it can never be too large
        If MaxBuffer > 65535 Then MaxBuffer = 65535
        ' Set byte array to max buffer size (times 2 for Wide) + 1
        ReDim baText((MaxBuffer * 2) + 1)
        ' Get bytes for max buffer size
        Dim bSize() As Byte
        bSize = BitConverter.GetBytes(MaxBuffer)
        '  Write max buffer size as WORD to begining of baText array
        baText(0) = bSize(0)
        baText(1) = bSize(1)
        ' Get Line data (iRetval = number of characters in line)
        iRetval = SendMessage(hwnd, EM_GETLINE, iLine, baText)
        ' Convert byte buffer to string trimmed to retval size
        sAnswer = System.Text.Encoding.Unicode.GetString(baText).Substring(0, iRetval)
        ' Return the retrieved string
        Return sAnswer
    End Function


I still cap the buffer, but at the full 65535 size that EM_GETLINE can retrieve.

Also due to the Pal limit on text, i lowered the default MaxBuffer size to 500
User avatar
autopilot
Forum Moderator
Forum Moderator
 
Posts: 358
Joined: Sat Sep 23, 2006 7:19 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby Chike » Tue Aug 16, 2011 2:42 pm

Little endian means last significant byte first, that's why the first byte is the lower part of the WORD, and the word is the lower part of DWORD etc.
Big endian most significant byte first, and would be just the oposite.

if iRetval was greater than the buffer it means memory outside the buffer was overriden.
There is also no need to add a null termination byte to the buffer, EM_GETLINE won't fill the NULL charachter i there is no space for it, and if you do want it than add 2(unicode char size)

Now for the other question I had, is the returned array is really unicode or is it just ascii, you can see this quite clear with the debugger before converting.
Image
Chike
imFiles Master
imFiles Master
 
Posts: 583
Joined: Sun May 13, 2007 6:20 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby autopilot » Tue Aug 16, 2011 3:30 pm

Chike wrote:Now for the other question I had, is the returned array is really unicode or is it just ascii, you can see this quite clear with the debugger before converting.

I am saying it is unicode as every other byte (alternating) in the array is = 0 and the "System.Text.Encoding.Unicode.GetString" does return the string.

Code: Select all
-      baText   {Length=1001}   Byte()
      (0)         65             Byte
      (1)         0              Byte
      (2)         108            Byte
      (3)         0              Byte
      (4)         101            Byte
      (5)         0              Byte
      (6)         114            Byte
      (7)         0              Byte
      (8)         116            Byte
      (9)         0              Byte
      ...
Last edited by autopilot on Tue Aug 16, 2011 3:52 pm, edited 1 time in total.
User avatar
autopilot
Forum Moderator
Forum Moderator
 
Posts: 358
Joined: Sat Sep 23, 2006 7:19 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby Chike » Tue Aug 16, 2011 3:45 pm

And SendMessage is SendMessageA or SendMessageW?
Image
Chike
imFiles Master
imFiles Master
 
Posts: 583
Joined: Sun May 13, 2007 6:20 pm

Re: [VB .NET] Read Line from Paltalk 10

Postby autopilot » Tue Aug 16, 2011 3:53 pm

Chike wrote:And SendMessage is SendMessageA or SendMessageW?

it is set to auto
Code: Select all
Declare Auto Function SendMessage Lib "USER32" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Byte()) As Integer
User avatar
autopilot
Forum Moderator
Forum Moderator
 
Posts: 358
Joined: Sat Sep 23, 2006 7:19 pm

Next

Return to Visual Basic Programming

 


  • Related topics
    Replies
    Views
    Last post

Who is online

Users browsing this forum: No registered users and 0 guests

cron