// LuaEdit.cpp: C++ derived edit control parsing with lua #include "stdafx.h" #include "lua.h" // COMMAND IDs used in the context menu #define APSTUDIO_INVOKED #undef APSTUDIO_READONLY_SYMBOLS #include "resource.h" #define ID_LUA_PARSE _APS_NEXT_COMMAND_VALUE+1 extern lua_State * lua; ///////////////////////////////////////////////////////////////////////////// // LuaEdit BEGIN_MESSAGE_MAP(CLuaEdit, CEdit) //{{AFX_MSG_MAP(CLuaEdit) ON_WM_CHAR() ON_WM_RBUTTONUP() //}}AFX_MSG_MAP ON_COMMAND(ID_EDIT_CUT, Cut) ON_COMMAND(ID_EDIT_COPY, Copy) ON_COMMAND(ID_EDIT_PASTE, Paste) ON_COMMAND(ID_EDIT_UNDO, Undo) ON_COMMAND(ID_EDIT_CLEAR, Clear) ON_COMMAND(ID_EDIT_SELECT_ALL, SelectAll) ON_COMMAND(ID_LUA_PARSE, ParseWithLua) END_MESSAGE_MAP() void CLuaEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { if (nChar == 12) ParseWithLua(); // hook that implements evaluation of Lua input via // Shift+Enter in the Lua console if ((nChar == 13) && (GetKeyState(VK_SHIFT) & 0x8000)) GetParent()->PostMessage(WM_COMMAND,IDC_EVALUATE); else CEdit::OnChar(nChar, nRepCnt, nFlags); } void CLuaEdit::Undo() { CEdit::Undo(); } void CLuaEdit::ParseWithLua() { int nStart,nEnd,i,k; CString tolua; GetSel(nStart,nEnd); GetWindowText(tolua); if (nStart!=nEnd) { tolua="return " + tolua.Mid(nStart,nEnd-nStart) + "\n"; i=lua_gettop(lua); lua_dostring(lua,tolua); k=lua_gettop(lua); if (i!=k){ tolua=lua_tostring(lua,-1); if (tolua.GetLength()==0){ AfxMessageBox("Input does not evaluate to a numerical value"); } else ReplaceSel(tolua,TRUE); lua_pop(lua, 1); // pop result from Lua stack so we don't get an overflow. } } } BOOL CLuaEdit::IsSelection() { int nStart,nEnd; GetSel(nStart,nEnd); if (nStart!=nEnd) return TRUE; return FALSE; } void CLuaEdit::OnRButtonUp(UINT nFlags, CPoint point) { HANDLE hClip = ::GetClipboardData(CF_TEXT); CMenu* pMenu = NULL; try { pMenu = new CMenu; } catch(...) { pMenu = NULL; } ASSERT(pMenu); VERIFY(pMenu->CreatePopupMenu()); if (CanUndo()) VERIFY(pMenu->AppendMenu(MF_STRING, ID_EDIT_UNDO, "Undo")); else VERIFY(pMenu->AppendMenu(MF_GRAYED, ID_EDIT_UNDO, "Undo")); VERIFY(pMenu->AppendMenu(MF_SEPARATOR, 0, "")); if (IsSelection() || hClip) VERIFY(pMenu->AppendMenu(MF_STRING, ID_EDIT_CUT, "Cut")); else VERIFY(pMenu->AppendMenu(MF_GRAYED, ID_EDIT_CUT, "Cut")); if (IsSelection()) VERIFY(pMenu->AppendMenu(MF_STRING, ID_EDIT_COPY, "Copy")); else VERIFY(pMenu->AppendMenu(MF_GRAYED, ID_EDIT_COPY, "Copy")); if (hClip) VERIFY(pMenu->AppendMenu(MF_STRING, ID_EDIT_PASTE, "Paste")); else VERIFY(pMenu->AppendMenu(MF_STRING, ID_EDIT_PASTE, "Paste")); if (IsSelection()) VERIFY(pMenu->AppendMenu(MF_STRING, ID_EDIT_CLEAR, "Delete")); else VERIFY(pMenu->AppendMenu(MF_GRAYED, ID_EDIT_CLEAR, "Delete")); VERIFY(pMenu->AppendMenu(MF_SEPARATOR, 0, "")); if (IsSelection()) VERIFY(pMenu->AppendMenu(MF_STRING, ID_LUA_PARSE, "Evaluate")); else VERIFY(pMenu->AppendMenu(MF_GRAYED, ID_LUA_PARSE, "Evaluate")); VERIFY(pMenu->AppendMenu(MF_SEPARATOR, 0, "")); int nStart,nEnd,nLength; CString strText; GetWindowText(strText); GetSel(nStart,nEnd); nLength=strText.GetLength(); if ((nLength!=0) && (nLength-nEnd+nStart>0)) VERIFY(pMenu->AppendMenu(MF_STRING, ID_EDIT_SELECT_ALL, "Select All")); else VERIFY(pMenu->AppendMenu(MF_GRAYED, ID_EDIT_SELECT_ALL, "Select All")); if (!hClip) ::CloseHandle(hClip); ClientToScreen(&point); pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, point.x, point.y, this); try { delete pMenu; } catch(...) { ASSERT(FALSE); TRACE("CLuaEdit::OnRButtonUp failed to destroy menu resource\n"); pMenu = FALSE; } } void CLuaEdit::SelectAll() { CString strText; GetWindowText(strText); SetSel(0, strText.GetLength()); }