How to insert hyperlink without underline to Win32 RichEdit? - c++

I added a link to RichEdit, use CFM_LINK/CHARFORMAT2 structure. But I can't figure out how to remove the underline effect. I tried:
SendMessage(richEditHWND, EM_AUTOURLDETECT, FALSE, NULL);
SendMessage(richEditHWND, EM_SETEDITSTYLEEX, 0, SES_EX_HANDLEFRIENDLYURL);
CHARFORMAT2 cf2;
memset(&cf2, 0, sizeof(CHARFORMAT2));
cf2.dwMask = CFM_LINK| CFM_UNDERLINE | CFM_COLOR | CFM_LINKPROTECTED;
cf2.dwEffects = CFE_LINK| CFE_UNDERLINE | CFE_LINKPROTECTED;
cf2.crTextColor = RGB(255, 0, 0);
cf2.bUnderlineType = CFU_UNDERLINENONE;
SendMessage(richEditHWND, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
But it don'n work.
Another way is set underline color to white color, which is the RichEdit background color, but it is a hacky way, make character like q, j,... being cut apart, also show the line when select text.
So what's the correct way to do this?
Note: I'm using RICHEDIT50W class.

You can do this using a friendly-name hyperlink. These let you specify arbitrary text (along with its own color and formatting) that is used for display, and the actual URL is hidden.
By default, friendly-name hyperlink text is also displayed in blue
with a blue underline unless the name text is formatted with an
explicit color. Explicit formatting takes precedence
The displayed text needs to have the CFE_LINK and CFE_LINKPROTECTED styles, along with explicit color and formatting styles. You then set the URL using the ITextRange2::SetURL method.
The MSDN blog post RichEdit Friendly Name Hyperlinks has a more detailed description of how to use them.

I just encountered the same problem recently and I just found that it's a bug of Richedit library. When I updated it from v4.1 to v5.0 the underline could be removed with no issues

Try sending an EM_AUTOURLDETECT message to the RichEdit control with wParam=0, lParam=0
"Specify 0 to disable automatic link detection...": https://msdn.microsoft.com/en-us/library/windows/desktop/bb787991(v=vs.85).aspx

Related

Multi line tooltip with CStatusBar and always activated

I am using the CStatusBar control and here is an example of trying to set the tooltips:
m_StatusBar.CreateEx(this, SBT_TOOLTIPS);
m_StatusBar.SetIndicators(indicators_oclm, paneCount); //We create the status bar
m_StatusBar.SetPaneInfo(paneDate, ID_INDICATOR_DATE, SBPS_NORMAL, 200);
m_StatusBar.SetPaneInfo(paneProgressOrZoomFactor, ID_INDICATOR_ZOOM, SBPS_NORMAL, 200);
m_StatusBar.SetPaneInfo(panePageBreaks, ID_INDICATOR_PAGE_BREAK, SBPS_NORMAL, 200);
m_StatusBar.SetPaneInfo(paneSlipsPerPage, ID_INDICATOR_SLIPS_COUNT, SBPS_NORMAL, 10);
m_StatusBar.SetPaneInfo(paneForeignLanguageGroup, ID_INDICATOR_FOREIGN_LANGUAGE_GROUP, SBPS_NORMAL, 200);
m_StatusBar.GetStatusBarCtrl().SetTipText(paneSlipsPerPage, _T("Line 1\r\nLine2"));
When I display the tooltip:
As you can see, it has not shown two lines:
Line 1
Line 2
I have researched it (example here) but to no avail.
Update
Using slightly different code, sticking with just one line for the tip I now have:
You can see why I prefer multiline. In addition, I really want the pane text to read "Calendar to use" and the tip to have the information. But the tips only show if all the text is not visible. So I also need to make it always activated if possible.
Update
I still can't get multiline but I have come up with a workaround for some of it:
Get the width for "Calendars to Use"
Set the pane width to that value
Update the pane text as "Calendars to Use " (causes the tooltip notification)
Set the tip text
The icon on the cake is getting the multi line support
I tried:
static CToolTipCtrl* pToolTip = NULL;
CToolTipCtrl* ptt = AfxGetModuleState()->m_thread.GetDataNA()->m_pToolTip;
if (ptt != pToolTip) {
// new tooltip
ptt->SetMaxTipWidth(400);
pToolTip = ptt;
}
But the code never gets called.
Update
I have raised this as a feature request with Microsoft.

QCompleter not support up and down key

I use setEditable(true) to make QComboBox editable, when I input cy, then the completer's popup view will be visible and lists all possible results like: cyan, cyana, liecyan ... But when I press Down in keyboard (Qt::Key_Down), the first one cyan will be selected and QComboBox's lineedit's text will be set cyan , meanwhile, completer's popup view updates, only cyan shows. How can I customize it to make it behave like web's select component.
I have solved this question.
1.class MyListView : public QListView
2.MyListView's bool event(...) need to be implemented to concern about type is QEvent::ShortcutOverride
3.based on QEvent::ShortcutOverride, when user press Qt:Key_Up or Qt::Key_Down,setfalg false, when user release key,set flag true
3.QCompleter use setPopup(MyListView's instance) to override default listview
4. set QCompleter's regexp to work when falg is true
5.I got what I want

Get back Bold Bullet that is displayed when CEdit with ES_PASSWORD MFC

How to get back default bold bullet (ES_PASSWORD) that is displayed when CEdit with ES_PASSWORD is created from resource.
What I have tried:
void CDialogMain::OnBnClickedCheckShowPwd()
{
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_EDIT_PASSWORD);
if (m_CheckShowPwd.GetState() & BST_CHECKED)
{
pEdit->SetPasswordChar(0);
ASSERT(!(pEdit->GetStyle() & ES_PASSWORD));
}
else{
pEdit->SetPasswordChar(L'*');
ASSERT((pEdit->GetStyle() & ES_PASSWORD));
}
pEdit->Invalidate(FALSE);
}
I want to change the ES_PASSWORD style of CEdit Control. Below code Changes it in runtime but visual look of CEdit is changed from Bold Bullet to plain ugly looking asterisks.
How to get back those beautiful bold bullets instead of plain asterisks
To set the password characters back to bullets use:
pEdit->SetPasswordChar(9679);
or in hex:
pEdit->SetPasswordChar(0x25CF);

How to display Red Squiggly Lines in CRichEditCtrl in MFC

I am working on implementing spellchecker in an MFC application. What I want to do is display red lines under incorrectly spelled words.
I found one example where it is done but it works only for a simple edit box because it can simply use the edit controls default font for doing calculations to draw the squiggly lines. But it does not work for a rich edit control as in rich edit control it is possible that different words can have different fonts. In this case the example I found draws lines at incorrect places.
Please let me know if someone has already done this for CRichEditCtrl? (it must handle text of any font/size that is present in the rich edit control.)
Thanks,
Sachin
CHARFORMAT2 format;
SecureZeroMemory(&format, sizeof(CHARFORMAT2));
format.cbSize = sizeof(CHARFORMAT2);
format.dwMask = CFM_UNDERLINE|CFM_UNDERLINETYPE;
format.dwEffects = CFE_UNDERLINE;
format.bUnderlineType = CFU_UNDERLINEWAVE | 0x50;
SendMessage(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&format);
I hope this will get the underline in your text
Use the EM_SETCHARFORMAT message:
CHARFORMAT2 format;
SecureZeroMemory(&format, sizeof(CHARFORMAT2));
format.cbSize = sizeof(CHARFORMAT2);
format.dwMask = CFM_UNDERLINE|CFM_UNDERLINETYPE;
format.dwEffects = CFE_UNDERLINE;
format.bUnderlineType = CFU_UNDERLINE
window->SendMessage(EM_EXSETSEL, NULL, (LPARAM)&range);
window->SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);

Tool tips for custom made control using CToolTipCtrl ? (MFC)

I made a custom control derived from CWnd (a line chart) and I'm wondering if I can use CToolTipCtrl for displaying tool tips for points on the graph. If yes, how could I do that?
Btw, when I move my mouse over the point, the rectangle containg string with information about values of the point, should pop up.
Yes, this works, actually I do this exact same thing, also in a line graph chart, however there are a few drawbacks/remarks. The message handling is a bit wonky, with some messages not being send according to the documentation, and some workarounds being necessary to keep the control self-contained (not requiring help from the parent to reflect notifications).
What you do is declare a variable in your CWnd-derived class
CToolTipCtrl m_ToolTipCtrl;
CString m_ToolTipContent;
Then do this on OnCreate:
m_ToolTipCtrl.Create(this, TTS_ALWAYSTIP);
m_ToolTipCtrl.Activate(TRUE);
Optionally, you can also set the delay time:
m_ToolTipCtrl.SetDelayTime(TTDT_AUTOPOP, -1);
m_ToolTipCtrl.SetDelayTime(TTDT_INITIAL, 0);
m_ToolTipCtrl.SetDelayTime(TTDT_RESHOW, 0);
When you want to show your tooltip (presumably in OnMouseMove()), use
m_ToolTipCtrl.Pop();
BUT this only works in UNICODE builds. So if you're still on MBCS (like I am), you can only show the tooltip after a certain delay.
Use this to set your tooltip text (also in OnMouseMove):
// Not using CToolTipCtrl::AddTool() because
// it redirects the messages to the parent
TOOLINFO ti = {0};
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_IDISHWND; // Indicate that uId is handle to a control
ti.uId = (UINT_PTR)m_hWnd; // Handle to the control
ti.hwnd = m_hWnd; // Handle to window
// to receive the tooltip-messages
ti.hinst = ::AfxGetInstanceHandle();
ti.lpszText = LPSTR_TEXTCALLBACK;
ti.rect = <rectangle where, when the mouse is over it, the tooltip should be shown>;
m_ToolTipCtrl.SendMessage(TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
m_ToolTipCtrl.Activate(TRUE);
m_ToolTipContent = "my tooltip content";
Furthermore, you need to handle TTNNeedText:
// The build-agnostic one doesn't work for some reason.
ON_NOTIFY_EX(TTN_NEEDTEXTA, 0, OnTTNNeedText)
ON_NOTIFY_EX(TTN_NEEDTEXTW, 0, OnTTNNeedText)
BOOL GraphCtrlOnTTNNeedText(UINT id, NMHDR* pTTTStruct, LRESULT* pResult)
{
TOOLTIPTEXT* pTTT = (TOOLTIPTEXT*)pTTTStruct;
//pTTT->lpszText = "some test text";
//pTTT->lpszText = m_ToolTipContent;
strncpy_s(pTTT->lpszText, 80, m_ToolTipContent, _TRUNCATE);
return TRUE;
}
You'll have to modify this a bit, and read the documentation of the functions and messages, to get this to work in your project but yes it can be done.
For those that may still be looking for an answer to this as I was. (I couldn't get the one above to work - Things in MFC may have changed.)
All code is contained within the custom control class.
In your class definition add:
CToolTipCtrl ToolTip;
In PreSubclassWindow() add:
#define TOOLTIP_ID 1
ToolTip.Create(this, TTS_ALWAYSTIP );
CRect rc;
GetClientRect(rc);
ToolTip.AddTool(this, "Tool tip text", rc, TOOLTIP_ID);
In PreTranslateMessage() add:
ToolTip.RelayEvent(msg);
Whenever your tool tip text changes add:
ToolTip.UpdateTipText("New Tip Text", this, TOOLTIP_ID);