CEdit control MFC, placing cursor to end of string after SetWindowText - c++

I am using VC9, I've a CEdit control whose contents are reset to default test (say - "fill-in") at the click of a button and then I call SetFocus for the CEdit control. The problem is that the cursor blinks at the start of the default text, and i want it to blink an the end of the default string.
How can this be done?

You can use CEdit::SetSel to accomplish that.
Example:
CEdit* e = (CEdit*)GetDlgItem(IDC_EDIT1);
e->SetWindowText("hello world");
e->SetFocus();
e->SetSel(0,-1); // select all text and move cursor at the end
e->SetSel(-1); // remove selection

You can use CEdit::SetSel to accomplish that:
CEdit* e = (CEdit*)GetDlgItem(IDC_EDIT1);
e->SetWindowText("hello world");
// e->SetSel(0,-1); // you don't need this line
e->SetFocus();
e->SetSel(-1);
It will place the cursor in the end of the string.

I had a strange finding but still relevant to it.
This solution did not work for me initially. Even after calling SetSel(-1) my cursor was moving to the top of the edit box.
Then I did some code reshuffle and it started working.
The learning was that if I update any other control after updating the edit control, the cursor will move to the top of the edit box. But if edit box is the last control updated, the cursor remains in the end of the edit box.
Like I had a code something like
Add text to edit & call SetSel(-1)
update static control
And the cursor would not stay in the end. But when I changed it to
update static control
Add text to edit & call SetSel(-1)
My cursor was displayed in the end of the edit box.
I had it on my mind since the day I had this finding to update the knowledge base here. Hope it helps some random soul whose cursor jumps to top of edit box even after calling the API.

Related

wxWidgets: make tooltips less annoying,

I have added tooltips to my checkbox elements, but they are too annoying. They appear immediately after hovering the mouse cursor over the element and do not disappear after the cursor has left the checkbox.
I could start a timer, but I don't know how I can check if the cursor is within the desired element or has left it.
And the second question is, is there any event like wxEVT_LEAVE_WINDOW, but for the checkbox to remove the tooltip when the cursor goes out of bounds.
Thanks, #New Pagodi
I am still dont get normal behaivor of tips, but your trich works. I can get tip window from wxCheckBox element just calling GetChildren().
wxRichToolTip* tip = new wxRichToolTip(wxT("INFO"), msg);
tip->SetTimeout(0, 500);
tip->ShowFor(it->second.first);
wxWindowList tipWindow = it->second.first->GetChildren();
auto a = tipWindow.GetLast()->GetData();
a->Bind(wxEVT_MOTION, &DeviceListDialog::onLeaveCheckbox, this);

Visual Studio MFC C++ Move cursor after SetDlgItemText

I am making a Visual Studio MFC C++ App, and I am having a (hopefully) small problem.
I have an Edit Control text box with ID txtInputBox, and it has a value C-String variable m_inputText assigned to it. After I do a SetDlgItemText(txtInputBox, L"Hello World"); the cursor moves to the front of the text, before the 'H'. How would I get the cursor to be at the end (after the 'd') right after doing a SetDlgItemText?
I read of a SetSel method, but don't know how to implement it if that's the right one.
CEdit control MFC, placing cursor to end of string after SetWindowText
What I have is:
someDlg::someFunction() //this is used in an EN_CHANGE event
{
//some logic stuff to get a result string
SetDlgItemText(txtInputBox, L"Hello World");
//need it to set the cursor to the end
//I tried these, but it didn't recognize (expression must have class type?)
//txtInputBox.SetSel(0, -1);
//txtInputBox.SetSel(-1);
}
void someDlg::EnChangetxtinputbox()
{
someFunction();
}
you said txtInputBox is the ID to your edit control (which should be written like so: IDC_NAME), you can pass IDs to SetDlgItemText.
what they are refering to in the link you posted is a member variable, you can't pass a member variable to SetDlgItemText. you can add a variable to a control by right clicking it in editor and clicking "Add variable".

Performantly appending (rich) text into QTextEdit or QTextBrowser in Qt

QTextEdit can be appended text to simply using append(). However, if the document is rich text, every time you append to the document, it is apparently reparsed. This seems like a bit of a trap in Qt.
If you're using the edit box as a log window and appending text in fast successions as a result of external signals, the appending can easily hang your app with no intermediate appends shown until each of the appends have completed.
How do I append rich text to a QTextEdit without it slowing down the entire UI?
If you want each append to actually show quickly & separately (instead of waiting until they've all been appended before they are shown), you need to access the internal QTextDocument:
void fastAppend(QString message,QTextEdit *editWidget)
{
const bool atBottom = editWidget->verticalScrollBar()->value() == editWidget->verticalScrollBar()->maximum();
QTextDocument* doc = editWidget->document();
QTextCursor cursor(doc);
cursor.movePosition(QTextCursor::End);
cursor.beginEditBlock();
cursor.insertBlock();
cursor.insertHtml(message);
cursor.endEditBlock();
//scroll scrollarea to bottom if it was at bottom when we started
//(we don't want to force scrolling to bottom if user is looking at a
//higher position)
if (atBottom) {
scrollLogToBottom(editWidget);
}
}
void scrollLogToBottom(QTextEdit *editWidget)
{
QScrollBar* bar = editWidget->verticalScrollBar();
bar->setValue(bar->maximum());
}
The scrolling to bottom is optional, but in logging use it's a reasonable default for UI behaviour.
Also, if your app is doing lots of other processing at the same time, appending this at the end of fastAppend, will prioritize actually getting the message displayed asap:
//show the message in output right away by triggering event loop
QCoreApplication::processEvents();
This actually seems a kind of trap in Qt. I would know why there isn't a fastAppend method directly in QTextEdit? Or are there caveats to this solution?
(My company actually paid KDAB for this advice, but this seems so silly that I thought this should be more common knowledge.)

How to catch KeyEvents when wxGrid Editor is Shown

When typing in a cell in wxGrid, the arrow keys function to go back and forward between the characters. However, depending on caret position I would like to move the cursor to the next cell when an arrow key is pressed. Currently, wxGrid is configured to capture Enter key, which makes the cursor to move downwards (to the cell below).
My question is how can I capture KeyEvent when editor is still shown.
My approach:
void Grid::OnGridCmdEditorShown( wxGridEvent& event )
{
m_IsEditorShown=true;
//Connect(wxEVT_KEY_DOWN,wxKeyEventHandler(Grid::OnKeyDown),NULL, this); //This approach did not help either
event.Skip();
}
void Grid::OnKeyDown(wxKeyEvent& event)
{
if(m_IsEditorShown) wxMessageBox("You are keying");
event.Skip();
}
When the editor is shown and say I type abc to the current cell, the MessageBox only appears when I press enter. How can catch the KeyEvents when the editor is still shown, for example, the user types a to the current cell and the MessageBox is shown.
You need to use a custom editor (probably just deriving from the standard wxGridCellTextEditor) and bind to the wxEVT_CHAR event of the editing control created in its Create().
Notice that if you want to handle the initial key press, which results in showing the editor in the first place, you need to override wxGridCellEditor::StartingKey() instead, as this key press happens before the editing control is shown.
One way that worked for me was to connect a handler to each grid editor after it had been created, by adding this to Grid constructor:
Bind(wxEVT_GRID_EDITOR_CREATED, [=](wxGridEditorCreatedEvent& event) {
event.GetControl()->Bind(wxEVT_KEY_DOWN, &Grid::OnKeyDown, this);
});
This will not handle the initial key press which results in showing the editor in the first place, but from what I understand that would not be necessary here.

Creating HyperLink in Notepad(textEdit)[MFC]

I am building a textEdit application with MFC. Is there a way to create a hyperlink automatically when a user write web address? It's like when you write a web address "www.google.com" the application detects web address and create a hyperlink right away. I have searched documents that explains about this, but couldn't find it..
and i couldn't make it..
i already have made notepad but i couldn't add the function of hyperlink on the notepad.
the following sentences are functions of hyperlink.
Clicking the text needs to open a browser window to the location specified by the text.
The cursor needs to change from the standard arrow cursor to a pointing index finger when it moves over the control.
The text in the control needs to be underlined when the cursor moves over the control.
A hyperlink control needs to display text in a different color—black just won't do.
The features that I added are:
5.A hyperlink control once visited needs to change color.
6.The hyperlink control should be accessible from the keyboard.
7.It should install some kind of hooks to allow the programmer to perform some actions when the control has the focus or when the cursor is hovering over the control.
Among the functions, What I mostly want to complete is the first one.
If I click a Hyperlink text, it should be linked to a browser window on the Internet.
Please answer and help me. Thanks.
Just use a CRichEditCtrl control (remember to call AfxInitRichEdit2 in your InitInstance). Call SetAutoURLDetect. Done.
Unfortunately this is not enough to make it work. It will display text that resembles URL as blue underlined but it will not invoke the link.
This will have to be handled by additional code. This will set needed event mask:
long lMask = m_RichEditCtrl.GetEventMask();
m_RichEditCtrl.SetEventMask(lMask | ENM_LINK);
m_RichEditCtrl.SetAutoURLDetect();
Also reflected EN_LINK will has to be handled to follow the link. For example:
void CHyperLinkInEditView::OnEnLink(NMHDR *pNMHDR, LRESULT *pResult)
{
ENLINK *p_Link = reinterpret_cast<ENLINK *>(pNMHDR);
if(p_Link && p_Link->msg == WM_LBUTTONDOWN)
{
//int iRange = m_RichEditCtrl.GetTextRange(p_enLinkInfo->chrg.cpMin, p_enLinkInfo->chrg.cpMax);
m_RichEditCtrl.SetSel(p_Link->chrg);
CString szLinkString = m_RichEditCtrl.GetSelText ();
ShellExecute(m_hWnd, L"Open", szLinkString, NULL, NULL, SW_MAXIMIZE);
}
*pResult = 0;
}
All of the above will solve requirement 1, 2, 3 (partially –text is underlined always), and 4.
I do not quite understand 5, 6 and 7.
Could you elaborate?