Solved

Windows 2000, Rich Text Box  and WM_GETTEXT

Posted on 2000-04-30
15
770 Views
Last Modified: 2008-03-17
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
Comment
Question by:orbitaltech
  • 8
  • 5
  • 2
15 Comments
 
LVL 2

Author Comment

by:orbitaltech
ID: 2764544
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
 
LVL 28

Expert Comment

by:AzraSound
ID: 2764685
have you done a check to ensure that all handles involved are valid handles?
0
 
LVL 2

Author Comment

by:orbitaltech
ID: 2764829
yup Everything is valid
0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 28

Expert Comment

by:AzraSound
ID: 2764840
just for grins, maybe try postmessage and see if the result is any different
0
 
LVL 2

Author Comment

by:orbitaltech
ID: 2765126
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
 
LVL 14

Expert Comment

by:wsh2
ID: 2765200
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
 
LVL 2

Author Comment

by:orbitaltech
ID: 2765828
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
 
LVL 28

Expert Comment

by:AzraSound
ID: 2766226
looks like this probably:

Public Type GETTEXTLENGTHEX
   flags As Long
   codepage As Integer
End Type
0
 
LVL 2

Author Comment

by:orbitaltech
ID: 2766302
I got that far, now how do you reference in in sendmessage?
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2766307
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
 
LVL 2

Author Comment

by:orbitaltech
ID: 2767962
by using that method... a type mismatch occurs in
retval = SendMessage(hwnd,EM_GETTEXTLENGTHEX,gtStruct,0)

on gtStruct
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2767973
probably b/c your declaration of sendmessage is still expecting a Long parameter, try changing it to
ByRef wParam As GETTEXTLENGTHEX
0
 
LVL 14

Accepted Solution

by:
wsh2 earned 100 total points
ID: 2768031
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
 
LVL 2

Author Comment

by:orbitaltech
ID: 2773160
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
 
LVL 2

Author Comment

by:orbitaltech
ID: 2773173
P.S. to my last comment....

Dont forget the
Dim lngLineIndex as Long
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now