From 534ebfabeaf6965c68e75de82de2442f739719d5 Mon Sep 17 00:00:00 2001 From: harrybharry Date: Wed, 26 Nov 2008 23:31:13 +0000 Subject: [PATCH] [FIX_BUG] Crash in FileDialog if too many languages or extensions were added. [FIX_BUG] Crash after handling crash (or, stop pure virtual functioncall after crash). [FIX_BUG] Notepad++ fully accessible in crash error messagepump (or, you can still go on if a crash occurs). Show shortcut for restore zoom option. git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository@358 f5eea248-9336-0410-98b8-ebc06183d4e3 --- PowerEditor/src/MISC/Common/Common.cpp | 10 ++- PowerEditor/src/MISC/Common/Common.h | 1 + PowerEditor/src/MISC/FileNameStringSplitter.h | 2 +- PowerEditor/src/Notepad_plus.cpp | 7 +- PowerEditor/src/Notepad_plus.h | 1 + PowerEditor/src/Parameters.cpp | 4 +- .../OpenSaveFileDialog/FileDialog.cpp | 71 +++++++++++++------ .../OpenSaveFileDialog/FileDialog.h | 3 +- .../WinControls/StaticDialog/StaticDialog.h | 4 +- PowerEditor/src/winmain.cpp | 19 +++-- 10 files changed, 85 insertions(+), 37 deletions(-) diff --git a/PowerEditor/src/MISC/Common/Common.cpp b/PowerEditor/src/MISC/Common/Common.cpp index e651430be..37ad44bcf 100644 --- a/PowerEditor/src/MISC/Common/Common.cpp +++ b/PowerEditor/src/MISC/Common/Common.cpp @@ -19,6 +19,7 @@ #include #include #include "Common.h" +#include "Notepad_plus.h" WcharMbcsConvertor * WcharMbcsConvertor::_pSelf = new WcharMbcsConvertor; @@ -40,12 +41,17 @@ void printInt(int int2print) { TCHAR str[32]; wsprintf(str, TEXT("%d"), int2print); - ::MessageBox(NULL, str, TEXT(""), MB_OK); + ::MessageBox(Notepad_plus::gNppHWND, str, TEXT(""), MB_OK); } void printStr(const TCHAR *str2print) { - ::MessageBox(NULL, str2print, TEXT(""), MB_OK); + ::MessageBox(Notepad_plus::gNppHWND, str2print, TEXT(""), MB_OK); +} + +void printMsg(const TCHAR *msg2print, const TCHAR *title, DWORD flags) +{ + ::MessageBox(Notepad_plus::gNppHWND, msg2print, title, flags); } void writeLog(const TCHAR *logFileName, const TCHAR *log2write) diff --git a/PowerEditor/src/MISC/Common/Common.h b/PowerEditor/src/MISC/Common/Common.h index 66b151238..41922580d 100644 --- a/PowerEditor/src/MISC/Common/Common.h +++ b/PowerEditor/src/MISC/Common/Common.h @@ -88,6 +88,7 @@ void systemMessage(const TCHAR *title); //DWORD ShortToLongPathName(LPCTSTR lpszShortPath, LPTSTR lpszLongPath, DWORD cchBuffer); void printInt(int int2print); void printStr(const TCHAR *str2print); +void printMsg(const TCHAR *msg2print, const TCHAR *title, DWORD flags = MB_OK); void writeLog(const TCHAR *logFileName, const TCHAR *log2write); int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep); int getCpFromStringValue(const char * encodingStr); diff --git a/PowerEditor/src/MISC/FileNameStringSplitter.h b/PowerEditor/src/MISC/FileNameStringSplitter.h index 8d23677d7..b787f5b78 100644 --- a/PowerEditor/src/MISC/FileNameStringSplitter.h +++ b/PowerEditor/src/MISC/FileNameStringSplitter.h @@ -27,7 +27,7 @@ public : //if (!fileNameStr) return; TCHAR *pStr = NULL; bool isInsideQuotes = false; - TCHAR str[256]; + TCHAR str[MAX_PATH]; int i = 0; bool fini = false; for (pStr = (TCHAR *)fileNameStr ; !fini ; ) diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 4930c7683..f99862cc1 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -40,6 +40,7 @@ #include "xmlMatchedTagsHighlighter.h" const TCHAR Notepad_plus::_className[32] = TEXT("Notepad++"); +HWND Notepad_plus::gNppHWND = NULL; const char *urlHttpRegExpr = "http://[a-z0-9_\\-\\+.:?&@=/%#]*"; int docTabIconIDs[] = {IDI_SAVED_ICON, IDI_UNSAVED_ICON, IDI_READONLY_ICON}; @@ -241,6 +242,8 @@ void Notepad_plus::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdL throw int(777); } + gNppHWND = _hSelf; + // In setting the startup window position, take into account that the last-saved // position might have assumed a second monitor that's no longer available. POINT newUpperLeft; @@ -3636,7 +3639,8 @@ void Notepad_plus::command(int id) break; case IDM_VIEW_ZOOMRESTORE: - _pEditView->execute(SCI_SETZOOM, _zoomOriginalValue); + //Zoom factor of 0 points means default view + _pEditView->execute(SCI_SETZOOM, 0);//_zoomOriginalValue); break; case IDM_VIEW_SYNSCROLLV: @@ -7922,6 +7926,7 @@ LRESULT Notepad_plus::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa { killAllChildren(); ::PostQuitMessage(0); + gNppHWND = NULL; return TRUE; } diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 18ab7120f..aa7b722e6 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -192,6 +192,7 @@ public: void notifyBufferChanged(Buffer * buffer, int mask); bool findInFiles(); + static HWND gNppHWND; //static handle to Notepad++ window, NULL if non-existant private: static const TCHAR _className[32]; TCHAR _nppPath[MAX_PATH]; diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 169ff6c6b..543bef1de 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -128,7 +128,7 @@ WinMenuKeyDefinition winKeyDefs[] = { //array of accelerator keys for all std me {VK_NULL, IDM_VIEW_USER_DLG, false, false, false, NULL}, //{VK_NULL, IDM_VIEW_ZOOMIN, false, false, false, NULL}, //{VK_NULL, IDM_VIEW_ZOOMOUT, false, false, false, NULL}, - {VK_NULL, IDM_VIEW_ZOOMRESTORE, false, false, false, NULL}, + //{VK_NULL, IDM_VIEW_ZOOMRESTORE, false, false, false, NULL}, {VK_0, IDM_VIEW_TOGGLE_FOLDALL, false, true, false, NULL}, {VK_F, IDM_VIEW_FOLD_CURRENT, true, true, false, NULL}, {VK_1, IDM_VIEW_FOLD_1, false, true, false, NULL}, @@ -216,7 +216,7 @@ ScintillaKeyDefinition scintKeyDefs[] = { //array of accelerator keys for all po {TEXT("SCI_FORMFEED"), SCI_FORMFEED, false, false, false, 0, 0}, {TEXT("SCI_ZOOMIN"), SCI_ZOOMIN, true, false, false, VK_ADD, IDM_VIEW_ZOOMIN}, {TEXT("SCI_ZOOMOUT"), SCI_ZOOMOUT, true, false, false, VK_SUBTRACT,IDM_VIEW_ZOOMOUT}, - {TEXT("SCI_SETZOOM"), SCI_SETZOOM, true, false, false, VK_DIVIDE, 0}, + {TEXT("SCI_SETZOOM"), SCI_SETZOOM, true, false, false, VK_DIVIDE, IDM_VIEW_ZOOMRESTORE}, {TEXT("SCI_SELECTIONDUPLICATE"), SCI_SELECTIONDUPLICATE, true, false, false, VK_D, IDM_EDIT_DUP_LINE}, {TEXT("SCI_LINESJOIN"), SCI_LINESJOIN, false, false, false, 0, 0}, {TEXT("SCI_SCROLLCARET"), SCI_SCROLLCARET, false, false, false, 0, 0}, diff --git a/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.cpp b/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.cpp index 2adcf9fc5..33edc2a8a 100644 --- a/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.cpp +++ b/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.cpp @@ -22,13 +22,12 @@ FileDialog *FileDialog::staticThis = NULL; //int FileDialog::_dialogFileBoxId = (NppParameters::getInstance())->getWinVersion() < WV_W2K?edt1:cmb13; FileDialog::FileDialog(HWND hwnd, HINSTANCE hInst) - : _nbCharFileExt(0), _nbExt(0) + : _nbCharFileExt(0), _nbExt(0), _fileExt(NULL) { staticThis = this; //for (int i = 0 ; i < nbExtMax ; i++) // _extArray[i][0] = '\0'; - memset(_fileExt, 0x00, sizeof(_fileExt)); _fileName[0] = '\0'; _winVersion = (NppParameters::getInstance())->getWinVersion(); @@ -38,7 +37,6 @@ FileDialog::FileDialog(HWND hwnd, HINSTANCE hInst) _ofn.lStructSize = sizeof(OPENFILENAME); _ofn.hwndOwner = hwnd; _ofn.hInstance = hInst; - _ofn.lpstrFilter = _fileExt; _ofn.lpstrCustomFilter = (LPTSTR) NULL; _ofn.nMaxCustFilter = 0L; _ofn.nFilterIndex = 1L; @@ -59,6 +57,15 @@ FileDialog::FileDialog(HWND hwnd, HINSTANCE hInst) _ofn.FlagsEx = 0; } +FileDialog::~FileDialog() +{ + if (_fileExt) + { + delete[] _fileExt; + _fileExt = NULL; + } +} + // This function set and concatenate the filter into the list box of FileDialog. // The 1st parameter is the description of the file type, the 2nd .. Nth parameter(s) is (are) // the file extension which should be ".WHATEVER", otherwise it (they) will be considered as @@ -72,7 +79,6 @@ void FileDialog::setExtFilter(const TCHAR *extText, const TCHAR *ext, ...) //if (_nbExt < nbExtMax) // lstrcpy(_extArray[_nbExt++], ext); // - std::generic_string extFilter = extText; std::generic_string exts; va_list pArg; @@ -94,18 +100,7 @@ void FileDialog::setExtFilter(const TCHAR *extText, const TCHAR *ext, ...) // remove the last ';' exts = exts.substr(0, exts.length()-1); - extFilter += TEXT(" ("); - extFilter += exts + TEXT(")"); - - TCHAR *pFileExt = _fileExt + _nbCharFileExt; - //memcpy(pFileExt, extFilter.c_str(), extFilter.length() + 1); - lstrcpy(pFileExt, extFilter.c_str()); - _nbCharFileExt += extFilter.length() + 1; - - pFileExt = _fileExt + _nbCharFileExt; - //memcpy(pFileExt, exts.c_str(), exts.length() + 1); - lstrcpy(pFileExt, exts.c_str()); - _nbCharFileExt += exts.length() + 1; + setExtsFilter(extText, exts.c_str()); } int FileDialog::setExtsFilter(const TCHAR *extText, const TCHAR *exts) @@ -115,21 +110,47 @@ int FileDialog::setExtsFilter(const TCHAR *extText, const TCHAR *exts) // lstrcpy(_extArray[_nbExt++], exts); // std::generic_string extFilter = extText; + TCHAR *oldFilter = NULL; extFilter += TEXT(" ("); extFilter += exts; - extFilter += TEXT(")"); - + extFilter += TEXT(")"); + + // Resize filter buffer + int nbCharAdditional = extFilter.length() + lstrlen(exts) + 3; // 3 additional for nulls + if (_fileExt) + { + oldFilter = new TCHAR[_nbCharFileExt]; + memcpy(oldFilter, _fileExt, _nbCharFileExt * sizeof(TCHAR)); + + delete[] _fileExt; + _fileExt = NULL; + } + + int nbCharNewFileExt = _nbCharFileExt + nbCharAdditional; + _fileExt = new TCHAR[nbCharNewFileExt]; + memset(_fileExt, 0, nbCharNewFileExt * sizeof(TCHAR)); + + // Restore previous filters + if (oldFilter) + { + memcpy(_fileExt, oldFilter, _nbCharFileExt * sizeof(TCHAR)); + delete[] oldFilter; + oldFilter = NULL; + } + + // Append new filter TCHAR *pFileExt = _fileExt + _nbCharFileExt; lstrcpy(pFileExt, extFilter.c_str()); - //memcpy(pFileExt, extFilter.c_str(), extFilter.length() + 1); _nbCharFileExt += extFilter.length() + 1; pFileExt = _fileExt + _nbCharFileExt; lstrcpy(pFileExt, exts); - //memcpy(pFileExt, exts, lstrlen(exts) + 1); _nbCharFileExt += lstrlen(exts) + 1; + // Set file dialog pointer + _ofn.lpstrFilter = _fileExt; + return _nbExt; } @@ -291,15 +312,21 @@ static generic_string addExt(HWND textCtrl, HWND typeCtrl) { ::GetWindowText(textCtrl, fn, MAX_PATH); int i = ::SendMessage(typeCtrl, CB_GETCURSEL, 0, 0); - TCHAR ext[256]; + + int cbTextLen = ::SendMessage(typeCtrl, CB_GETLBTEXTLEN, i, 0); + TCHAR * ext = new TCHAR[cbTextLen + 1]; ::SendMessage(typeCtrl, CB_GETLBTEXT, i, (LPARAM)ext); + TCHAR *pExt = get1stExt(ext); if (*fn != '\0') { generic_string fnExt = changeExt(fn, pExt); ::SetWindowText(textCtrl, fnExt.c_str()); } - return pExt; + + generic_string returnExt = pExt; + delete[] ext; + return returnExt; }; diff --git a/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.h b/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.h index 421629e34..abe1a3ff2 100644 --- a/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.h +++ b/PowerEditor/src/WinControls/OpenSaveFileDialog/FileDialog.h @@ -115,6 +115,7 @@ class FileDialog { public: FileDialog(HWND hwnd, HINSTANCE hInst); + ~FileDialog(); void setExtFilter(const TCHAR *, const TCHAR *, ...); int setExtsFilter(const TCHAR *extText, const TCHAR *exts); @@ -133,7 +134,7 @@ protected : private: TCHAR _fileName[MAX_PATH*8]; - TCHAR _fileExt[MAX_PATH*10]; + TCHAR * _fileExt; int _nbCharFileExt; stringVector _fileNames; diff --git a/PowerEditor/src/WinControls/StaticDialog/StaticDialog.h b/PowerEditor/src/WinControls/StaticDialog/StaticDialog.h index 72670c684..9b42e1ffb 100644 --- a/PowerEditor/src/WinControls/StaticDialog/StaticDialog.h +++ b/PowerEditor/src/WinControls/StaticDialog/StaticDialog.h @@ -47,8 +47,10 @@ class StaticDialog : public Window public : StaticDialog() : Window() {}; ~StaticDialog(){ - if (isCreated()) + if (isCreated()) { + ::SetWindowLongPtr(_hSelf, GWL_USERDATA, (long)NULL); //Prevent run_dlgProc from doing anything, since its virtual destroy(); + } }; virtual void create(int dialogID, bool isRTL = false); diff --git a/PowerEditor/src/winmain.cpp b/PowerEditor/src/winmain.cpp index a8268fa0a..fef7870f6 100644 --- a/PowerEditor/src/winmain.cpp +++ b/PowerEditor/src/winmain.cpp @@ -289,9 +289,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR cmdLineAnsi, int nCmdSh TCHAR str[50] = TEXT("God Damned Exception : "); TCHAR code[10]; wsprintf(code, TEXT("%d"), i); - ::MessageBox(NULL, lstrcat(str, code), TEXT("Notepad++ Exception"), MB_OK); + printMsg(lstrcat(str, code), TEXT("Notepad++ Exception")); + doException(notepad_plus_plus); } - doException(notepad_plus_plus); } catch (const Win32Exception & ex) { TCHAR message[1024]; //TODO: sane number wsprintf(message, TEXT("An exception occured. Notepad++ cannot recover and must be shut down.\r\nThe exception details are as follows:\r\n") @@ -301,10 +301,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR cmdLineAnsi, int nCmdSh TEXT("Code:\t0x%08X\r\nType:\t%s\r\nException address: 0x%08X"), #endif ex.code(), ex.what(), ex.where()); - ::MessageBox(NULL, message, TEXT("Win32Exception"), MB_OK | MB_ICONERROR); + printMsg(message, TEXT("Win32Exception"), MB_OK | MB_ICONERROR); doException(notepad_plus_plus); } catch(std::exception ex) { - ::MessageBoxA(NULL, ex.what(), "C++ Exception", MB_OK); +#ifdef UNICODE + const wchar_t * text = WcharMbcsConvertor::getInstance()->char2wchar(ex.what(), CP_ACP); + printMsg(text, TEXT("C++ Exception")); +#else + printMsg(ex.what(), TEXT("C++ Exception")); +#endif doException(notepad_plus_plus); } catch(...) { //this shouldnt ever have to happen doException(notepad_plus_plus); @@ -315,11 +320,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR cmdLineAnsi, int nCmdSh void doException(Notepad_plus & notepad_plus_plus) { Win32Exception::removeHandler(); //disable exception handler after excpetion, we dont want corrupt data structurs to crash the exception handler - ::MessageBox(NULL, TEXT("Notepad++ will attempt to save any unsaved data. However, dataloss is very likely."), TEXT("Recovery initiating"), MB_OK | MB_ICONINFORMATION); + printMsg(TEXT("Notepad++ will attempt to save any unsaved data. However, dataloss is very likely."), TEXT("Recovery initiating"), MB_OK | MB_ICONINFORMATION); bool res = notepad_plus_plus.emergency(); if (res) { - ::MessageBox(NULL, TEXT("Notepad++ was able to successfully recover some unsaved documents, or nothing to be saved could be found.\r\nYou can find the results at C:\\N++RECOV"), TEXT("Recovery success"), MB_OK | MB_ICONINFORMATION); + printMsg(TEXT("Notepad++ was able to successfully recover some unsaved documents, or nothing to be saved could be found.\r\nYou can find the results at C:\\N++RECOV"), TEXT("Recovery success"), MB_OK | MB_ICONINFORMATION); } else { - ::MessageBox(NULL, TEXT("Unfortunatly, Notepad++ was not able to save your work. We are sorry for any lost data."), TEXT("Recovery failure"), MB_OK | MB_ICONERROR); + printMsg(TEXT("Unfortunatly, Notepad++ was not able to save your work. We are sorry for any lost data."), TEXT("Recovery failure"), MB_OK | MB_ICONERROR); } }