GME  13
ScriptEdit.cpp
Go to the documentation of this file.
00001 // ScriptEdit.cpp: implementation of the CScriptEdit class.
00002 //
00004 
00005 #include "stdafx.h"
00006 #include "ScriptEdit.h"
00007 #include "ConsoleCtl.h"
00008 #include "MgaUtil.h"
00009 #include "GME.h"
00011 // Construction/Destruction
00013 BEGIN_MESSAGE_MAP(CScriptEdit, CEdit)
00014         //{{AFX_MSG_MAP(CHtmlCtrl)
00015         ON_WM_KEYUP()
00016         ON_CONTROL_REFLECT(EN_KILLFOCUS, OnEnKillfocus)
00017         ON_CONTROL_REFLECT(EN_SETFOCUS, OnEnSetfocus)
00018         //}}AFX_MSG_MAP
00019 END_MESSAGE_MAP()
00020 
00021 /*static*/ const TCHAR* CScriptEdit::defPrompt = _T(">");
00022 CScriptEdit::CScriptEdit()
00023 {
00024 
00025 }
00026 
00027 CScriptEdit::~CScriptEdit()
00028 {
00029         m_host->InitEngine(NULL, NULL);
00030 }
00031 
00032 bool CScriptEdit::Init(CConsoleCtrl *cons)
00033 {
00034         try
00035         {
00036                 m_console = cons;
00037 
00038                 HRESULT hr;
00039                 COMTHROW(hr = m_host.CreateInstance(CLSID_ScriptHost, 0, CLSCTX_ALL));
00040 
00041                 _bstr_t engine(L"JScript");
00042 //              _bstr_t engine(L"Python.AXScript.2");
00043                 COMTHROW(m_host->InitEngine(m_console->GetIDispatch(false), engine));
00044                 this->LimitText(1024 * 4);
00045                 this->SetWindowText( defPrompt); // to attract user attention
00046         }
00047         catch(hresult_exception &e) 
00048         { 
00049                 TCHAR s[200];
00050                 _stprintf_s(s, _T("Scripting Initialization Error: 0x%x"), e.hr);
00051                 m_console->Message(s, MSG_ERROR);
00052                 _ftprintf(stderr, _T("%s"), s);
00053                 return false;
00054         }
00055 
00056         return true;
00057 }
00058 
00059 void CScriptEdit::showPrev()
00060 {
00061         OnKeyUp( VK_UP, 0, 0);
00062 }
00063 
00064 void CScriptEdit::showNext()
00065 {
00066         OnKeyUp( VK_DOWN, 0, 0);
00067 }
00068 
00069 void CScriptEdit::returnHit()
00070 {
00071         OnKeyUp( VK_RETURN, 0, 0);
00072 }
00073 
00074 void CScriptEdit::OnKeyUp( UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/ )
00075 {
00076         static int lastup = -1;
00077 
00078         if (nChar == VK_ESCAPE)
00079         {
00080                 lastup = -1;
00081                 SetSel(0, -1);
00082                 ReplaceSel(_T(""));
00083         }
00084         else if (nChar == VK_UP)
00085         {
00086                 lastup++;
00087                 if (lastup >= (int) m_inputlist.size())
00088                         lastup = (m_inputlist.size()==0)? 0: m_inputlist.size()-1;
00089                 if (!m_inputlist.empty())
00090                 {
00091                         SetSel(0, -1);
00092                         ReplaceSel(m_inputlist[m_inputlist.size()-1-lastup]);
00093                 }
00094         }
00095         else if (nChar == VK_DOWN)
00096         {
00097                 lastup --;
00098                 if (lastup < 0)
00099                         lastup = 0;
00100                 if (!m_inputlist.empty())
00101                 {
00102                         SetSel(0, -1);
00103                         ReplaceSel(m_inputlist[m_inputlist.size()-1-lastup]);
00104                 }
00105         }
00106         else if (nChar == VK_RETURN)
00107         {
00108                 lastup = -1;
00109                 CString inp = CEditGetLine(*this, 0);
00110 
00111                 _bstr_t binp = inp;
00112                 // echo
00113                 m_console->Message((LPCTSTR)inp, MSG_NORMAL);
00114                 // check if inp already exists
00115                 int k;
00116                 for (k=0; k<(int) m_inputlist.size(); k++)
00117                 {
00118                         if (m_inputlist[k] == inp)
00119                         {
00120                                 // shift m_inputlist[k..size - 1] by 1 to the left, to have preserve 'recentness'
00121                                 int l;
00122                                 for( l  = k; l < (int) m_inputlist.size() - 1; ++l)
00123                                         m_inputlist[l] = m_inputlist[l + 1];
00124                                 m_inputlist[ l] = inp; // last element
00125                                 break;
00126                         }
00127                 }
00128                 // add if inp is new
00129                 if (k == m_inputlist.size())
00130                 {
00131                         m_inputlist.push_back(inp);
00132                         if (m_inputlist.size() > 15) // do not store more than 15 items
00133                         {
00134                                 Strings::iterator it = m_inputlist.begin();
00135                                 m_inputlist.erase(it);
00136                         }
00137                 }
00138 
00139                 
00140                 static const TCHAR *cls_c = _T("!cls");
00141                 static const TCHAR *run_c = _T("!run");
00142                 static const TCHAR *lod_c = _T("!load ");
00143                 static const TCHAR *lor_c = _T("!loadr "); // load & run
00144                 static const TCHAR *rel_c = _T("!rel"); // reload
00145                 static const TCHAR *rlr_c = _T("!rlr"); // reload & run
00146                 bool             handled = false;
00147 
00148                 if(      inp == run_c) handled = true, m_console->RunScript();
00149                 else if(wcsncmp(inp, lod_c, wcslen(lod_c)) == 0) handled = true, m_console->LoadScript( _bstr_t(inp.Mid( _tcslen( lod_c))));
00150                 else if(wcsncmp(inp, lor_c, wcslen(lor_c)) == 0)
00151                 {
00152                         handled = true;
00153                         m_console->LoadScript( _bstr_t(inp.Mid( _tcslen( lor_c))));
00154                         m_console->RunScript();
00155                 }
00156                 else if( inp == rel_c) handled = true, m_console->LoadScript( _bstr_t(m_loadedFileName));
00157                 else if( inp == rlr_c) handled = true, m_console->LoadScript( _bstr_t(m_loadedFileName)), m_console->RunScript();
00158                 else if( inp == cls_c) handled = true, m_console->Clear();
00159                 
00160                 if( handled) {
00161                         SetSel(0, -1);
00162                         Clear();
00163                         return;
00164                 }
00165                 else
00166                         ExecuteScript( inp);
00167         }
00168 }
00169 
00170 void CScriptEdit::SetGMEApp(IDispatch *disp)
00171 {
00172         try
00173         {
00174                 COMTHROW(m_host->SetGMEApp(disp));
00175         }
00176         catch(hresult_exception &e) 
00177         { 
00178                 TCHAR s[1000];
00179                 _stprintf_s(s, _T("Scripting Error: 0x%x"), e.hr);
00180                 m_console->Message((LPCTSTR)s, MSG_ERROR);
00181                 _ftprintf(stderr, _T("%s"), s);
00182         }
00183         catch(_com_error &e) 
00184         { 
00185                 TCHAR s[1000];
00186                 _stprintf_s(s, _T("Scripting Error: 0x%x"), e.Error());
00187                 m_console->Message(s, MSG_ERROR);
00188                 _ftprintf(stderr, _T("%s"), s);
00189         }
00190 }
00191 
00192 void CScriptEdit::SetGMEProj(IDispatch *disp)
00193 {
00194         try
00195         {
00196                 COMTHROW(m_host->SetGMEProj(disp));
00197         }
00198         catch(hresult_exception &e) 
00199         { 
00200                 TCHAR s[1000];
00201                 _stprintf_s(s, _T("Scripting Error: 0x%x"), e.hr);
00202                 m_console->Message(s, MSG_ERROR);
00203                 _ftprintf(stderr, _T("%s"), s);
00204         }
00205         catch(_com_error &e) 
00206         { 
00207                 TCHAR s[1000];
00208                 _stprintf_s(s, _T("Scripting Error: 0x%x"), e.Error());
00209                 m_console->Message(s, MSG_ERROR);
00210                 _ftprintf(stderr, _T("%s"), s);
00211         }
00212 }
00213 
00214 void CScriptEdit::OnEnKillfocus()
00215 {
00216         CString buff;
00217         this->GetWindowText( buff);
00218         if( buff.IsEmpty()) // if no user written command while leaving field
00219         {
00220                 this->SetWindowText( defPrompt); // to attract user attention
00221         }
00222 }
00223 
00224 void CScriptEdit::OnEnSetfocus()
00225 {
00226         CString buff;
00227         this->GetWindowText( buff);
00228         if( buff == defPrompt) // if found the default prompt
00229         {
00230                 this->SetWindowText( _T("")); // when it has start typing remove '>'
00231         }
00232 }
00233 
00234 void CScriptEdit::ExecuteScript( CString& p_str)
00235 {
00236         try {
00237                 // load engine info from registry 
00238                 CComPtr<IMgaRegistrar> registrar;
00239                 COMTHROW(registrar.CoCreateInstance(L"Mga.MgaRegistrar"));
00240                 ASSERT( registrar != NULL );
00241                 _bstr_t eng;
00242                 COMTHROW(registrar->get_ScriptEngine(REGACCESS_USER, eng.GetAddress()));
00243                 _bstr_t engine(L"JScript");
00244                 int len = eng.length();
00245                 if (eng.length() != 0)
00246                         engine = eng;
00247 
00248                 _bstr_t input = p_str;
00249                 COMTHROW(m_host->InitEngine(m_console->GetIDispatch(false), engine));
00250                 COMTHROW(m_host->ProcessString(input));
00251         }
00252         catch(hresult_exception& e) {
00253                 TCHAR s[1000];
00254                 _stprintf_s(s, _T("Scripting Error: 0x%x"), e.hr);
00255                 m_console->Message(s, MSG_ERROR);
00256         }
00257         catch(_com_error& e) {
00258                 TCHAR s[1000];
00259                 COMTHROW(e.Error());
00260                 _stprintf_s(s, _T("Execute Script Error: 0x%x"), e.Error());
00261                 m_console->Message(s, MSG_ERROR);
00262         }
00263         catch(...) {
00264                 m_console->Message( _T("Exception handled."), MSG_ERROR);
00265         }
00266 
00267         SetSel(0, -1);
00268         Clear();
00269 }
00270