Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Position TRichEdit Caret Based on right-click 1

Status
Not open for further replies.

roadbeer69

Programmer
Mar 24, 2007
14
US
Hi All,

I am trying to position the caret in a TRichEdit based on where a user right clicks, but TRichEdit only seems to position the cursor when a user left clicks.

When a right click occurs, I can get the mouse pointer position in pixels within the control, but I am not sure how to translate this into character position to place the caret at the point of the right click. I suspect I can coble something together, but was hoping there'd be an easy way to do this, sort of a "Place caret under mouse cursor on right-click" type of call.

Thanks in advance,
Jeff
 
I realized that getting the character in the TRichEdit that is under the mouse cursor when it is right-clicked would accomplish what I am trying to do as well - I don't actually need to reposition the cursor.

So, for example, if a TRichEdit has the following text in it:

"The quick brown fox"

And the user right clicks over the 'q', I'd like to know that they clicked over the q (e.g. know the index of the character they clicked over).

Thanks again,
Jeff
 
I don't use usually use TRichEdit but see if this helps. It's from C++ Builder's Commonly Asked Questions:
(Q3.8) How do I determine the position of a TRichEdit's caret in a
(row, col) format?

(A3.8) Use the EM_EXLINEFROMCHAR and EM_LINEINDEX messages to retrieve
this information.

int col = RichEdit1->SelStart;
int row = SNDMSG(RichEdit1->Handle, EM_EXLINEFROMCHAR,
0, static_cast<LPARAM>(col));
col = col - SNDMSG(RichEdit1->Handle, EM_LINEINDEX, row, 0);


James P. Cottingham
-----------------------------------------
[sup]I'm number 1,229!
I'm number 1,229![/sup]
 
2ffat,

Thanks for the response. Your link led me indirectly to delve into the WIN32 API and come up with a solution.

Here's what I did for future reference:

1. Register a new Windows Procedure for the TRichEdit's underlying window.

2. Catch a right click event in the new Windows Procedure.

3. Call the TRichEdit's original Windows Procedure with a left click event.

The above basically tells the TRichEdit to interpret a right click as if it had received a left click and invoke its default behavior for processing left click events.

Example Code:

//Handle to the TRichEdit's old Windows Procedure.
WNDPROC oldproc;

//New Window Procedure overides TRichEdit default procedure.
LRESULT CALLBACK RichEditWndProc(HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
switch(msg)
{
case WM_RBUTTONDOWN:
{
//Catch the user clicking the right mouse
//button and call the TRichEdit's original
//Windows Procedure as if the user had clicked
//the left mouse button.
return CallWindowProc(oldproc,
hwnd,
WM_LBUTTONDOWN,
wParam,
lParam);
}

default:
{
//Pass all other messages to the TRichEdit on to
//the original Windows Procedure.
return CallWindowProc(oldproc,
hwnd,
msg,
wParam,
lParam);
}
}

return 0;
}

void SomeForm::SomeMethod()
{
//Tell a TRichEdit control to use the new windows
//procedure. SHOULD DO ERROR CHECKING OF RETURN VALUE
//HERE, TOO!
oldproc = (WNDPROC)SetWindowLong(RichEdit1->Handle,
GWL_WNDPROC,
(long)&RichEditWndProc);
}

One final note: I had to #define STRICT to keep the compiler from bitching about some function pointer mismatches.
 
Very Cool.


James P. Cottingham
-----------------------------------------
[sup]I'm number 1,229!
I'm number 1,229![/sup]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top