如何实现右键点击TRichEdit控件单词时光标定位至单词内部?
Absolutely! You can totally get your TRichEdit control to position the cursor inside a clicked word when you right-click—just like a left-click does. Here's a straightforward way to make this work in Delphi:
Step 1: Handle the OnMouseDown Event
Hook into the TRichEdit's OnMouseDown event to capture right-clicks and adjust the cursor position before the context menu pops up.
Step 2: Add the Implementation Code
Drop this code into your form's unit. It converts the mouse position to a character index, then moves the cursor to that exact spot:
procedure TYourForm.RichEdit1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var ClickPoint: TPoint; CharIndex: Integer; begin // Only act on right-clicks if Button = mbRight then begin // Convert screen cursor position to the RichEdit's client coordinates ClickPoint := RichEdit1.ScreenToClient(Mouse.CursorPos); // Use the native Windows message to get the character index at the clicked spot CharIndex := RichEdit1.Perform(EM_CHARFROMPOS, 0, LPARAM(@ClickPoint)); // Make sure we're within valid text bounds if (CharIndex >= 0) and (CharIndex < RichEdit1.GetTextLen) then begin // Position the cursor at the clicked character (match left-click behavior) RichEdit1.SelStart := CharIndex; RichEdit1.SelLength := 0; // If you have a custom popup menu, uncomment this to show it // YourPopupMenu.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y); end; end; end;
Key Details:
EM_CHARFROMPOS: This native Windows message tells the TRichEdit to return the 0-based index of the character under the specified mouse position—perfect for pinpointing where the user clicked.- Cursor Positioning: Setting
SelStartto the character index andSelLengthto 0 moves the cursor to that exact spot, matching left-click behavior exactly. - Custom Menus: If you’re using a custom popup menu, call its
Popupmethod after adjusting the cursor to ensure it behaves as expected.
Optional: Ensure Cursor Lands on a Word
If you want to only adjust the cursor when clicking actual words (not blank spaces), add a check to verify the character is part of a word:
// Add this right after getting CharIndex if (CharIndex >= 0) and (CharIndex < RichEdit1.GetTextLen) then begin // Check if the character is alphanumeric (part of a word) if IsCharAlphaNumeric(RichEdit1.Text[CharIndex + 1]) then // Delphi strings are 1-based begin RichEdit1.SelStart := CharIndex; RichEdit1.SelLength := 0; end; end;
This way, right-clicking on blank space won’t move the cursor—only clicks on words will trigger the positioning.
内容的提问来源于stack exchange,提问作者Max Smith

