From 926e6e97d82b3d63103cb2297b372af5cd469ca6 Mon Sep 17 00:00:00 2001 From: Udo Hoffmann Date: Tue, 23 Feb 2021 19:04:12 +0100 Subject: [PATCH] Catch regex search exceptions and show exception message Fix #9565, close #9566 --- PowerEditor/installer/nativeLang/english.xml | 1 + PowerEditor/src/MISC/Common/Common.cpp | 42 +++++++++++ PowerEditor/src/MISC/Common/Common.h | 1 + PowerEditor/src/Notepad_plus.cpp | 10 +-- PowerEditor/src/Notepad_plus.rc | 1 + .../src/ScintillaComponent/AutoCompletion.cpp | 4 +- .../src/ScintillaComponent/FindReplaceDlg.cpp | 67 ++++++++++++++++-- .../src/ScintillaComponent/FindReplaceDlg.h | 7 +- .../ScintillaComponent/ScintillaEditView.h | 1 + .../FunctionList/functionListPanel.cpp | 6 +- .../FunctionList/functionParser.cpp | 12 ++-- PowerEditor/src/icons/moreOnTooltip.ico | Bin 0 -> 905 bytes PowerEditor/src/resource.h | 2 + scintilla/boostregex/BoostRegExSearch.cxx | 19 ++++- scintilla/include/BoostRegexSearch.h | 4 ++ scintilla/include/Scintilla.h | 2 + scintilla/win32/ScintillaWin.cxx | 20 ++++++ 17 files changed, 173 insertions(+), 26 deletions(-) create mode 100644 PowerEditor/src/icons/moreOnTooltip.ico diff --git a/PowerEditor/installer/nativeLang/english.xml b/PowerEditor/installer/nativeLang/english.xml index ed6d9c3ce..dd05fda11 100644 --- a/PowerEditor/installer/nativeLang/english.xml +++ b/PowerEditor/installer/nativeLang/english.xml @@ -1330,6 +1330,7 @@ Find in all files except exe, obj && log: + diff --git a/PowerEditor/src/MISC/Common/Common.cpp b/PowerEditor/src/MISC/Common/Common.cpp index 483e56779..f72deb52e 100644 --- a/PowerEditor/src/MISC/Common/Common.cpp +++ b/PowerEditor/src/MISC/Common/Common.cpp @@ -1018,6 +1018,48 @@ HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText) return hwndTip; } +HWND CreateToolTipRect(int toolID, HWND hWnd, HINSTANCE hInst, const PTSTR pszText, const RECT rc) +{ + if (!toolID || !hWnd || !pszText) + { + return NULL; + } + + // Create the tooltip. g_hInst is the global instance handle. + HWND hwndTip = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, + WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + hWnd, NULL, + hInst, NULL); + + if (!hwndTip) + { + return NULL; + } + + // Associate the tooltip with the tool. + TOOLINFO toolInfo = { 0 }; + toolInfo.cbSize = sizeof(toolInfo); + toolInfo.hwnd = hWnd; + toolInfo.uFlags = TTF_SUBCLASS; + toolInfo.uId = toolID; + toolInfo.lpszText = pszText; + toolInfo.rect = rc; + if (!SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolInfo)) + { + DestroyWindow(hwndTip); + return NULL; + } + + SendMessage(hwndTip, TTM_ACTIVATE, TRUE, 0); + SendMessage(hwndTip, TTM_SETMAXTIPWIDTH, 0, 200); + // Make tip stay 15 seconds + SendMessage(hwndTip, TTM_SETDELAYTIME, TTDT_AUTOPOP, MAKELPARAM((15000), (0))); + + return hwndTip; +} + bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check) { bool isOK = false; diff --git a/PowerEditor/src/MISC/Common/Common.h b/PowerEditor/src/MISC/Common/Common.h index c1042c5d3..1bcf8a3dd 100644 --- a/PowerEditor/src/MISC/Common/Common.h +++ b/PowerEditor/src/MISC/Common/Common.h @@ -186,6 +186,7 @@ generic_string intToString(int val); generic_string uintToString(unsigned int val); HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText); +HWND CreateToolTipRect(int toolID, HWND hWnd, HINSTANCE hInst, const PTSTR pszText, const RECT rc); bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check); bool isAssoCommandExisting(LPCTSTR FullPathName); diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 1c6cc7172..8abe71733 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -991,7 +991,7 @@ int Notepad_plus::getHtmlXmlEncoding(const TCHAR *fileName) const _invisibleEditView.execute(SCI_SETTARGETRANGE, startPos, endPos); auto posFound = _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(xmlHeaderRegExpr), reinterpret_cast(xmlHeaderRegExpr)); - if (posFound != -1 && posFound != -2) + if (posFound >= 0) { const char *encodingBlockRegExpr = "encoding[ \\t]*=[ \\t]*\"[^\".]+\""; _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(encodingBlockRegExpr), reinterpret_cast(encodingBlockRegExpr)); @@ -1035,10 +1035,10 @@ int Notepad_plus::getHtmlXmlEncoding(const TCHAR *fileName) const int posFound = static_cast(_invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(htmlHeaderRegExpr), reinterpret_cast(htmlHeaderRegExpr))); - if (posFound == -1 || posFound == -2) + if (posFound < 0) { posFound = static_cast(_invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(htmlHeaderRegExpr2), reinterpret_cast(htmlHeaderRegExpr2))); - if (posFound == -1 || posFound == -2) + if (posFound < 0) return -1; } _invisibleEditView.execute(SCI_SEARCHINTARGET, strlen(charsetBlock), reinterpret_cast(charsetBlock)); @@ -3000,7 +3000,7 @@ bool Notepad_plus::isConditionExprLine(int lineNumber) const char ifElseForWhileExpr[] = "((else[ \t]+)?if|for|while)[ \t]*[(].*[)][ \t]*|else[ \t]*"; auto posFound = _pEditView->execute(SCI_SEARCHINTARGET, strlen(ifElseForWhileExpr), reinterpret_cast(ifElseForWhileExpr)); - if (posFound != -1 && posFound != -2) + if (posFound >= 0) { auto end = _pEditView->execute(SCI_GETTARGETEND); if (end == endPos) @@ -3147,7 +3147,7 @@ void Notepad_plus::maintainIndentation(TCHAR ch) const char braceExpr[] = "[ \t]*\\{.*"; int posFound = static_cast(_pEditView->execute(SCI_SEARCHINTARGET, strlen(braceExpr), reinterpret_cast(braceExpr))); - if (posFound != -1 && posFound != -2) + if (posFound >= 0) { int end = int(_pEditView->execute(SCI_GETTARGETEND)); if (end == endPos2) diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index bcbae5ea5..5915584ef 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -218,6 +218,7 @@ IDI_VIEW_FILEBROWSER_OFF_ICON ICON "icons/fileBrowser_off.ico" IDI_VIEW_MONITORING_ON_ICON ICON "icons/monitoring_on.ico" IDI_VIEW_MONITORING_OFF_ICON ICON "icons/monitoring_off.ico" +IDI_MORE_ON_TOOLTIP ICON "icons/MoreOnTooltip.ico" IDR_M30_MENU MENU BEGIN diff --git a/PowerEditor/src/ScintillaComponent/AutoCompletion.cpp b/PowerEditor/src/ScintillaComponent/AutoCompletion.cpp index 9a7acff6a..90a14a5b2 100644 --- a/PowerEditor/src/ScintillaComponent/AutoCompletion.cpp +++ b/PowerEditor/src/ScintillaComponent/AutoCompletion.cpp @@ -155,7 +155,7 @@ void AutoCompletion::getWordArray(vector & wordArray, TCHAR *beg _pEditView->execute(SCI_SETSEARCHFLAGS, flags); int posFind = _pEditView->searchInTarget(expr.c_str(), int(expr.length()), 0, docLength); - while (posFind != -1 && posFind != -2) + while (posFind >= 0) { int wordStart = int(_pEditView->execute(SCI_GETTARGETSTART)); int wordEnd = int(_pEditView->execute(SCI_GETTARGETEND)); @@ -432,7 +432,7 @@ void AutoCompletion::getCloseTag(char *closeTag, size_t closeTagSize, size_t car int targetStart = _pEditView->searchInTarget(tag2find, lstrlen(tag2find), caretPos, 0); - if (targetStart == -1 || targetStart == -2) + if (targetStart < 0) return; int targetEnd = int(_pEditView->execute(SCI_GETTARGETEND)); diff --git a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp index 053b4a885..968c82a67 100644 --- a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp @@ -1840,7 +1840,7 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, const FindOption *op } if (posFind == -1) - { + { // not found if (oFindStatus) *oFindStatus = FSNotFound; //failed, or failed twice with wrap @@ -1866,11 +1866,22 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, const FindOption *op return false; } } - else if (posFind == -2) // Invalid Regular expression - { + else if (posFind < -1) + { // error NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance()).getNativeLangSpeaker(); - generic_string msg = pNativeSpeaker->getLocalizedStrFromID("find-status-invalid-re", TEXT("Find: Invalid regular expression")); - setStatusbarMessage(msg, FSNotFound); + generic_string msgGeneral; + if (posFind == -2) + { + msgGeneral = pNativeSpeaker->getLocalizedStrFromID("find-status-invalid-re", TEXT("Find: Invalid regular expression")); + } + else + { + msgGeneral = pNativeSpeaker->getLocalizedStrFromID("find-status-search-failed", TEXT("Find: Search failed")); + } + + char szMsg [511] = ""; + (*_ppEditView)->execute (SCI_GETBOOSTREGEXERRMSG, _countof (szMsg), reinterpret_cast(szMsg)); + setStatusbarMessage(msgGeneral, FSNotFound, szMsg); return false; } @@ -2202,7 +2213,7 @@ int FindReplaceDlg::processRange(ProcessOperation op, FindReplaceInfo & findRepl bool findAllFileNameAdded = false; - while (targetStart != -1 && targetStart != -2) + while (targetStart >= 0) { targetStart = pEditView->searchInTarget(pTextFind, stringSizeFind, findReplaceInfo._startRange, findReplaceInfo._endRange); @@ -2899,8 +2910,15 @@ void FindReplaceDlg::saveInMacro(size_t cmd, int cmdType) ::SendMessage(_hParent, WM_FRSAVE_INT, IDC_FRCOMMAND_EXEC, cmd); } -void FindReplaceDlg::setStatusbarMessage(const generic_string & msg, FindStatus staus) +void FindReplaceDlg::setStatusbarMessage(const generic_string & msg, FindStatus staus, char const *pTooltipMsg) { + if (_statusbarTooltipWnd) + { + ::DestroyWindow(_statusbarTooltipWnd); + _statusbarTooltipWnd = nullptr; + } + _statusbarTooltipMsg = (pTooltipMsg && (*pTooltipMsg)) ? s2ws(pTooltipMsg) : TEXT(""); + if (staus == FSNotFound) { if (!NppParameters::getInstance().getNppGUI()._muteSounds) @@ -3599,6 +3617,41 @@ void FindReplaceDlg::drawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) RECT rect; _statusBar.getClientRect(rect); ::DrawText(lpDrawItemStruct->hDC, ptStr, lstrlen(ptStr), &rect, DT_SINGLELINE | DT_VCENTER | DT_LEFT); + + if (_statusbarTooltipMsg.length() == 0) return; + + SIZE size; + ::GetTextExtentPoint32(lpDrawItemStruct->hDC, ptStr, lstrlen(ptStr), &size); + int s = (rect.bottom - rect.top) & 0x70; // limit s to available icon sizes and avoid uneven scalings + if (s > 0) + { + if (_statusbarTooltipIcon && (_statusbarTooltipIconSize != s)) + { + DestroyIcon (_statusbarTooltipIcon); + _statusbarTooltipIcon = nullptr; + } + + if (!_statusbarTooltipIcon) + _statusbarTooltipIcon = (HICON)::LoadImage(_hInst, MAKEINTRESOURCE(IDI_MORE_ON_TOOLTIP), IMAGE_ICON, s, s, 0); + + if (_statusbarTooltipIcon) + { + _statusbarTooltipIconSize = s; + rect.left = rect.left + size.cx + s / 2; + rect.top = (rect.top + rect.bottom - s) / 2; + DrawIconEx (lpDrawItemStruct->hDC, rect.left, rect.top, _statusbarTooltipIcon, s, s, 0, NULL, DI_NORMAL); + if (!_statusbarTooltipWnd) + { + rect.right = rect.left + s; + rect.bottom = rect.top + s; + _statusbarTooltipWnd = CreateToolTipRect(1, _statusBar.getHSelf(), _hInst, const_cast(_statusbarTooltipMsg.c_str()), rect); + } + } + else + { + _statusbarTooltipIconSize = 0; + } + } } bool FindReplaceDlg::replaceInFilesConfirmCheck(generic_string directory, generic_string fileTypes) diff --git a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.h b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.h index 77d1d6ca8..a86b2efc0 100644 --- a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.h +++ b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.h @@ -339,7 +339,7 @@ public : void execSavedCommand(int cmd, uptr_t intValue, const generic_string& stringValue); void clearMarks(const FindOption& opt); - void setStatusbarMessage(const generic_string & msg, FindStatus staus); + void setStatusbarMessage(const generic_string & msg, FindStatus staus, char const *pTooltipMsg = NULL); generic_string getScopeInfoForStatusBar(FindOption const *pFindOpt) const; Finder * createFinder(); bool removeFinder(Finder *finder2remove); @@ -391,6 +391,11 @@ private : StatusBar _statusBar; FindStatus _statusbarFindStatus; + generic_string _statusbarTooltipMsg; + HWND _statusbarTooltipWnd = nullptr; + HICON _statusbarTooltipIcon = nullptr; + int _statusbarTooltipIconSize = 0; + HFONT _hMonospaceFont = nullptr; std::map _controlEnableMap; diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h index 3e18b49e4..965e4d001 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h @@ -615,6 +615,7 @@ public: protected: static HINSTANCE _hLib; + static int _refCount; static UserDefineDialog _userDefineDlg; diff --git a/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp b/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp index 41c2bfe9d..42fbf13c0 100644 --- a/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp +++ b/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp @@ -100,13 +100,13 @@ size_t FunctionListPanel::getBodyClosePos(size_t begin, const TCHAR *bodyOpenSym do { - if (targetStart != -1 && targetStart != -2) // found open or close symbol + if (targetStart >= 0) // found open or close symbol { targetEnd = int((*_ppEditView)->execute(SCI_GETTARGETEND)); // Now we determinate the symbol (open or close) int tmpStart = (*_ppEditView)->searchInTarget(bodyOpenSymbol, lstrlen(bodyOpenSymbol), targetStart, targetEnd); - if (tmpStart != -1 && tmpStart != -2) // open symbol found + if (tmpStart >= 0) // open symbol found { ++cntOpen; } @@ -145,7 +145,7 @@ generic_string FunctionListPanel::parseSubLevel(size_t begin, size_t end, std::v const TCHAR *regExpr2search = dataToSearch[0].c_str(); int targetStart = (*_ppEditView)->searchInTarget(regExpr2search, lstrlen(regExpr2search), begin, end); - if (targetStart == -1 || targetStart == -2) + if (targetStart < 0) { foundPos = -1; return TEXT(""); diff --git a/PowerEditor/src/WinControls/FunctionList/functionParser.cpp b/PowerEditor/src/WinControls/FunctionList/functionParser.cpp index 4f8613579..1ba1eb7d3 100644 --- a/PowerEditor/src/WinControls/FunctionList/functionParser.cpp +++ b/PowerEditor/src/WinControls/FunctionList/functionParser.cpp @@ -392,7 +392,7 @@ void FunctionParser::funcParse(std::vector & foundInfos, size_t begin int targetEnd = 0; //foundInfos.clear(); - while (targetStart != -1 && targetStart != -2) + while (targetStart >= 0) { targetStart = int((*ppEditView)->execute(SCI_GETTARGETSTART)); targetEnd = int((*ppEditView)->execute(SCI_GETTARGETEND)); @@ -471,7 +471,7 @@ generic_string FunctionParser::parseSubLevel(size_t begin, size_t end, std::vect const TCHAR *regExpr2search = dataToSearch[0].c_str(); int targetStart = (*ppEditView)->searchInTarget(regExpr2search, lstrlen(regExpr2search), begin, end); - if (targetStart == -1 || targetStart == -2) + if (targetStart < 0) { foundPos = -1; return generic_string(); @@ -532,7 +532,7 @@ size_t FunctionZoneParser::getBodyClosePos(size_t begin, const TCHAR *bodyOpenSy do { - if (targetStart != -1 && targetStart != -2) // found open or close symbol + if (targetStart >= 0) // found open or close symbol { targetEnd = (*ppEditView)->execute(SCI_GETTARGETEND); @@ -541,7 +541,7 @@ size_t FunctionZoneParser::getBodyClosePos(size_t begin, const TCHAR *bodyOpenSy { // Now we determinate the symbol (open or close) int tmpStart = (*ppEditView)->searchInTarget(bodyOpenSymbol, lstrlen(bodyOpenSymbol), targetStart, targetEnd); - if (tmpStart != -1 && tmpStart != -2) // open symbol found + if (tmpStart >= 0) // open symbol found { ++cntOpen; } @@ -576,7 +576,7 @@ void FunctionZoneParser::classParse(vector & foundInfos, vector< pair int targetEnd = 0; - while (targetStart != -1 && targetStart != -2) + while (targetStart >= 0) { targetEnd = int((*ppEditView)->execute(SCI_GETTARGETEND)); @@ -622,7 +622,7 @@ void FunctionParser::getCommentZones(vector< pair > & commentZone, siz int targetStart = (*ppEditView)->searchInTarget(_commentExpr.c_str(), _commentExpr.length(), begin, end); int targetEnd = 0; - while (targetStart != -1 && targetStart != -2) + while (targetStart >= 0) { targetStart = int((*ppEditView)->execute(SCI_GETTARGETSTART)); targetEnd = int((*ppEditView)->execute(SCI_GETTARGETEND)); diff --git a/PowerEditor/src/icons/moreOnTooltip.ico b/PowerEditor/src/icons/moreOnTooltip.ico new file mode 100644 index 0000000000000000000000000000000000000000..c1a7c12412b5ce7ef5b764c9ac065065d2c1e284 GIT binary patch literal 905 zcmZQzU}Rus5D;Jh(h3X*85kJMfLK8R!slaTVE7K?8yGzopruy{ZLD6IhYKyg*o7a-><$O93rZ>JgZ z9Wvl?tq&~b46|Uk`!Fifru^i~9SrIx1;m0?0}n1T`R1@MWM!z*-gNaz++SX#pRsSN zx>`Ly>XI`D>*fs~?=7#K7yXG*;i?d~&9N1qp2XU1(F^wyHxQRt%6o3-Q`=)ZPDjao z=9|IY;r?M|ZS?g|Gs+im&)^ohDBIXj>O&cArtn ziQ{38(t!`02b^OY9-1?JkAIl-%KAWhT_#_gaKaBy-g(?B!sl@t{8`0U&&e>u=fRxC zs(BdW*8%3O5a$#cXjrxS1i61nMRm;b)Gn!RCzfIbCS4t$e&U#`Vl(&)3#Fbyc z7lJ-B2CWy0pSetP$Gqo1(@iaBy?5YOIQy`A!IL#{p_3Q?}GxR=IQ^*RYLp+Ht`4Ep4x5x&{oqE+b^op08!dP0$vlysTdGeUE@GcK#U@6; zAxO@TZNjv6VMdb^hYvDDJ$dNB;QJ}RbCOl^nd1F^QF48 #include #include - #include "Scintilla.h" #include "Platform.h" #include "ILoader.h" @@ -251,6 +250,8 @@ RegexSearchBase *CreateRegexSearch(CharClassify* /* charClassTable */) #endif } +std::string g_exceptionMessage; + /** * Find text in document, supporting both forward and backward * searches (just pass startPosition > endPosition to do a backward search). @@ -259,6 +260,7 @@ RegexSearchBase *CreateRegexSearch(CharClassify* /* charClassTable */) Sci::Position BoostRegexSearch::FindText(Document* doc, Sci::Position startPosition, Sci::Position endPosition, const char *regexString, bool caseSensitive, bool /*word*/, bool /*wordStart*/, int sciSearchFlags, Sci::Position *lengthRet) { + g_exceptionMessage.clear(); try { SearchParameters search; @@ -319,11 +321,24 @@ Sci::Position BoostRegexSearch::FindText(Document* doc, Sci::Position startPosit } } - catch(regex_error& /*ex*/) + catch(regex_error& ex) { // -1 is normally used for not found, -2 is used here for invalid regex + g_exceptionMessage = ex.what(); return -2; } + + catch(boost::wrapexcept& ex) + { + g_exceptionMessage = ex.what(); + return -3; + } + + catch(...) + { + g_exceptionMessage = "Unexpected exception while searching"; + return -3; + } } template diff --git a/scintilla/include/BoostRegexSearch.h b/scintilla/include/BoostRegexSearch.h index e532c356d..6325475a0 100644 --- a/scintilla/include/BoostRegexSearch.h +++ b/scintilla/include/BoostRegexSearch.h @@ -9,4 +9,8 @@ #define SCFIND_REGEXP_EMPTYMATCH_ALLOWATSTART 0x80000000 #define SCFIND_REGEXP_SKIPCRLFASONE 0x08000000 +#ifdef SCI_OWNREGEX +extern std::string g_exceptionMessage; +#endif + #endif \ No newline at end of file diff --git a/scintilla/include/Scintilla.h b/scintilla/include/Scintilla.h index b5fa09884..f5cd312ad 100644 --- a/scintilla/include/Scintilla.h +++ b/scintilla/include/Scintilla.h @@ -1173,6 +1173,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_INDEXPOSITIONFROMLINE 2714 #endif +#define SCI_GETBOOSTREGEXERRMSG 5000 + #define SCN_SCROLLED 2080 #define SCN_FOLDINGSTATECHANGED 2081 diff --git a/scintilla/win32/ScintillaWin.cxx b/scintilla/win32/ScintillaWin.cxx index 27ff52cd3..1e3c5144c 100644 --- a/scintilla/win32/ScintillaWin.cxx +++ b/scintilla/win32/ScintillaWin.cxx @@ -88,6 +88,7 @@ #include "PlatWin.h" #include "HanjaDic.h" #include "ScintillaWin.h" +#include "BoostRegexSearch.h" #ifndef SPI_GETWHEELSCROLLLINES #define SPI_GETWHEELSCROLLLINES 104 @@ -1800,6 +1801,22 @@ sptr_t ScintillaWin::SciMessage(unsigned int iMessage, uptr_t wParam, sptr_t lPa case SCI_GETDIRECTPOINTER: return reinterpret_cast(this); +#ifdef SCI_OWNREGEX + case SCI_GETBOOSTREGEXERRMSG: + { + // copies behavior of SCI_GETTEXT + if (lParam == 0) + return g_exceptionMessage.length() + 1; + if (wParam == 0) + return 0; + char *ptr = CharPtrFromSPtr(lParam); + const Sci_Position len = std::min(wParam - 1, g_exceptionMessage.length()); + strncpy (ptr, g_exceptionMessage.c_str(), len); + ptr [len] = '\0'; + return len; + } +#endif + case SCI_GRABFOCUS: ::SetFocus(MainHWND()); break; @@ -2031,6 +2048,9 @@ sptr_t ScintillaWin::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam case SCI_GETDIRECTFUNCTION: case SCI_GETDIRECTPOINTER: +#ifdef SCI_OWNREGEX + case SCI_GETBOOSTREGEXERRMSG: +#endif case SCI_GRABFOCUS: #ifdef INCLUDE_DEPRECATED_FEATURES case SCI_SETKEYSUNICODE: