diff --git a/PowerEditor/src/MISC/Process/Process.cpp b/PowerEditor/src/MISC/Process/Process.cpp index 4fba65252..855d262b7 100644 --- a/PowerEditor/src/MISC/Process/Process.cpp +++ b/PowerEditor/src/MISC/Process/Process.cpp @@ -16,280 +16,16 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "precompiledHeaders.h" +#include "Parameters.h" #include "process.h" -BOOL Process::run() + +void Process::run() { - BOOL result = TRUE; - - // stdout & stderr pipes for process to write - HANDLE hPipeOutW = NULL; - HANDLE hPipeErrW = NULL; - - HANDLE hListenerStdOutThread = NULL; - HANDLE hListenerStdErrThread = NULL; - - HANDLE hWaitForProcessEndThread = NULL; - - HANDLE hListenerEvent[2]; - hListenerEvent[0] = NULL; - hListenerEvent[1] = NULL; - - SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; // inheritable handle - - try { - // Create stdout pipe - if (!::CreatePipe(&_hPipeOutR, &hPipeOutW, &sa, 0)) - throw std::runtime_error("Create stdout pipe failed"); - - // Create stderr pipe - if (!::CreatePipe(&_hPipeErrR, &hPipeErrW, &sa, 0)) - throw std::runtime_error("Create stderr pipe failed"); - - STARTUPINFO startup; - PROCESS_INFORMATION procinfo; - ::ZeroMemory(&startup, sizeof(startup)); - startup.cb = sizeof(startup); - startup.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; - startup.wShowWindow = (_type == WIN32_PROG)?SW_SHOW:SW_HIDE; // hidden console window - startup.hStdInput = NULL; // not used - startup.hStdOutput = hPipeOutW; - startup.hStdError = hPipeErrW; - - generic_string cmd = TEXT("\""); - cmd += _command; - cmd += TEXT("\""); - - if (_args[0]) - { - cmd += TEXT(" "); - cmd += _args; - } - BOOL started = ::CreateProcess(NULL, // command is part of input generic_string - (TCHAR *)cmd.c_str(), // (writeable) command generic_string - NULL, // process security - NULL, // thread security - TRUE, // inherit handles flag - (_type == WIN32_PROG)?NULL:CREATE_SUSPENDED, // flags - NULL, // inherit environment - _curDir.c_str(), // inherit directory - &startup, // STARTUPINFO - &procinfo); // PROCESS_INFORMATION - - _hProcess = procinfo.hProcess; - _hProcessThread = procinfo.hThread; - - if(!started) - throw std::runtime_error("CreateProcess function call failed"); - - if (_type == CONSOLE_PROG) - { - hListenerEvent[0] = ::CreateEvent(NULL, FALSE, FALSE, TEXT("listenerEvent")); - if(!hListenerEvent[0]) - throw std::runtime_error("Create listenerEvent failed"); - - hListenerEvent[1] = ::CreateEvent(NULL, FALSE, FALSE, TEXT("listenerStdErrEvent")); - if(!hListenerEvent[1]) - throw std::runtime_error("Create listenerStdErrEvent failed"); - - - // The process is running so we set this to FALSE - _bProcessEnd = FALSE; - - hWaitForProcessEndThread = ::CreateThread(NULL, 0, staticWaitForProcessEnd, this, 0, NULL); - if (!hWaitForProcessEndThread) - throw std::runtime_error("CreateThread for staticWaitForProcessEnd failed"); - - hListenerStdOutThread = ::CreateThread(NULL, 0, staticListenerStdOut, this, 0, NULL); - if (!hListenerStdOutThread) - throw std::runtime_error("CreateThread for staticListenerStdOut failed"); - - hListenerStdErrThread = ::CreateThread(NULL, 0, staticListenerStdErr, this, 0, NULL); - if (!hListenerStdErrThread) - throw std::runtime_error("CreateThread for staticListenerStdErr failed"); - - // We wait until the process is over - // TO DO: This should be a bit secured in case something happen and the - // _bProcessEnd variable never gets set to TRUE... (by checking process - // state as well for instance to see if it is still running...) - while (!_bProcessEnd) - { - MSG msg; - while( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE)) - { - if( msg.message == WM_QUIT) - { - ::PostQuitMessage(0); - // We do not exit but simply break in order to close - // handles properly - _bProcessEnd = TRUE; - break; - } - else - { - ::TranslateMessage( &msg); - ::DispatchMessage( &msg); - } - } - } - } - } catch (int coderr){ - TCHAR str[10]; - wsprintf(str, TEXT("%d"), coderr); - ::MessageBox(NULL, str, TEXT("Exception :"), MB_OK); - } - - // on va fermer toutes les handles - if (hPipeOutW) - ::CloseHandle(hPipeOutW); - if (hPipeErrW) - ::CloseHandle(hPipeErrW); - if (_hPipeOutR) - ::CloseHandle(_hPipeOutR); - if (_hPipeErrR) - ::CloseHandle(_hPipeErrR); - if (hListenerStdOutThread) - ::CloseHandle(hListenerStdOutThread); - if (hListenerStdErrThread) - ::CloseHandle(hListenerStdErrThread); - if (hWaitForProcessEndThread) - ::CloseHandle(hWaitForProcessEndThread); - if (hListenerEvent[0]) - ::CloseHandle(hListenerEvent[0]); - if (hListenerEvent[1]) - ::CloseHandle(hListenerEvent[1]); - - return result; + TCHAR *opVerb = TEXT("open"); + winVer winVersion = (NppParameters::getInstance())->getWinVersion(); + if (winVersion == WV_VISTA || winVersion == WV_WIN7) + opVerb = TEXT("runas"); + ::ShellExecute(NULL, opVerb, _command.c_str(), _args.c_str(), _curDir.c_str(), SW_SHOWNORMAL); } - -#define MAX_LINE_LENGTH 1024 - -void Process::listenerStdOut() -{ - //BOOL Result = 0; - //DWORD size = 0; - DWORD bytesAvail = 0; - BOOL result = 0; - HANDLE hListenerEvent = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("listenerEvent")); - //FILE *fp = NULL; - - int taille = 0; - TCHAR bufferOut[MAX_LINE_LENGTH + 1]; - //TCHAR bufferErr[MAX_LINE_LENGTH + 1]; - - int nExitCode = STILL_ACTIVE; - - DWORD outbytesRead; - - ::ResumeThread(_hProcessThread); - - for(;;) - { // got data - memset(bufferOut,0x00,MAX_LINE_LENGTH + 1); - //memset(bufferErr,0x00,MAX_LINE_LENGTH + 1); - taille = sizeof(bufferOut) - sizeof(TCHAR); - - Sleep(50); - - if (!::PeekNamedPipe(_hPipeOutR, bufferOut, taille, &outbytesRead, &bytesAvail, NULL)) - { - bytesAvail = 0; - break; - } - - if(outbytesRead) - { - result = :: ReadFile(_hPipeOutR, bufferOut, taille, &outbytesRead, NULL); - if ((!result) && (outbytesRead == 0)) - break; - } - //outbytesRead = lstrlen(bufferOut); - bufferOut[outbytesRead] = '\0'; - generic_string s; - s.assign(bufferOut); - _stdoutStr += s; - - if (::GetExitCodeProcess(_hProcess, (unsigned long*)&nExitCode)) - { - if (nExitCode != STILL_ACTIVE) - break; // EOF condition - } - //else - //break; - } - _exitCode = nExitCode; - - if(!::SetEvent(hListenerEvent)) - { - ::MessageBox(NULL, TEXT("SetEvent function call failed"), TEXT("Thread listenerStdOut"), MB_OK); - } -} - -void Process::listenerStdErr() -{ - //BOOL Result = 0; - //DWORD size = 0; - DWORD bytesAvail = 0; - BOOL result = 0; - HANDLE hListenerEvent = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("listenerStdErrEvent")); - - int taille = 0; - //TCHAR bufferOut[MAX_LINE_LENGTH + 1]; - TCHAR bufferErr[MAX_LINE_LENGTH + 1]; - - int nExitCode = STILL_ACTIVE; - - DWORD errbytesRead; - - ::ResumeThread(_hProcessThread); - - for(;;) - { // got data - memset(bufferErr, 0x00, MAX_LINE_LENGTH + 1); - taille = sizeof(bufferErr) - sizeof(TCHAR); - - Sleep(50); - - if (!::PeekNamedPipe(_hPipeErrR, bufferErr, taille, &errbytesRead, &bytesAvail, NULL)) - { - bytesAvail = 0; - break; - } - - if(errbytesRead) - { - result = :: ReadFile(_hPipeErrR, bufferErr, taille, &errbytesRead, NULL); - if ((!result) && (errbytesRead == 0)) - break; - } - //outbytesRead = lstrlen(bufferOut); - bufferErr[errbytesRead] = '\0'; - generic_string s; - s.assign(bufferErr); - _stderrStr += s; - - if (::GetExitCodeProcess(_hProcess, (unsigned long*)&nExitCode)) - { - if (nExitCode != STILL_ACTIVE) - break; // EOF condition - } - } - - if(!::SetEvent(hListenerEvent)) - { - ::MessageBox(NULL, TEXT("SetEvent function call failed"), TEXT("Thread stdout listener"), MB_OK); - } -} - -void Process::waitForProcessEnd() -{ - HANDLE hListenerEvent[2]; - hListenerEvent[0] = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("listenerEvent")); - hListenerEvent[1] = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("listenerStdErrEvent")); - - ::WaitForSingleObject(_hProcess, INFINITE); - ::WaitForMultipleObjects(2, hListenerEvent, TRUE, INFINITE); - - _bProcessEnd = TRUE; -} diff --git a/PowerEditor/src/MISC/Process/Process.h b/PowerEditor/src/MISC/Process/Process.h index f374ab183..6f5649a03 100644 --- a/PowerEditor/src/MISC/Process/Process.h +++ b/PowerEditor/src/MISC/Process/Process.h @@ -25,76 +25,15 @@ enum progType {WIN32_PROG, CONSOLE_PROG}; class Process { public: - Process(progType pt = WIN32_PROG) : _type(pt) {}; - Process(const TCHAR *cmd, const TCHAR *args, const TCHAR *cDir, progType pt = WIN32_PROG) - : _type(pt), _stdoutStr(TEXT("")), _stderrStr(TEXT("")), _hPipeOutR(NULL), - _hPipeErrR(NULL), _hProcess(NULL), _hProcessThread(NULL), - _command(cmd), _args(args), _curDir(cDir), _bProcessEnd(TRUE) - {}; + Process(const TCHAR *cmd, const TCHAR *args, const TCHAR *cDir) + :_command(cmd), _args(args), _curDir(cDir){}; - BOOL run(); - - const TCHAR * getStdout() const { - return _stdoutStr.c_str(); - }; - - const TCHAR * getStderr() const { - return _stderrStr.c_str(); - }; - - int getExitCode() const { - return _exitCode; - }; - - bool hasStdout() { - return (_stdoutStr.compare(TEXT("")) != 0); - }; - - bool hasStderr() { - return (_stderrStr.compare(TEXT("")) != 0); - }; + void run(); protected: - progType _type; - - // LES ENTREES generic_string _command; generic_string _args; generic_string _curDir; - - // LES SORTIES - generic_string _stdoutStr; - generic_string _stderrStr; - int _exitCode; - - // LES HANDLES - HANDLE _hPipeOutR; - HANDLE _hPipeErrR; - HANDLE _hProcess; - HANDLE _hProcessThread; - - BOOL _bProcessEnd; - - //UINT _pid; // process ID assigned by caller - - static DWORD WINAPI staticListenerStdOut(void * myself){ - ((Process *)myself)->listenerStdOut(); - return 0; - }; - static DWORD WINAPI staticListenerStdErr(void * myself) { - ((Process *)myself)->listenerStdErr(); - return 0; - }; - static DWORD WINAPI staticWaitForProcessEnd(void * myself) { - ((Process *)myself)->waitForProcessEnd(); - return 0; - }; - - void listenerStdOut(); - void listenerStdErr(); - void waitForProcessEnd(); - - void error(const TCHAR *txt2display, BOOL & returnCode, int errCode); }; #endif //PROCESSUS_H diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index 7fccd0e50..773d206cc 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -939,11 +939,11 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lPa return (_macro.empty())?0:MACRO_RECORDING_HAS_STOPPED; case WM_FRSAVE_INT: - _macro.push_back(recordedMacroStep(wParam, 0, lParam, NULL)); + _macro.push_back(recordedMacroStep(wParam, 0, lParam, NULL, recordedMacroStep::mtSavedSnR)); break; case WM_FRSAVE_STR: - _macro.push_back(recordedMacroStep(wParam, 0, 0, (const TCHAR *)lParam)); + _macro.push_back(recordedMacroStep(wParam, 0, 0, (const TCHAR *)lParam, recordedMacroStep::mtSavedSnR)); break; case WM_MACRODLGRUNMACRO: diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index 224a11206..1099c18f6 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -1757,6 +1757,7 @@ void Notepad_plus::command(int id) generic_string param = TEXT("-verbose -v"); param += VERSION_VALUE; Process updater(updaterFullPath.c_str(), param.c_str(), updaterDir.c_str()); + updater.run(); break; } diff --git a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp index 631fbb142..e60339421 100644 --- a/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScitillaComponent/FindReplaceDlg.cpp @@ -1286,9 +1286,12 @@ bool FindReplaceDlg::processFindNext(const TCHAR *txt2find, const FindOption *op int start = posFind;//int((*_ppEditView)->execute(SCI_GETTARGETSTART)); int end = int((*_ppEditView)->execute(SCI_GETTARGETEND)); - // to make sure the found result is visible + // to make sure the found result is visible: + // prevent recording of absolute positioning commands issued in the process + (*_ppEditView)->execute(SCI_STOPRECORD); Searching::displaySectionCentered(start, end, *_ppEditView, pOptions->_whichDirection == DIR_DOWN); - + if (::SendMessage(_hParent, WM_GETCURRENTMACROSTATUS,0,0) == MACRO_RECORDING_IN_PROGRESS) + (*_ppEditView)->execute(SCI_STARTRECORD); delete [] pText; return true; diff --git a/PowerEditor/src/WinControls/Preference/preference.rc b/PowerEditor/src/WinControls/Preference/preference.rc index 4d3625a3a..67cca6930 100644 --- a/PowerEditor/src/WinControls/Preference/preference.rc +++ b/PowerEditor/src/WinControls/Preference/preference.rc @@ -101,40 +101,40 @@ IDD_PREFERENCE_SETTING_BOX DIALOGEX 0, 0, 455, 185 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "Recent Files History",IDC_HISTORY_GB_STATIC,54,4,155,39,BS_CENTER - RTEXT "Max. number of entries :",IDC_MAXNBFILE_STATIC,57,14,112,8 + GROUPBOX "Recent Files History",IDC_HISTORY_GB_STATIC,37,4,155,39,BS_CENTER + RTEXT "Max. number of entries :",IDC_MAXNBFILE_STATIC,40,14,112,8 LTEXT "0",IDC_MAXNBFILEVAL_STATIC,176,14,15,8 CONTROL "Don't check at launch time",IDC_CHECK_DONTCHECKHISTORY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,62,27,140,10 - GROUPBOX "Document Switcher (Ctrl+TAB)",IDC_DOCUMENTSWITCHER_STATIC,54,48,155,39,BS_CENTER - CONTROL "Enable",IDC_CHECK_ENABLEDOCSWITCHER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,62,59,69,10 - CONTROL "Enable MRU behaviour",IDC_CHECK_STYLEMRU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,62,72,140,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,27,140,10 + GROUPBOX "Document Switcher (Ctrl+TAB)",IDC_DOCUMENTSWITCHER_STATIC,37,48,155,39,BS_CENTER + CONTROL "Enable",IDC_CHECK_ENABLEDOCSWITCHER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,59,69,10 + CONTROL "Enable MRU behaviour",IDC_CHECK_STYLEMRU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,45,72,140,10 CONTROL "Enable Notepad++ auto-updater",IDC_CHECK_AUTOUPDATE, - "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,55,94,150,10 - CONTROL "Smart highlighting",IDC_CHECK_ENABLSMARTHILITE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,55,136,150,10 - CONTROL "Auto-indent",IDC_CHECK_MAINTAININDENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,55,108,150,10 - CONTROL "Minimize to system tray",IDC_CHECK_MIN2SYSTRAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,55,122,150,10 + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,37,94,150,10 + CONTROL "Smart highlighting",IDC_CHECK_ENABLSMARTHILITE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,37,136,150,10 + CONTROL "Auto-indent",IDC_CHECK_MAINTAININDENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,108,150,10 + CONTROL "Minimize to system tray",IDC_CHECK_MIN2SYSTRAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,122,150,10 CONTROL "Show only filename in title bar",IDC_CHECK_SHORTTITLE, - "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,55,150,217,10 + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,37,150,217,10 CONTROL "Remember current session for next launch",IDC_CHECK_REMEMBERSESSION, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,55,164,217,10 - GROUPBOX "Clickable Link Settings",IDC_CLICKABLELINK_STATIC,232,4,155,39,BS_CENTER - CONTROL "Enable",IDC_CHECK_CLICKABLELINK_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,240,15,140,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,37,164,217,10 + GROUPBOX "Clickable Link Settings",IDC_CLICKABLELINK_STATIC,259,4,155,39,BS_CENTER + CONTROL "Enable",IDC_CHECK_CLICKABLELINK_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,15,140,10 CONTROL "No underline",IDC_CHECK_CLICKABLELINK_NOUNDERLINE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,240,28,140,10 - GROUPBOX "File Status Auto-Detection",IDC_FILEAUTODETECTION_STATIC,232,47,155,50,BS_CENTER - CONTROL "Enable",IDC_CHECK_FILEAUTODETECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,240,57,140,10 - CONTROL "Update silently",IDC_CHECK_UPDATESILENTLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,240,69,140,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,28,140,10 + GROUPBOX "File Status Auto-Detection",IDC_FILEAUTODETECTION_STATIC,259,47,155,50,BS_CENTER + CONTROL "Enable",IDC_CHECK_FILEAUTODETECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,57,140,10 + CONTROL "Update silently",IDC_CHECK_UPDATESILENTLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,69,140,10 CONTROL "Scroll to the last line after update",IDC_CHECK_UPDATEGOTOEOF, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,240,81,140,10 - GROUPBOX "Highlight Matching Tags",IDC_TAGMATCHEDHILITE_STATIC,232,101,155,50,BS_CENTER - CONTROL "Enable",IDC_CHECK_ENABLTAGSMATCHHILITE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,240,111,140,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,267,81,140,10 + GROUPBOX "Highlight Matching Tags",IDC_TAGMATCHEDHILITE_STATIC,259,101,155,50,BS_CENTER + CONTROL "Enable",IDC_CHECK_ENABLTAGSMATCHHILITE,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,267,111,140,10 CONTROL "Highlight tag attributes",IDC_CHECK_ENABLTAGATTRHILITE, - "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,240,123,140,10 + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,267,123,140,10 CONTROL "Highlight comment/php/asp zone",IDC_CHECK_HIGHLITENONEHTMLZONE, - "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,240,136,140,10 - RTEXT "Session file ext.:",IDC_SESSIONFILEEXT_STATIC,244,160,108,8 - EDITTEXT IDC_EDIT_SESSIONFILEEXT,354,157,34,14,ES_AUTOHSCROLL + "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,267,136,140,10 + RTEXT "Session file ext.:",IDC_SESSIONFILEEXT_STATIC,271,160,108,8 + EDITTEXT IDC_EDIT_SESSIONFILEEXT,381,157,34,14,ES_AUTOHSCROLL END IDD_PREFERENCE_NEWDOCSETTING_BOX DIALOGEX 0, 0, 455, 185 diff --git a/PowerEditor/src/WinControls/shortcut/shortcut.h b/PowerEditor/src/WinControls/shortcut/shortcut.h index c651eb0ef..4fa011efe 100644 --- a/PowerEditor/src/WinControls/shortcut/shortcut.h +++ b/PowerEditor/src/WinControls/shortcut/shortcut.h @@ -271,7 +271,7 @@ struct recordedMacroStep { recordedMacroStep(int iMessage, long wParam, long lParam); recordedMacroStep(int iCommandID) : message(0), wParameter(iCommandID), lParameter(0), MacroType(mtMenuCommand) {}; - recordedMacroStep(int iMessage, long wParam, long lParam, const TCHAR *sParam, int type = mtSavedSnR) + recordedMacroStep(int iMessage, long wParam, long lParam, const TCHAR *sParam, int type) : message(iMessage), wParameter(wParam), lParameter(lParam), MacroType(MacroTypeIndex(type)){ sParameter = (sParam)?generic_string(sParam):TEXT(""); };