Hi, I noticed that if I have a SetStatusText() function call inside the wxStyledTextCtrl's EVT_STC_UPDATEUI event handler, the brace highlight failed.
I'm using the Windows XP system, MinGW-Build GCC 5.2 compiler. See the below code snippet:
======================
void AppFrame::OnUpdate(wxStyledTextEvent &WXUNUSED(event))
{
int min = m_edit->GetCurrentPos ();
int max = m_edit->BraceMatch (min);
if (max > (min+1)) {
m_edit->BraceHighlight (min, max);
int pos = m_edit->GetCurrentLine();
static wxString msg;
msg.Printf(_("Line %d, Column %d"), m_edit->GetCurrentLine() + 1, m_edit->GetColumn(pos) + 1);
// note that if I comment out the below line, the bug disappeared
SetStatusText(msg, 0);
}else{
m_edit->BraceBadLight (min);
}
}======================SetStatusText(msg, 0) will destroy the previous BraceHighlight()'s behaviour.
To demonstrate this bug, you can just build the stc sample with my attached patch, I'm testing it under the wx trunk, also this bug exists in wx 3.0.2 release. But the official SciTE 3.6.2 for Windows does not show such issue, so I guess it is a bug inside the wx or the wx platform support for scintilla control.
Here is the steps to reproduce:
1, apply my attached path
2, build the stc(styledtextctrl) sample in the code repo
3, run the stc sample, and open a cpp file which have below contents.
======================
void main( )
{
}
======================
4, first, mouse click before the "(", you will noticed the brace highlight works OK for the "( )".
5, then, mouse click before the "{", you will noticed a new brace highlight on the "{", but "}" is not highlighted. Also the previous highlighted "( )" is still there.
That's the bug in step 5!
If you comment out the call "SetStatusText(msg, 0);", everything works fine!
Debugged for a while, I noticed that internally BraceHighlight() function will call the function:======================
bool Editor::AbandonPaint() {
if ((paintState == painting) && !paintingAllText) {
paintState = paintAbandoned;
}
return paintState == paintAbandoned;
}======================
And once this happens, a refresh() function is called through "stc->Refresh(false);", see below:
======================
void ScintillaWX::DoPaint(wxDC* dc, wxRect rect) {
paintState = painting;
AutoSurface surfaceWindow(dc, this);
if (surfaceWindow) {
rcPaint = PRectangleFromwxRect(rect);
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
ClipChildren(*dc, rcPaint);
Paint(surfaceWindow, rcPaint);
surfaceWindow->Release();
}
if (paintState == paintAbandoned) {
// Painting area was insufficient to cover new styling or brace
// highlight positions. So trigger a new paint event that will
// repaint the whole window.
stc->Refresh(false);
#if defined(__WXOSX__)
// On Mac we also need to finish the current paint to make sure that
// everything is on the screen that needs to be there between now and
// when the next paint event arrives.
FullPaintDC(dc);
#endif
}
paintState = notPainting;
}
======================
What's the strange thing is: when I received the paint event, I see that:======================
void wxStyledTextCtrl::OnPaint(wxPaintEvent& WXUNUSED(evt)) {
#ifdef __WXGTK__
wxBufferedPaintDC dc(this);
#else
wxPaintDC dc(this);
#endif
m_swx->DoPaint(&dc, GetUpdateRegion().GetBox());
}
======================
GetUpdateRegion().GetBox() only get a line region cover the "{", not the whole client area. So that the "}" is not highlighted, and the previous highlighted braces are not cleared.
Any one can help? Thanks.
In-fact this bug also happens in the Codeblocks internal wxScintilla control, you can see discussions here:
http://forums.codeblocks.org/index.php/topic,20795.msg141916.html#msg141916And you can also see the badly highlighted braces in the screen shot image:
http://i683.photobucket.com/albums/vv194/ollydbg_cb/2015-12-25%2012%2029%2037_zpsciuajuti.pngBTW: in stc sample, I think the code of Edit::OnBraceMatch is not correct.
======================void Edit::OnBraceMatch (wxCommandEvent &WXUNUSED(event)) {
int min = GetCurrentPos ();
int max = BraceMatch (min);
if (max > (min+1)) {
BraceHighlight (min+1, max);
SetSelection (min+1, max);
}else{
BraceBadLight (min);
}
}
======================
BraceHighlight (min+1, max); should be BraceHighlight (min, max);
In my attached patch, I don't change this, but I use the correct code in my added AppFrame::OnUpdate() function.
Asmwarrior(C::B developer)