Text Selection Change Event for wxTextCtrl
Text Selection Change Event for wxTextCtrl
Is there a selection changed event for wxTextCtrl? What I am trying to do is get the "number of characters" which are selected as the selection changes.
Re: Text Selection Change Event for wxTextCtrl
As you probably already guessed: No.
Use the source, Luke!
Re: Text Selection Change Event for wxTextCtrl
Hi,
What is you wx version and OS?
Thank you.
What is you wx version and OS?
Thank you.
Re: Text Selection Change Event for wxTextCtrl
Windows 8.1 OS and wxWidgets 3.1. Perhaps, windows API allows for it?
Re: Text Selection Change Event for wxTextCtrl
Hi,
Yes, and not just Windows API. GTK and OSX implementation are also available.
There is a ticket on trac about it even.
Thank you.
Yes, and not just Windows API. GTK and OSX implementation are also available.
There is a ticket on trac about it even.
Thank you.
Re: Text Selection Change Event for wxTextCtrl
Just to be complete: here is the ticket with the patch implementing the feature.
Please apply, test and leave a comment, so that it could be included in the next release.
Thank you.
Please apply, test and leave a comment, so that it could be included in the next release.
Thank you.
Re: Text Selection Change Event for wxTextCtrl
In addition to the proper library patch referenced above, here is a quick untested MSW only hack that obtains information about selection change.
Please notice that you get the message whenever the cursor position changes as well. I recommend running the test code below and observing what gets logged after which user actions.
Please notice that you get the message whenever the cursor position changes as well. I recommend running the test code below and observing what gets logged after which user actions.
Code: Select all
#include <wx/wx.h>
#if defined(__WXMSW__) && defined(wxUSE_RICHEDIT)
#include <richedit.h>
class MyTextCtrl : public wxTextCtrl
{
public:
MyTextCtrl (wxWindow* parent, wxWindowID id,
const wxString& value = wxEmptyString,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxTextCtrlNameStr)
: wxTextCtrl(parent, id, value, pos, size, style | wxTE_RICH2, validator, name)
{
LRESULT flags = ::SendMessage(GetHWND(), EM_GETEVENTMASK, 0, 0);
if ( flags != 0 )
::SendMessage(GetHWND(), EM_SETEVENTMASK, 0, (LPARAM)(flags | ENM_SELCHANGE));
m_prevSeltyp = SEL_EMPTY;
m_ignoreConsecutiveSelEmptyNotifications = true;
}
void SetIgnoreConsecutiveSelEmptyNotifications(bool ignore)
{
m_ignoreConsecutiveSelEmptyNotifications = ignore;
}
bool GetIgnoreConsecutiveSelEmptyNotifications() const
{
return m_ignoreConsecutiveSelEmptyNotifications;
}
virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) wxOVERRIDE
{
const NMHDR* hdr = (NMHDR*)lParam;
if ( hdr->code == EN_SELCHANGE )
{
const SELCHANGE* selChange = (SELCHANGE*)lParam;
wxString selectionType = "EN_SELCHANGE:";
if ( selChange->seltyp == SEL_EMPTY )
{
if ( m_prevSeltyp == SEL_EMPTY && m_ignoreConsecutiveSelEmptyNotifications )
return true;
selectionType += " SEL_EMPTY";
}
else
{
if ( selChange->seltyp & SEL_TEXT )
selectionType+= " SEL_TEXT";
if ( selChange->seltyp & SEL_OBJECT )
selectionType += " SEL_OBJECT";
if ( selChange->seltyp & SEL_MULTICHAR )
selectionType += " SEL_MULTICHAR";
if ( selChange->seltyp & SEL_MULTIOBJECT )
selectionType += " SEL_MULTIOBJECT";
}
m_prevSeltyp = selChange->seltyp;
wxLogMessage("%s (%ld, %ld)", selectionType, selChange->chrg.cpMin, selChange->chrg.cpMax);
return true;
}
return wxTextCtrl::MSWOnNotify(idCtrl, lParam, result);
}
private:
WORD m_prevSeltyp;
bool m_ignoreConsecutiveSelEmptyNotifications;
};
#else
typedef wxTextCtrl MyTextCtrl;
#endif // #if defined(__WXMSW__) && defined(wxUSE_RICHEDIT)
class MyFrame : public wxFrame
{
public:
MyFrame() : wxFrame(NULL, wxID_ANY, "EN_SELCHANGE Test", wxDefaultPosition, wxSize(800, 600))
{
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
MyTextCtrl* editCtrl = new MyTextCtrl(this, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
mainSizer->Add(editCtrl, 3, wxEXPAND | wxALL , 5);
wxTextCtrl* logCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
mainSizer->Add(logCtrl, 2, wxEXPAND | wxALL , 5);
wxLog::SetActiveTarget(new wxLogTextCtrl(logCtrl));
SetSizer(mainSizer);
}
};
class MyApp : public wxApp
{
public:
bool OnInit()
{
(new MyFrame)->Show();
return true;
}
}; wxIMPLEMENT_APP(MyApp);