Win32 EM_GETTEXTEX causing the application to crash.

Locked Win32 EM_GETTEXTEX causing the application to crash.

  • 2012年2月28日 14:40
     
     

    Hi,

    Well this question is related to use of Win32 API. I am trying to get text of a RichTextBox which is located in one of my text application. I am trying to use EM_GETTEXTEX message  to collect the data.

    Here is the code

                Dim Struct As New GetTexTex
                Struct.cb = GetTextLength(hWnd, FlagVal)  'A wrapper function over WIN32 API Rich text box gettext message
                Struct.Flags = FlagVal
                Struct.CodePage = 1200
                Struct.LPBOOL = Nothing
                Struct.LPCSTR = Nothing

                Dim text As New StringBuilder("", CType(Struct.cb, Integer))
                Try
                    Win32_user32_Functions.SendMessage(hWnd, EM_GETTEXTEX, Struct, text)
                    Return text.ToString
                Catch ex As Exception
                    Return text.ToString
                End Try

     'Structure definition

        Public Structure GetTexTex
            Dim cb As Long
            Dim Flags As RichTextGetTextTexEnum
            Dim CodePage As Long
            Dim LPCSTR As String
            Dim LPBOOL As String
        End Structure

    'Enum Def

        Public Enum RichTextGetTextTexEnum
            GT_DEFAULT = 0
            GT_SELECTION
            GT_USECRLF = 1&
        End Enum

    When I run this code it causes the application to crash. Can some one tell me what is it that I am doing wrong?

    I tried sending the string both byval and byref. Each makes the test app to crash everytime.

    A help or pointer will help a lot.

    Regards

    Virender


    Regards Virender

すべての返信

  • 2012年2月28日 14:49
     
     

    These are VB6 declarations that don't work since 2002.

    Please also show the declarations for GetTextLength, hWnd, EM_GETTEXTEX and SendMessage.

    What's the reason for "Return text.ToString" in the Try block and also in the catch block?


    Armin


  • 2012年2月28日 15:21
     
     回答済み コードあり

    You can pick out the parts you need from this (untested!) code: 

    Imports System.Runtime.InteropServices
    Imports System.Text
    
    Public Class Main
       Shared Sub main()
    
       End Sub
    
       Const WM_USER As UInteger = &H400
    
       Const EM_GETTEXTEX As UInteger = WM_USER + 94
       Const EM_GETTEXTLENGTHEX As UInteger = WM_USER + 95
    
       Public Shared ReadOnly E_INVALIDARG As New IntPtr(&H80070057)
    
       <Flags()> _
       Public Enum GetTextFlags As UInteger
          [Default] = 0
          UserCrLF = 1
          Selection = 2
          RawText = 4
          NoHiddenText = 8
       End Enum
    
    
       <Flags()> _
       Public Enum GetTextLengthFlags As UInteger
          [Default] = 0
          UseCrLf = 1
          Precise = 2
          Close = 4
          NumChars = 8
          NumBytes = 16
       End Enum
    
       <StructLayout(LayoutKind.Sequential)> _
       Public Structure GetTextEx
          Public cb As UInt32
          Public Flags As GetTextFlags
          Public CodePage As UInt32
          <MarshalAs(UnmanagedType.LPStr)> Public DefaultChar As String
          Public UsedDefChar As IntPtr
       End Structure
    
       <StructLayout(LayoutKind.Sequential)> _
       Public Structure GetTextLengthEx
          Public flags As GetTextLengthFlags
          Public codepage As UInt32
       End Structure
    
       Public Declare Auto Function SendMessage Lib "user32.dll" ( _
          ByVal hWnd As IntPtr, ByVal Msg As UInteger, _
          ByRef wParam As GetTextEx, ByVal lParam As System.Text.StringBuilder) _
          As IntPtr
    
       Public Declare Auto Function SendMessage Lib "user32.dll" ( _
          ByVal hWnd As IntPtr, ByVal Msg As UInteger, _
          ByRef wParam As GetTextLengthEx, ByVal lParam As IntPtr) _
          As IntPtr
    
       Shared Function GetText( _
          ByVal hWnd As IntPtr, _
          ByVal GetLengthFlags As GetTextLengthFlags, _
          ByVal GetTextFlags As GetTextFlags) As String
    
          Dim Struct As GetTextEx
          Dim sb As StringBuilder
    
          Struct.cb = CUInt(GetTextLength(hWnd, GetLengthFlags))
          Struct.Flags = GetTextFlags
          Struct.CodePage = 1200
    
          sb = New StringBuilder(CInt(Struct.cb))
    
          SendMessage(hWnd, EM_GETTEXTEX, Struct, sb)
          Return sb.ToString
    
       End Function
       Shared Function GetTextLength(ByVal hWnd As IntPtr, ByVal flags As GetTextLengthFlags) As Integer
    
          Dim struct As GetTextLengthEx
          Dim result As IntPtr
    
          struct.flags = flags
    
          result = SendMessage(hWnd, EM_GETTEXTLENGTHEX, struct, IntPtr.Zero)
    
          If result = E_INVALIDARG Then
             Throw New System.ComponentModel.Win32Exception("Invalid argument calling SendMessage")
          Else
             Return CInt(result)
          End If
    
       End Function
    
    End Class
    


    Armin



  • 2012年2月28日 15:32
     
     

    'Get text length is defined as this

            Public Shared Function GetTextLength(ByVal hWnd As IntPtr, ByVal FlagVal As RichTextGetTextTexEnum) As Long
                Dim Struct As New RichTextGetTextLengthEx
                Struct.Codepage = 1200
                Struct.Flags = FlagVal
                Try
                    Return Win32_user32_Functions.SendMessage(hWnd, RichTextBoxMessages.EM_GETTEXTLENGTHEX, Struct, 0)
                Catch ex As Exception
                    Return -100
                End Try
            End Function

    This function uses

    Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As RichTextBoxMessages, ByRef wParam As RichTextGetTextLengthEx, ByVal lParam As Integer) As IntPtr

    dim hWnd as Intptr

    EM_GETTEXTLENGTHEX = (1024 + 95)

    Return text is just the way I have implemented it. It gives back the text from the richtext edit box

    Thanks

    And hoping for a reply from you


    Regards Virender

  • 2012年2月28日 15:35
     
     
    Thanks Armin. I will try to use this code and will post you back on the result.

    Regards Virender

  • 2012年3月1日 14:27
     
     

    SOlution given doesnt work. It is still crashing the application.


    Regards Virender

  • 2012年3月1日 14:44
     
     

    SOlution given doesnt work. It is still crashing the application.

    Again, please show the error line and all related declarations. We do not know which parts you've changed.

    Armin

  • 2012年3月26日 10:06
     
     
    Well it seems that the code given earlier is working. It was the way I was passing values. Thanks for all your help and sorry for replying to it so late.

    Regards Virender