Hyperlinks in TRichEdit

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

Hyperlinks in TRichEdit

Postby Marloes » Mon Dec 01, 2014 2:37 pm

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.
Marloes
Active Poster
Active Poster
 
Posts: 13
Joined: Mon Dec 01, 2014 5:35 am

Re: Hyperlinks in TRichEdit

Postby rlebeau » Tue Dec 02, 2014 3:50 am

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
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1457
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: Hyperlinks in TRichEdit

Postby Marloes » Tue Dec 02, 2014 6:30 am

Yes, the TRichEdit was inside a TPageControl but your solution worked perfectly. Thank you so much
Marloes
Active Poster
Active Poster
 
Posts: 13
Joined: Mon Dec 01, 2014 5:35 am


Return to Technical

Who is online

Users browsing this forum: No registered users and 16 guests

cron