Solved

Locating the x,y coordinates of text in a rich text control

Posted on 2002-03-07
13
546 Views
Last Modified: 2010-04-05
I'd like to be able to determine the x,y pixel coordinates of certain text in a rich text editing control (Delphi's TRichEdit). I tried to locate the text by coloring the text red with the intention of searching for red pixels using the GetPixel function. Apparently, the rich text editing control does not have a device context whose handle can be supplied to the GetPixel function (or at least I haven't figured out how it can be done in several days of playing around). Is there a way to do this using GetPixel? Or is there another way to do this?
0
Comment
Question by:efz
13 Comments
 
LVL 15

Expert Comment

by:simonet
Comment Utility
Is the TRichEdit in the same application as the desired routine?

Will there be a need to search for the selected text?

Keep in mind that it's just valid if the text searched is being displayed and not "scrolled".

Alex
0
 
LVL 9

Expert Comment

by:ginsonic
Comment Utility
What is your reason to do that ? I need this information to know how can I help you .

Untill then ... you can use the mouse events ?
I have a tip how to get the word under the mouse cursor in a TRichEdit .
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
do you mean screen-coords or caret-coords?
0
 
LVL 3

Expert Comment

by:gandalf_the_white
Comment Utility
listening...
0
 

Author Comment

by:efz
Comment Utility
Yes, the TRichEdit component is located in the same unit as the routine that will perform the search.

I don't expect there will be a need to actually search for the text for reasons stated below.

Because the form or window is always longer than the screen (ie., requires vertical scrolling), the desired code would need to work with the window containing the TRichEdit component as opposed to the viewable screen. The x,y coordinates to which I referred in the original question are the window or TRichEdit component's x,y pixel coordinates. The TRichEdit component is "maximized" or client-aligned within the containing form window.

I'm familiar with the mouse location tip, but that won't suffice because the text input box must move from one location to another when the user presses the TAB key. Thus far, I can move a red dot or text to the desired location (by altering the underlying RTF file), but I can't determine the x,y pixel coordinates of the window in order to then locate a text input box in that location (ie., overlapping and hiding the red dot).

The reason for locating the x,y coordinate is that we currently place a text edit box at certain locations so that users can make entries in those areas of our forms and TAB from one area of the form to the next. Until now we have measured each x,y location manually and that's worked reasonably well. However, we also have different percentages of scaling available so that users can size the forms to their liking. The problem is that when users choose percentages of scaling other than 100%, there's a tendency for the text input box to float off the desired location of the form (the form is presented in a TRichEdit component). The best solution I can think of would be to have the form itself tell us where the text input box should be located. That way the box will always be perfectly aligned with the area of the form where the text input box/answer should appear. Also we won't need to laboriously plot the x,y location of each answer on the form.
0
 
LVL 2

Expert Comment

by:classmate
Comment Utility
If i read this correctly, you are trying to use RTF to make a little "stunt"; you're using RTF as read-only so that you easily can make a tasefull look, but still you want users to be able to edit selected parts of the text.

If i were you i would experiment with the ReadOnly property to see if you can enter text directly into the richedit at desired locations instead of using another edit control for it. Adjust readonly when the caret has moved. Next, you probably should use some kind of searching in the richedits text property to be able to place the caret at the desired "field" when the user presses tab.

To do all this you might have to make a derived component from TRichEdit.

classmate.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:efz
Comment Utility
classmate:

Everything you say is true, we make the RTF editor read-only so users can't destroy the rather complicated and highly formatted forms we use. Your suggestion is a good one, but once we let the user enter directly into the RTF editor, it will be real easy for the user to skew the formatting. Our solution was to overlay a text input (sometimes a checkbox) over the top of the editor so we could police the user's entries and do error-trapping, etc. The system works real well except when the user selects a different viewing scale, then nomatter what algorithm we use, we find that for various reasons the text input boxes tend to float from from their designated areas. I was able to turn the location where the input box should appear red by altering the underlying RTF file and thought that if I could locate that red spot, I could make sure that nomatter what viewing scale the user chose, the input box would always align itself perfectly. If this can't be done, then I think I might have to lock the forms at 100% scaling because your solution would not account for the handling of checkboxes and other entry-validation, etc. Am I right or am I overlooking something?
0
 
LVL 2

Expert Comment

by:classmate
Comment Utility
Since you also use checkboxes, I only have one approach that might work:

1) Try to let the richedit selection move using some movement logic in the keyboard events or -messages of TRichEdit;

2) Use windows api GetCaretPos to find the position of the caret (selection), and place your "inplace control" at this point. You have to be sure that the richedit owns the caret each time. After this you can focus your inplaced control.

3) repeat 2 at each scroll or resize.
0
 

Author Comment

by:efz
Comment Utility
I think you're on to something. If I understand correctly I can:

1. Position the cursor (caret) via the RTF file while the RTF component is not read-only.

2. Then, using I can use your api call to get the x,y coordinates of the cursor.

3. Finally, switch back to read-only and position my text box.

Your solution sounds like the ticket, but I'm not sure how to position the caret (step 1) in the RTF file. I guess I'll need to review the RTF 1.5 specification to see if there's a command for positioning the cursor at a specific location in a RTF file. Many thanks for your suggestion. I'll need a day or two to see if this works. I'll be very grateful to you if this works. I'll let you know.
0
 

Author Comment

by:efz
Comment Utility
Sorry for being dense. You did mention that I might be able to use the search command to locate the cursor. I can hardly wait to see if this works. Many thanks again.
0
 
LVL 33

Accepted Solution

by:
Slick812 earned 300 total points
Comment Utility
hello efz, There is an API sendmessage of EM_POSFROMCHAR, which may be just what you need. Here is some code for a button click


procedure TForm1.sbut_FindPointClick(Sender: TObject);
var
ClarPos: TPoint;
begin
{I use RichEdit1.SelStart for the charater position, but you can use any number to specify
the charater (position) in the RichEdit}
SendMessage(RichEdit1.Handle, EM_POSFROMCHAR, Integer(@ClarPos),RichEdit1.SelStart);
{check to see if the charater is ot of view}
if (ClarPos.x < 0) or (ClarPos.y < 0) or (ClarPos.x > RichEdit1.ClientRect.Right) or
(ClarPos.y > RichEdit1.ClientRect.Bottom) then Exit;
{change the Point Mapping to the Main Form}
MapWindowPoints(RichEdit1.Handle, Handle, ClarPos, 1);
{set your control to the charater Position}
Panel1.Top := ClarPos.y;
Panel1.Left := ClarPos.x;
end;

- - - - - - - - - - - - - - - - - - - - -

the RichEdit1.SelStart give you the current Claret Position. You can put in a Charater Position in the last parameter of SendMessage to get the pixel position of Any charater, and the Claret can be any where. I beleive this will work with the richedit in ReadOnly
0
 

Author Comment

by:efz
Comment Utility
Your code was the right on! The MapWindowPoints call was especially necessary. I pretty much used classmate's generalized outline of the solution and Slick812's code. Isn't there a way to divide the points between several correct and excellent answers?
0
 
LVL 2

Expert Comment

by:classmate
Comment Utility
If the points were good for something in real life, I might have bothered. -Believe me, I don't!!

classmate.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

728 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

12 Experts available now in Live!

Get 1:1 Help Now