?
Solved

Problem calling ::SendMessage on a CRichEditCtrl

Posted on 2000-04-26
11
Medium Priority
?
366 Views
Last Modified: 2013-11-20
I am trying to find out the location of the pointer within a CRichEditCtrl without clicking within the control.  I need to know the character index it is on, not just the coordinates of the pointer.  To do this I'm calling
int charIndex = ::SendMessage(theCtrl, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y));

from within the view's OnMouseMove() function, to convert the mouse position to a character index.  theCtrl is the richeditctrl instance, and pt is a CPoint object that is based on the point passed into OnMouseMove, but might be a few pixels shifted (for a reason, but I won't bother explaining why unless someone needs to know.)

I get an access violation when I hit this code.  Not every time, most often when I am in a part of the richeditctrl that I had to scroll down to get to, but also in places at the top if I go over them a few times.  It will work a few times then give the access violation eventually.

Any ideas?  Other ways to get the character index I'm pointing at without using this code?
0
Comment
Question by:appleby
11 Comments
 
LVL 3

Expert Comment

by:GlennDean
ID: 2753282
You need to pass a handle to SendMessage.  If I understood you right, instead of passing theCtrl pass
theCtrl.m_hWnd to SendMessage.
0
 
LVL 3

Expert Comment

by:mnewton022700
ID: 2753761
According to MSDN the lparam parameter should be a pointer to a POINTL structure. Try this:

POINTL pointl;
pointl.x = pt.x;
pointl.y = pt.y;

int charIndex = ::SendMessage(theCtrl, EM_CHARFROMPOS, 0, &pointl);
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2754011
int RichEditCharFromPos(CRichEditCtrl& theCtrl, const CPoint& pt) {
  ASSERT(::IsWindow(theCtrl.m_hWnd));
  return (int)::SendMessage(theCtrl.m_hWnd, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y));
}

This should work fine

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 10

Accepted Solution

by:
RONSLOW earned 600 total points
ID: 2754020
Indeed .. tanks mnewton.

Richedit is indeed different from Edit control in this respect (why did MS do this?????).

So lets make it:

int RichEditCharFromPos(CRichEditCtrl& theCtrl, const CPoint& pt) {
  ASSERT(::IsWindow(theCtrl.m_hWnd));
  POINTL pointl;
  pointl.x = pt.x;
  pointl.y = pt.y;
  return (int)::SendMessage(theCtrl.m_hWnd, EM_CHARFROMPOS, 0, &pointl);
}

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2754026
Interestingly, the latest WTL from MS doesn't seem to know about this ... it uses this code for rich edit controls:

  int CharFromPos(POINT pt) const
  {
    ATLASSERT(::IsWindow(m_hWnd));
    return (int)::SendMessage(m_hWnd, EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y));
  }

Either MS is wrong, or MS is wrong.  How are we mere mortals supposed to know what is right if MS gets it wrong themselves??? :-(
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 2754514
<<lParam
Specifies the coordinates of a point in the control's client area. The coordinates are in screen units and are relative to the upper-left corner of the control's client area.

Rich edit controls: This is a pointer to a POINTL structure that contains the horizontal and vertical coordinates.

Edit controls: The low-order word contains the horizontal coordinate. The high-order word contains the vertical coordinate. >>

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2754707
thats what mnewton and I said.
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 2754892
Yes, I just want to say that it is documented in the new platform sdk.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2754959
Yes .. it is documented.  But the latest SDK also includes WTL, which has a bug in that it uses the wrong one.  So either the MS docs are wrong (unlikely) or the MS WTL library is wrong (quite likely).

It seems a very poor design decision to give the same message different parameters.  Surely separate messages would have been better.  One of the great mysteries of life :-)
0
 

Author Comment

by:appleby
ID: 2755144
I had to explicitly cast the &pointl param to long, but otherwise it worked fine.  I'm accepting RONSLOW's comment as the answer since it put together the two pieces I was missing.

Thank you all for the help.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2757839
BTW: the nice way to do the cast is

reinterpret_cast<LPARAM>(&pointl)

this makes it obvious that you are passing a pointer as an LPARAM.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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

Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
With just a little bit of  SQL and VBA, many doors open to cool things like synchronize a list box to display data relevant to other information on a form.  If you have never written code or looked at an SQL statement before, no problem! ...  give i…
Suggested Courses

862 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