/*------------------------------------------------------------------------ Procedure: AddLineToControl ID:1 Purpose: It will ad the given text at the end of the edit control, then it will send a return character to it. This simulates user input. The history will not be modified by this procedure. Input: The text to be added Output: None Errors: If the line is empty, nothing will be done ------------------------------------------------------------------------*/ void AddLineToControl(char *buf) { HWND hEditCtrl; if (*buf == 0) return; hEditCtrl = (HWND)GetWindowLongPtr(hwndSession,DWLP_USER); GotoEOF(); SendMessage(hEditCtrl,EM_REPLACESEL,0,(LPARAM)buf); SendMessage(hEditCtrl,WM_CHAR,'\r',0); }
/*------------------------------------------------------------------------ Procedure: AddStringToControl ID:1 Author: Chris Watford [email protected] Purpose: It will ad the given text at the end of the edit control. This simulates user input. The history will not be modified by this procedure. Input: The text to be added Output: None Errors: If the line is empty, nothing will be done -------------------------------------------------------------------------- Edit History: 16 Sept 2003 - Chris Watford [email protected] - Basically this is AddLineToControl, but without appending a newline ------------------------------------------------------------------------*/ void AddStringToControl(char* buf) { HWND hEditCtrl; if(buf == NULL) return; if((*buf) == 0) return; hEditCtrl = (HWND)GetWindowLongPtr(hwndSession, DWLP_USER); GotoEOF(); SendMessage(hEditCtrl ,EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)buf); }
/*------------------------------------------------------------------------ Procedure: SubClassEdit ID:1 Purpose: Handles messages to the editbox Input: Output: Errors: -------------------------------------------------------------------------- Edit History: 14 Sept 2003 - Chris Watford [email protected] - Setup handler for up and down arrows 15 Sept 2003 - Chris Watford [email protected] - Setup framework for history on up arrow - Saves lines you move off of in the edit buffer 16 Sept 2003 - Chris Watford [email protected] - Proper handling of newline message finished - Fixed ENTER on middle of interior line, moves cursor to the end and sends the line - Setup the copying and destroying of the old buffer - Included buffer rewrite 17 Sept 2003 - Chris Watford [email protected] - Added C-p/C-n support - Changed UpArrow to C-UpArrow so as to not confuse users 18 Sept 2003 - Chris Watford [email protected] - Added Left and Right arrow line saving - Added backspace and delete line saving and removing - Fixed history scrolling 21 Sept 2003 - Chris Watford [email protected] - Fixed pasting errors associated with lines being out of bounds for the buffer - Added error handling, possibly able to handle it diff down the line - Removed C-Up/C-Dn for history scrolling, buggy at best on my machine ------------------------------------------------------------------------*/ static LRESULT CALLBACK SubClassEdit(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2) { LRESULT r; int postit=0,nl; if (msg == WM_CHAR && mp1 == '\r') { if (!busy) { r = GetCurLineIndex(hwnd); nl = GetNumberOfLines(hwnd); // if we're not the last line if (r != nl-1) { // update or add us, we might not have any lines in the edit buffer editbuffer_updateoraddline(CurrentEditBuffer, r-LastPromptPosition.line, GetLastLine(hwnd)); // scroll to the end, add CrLf then post the newline message GotoEOF(); AddStringToControl("\r\n"); PostMessage(GetParent(hwnd),WM_NEWLINE,0,0); return 0; } CallWindowProc(lpEProc,hwnd,WM_KEYDOWN,VK_END,1); CallWindowProc(lpEProc,hwnd,WM_KEYUP,VK_END,1); postit = 1; } } else if (msg == WM_CHAR && mp1 == (char)0x08) { int lineindex = SendMessage(hwnd, EM_LINEINDEX, LastPromptPosition.line, 0) + 2; int curline = SendMessage(hwnd,EM_LINEFROMCHAR,(WPARAM)-1,0); int nextline = 0; int curpoint = 0; SendMessage(hwnd, EM_GETSEL, (WPARAM)&curpoint, (LPARAM)NULL); nextline = SendMessage(hwnd,EM_LINEFROMCHAR,(WPARAM)(curpoint - 1),0); if(curpoint <= lineindex) { return 0; } else if(nextline != curline) { // delete the line we're on // grab the index curline -= LastPromptPosition.line; // kill it editbuffer_removeline(CurrentEditBuffer, curline); } } else if (msg == WM_KEYDOWN && mp1 == VK_F1) { DoHelp(hwnd); } else if ((msg == WM_KEYDOWN || msg == WM_KEYUP) && mp1 == VK_UP) { int curline = GetCurLineIndex(hwnd); /*if((msg == WM_KEYDOWN) && (GetKeyState(VK_CONTROL) && 0x8000)) { // go forward once in history NextHistoryEntry(); return 0; } else */ if((curline > LastPromptPosition.line) && (curline <= (LastPromptPosition.line + CurrentEditBuffer->LineCount))) { // update current line if (msg == WM_KEYDOWN) { int lineidx = (curline - LastPromptPosition.line); CallWindowProc(lpEProc,hwnd,WM_KEYDOWN,VK_END,1); CallWindowProc(lpEProc,hwnd,WM_KEYUP,VK_END,1); // we may have to add this line, otherwise update it editbuffer_updateoraddline(CurrentEditBuffer, lineidx, GetLastLine(hwnd)); } } else { return 0; } } else if ((msg == WM_KEYDOWN || msg == WM_KEYUP) && (mp1 == VK_LEFT)) { int lineindex = SendMessage(hwnd, EM_LINEINDEX, LastPromptPosition.line, 0) + 2; int curline = SendMessage(hwnd,EM_LINEFROMCHAR,(WPARAM)-1,0); int nextline = 0; int curpoint = 0; SendMessage(hwnd, EM_GETSEL, (WPARAM)&curpoint, (LPARAM)NULL); nextline = SendMessage(hwnd,EM_LINEFROMCHAR,(WPARAM)(curpoint - 1),0); if(curpoint <= lineindex) { // no left arrow to the left of the prompt return 0; } else if(nextline != curline) { // update current line if (msg == WM_KEYDOWN) { int lineidx = (curline - LastPromptPosition.line); CallWindowProc(lpEProc,hwnd,WM_KEYDOWN,VK_END,1); CallWindowProc(lpEProc,hwnd,WM_KEYUP,VK_END,1); // we may have to add this line, otherwise update it editbuffer_updateoraddline(CurrentEditBuffer, lineidx, GetLastLine(hwnd)); CallWindowProc(lpEProc,hwnd,WM_KEYDOWN,VK_HOME,1); CallWindowProc(lpEProc,hwnd,WM_KEYUP,VK_HOME,1); } } } else if ((msg == WM_KEYDOWN || msg == WM_KEYUP) && (mp1 == VK_DOWN)) { int curline = GetCurLineIndex(hwnd); /*if((msg == WM_KEYDOWN) && (GetKeyState(VK_CONTROL) && 0x8000)) { // go back once in history PrevHistoryEntry(); return 0; } else*/ if((curline >= LastPromptPosition.line) && (curline < (LastPromptPosition.line + CurrentEditBuffer->LineCount))) { // We don't post the newline, but instead update the current line if (msg == WM_KEYDOWN) { int lineidx = (curline - LastPromptPosition.line); CallWindowProc(lpEProc,hwnd,WM_KEYDOWN,VK_END,1); CallWindowProc(lpEProc,hwnd,WM_KEYUP,VK_END,1); editbuffer_updateline(CurrentEditBuffer, lineidx, GetLastLine(hwnd)); } } else { return 0; } } else if ((msg == WM_KEYDOWN || msg == WM_KEYUP) && (mp1 == VK_RIGHT)) { int lineindex = SendMessage(hwnd, EM_LINEINDEX, LastPromptPosition.line, 0) + 1; int curline = SendMessage(hwnd,EM_LINEFROMCHAR,(WPARAM)-1,0); int nextline = 0; int curpoint = 0; SendMessage(hwnd, EM_GETSEL, (WPARAM)&curpoint, (LPARAM)NULL); nextline = SendMessage(hwnd,EM_LINEFROMCHAR,(WPARAM)(curpoint + 2),0); if(curpoint <= lineindex) { // no movement behind the prompt return 0; } else if((nextline != curline) && (msg = WM_KEYDOWN)) { int lineidx = (curline - LastPromptPosition.line); CallWindowProc(lpEProc,hwnd,WM_KEYDOWN,VK_END,1); CallWindowProc(lpEProc,hwnd,WM_KEYUP,VK_END,1); editbuffer_updateline(CurrentEditBuffer, lineidx, GetLastLine(hwnd)); } } else if ((msg == WM_KEYDOWN) && (mp1 == VK_PRIOR) && (GetKeyState(VK_CONTROL) && 0x8000)) { // C-p NextHistoryEntry(); return 0; } else if ((msg == WM_KEYDOWN) && (mp1 == VK_NEXT) && (GetKeyState(VK_CONTROL) && 0x8000)) { // C-n PrevHistoryEntry(); return 0; } else if ((msg == WM_KEYDOWN || msg == WM_KEYUP) && (mp1 == VK_DELETE)) { // see if we're the last char on the line, if so delete the next line // don't allow deleting left of the prompt int lineindex = SendMessage(hwnd, EM_LINEINDEX, LastPromptPosition.line, 0) + 2; int curline = SendMessage(hwnd,EM_LINEFROMCHAR,(WPARAM)-1,0); int nextline = 0; int curpoint = 0; SendMessage(hwnd, EM_GETSEL, (WPARAM)&curpoint, (LPARAM)NULL); nextline = SendMessage(hwnd,EM_LINEFROMCHAR,(WPARAM)(curpoint + 2),0); if(curpoint < lineindex) { // no chomping behind the prompt return 0; } else if(nextline != curline) { // deleting // grab the next line index curline -= LastPromptPosition.line; // kill it editbuffer_removeline(CurrentEditBuffer, curline+1); } } else if (msg == WM_PASTE) { // if they paste text, allow it r = CallWindowProc(lpEProc, hwnd, msg, mp1, mp2); // update the current edit buffer RefreshCurrentEditBuffer(); return r; } // handle errors switch(msg) { case WM_SYNTAXERROR: case WM_ILLEGALCHAR: case WM_UNBOUNDVAL: { // currently I handle them all the same // get the start of the line int start = SendMessage(hwnd, EM_LINEINDEX, LastPromptPosition.line, 0) + 2; // get the statement that error'd NextHistoryEntry(); // tell the history that the last line errored if(History != NULL) if(History->Statement != NULL) History->Statement->isCorrect = FALSE; // highlight the offending chars SendMessage(hwnd,EM_SETSEL,(WPARAM)(start + mp1), (LPARAM)(start + mp2)); return 0; } } r = CallWindowProc(lpEProc, hwnd, msg, mp1, mp2); if (postit) PostMessage(GetParent(hwnd),WM_NEWLINE,0,0); return r; }