Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 823
  • Last Modified:

Windows 2000, Rich Text Box and WM_GETTEXT

I have been having trouble returning a string from a richtextbox control in Windows 2000 and I need help.

CODE:
child = findchildbyclass(getpar, "RICHCNTL")
GetTrim = sendmessage(child, WM_GETTEXTLEN, 0, 0)
TrimSpace$ = Space$(GetTrim)
GetString = sendmessage(child, WM_GETTEXT, GetTrim + 1, TrimSpace$)

PROBLEM:
   This works under Windows NT 4.0, 95, 98 but doesn't work under Windows 2000. getpar is the handle of the "RICHCNTL" richtextbox control.  WM_GetTextLength works fine and return a length of say 1380 chars.  But after I call the WM_GETTEXT I get a return strign of 0 in the TrimSpace$ buffer... Anybody know what's going on??? HELP???
0
orbitaltech
Asked:
orbitaltech
  • 8
  • 5
  • 2
1 Solution
 
orbitaltechAuthor Commented:
sorry, getpar is the handle of the window housing the Rich textbox control.. it's an out-of-process (in somebody elses program) -works fine
0
 
AzraSoundCommented:
have you done a check to ensure that all handles involved are valid handles?
0
 
orbitaltechAuthor Commented:
yup Everything is valid
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
AzraSoundCommented:
just for grins, maybe try postmessage and see if the result is any different
0
 
orbitaltechAuthor Commented:
gave it a shot and no luck... Postmessage will return 0 on when used with WM_GETTEXTLENGTH and return nothing as well with WM_GETTEXT.

Any other ideas?
0
 
wsh2Commented:
WM_GETTEXT has changed for Windows/2000.. MS recommends you use one of the following instead.

From MSDN:
--------------------------------------
Rich Edit Text Operations

An application can send messages to retrieve or find text in a rich edit control. You can retrieve either the selected text or a specified range of text.

To get the selected text in a rich edit control, use the EM_GETSELTEXT message. The text is copied to the specified character array. You must ensure that the array is large enough to hold the selected text plus a terminating null character.

To retrieve a specified range of text, use the EM_GETTEXTRANGE message. The TEXTRANGE structure used with this message specifies the text range to retrieve and points to a character array that receives the text. Here again, the application must ensure that the array is large enough for the specified text plus a terminating null character.

You can search for a string in a rich edit control by using the EM_FINDTEXT message. The FINDTEXT structure used with this message specifies the text range to search and the string to search for. You can also specify such options as whether the search is case-sensitive.
0
 
orbitaltechAuthor Commented:
I have researched that article on MSDN and found it to not work quite the way it states.. First off to use EM_GETTEXTEX, EM_GETTEXTLENGTHEX (not mentioned above) or EM_GETSELTEXT -

 it uses sendmessage(hWnd, EM_GETTEXTEX, (pointer to gettextex),0)

the pointer to gettextex is a class typedef which I have no idea how to transform into VB code.  

SendMessage(
  (HWND) hWnd,            // handle to destination window
  EM_GETTEXTLENGTHEX,     // message to send
  (WPARAM) wParam;        // text length (GETTEXTLENGTHEX *)
  (LPARAM) lParam;        // not used; must be zero
);

Which references

typedef struct _gettextlengthex {
    DWORD    flags;
    UINT    codepage;
} GETTEXTLENGTHEX;


Therefore, without the typedef transformation, this will not work and returns the same old 0's that the program always has... Any other thoughts?  Ideas to change typedefs to VB code??

-Still searching
0
 
AzraSoundCommented:
looks like this probably:

Public Type GETTEXTLENGTHEX
   flags As Long
   codepage As Integer
End Type
0
 
orbitaltechAuthor Commented:
I got that far, now how do you reference in in sendmessage?
0
 
AzraSoundCommented:
before you call SendMessage declare a variable as that type, for example:

Dim gtStruct As GETEXTLENGTHEX

I dont know if they say this structure should pass parameters or receive parameters. if it passes them then initialize them to whatever they need to be,

gtStruct.flags = ????
gtStruct.codepage = ????

then call the function


retval = SendMessage(hWnd,EM_GETTEXTLENGTHEX,gtStruct,0)
0
 
orbitaltechAuthor Commented:
by using that method... a type mismatch occurs in
retval = SendMessage(hwnd,EM_GETTEXTLENGTHEX,gtStruct,0)

on gtStruct
0
 
AzraSoundCommented:
probably b/c your declaration of sendmessage is still expecting a Long parameter, try changing it to
ByRef wParam As GETTEXTLENGTHEX
0
 
wsh2Commented:
The EM_GETTEXTEX and EM_GETTEXTLENGTHEX APIs that you are trying to employ are only compatable with Rich Edit Controls equal to or greater than Version 2. The example below is compatable with RichText v1, v2 and v3.

The xEchoRichTextBox1 Sub clears a ListBox.. and then copies all lines from a RichTextBox into the ListBox. Additionally, it stores the RichTextBox line delineatred into an Array named strLineText. As it runs from an hWnd, you can modify the code to your purpose.. <smile>.

======================================

1. Start a New Standard.Exe Project.
2. Add a RichTextBox (RichTextBox1) and a ListBox (List1) to it.
3. Set the MultiLine property of the RichTextBox to True.
4. In the Form1 code window Copy/Paste the following.
5. Press F5 to Run. Anything placed in the RichTextBox is echoed into the ListBox.

<----- Code Begin ----->

Option Explicit

Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" _
   (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) _
   As Long

Private Sub Form_Load()

   With Form1
      .Left = Screen.Width * 0.1
      .Height = Screen.Height * 0.8
      .Top = Screen.Height * 0.1
      .Width = Screen.Width * 0.8
   End With

   With RichTextBox1
      .Left = Form1.ScaleWidth * 0.1
      .Height = Form1.ScaleHeight * 0.8
      .Top = Form1.ScaleHeight * 0.1
      .Width = Form1.ScaleWidth * 0.4
   End With

   With List1
      .BackColor = Form1.BackColor
      .Left = Form1.ScaleWidth * 0.5
      .Height = Form1.ScaleHeight * 0.8
      .Top = Form1.ScaleHeight * 0.1
      .Width = Form1.ScaleWidth * 0.45
   End With
   
   RichTextBox1.Text = "RichTextbox1: Enter Data Here"
   RichTextBox1.SelStart = Len(RichTextBox1.Text)
   
End Sub

Private Sub RichTextBox1_Change()
   
   xEchoRichTextBox1

End Sub

Private Sub xEchoRichTextBox1()
   
   Const EM_GETLINE = &HC4
   Const EM_GETLINECOUNT = &HBA
   Const EM_LINELENGTH = &HC1
   
   Dim lngLineCount As Long
   Dim lngLineLength As Long
   Dim lngLineNumber As Long
   Dim lngLinePosition As Long
   Dim strLineText() As String
   List1.Clear
   lngLineCount = SendMessageLong(RichTextBox1.hwnd, EM_GETLINECOUNT, 0, 0)
   ReDim strLineText(lngLineCount)
   For lngLineNumber = 0 To lngLineCount - 1
      lngLineLength = SendMessageLong(RichTextBox1.hwnd, EM_LINELENGTH, lngLinePosition, 0)
      strLineText(lngLineNumber) = Space(lngLineLength + 1)
      lngLinePosition = lngLinePosition _
         + SendMessageLong(RichTextBox1.hwnd, EM_GETLINE, lngLineNumber, strLineText(lngLineNumber))
      strLineText(lngLineNumber) = Left(strLineText(lngLineNumber), Len(strLineText(lngLineNumber)) - 1)
      List1.AddItem strLineText(lngLineNumber)
      List1.Selected(lngLineNumber) = True
   Next lngLineNumber

End Sub

<----- Code End ----->

0
 
orbitaltechAuthor Commented:
Well, after a little modification the code has worked. Thank you wsh2.

NOTE:  I have added the constant EM_LINEINDEX to determine the offset of the first character in the specified line of the edit control(rich text box). This needs to be referenced or the  EM_LINELENGTH call will not return the proper character length (and will call GPF if I might add) since EM_LINELENGTH determines the length of the line containing an offset in the edit control text string.

After the slight modification, the commands work perfectly. Thanks again wsh2


Private Sub xEchoRichTextBox1()
   
   Const EM_GETLINE = &HC4
   Const EM_GETLINECOUNT = &HBA
   Const EM_LINELENGTH = &HC1
   Const EM_LINEINDEX = &HBB  
 
   Dim lngLineCount As Long
   Dim lngLineLength As Long
   Dim lngLineNumber As Long
   Dim lngLinePosition As Long
   Dim strLineText() As String
   List1.Clear
   lngLineCount = SendMessageLong(RichTextBox1.hwnd, EM_GETLINECOUNT, 0, 0)
   ReDim strLineText(lngLineCount)
   For lngLineNumber = 0 To lngLineCount - 1
      lngLineIndex = SendMessageLong(RichTextBox1.hwnd,EM_LINEINDEX,lngLineNumber,0)
      lngLineLength = SendMessageLong(RichTextBox1.hwnd, EM_LINELENGTH, lngLineIndex, 0)
      strLineText(lngLineNumber) = Space(lngLineLength + 1)
      lngLinePosition = lngLinePosition _
         + SendMessageLong(RichTextBox1.hwnd, EM_GETLINE, lngLineNumber, strLineText(lngLineNumber))
      strLineText(lngLineNumber) = Left(strLineText(lngLineNumber), Len(strLineText(lngLineNumber)) - 1)
      List1.AddItem strLineText(lngLineNumber)
      List1.Selected(lngLineNumber) = True
   Next lngLineNumber

End Sub
0
 
orbitaltechAuthor Commented:
P.S. to my last comment....

Dont forget the
Dim lngLineIndex as Long
0

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 8
  • 5
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now