Solved

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

Posted on 2002-03-07
13
569 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
[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
13 Comments
 
LVL 15

Expert Comment

by:simonet
ID: 6849683
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
ID: 6849704
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
ID: 6849752
do you mean screen-coords or caret-coords?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 3

Expert Comment

by:gandalf_the_white
ID: 6850077
listening...
0
 

Author Comment

by:efz
ID: 6850224
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
ID: 6850846
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
 

Author Comment

by:efz
ID: 6851138
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
ID: 6851628
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
ID: 6851849
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
ID: 6851860
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 34

Accepted Solution

by:
Slick812 earned 300 total points
ID: 6851963
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
ID: 6852643
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
ID: 6855507
If the points were good for something in real life, I might have bothered. -Believe me, I don't!!

classmate.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Suggested Courses
Course of the Month7 days, 7 hours left to enroll

622 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