#include "comline.hpp" //#include #include #include "comline.h" #define COMLINE_WINDOW_NAME "Command Window" #define COMLINE_WINDOW_CLASS_NAME "COMLINEWindowClass" namespace NCOMLINE { const DWORD c_dwWindowedStyle = WS_OVERLAPPED|WS_VSCROLL; const DWORD c_dwWindowedStyleEx = WS_EX_WINDOWEDGE; const int c_FontSize = 12; const int c_LineSpace = 2; const int c_FlashTimerID = 37; const int c_FlashElapse = 125; const int c_ServerTimerID = 38; const int c_ServerTimerElapse = 1000; CCom_String n_Commands[] = // order is VERY important, see the ExecuteCommand function { "dumpfile", "exit", "attach", "detach", "killserver" }; // CCommandLineClient *n_CurClient; }; int CCommandLineClient::m_WndClassRefCount = 0; using namespace NCOMLINE; void CCommandLineClient::PushLine (const LineData& data) { if (m_NumLines == m_SizeLines) { int i; LineData *temp; temp = new LineData[m_SizeLines+50]; for (i=0;i m_DisplayLines) { int min,max; m_TopDisplay++; GetScrollRange (m_Window,SB_VERT,&min,&max); SetScrollRange (m_Window,SB_VERT,0,max+1,FALSE); } } CCommandLineClient::CCommandLineClient (HINSTANCE inst) { m_Instance = inst; m_Attached = false; if (!m_WndClassRefCount) { WNDCLASS rootclass; rootclass.style = CS_OWNDC|CS_DBLCLKS; rootclass.lpfnWndProc = CommandLineWndProc; rootclass.cbClsExtra = 0; rootclass.cbWndExtra = sizeof (DWORD); rootclass.hInstance = m_Instance; rootclass.hIcon = LoadIcon (NULL,MAKEINTRESOURCE (IDI_APPLICATION)); rootclass.hCursor = LoadCursor (NULL,MAKEINTRESOURCE (IDC_ARROW)); rootclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); rootclass.lpszMenuName = NULL; rootclass.lpszClassName = COMLINE_WINDOW_CLASS_NAME; if (!RegisterClass (&rootclass)) // register the class for the command line window return; } m_WndClassRefCount++; m_Window = CreateWindowEx (c_dwWindowedStyleEx,COMLINE_WINDOW_CLASS_NAME,COMLINE_WINDOW_NAME,c_dwWindowedStyle, CW_USEDEFAULT,CW_USEDEFAULT,80*12,(50*c_FontSize)+10,NULL,NULL,m_Instance,this); if (!m_Window) return; SetScrollRange (m_Window,SB_VERT,0,1,FALSE); SetWindowLong (m_Window,GWL_USERDATA,(LONG) this); SetTimer (m_Window,c_FlashTimerID,c_FlashElapse,NULL); SetTimer (m_Window,c_ServerTimerID,c_ServerTimerElapse,NULL); m_Font = CreateFont (-c_FontSize,0,0,0,FW_DONTCARE,FALSE,FALSE,FALSE,DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY, DEFAULT_PITCH+FF_DONTCARE,"Courier"); m_CursorPen = CreatePen (PS_SOLID,1,RGB (0,0,0)); m_ShowCursor = true; m_CursorLoc.x = 5; m_CursorLoc.y = 1; m_CursorPos = 0; m_CurrentLine = ""; m_Lines = new NCOMLINE::LineData[50]; m_NumLines = 0; m_SizeLines = 50; // m_Lines.clear (); m_TopDisplay = 0; PushLine (LineData ("Command Line interface started",LINE_OUTPUT)); m_CurLineColor = RGB (0,0,0 ); m_CommandColor = RGB (128,0,0); m_ArgColor = RGB (0,128,0); m_OutColor = RGB (0,0,255); // NCOMLINE::n_CurClient = this; } CCommandLineClient::~CCommandLineClient (void) { LineData data ("detach all",LINE_COMMAND); ParseLine (data); if (m_Attached) DetachServer (data); DeleteObject (m_Font); DeleteObject (m_CursorPen); m_WndClassRefCount--; if (!m_WndClassRefCount) UnregisterClass (COMLINE_WINDOW_CLASS_NAME,m_Instance); } RPC_STATUS CCommandLineClient::AttachServer (NCOMLINE::LineData& data) { if (m_Attached) { LineData fred ("detach all",LINE_COMMAND); ParseLine (fred); DetachServer (fred); } char compname[255]; RPC_STATUS status; unsigned char * pszUuid = (unsigned char *) NULL; // unsigned char * pszProtocolSequence = (unsigned char *) "ncalrpc"; // unsigned char * pszEndpoint = (unsigned char *) "ComLine"; // unsigned char * pszProtocolSequence = (unsigned char *) "ncacn_ip_tcp"; // unsigned char * pszEndpoint = (unsigned char *) "morfane[1404]"; unsigned char * pszNetworkAddress = (unsigned char *) NULL; unsigned char * pszOptions = (unsigned char *) NULL; /* pszStringBinding = (unsigned char *) NULL; status = RpCCom_StringBindingCompose(pszUuid,pszProtocolSequence,pszNetworkAddress,pszEndpoint,pszOptions,&pszStringBinding); if (status) return status; */ if (data.m_NumArgs == 1) { sprintf ((char *) pszStringBinding,"ncalrpc:[ComLine]"); } else { CCom_String name; name = data.m_Data.Mid (data.m_ArgBreak[0]+1,data.m_ArgBreak[1]-data.m_ArgBreak[0]+1); strcpy (compname,(LPCTSTR) name); sprintf ((char *) pszStringBinding,"ncacn_ip_tcp:%s[1404]",compname); } // pszStringBinding = (unsigned char *) "ncacn_ip_tcp:209.20.251.178[1404]"; /* Set the binding handle that will be used to bind to the server. */ status = RpcBindingFromStringBinding(pszStringBinding,&comline_IfHandle); if (status) return status; m_Attached = true; return 0; } RPC_STATUS CCommandLineClient::DetachServer (NCOMLINE::LineData& data) { RPC_STATUS status; m_Attached = false; #if 0 status = RpCCom_StringFree(&pszStringBinding); // remote calls done; unbind if (status) return (status); #endif pszStringBinding[0] = 0; status = RpcBindingFree(&comline_IfHandle); // remote calls done; unbind if (status) return (status); return 0; } void CCommandLineClient::ListServers (void) { } void CCommandLineClient::ShowWindow (void) { assert (m_Window); ::ShowWindow (m_Window,SW_SHOW); GetClientRect (m_Window,&m_WindowRect); m_DisplayLines = (m_WindowRect.bottom - m_WindowRect.top) / (c_FontSize+c_LineSpace); } void CCommandLineClient::HideWindow (void) { assert (m_Window); ::ShowWindow (m_Window,SW_HIDE); } bool CCommandLineClient::DumpFile (NCOMLINE::LineData& data) { CCom_String filename; if (data.m_NumArgs < 2) return false; filename = data.m_Data.Left (data.m_ArgBreak[1]); filename = filename.Right (data.m_ArgBreak[1] - data.m_ComBreak-1); return DumpFile (filename); } bool CCommandLineClient::DumpFile (const CCom_String& filename) { FILE *thefile; CCom_String temp; LineData *iter; int i; thefile = fopen (filename,"w"); if (!thefile) return false; iter = m_Lines; for (i=0;im_Data); fprintf (thefile,"\n"); iter++; } fprintf (thefile,(LPCTSTR) m_CurrentLine); temp = "Data dumped to file "; temp += filename; PushLine ((LPCTSTR) temp); if (!fclose (thefile)) return false; return true; } void CCommandLineClient::DumpToFile (const char *filename) { DumpFile (filename); } void CCommandLineClient::PushLine (const char *line) { LineData data(line,LINE_OUTPUT); PushLine (data); InvalidateRect (m_Window,NULL,TRUE); } void CCommandLineClient::ExecuteLine (const char *line) { LineData data(line,LINE_COMMAND); ParseLine (data); PushLine (data); ExecuteLine (data); } void CCommandLineClient::KillServer (NCOMLINE::LineData& data) { unsigned long ulCode; m_Attached = false; RpcTryExcept { Shutdown(); // shut down the server side } RpcExcept(1) { ulCode = RpcExceptionCode(); } RpcEndExcept } void CCommandLineClient::ExecuteLine (LineData& data) { int i,count; CCom_String com; bool flag = false; com = data.m_Data.Left (data.m_ComBreak); count = sizeof (n_Commands) /sizeof (CCom_String); for (i=0;im_Type == LINE_OUTPUT) { SetTextColor (ps.hdc,m_OutColor); TextOut (ps.hdc,curx,cury,(LPCTSTR)iter->m_Data,iter->m_Data.GetLength ()); } else if (iter->m_Type == LINE_COMMAND) { char *buf; buf = iter->m_Data.GetBuffer (0); SetTextColor (ps.hdc,m_CommandColor); TextOut (ps.hdc,curx,cury,(LPCTSTR)buf,iter->m_ComBreak); if ((iter->m_Data.GetLength () - iter->m_ComBreak) > 0) { GetTextExtentPoint32 ( ps.hdc, (LPCTSTR)buf,iter->m_ComBreak ,&TextSize ); LPtoDP (ps.hdc,(POINT *)&TextSize,1); curx += TextSize.cx; SetTextColor (ps.hdc,m_ArgColor); TextOut (ps.hdc,curx,cury,(LPCTSTR)&(buf[iter->m_ComBreak]),iter->m_Data.GetLength () - iter->m_ComBreak); } iter->m_Data.ReleaseBuffer (); curx = 0; } else { } cury += c_FontSize; cury += c_LineSpace; iter++; } SetTextColor (ps.hdc,m_CurLineColor); TextOut (ps.hdc,curx,cury,(LPCTSTR)m_CurrentLine,m_CurrentLine.GetLength ()); GetTextExtentPoint32 ( ps.hdc, (LPCTSTR)m_CurrentLine, m_CursorPos ,&TextSize ); LPtoDP (ps.hdc,(POINT *)&TextSize,1); m_CursorLoc.x = TextSize.cx; m_CursorLoc.y = cury; if (m_ShowCursor && m_CursorFlash) { temppen = (HPEN) SelectObject (ps.hdc,m_CursorPen); MoveToEx (ps.hdc,m_CursorLoc.x,m_CursorLoc.y,NULL); LineTo (ps.hdc,m_CursorLoc.x,m_CursorLoc.y+c_FontSize); SelectObject (ps.hdc,temppen); } SelectObject (ps.hdc,oldfont); EndPaint (thewnd,&ps); return 0; } break; case WM_TIMER: if (wParam == c_FlashTimerID) { m_CursorFlash = !m_CursorFlash; { RECT temprect; temprect.left = m_CursorLoc.x; temprect.top = m_CursorLoc.y; temprect.right = m_CursorLoc.x+2; temprect.bottom = m_CursorLoc.y+c_FontSize; InvalidateRect (m_Window,&temprect,TRUE); } } else if (wParam == c_ServerTimerID) { int num,i; char line[256]; if (m_Attached) { try { num = NumOutputLines (); for (i=0;i (0,m_CursorPos-1,m_CurrentLine.GetLength ()); InvalidateRect (m_Window,NULL,TRUE); break; case VK_RIGHT: m_CursorPos = clamp (0,m_CursorPos+1,m_CurrentLine.GetLength ()); InvalidateRect (m_Window,NULL,TRUE); break; case VK_HOME: m_CursorPos = 0; InvalidateRect (m_Window,NULL,TRUE); break; case VK_END: m_CursorPos = m_CurrentLine.GetLength (); InvalidateRect (m_Window,NULL,TRUE); break; case VK_DELETE: m_CurrentLine.Delete (m_CursorPos); InvalidateRect (m_Window,NULL,TRUE); break; } break; case WM_VSCROLL: switch (LOWORD (wParam)) { case SB_BOTTOM: break; case SB_ENDSCROLL: break; case SB_LINEDOWN: break; case SB_LINEUP: break; case SB_PAGEDOWN: break; case SB_PAGEUP: break; case SB_THUMBPOSITION: break; case SB_THUMBTRACK: break; case SB_TOP: break; } InvalidateRect (m_Window,NULL,FALSE); break; case WM_CHAR: switch (wParam) { case '\b': if (m_CursorPos) { m_CurrentLine.Delete (m_CursorPos-1); m_CursorPos--; } break; case '\r': { m_CurrentLine.Insert (m_CursorPos,'\0'); LineData data(m_CurrentLine,LINE_COMMAND); ParseLine (data); PushLine (data); ExecuteLine (data); m_CurrentLine = ""; m_CursorPos = 0; LineData *iter; iter = &(m_Lines[m_TopDisplay]); int count=0; int i; for (i=m_TopDisplay;i m_DisplayLines) { int min,max; m_TopDisplay++; GetScrollRange (m_Window,SB_VERT,&min,&max); SetScrollRange (m_Window,SB_VERT,0,max+1,FALSE); } } break; default: m_CurrentLine.Insert (m_CursorPos,wParam); m_CursorPos++; break; } InvalidateRect (m_Window,NULL,TRUE); break; } return DefWindowProc (thewnd,themsg,wParam,lParam); } LRESULT WINAPI NCOMLINE::CommandLineWndProc (HWND thewnd,UINT themsg,WPARAM wParam,LPARAM lParam) { void *temp; switch (themsg) { case WM_CREATE: CREATESTRUCT *cs; cs = (CREATESTRUCT *) lParam; temp = cs->lpCreateParams; SetWindowLong (thewnd,GWL_USERDATA,(long) temp); break; case WM_DESTROY: SetWindowLong (thewnd,GWL_USERDATA,0); break; default: CCommandLineClient *fred = (CCommandLineClient *) GetWindowLong (thewnd,GWL_USERDATA); if (fred) return fred->WndProc (thewnd,themsg,wParam,lParam); break; } return DefWindowProc (thewnd,themsg,wParam,lParam); }