Hyperlinks in TRichEdit

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

Post Reply
Marloes
Active Poster
Active Poster
Posts: 13
Joined: Mon Dec 01, 2014 5:35 am

Hyperlinks in TRichEdit

Post by Marloes »

I've got a strange problem. I've enabled the TRichEdit for hyperlinks

Code: Select all

	unsigned masktxt = SendMessage(redText->Handle, EM_GETEVENTMASK, 0, 0);
	SendMessage(redText->Handle, EM_SETEVENTMASK, 0, masktxt | ENM_LINK);
	SendMessage(redText->Handle, EM_AUTOURLDETECT, true, 0);
and

Code: Select all

void __fastcall TMainForm::WndProc(Messages::TMessage &Message) {
	if (Message.Msg == WM_NOTIFY) {
		if (((LPNMHDR) Message.LParam)->code == EN_LINK) {
			ENLINK *p = (ENLINK*) Message.LParam;
			if (p->msg == WM_LBUTTONDOWN) {
				ShowMessage("I'm here!");
				SendMessage(redText->Handle, EM_EXSETSEL, 0, (LPARAM) &(p->chrg));
				ShellExecute(Handle, "open", redText->SelText.c_str(), 0, 0, SW_SHOWNORMAL);
			}
		}
	}

	TForm::WndProc(Message);
}
The hyperlinks display correctly and when I put the mouse over the link the cursor changes to a hand point as it should. But when I click, nothing happens. As per the code above, the message "I'm here!" should display, but it does not. For some reason no message seem to be sent that the hyperlink is clicked. Does anybody have any idea what could be going on?

When I put the code in a separate test app with just a the TRichEdit component, everything works fine, so I am worried there is something prevent my app from working as intended but I cannot understand what that could be.
rlebeau
BCBJ Author
BCBJ Author
Posts: 1714
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: Hyperlinks in TRichEdit

Post by rlebeau »

Is TMainForm the direct parent of the TRichEdit? I'm guessing no. Which would explain why it works in your test app. The WM_NOTIFY message is sent to the RichEdit's immediate parent window.

A more reliable way to handle this would be to subclass the TRichEdit itself and handle the CN_NOTIFY message. The VCL is designed to forward WM_NOTIFY (and WM_COMMAND) messages as CN_NOTIFY (and CN_COMMAND) to the original control that generated them, so controls can handle their own messages. For example:

Code: Select all

class TMainForm : public TForm
{
...
private:
    TWndMethod PrevRichEditWndProc;
    void __fastcall RichEditWndProc(Messages::TMessage &Message);
...
public:
    __fastcall TMainForm(TComponent *Owner);
...
};

Code: Select all

__fastcall TMainForm::TMainForm(TComponent *Owner)
    : TForm(Owner)
{
    PrevRichEditWndProc = redText->WindowProc;
    redText->WindowProc = &RichEditWndProc;
}

void __fastcall TMainForm::RichEditWndProc(Messages::TMessage &Message)
{
    if (Message.Msg == CN_NOTIFY)
    {
        if (reinterpret_cast<LPNMHDR>(Message.LParam)->code == EN_LINK)
        {
            ENLINK *p = reinterpret_cast<ENLINK*>(Message.LParam);
            if (p->msg == WM_LBUTTONDOWN)
            {
                ShowMessage("I'm here!");
                SendMessage(redText->Handle, EM_EXSETSEL, 0, reinterpret_cast<LPARAM>(&(p->chrg)));
                ShellExecute(Handle, NULL, redText->SelText.c_str(), 0, 0, SW_SHOWNORMAL);
                return;
           }
        }
    }
    PrevRichEditWndProc(Message);
}
Remy Lebeau (TeamB)
Lebeau Software
Marloes
Active Poster
Active Poster
Posts: 13
Joined: Mon Dec 01, 2014 5:35 am

Re: Hyperlinks in TRichEdit

Post by Marloes »

Yes, the TRichEdit was inside a TPageControl but your solution worked perfectly. Thank you so much
charlottejw23
Posts: 1
Joined: Sat Apr 25, 2020 4:56 am

Re: Hyperlinks in TRichEdit

Post by charlottejw23 »

Thanks for the code. It's helpful much.
abcya intelligent game
Post Reply