Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Windows 2000, Rich Text Box  and WM_GETTEXT

Posted on 2000-04-30
15
Medium Priority
?
810 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
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.

 
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 400 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

721 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