CTelnetView.cpp
上传用户:dzbfjx
上传日期:2015-04-22
资源大小:42k
文件大小:11k
源码类别:

Telnet客户端

开发平台:

Visual C++

  1. // CTelnetView.cpp : implementation of the CTelnetView class
  2. //
  3. #include "stdafx.h"
  4. #include "CTelnet.h"
  5. #include "CTelnetDoc.h"
  6. #include "CTelnetView.h"
  7. #include "MainFrm.h"
  8. #include "ClientSocket.h"
  9. #include "Process.h"
  10. #include "HostDialog.h"
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. extern CMultiDocTemplate * pDocTemplate;
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CTelnetView
  19. IMPLEMENT_DYNCREATE(CTelnetView, CScrollView)
  20. BEGIN_MESSAGE_MAP(CTelnetView, CScrollView)
  21. //{{AFX_MSG_MAP(CTelnetView)
  22. ON_WM_CHAR()
  23. ON_WM_SIZE()
  24. ON_WM_ERASEBKGND()
  25. //}}AFX_MSG_MAP
  26. // Standard printing commands
  27. ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
  28. ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
  29. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
  30. END_MESSAGE_MAP()
  31. /////////////////////////////////////////////////////////////////////////////
  32. // CTelnetView construction/destruction
  33. CTelnetView::CTelnetView()
  34. {
  35. cTextColor = RGB(200,200,000);
  36. cBackgroundColor = RGB(000,000,222);
  37. cSock = NULL;
  38. bOptionsSent = FALSE;
  39. TempCounter = 0;
  40. cCursX = 0;
  41. for(int x = 0; x < 80; x++)
  42. {
  43. for(int y = 0; y < bufferLines; y++)
  44. {
  45. cText[x][y] = ' ';
  46. }
  47. }
  48. }
  49. CTelnetView::~CTelnetView()
  50. {
  51. }
  52. BOOL CTelnetView::PreCreateWindow(CREATESTRUCT& cs)
  53. {
  54. // TODO: Modify the Window class or styles here by modifying
  55. //  the CREATESTRUCT cs
  56. return CScrollView::PreCreateWindow(cs);
  57. }
  58. /////////////////////////////////////////////////////////////////////////////
  59. // CTelnetView drawing
  60. void CTelnetView::OnDraw(CDC* pDC)
  61. {
  62. CTelnetDoc* pDoc = GetDocument();
  63. ASSERT_VALID(pDoc);
  64. // pDC->SelectObject(GetStockObject(SYSTEM_FONT));
  65. pDC->SelectObject(GetStockObject(ANSI_FIXED_FONT));
  66. DrawCursor(pDC,FALSE);
  67. DoDraw(pDC);
  68. DrawCursor(pDC,FALSE);
  69. }
  70. void CTelnetView::DoDraw(CDC* pDC)
  71. {
  72. CRect clip;
  73. pDC->GetClipBox(clip);
  74. clip.top -= dtY;
  75. pDC->SetTextColor(cTextColor);
  76. pDC->SetBkColor(cBackgroundColor);
  77. char text[2] = {0x00, 0x00};
  78. for(int y = 0; y < bufferLines; y++)
  79. {
  80. if(y * dtY >= clip.top)
  81. {
  82. for(int x = 0; x < 80; x++)
  83. {
  84. text[0] = cText[x][y];
  85. if(text[0] == ' ')
  86. {
  87. pDC->FillSolidRect(CRect(x * dtX, y * dtY, 
  88. x * dtX + dtX, y * dtY + dtY), 
  89. cBackgroundColor);
  90. }
  91. else
  92. {
  93. pDC->TextOut(x * dtX, y * dtY, text);
  94. }
  95. }
  96. }
  97. }
  98. }
  99. void CTelnetView::OnInitialUpdate()
  100. {
  101. CScrollView::OnInitialUpdate();
  102. CSize sizeTotal;
  103. // TODO: calculate the total size of this view
  104. sizeTotal.cx = dtX * 80 + 3;
  105. sizeTotal.cy = dtY * bufferLines + 3;
  106. SetScrollSizes(MM_TEXT, sizeTotal);
  107. ScrollToPosition(CPoint(0, bufferLines * 1000)); //go way past the end
  108. CHostDialog host;
  109. host.DoModal();
  110. cHostName = host.m_HostName;
  111. //create the socket and hook up to the host
  112. BOOL bOK;
  113. cSock = new CClientSocket(this);
  114. if(cSock != NULL)
  115. {
  116. bOK = cSock->Create();
  117. if(bOK == TRUE)
  118. {
  119. cSock->AsyncSelect(FD_READ | FD_WRITE | FD_CLOSE | FD_CONNECT | FD_OOB);
  120. cSock->Connect(cHostName, 23);
  121. GetDocument()->SetTitle(cHostName);
  122. Sleep(90);
  123. }
  124. else
  125. {
  126. ASSERT(FALSE);  //Did you remember to call AfxSocketInit()?
  127. delete cSock;
  128. cSock = NULL;
  129. }
  130. }
  131. else
  132. {
  133. AfxMessageBox("Could not create new socket",MB_OK);
  134. }
  135. }
  136. /////////////////////////////////////////////////////////////////////////////
  137. // CTelnetView printing
  138. BOOL CTelnetView::OnPreparePrinting(CPrintInfo* pInfo)
  139. {
  140. // default preparation
  141. return DoPreparePrinting(pInfo);
  142. }
  143. void CTelnetView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  144. {
  145. // TODO: add extra initialization before printing
  146. }
  147. void CTelnetView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
  148. {
  149. // TODO: add cleanup after printing
  150. }
  151. /////////////////////////////////////////////////////////////////////////////
  152. // CTelnetView diagnostics
  153. #ifdef _DEBUG
  154. void CTelnetView::AssertValid() const
  155. {
  156. CScrollView::AssertValid();
  157. }
  158. void CTelnetView::Dump(CDumpContext& dc) const
  159. {
  160. CScrollView::Dump(dc);
  161. }
  162. CTelnetDoc* CTelnetView::GetDocument() // non-debug version is inline
  163. {
  164. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTelnetDoc)));
  165. return (CTelnetDoc*)m_pDocument;
  166. }
  167. #endif //_DEBUG
  168. /////////////////////////////////////////////////////////////////////////////
  169. // CTelnetView message handlers
  170. void CTelnetView::ProcessMessage(CClientSocket * pSock)
  171. {
  172. if(!IsWindow(m_hWnd)) return;
  173. if(!IsWindowVisible()) return;
  174. int nBytes = pSock->Receive(m_bBuf ,ioBuffSize );
  175. if(nBytes != SOCKET_ERROR)
  176. {
  177. int ndx = 0;
  178. while(GetLine(m_bBuf, nBytes, ndx) != TRUE);
  179. ProcessOptions();
  180. MessageReceived(m_strNormalText);
  181. }
  182. m_strLine.Empty();
  183. m_strResp.Empty();
  184. }
  185. void CTelnetView::ProcessOptions()
  186. {
  187. CString m_strTemp;
  188. CString m_strOption;
  189. unsigned char ch;
  190. int ndx;
  191. int ldx;
  192. BOOL bScanDone = FALSE;
  193. m_strTemp = m_strLine;
  194. while(!m_strTemp.IsEmpty() && bScanDone != TRUE)
  195. {
  196. ndx = m_strTemp.Find(IAC);
  197. if(ndx != -1)
  198. {
  199. m_strNormalText += m_strTemp.Left(ndx);
  200. ch = m_strTemp.GetAt(ndx + 1);
  201. switch(ch)
  202. {
  203. case DO:
  204. case DONT:
  205. case WILL:
  206. case WONT:
  207. m_strOption = m_strTemp.Mid(ndx, 3);
  208. m_strTemp = m_strTemp.Mid(ndx + 3);
  209. m_strNormalText = m_strTemp.Left(ndx);
  210. m_ListOptions.AddTail(m_strOption);
  211. break;
  212. case IAC:
  213. m_strNormalText = m_strTemp.Left(ndx);
  214. m_strTemp = m_strTemp.Mid(ndx + 1);
  215. break;
  216. case SB:
  217. m_strNormalText = m_strTemp.Left(ndx);
  218. ldx = m_strTemp.Find(SE);
  219. m_strOption = m_strTemp.Mid(ndx, ldx);
  220. m_ListOptions.AddTail(m_strOption);
  221. m_strTemp = m_strTemp.Mid(ldx);
  222. AfxMessageBox(m_strOption,MB_OK);
  223. break;
  224. }
  225. }
  226. else
  227. {
  228. m_strNormalText = m_strTemp;
  229. bScanDone = TRUE;
  230. }
  231. RespondToOptions();
  232. }
  233. void CTelnetView::RespondToOptions()
  234. {
  235. CString strOption;
  236. while(!m_ListOptions.IsEmpty())
  237. {
  238. strOption = m_ListOptions.RemoveHead();
  239. ArrangeReply(strOption);
  240. }
  241. DispatchMessage(m_strResp);
  242. m_strResp.Empty();
  243. }
  244. void CTelnetView::ArrangeReply(CString strOption)
  245. {
  246. unsigned char Verb;
  247. unsigned char Option;
  248. unsigned char Modifier;
  249. unsigned char ch;
  250. BOOL bDefined = FALSE;
  251. if(strOption.GetLength() < 3) return;
  252. Verb = strOption.GetAt(1);
  253. Option = strOption.GetAt(2);
  254. switch(Option)
  255. {
  256. case 1: // Echo
  257. case 3: // Suppress Go-Ahead
  258. bDefined = TRUE;
  259. break;
  260. }
  261. m_strResp += IAC;
  262. if(bDefined == TRUE)
  263. {
  264. switch(Verb)
  265. {
  266. case DO:
  267. ch = WILL;
  268. m_strResp += ch;
  269. m_strResp += Option;
  270. break;
  271. case DONT:
  272. ch = WONT;
  273. m_strResp += ch;
  274. m_strResp += Option;
  275. break;
  276. case WILL:
  277. ch = DO;
  278. m_strResp += ch;
  279. m_strResp += Option;
  280. break;
  281. case WONT:
  282. ch = DONT;
  283. m_strResp += ch;
  284. m_strResp += Option;
  285. break;
  286. case SB:
  287. Modifier = strOption.GetAt(3);
  288. if(Modifier == SEND)
  289. {
  290. ch = SB;
  291. m_strResp += ch;
  292. m_strResp += Option;
  293. m_strResp += IS;
  294. m_strResp += IAC;
  295. m_strResp += SE;
  296. }
  297. break;
  298. }
  299. }
  300. else
  301. {
  302. switch(Verb)
  303. {
  304. case DO:
  305. ch = WONT;
  306. m_strResp += ch;
  307. m_strResp += Option;
  308. break;
  309. case DONT:
  310. ch = WONT;
  311. m_strResp += ch;
  312. m_strResp += Option;
  313. break;
  314. case WILL:
  315. ch = DONT;
  316. m_strResp += ch;
  317. m_strResp += Option;
  318. break;
  319. case WONT:
  320. ch = DONT;
  321. m_strResp += ch;
  322. m_strResp += Option;
  323. break;
  324. }
  325. }
  326. }
  327. //send to the telnet server
  328. void CTelnetView::DispatchMessage(CString strText)
  329. {
  330. ASSERT(cSock);
  331. cSock->Send(strText, strText.GetLength());
  332. }
  333. BOOL CTelnetView::GetLine( unsigned char * bytes, int nBytes, int& ndx )
  334. {
  335. BOOL bLine = FALSE;
  336. while ( bLine == FALSE && ndx < nBytes )
  337. {
  338. unsigned char ch = bytes[ndx];
  339. switch( ch )
  340. {
  341. case 'r': // ignore
  342. m_strLine += "rn"; //"CR";
  343. break;
  344. case 'n': // end-of-line
  345. // m_strLine += 'n'; //"LF";
  346. // bLine = TRUE;
  347. break;
  348. default:   // other....
  349. m_strLine += ch;
  350. break;
  351. ndx ++;
  352. if (ndx == nBytes)
  353. {
  354. bLine = TRUE;
  355. }
  356. }
  357. return bLine;
  358. }
  359. void CTelnetView::MessageReceived(LPCSTR pText)
  360. {
  361. CDC * pDC = GetDC();
  362. OnPrepareDC(pDC);
  363. DrawCursor(pDC,FALSE);
  364. CMainFrame * frm = (CMainFrame*)GetTopLevelFrame();
  365. pDC->SetTextColor(cTextColor);
  366. pDC->SetBkColor(cBackgroundColor);
  367. // dc.SelectObject(GetStockObject(SYSTEM_FONT));
  368. pDC->SelectObject(GetStockObject(ANSI_FIXED_FONT));
  369. int length = strlen(pText);
  370. char text[2] = {0x00, 0x00};
  371. for(int loop = 0; loop < length; loop++)
  372. {
  373. switch(pText[loop])
  374. {
  375. case 8: //Backspace
  376. cCursX--;
  377. if(cCursX < 0) cCursX = 0;
  378. break;
  379. case 9: //TAB
  380. cCursX++; //TBD make this smarter
  381. break;
  382. case 13: //CR
  383. cCursX = 0;
  384. break;
  385. case 10: //LF
  386. {
  387. for(int row = 0; row < bufferLines-1; row++)
  388. {
  389. for(int  col = 0; col < 80; col++)
  390. {
  391. cText[col][row] = cText[col][row+1];
  392. }
  393. }
  394. for(int  col = 0; col < 80; col++)
  395. {
  396. cText[col][bufferLines-1] = ' ';
  397. }
  398. DoDraw(pDC);
  399. }
  400. break;
  401. default:
  402. {
  403. cText[cCursX][bufferLines-1] = pText[loop];
  404. text[0] = cText[cCursX][bufferLines-1];
  405. if(text[0] == ' ')
  406. {
  407. pDC->FillSolidRect(CRect(cCursX * dtX, (bufferLines-1) * dtY, 
  408. cCursX * dtX + dtX, (bufferLines-1) * dtY + dtY), 
  409. cBackgroundColor);
  410. }
  411. else
  412. {
  413. pDC->TextOut(cCursX * dtX, (bufferLines-1) * dtY, text);
  414. }
  415. cCursX++;
  416. if(cCursX >= 80)
  417. {
  418. for(int row = 0; row < bufferLines-1; row++)
  419. {
  420. for(int  col = 0; col < 80; col++)
  421. {
  422. cText[col][row] = cText[col][row+1];
  423. }
  424. }
  425. for(int  col = 0; col < 80; col++)
  426. {
  427. cText[col][bufferLines-1] = ' ';
  428. }
  429. cCursX = 0;
  430. DoDraw(pDC);
  431. }
  432. }
  433. break;
  434. }
  435. }
  436. DrawCursor(pDC,TRUE);
  437. ReleaseDC(pDC);
  438. }
  439. void CTelnetView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
  440. {
  441. if (nChar == VK_RETURN)
  442. {
  443. DispatchMessage("rn");
  444. }
  445. else
  446. {
  447. DispatchMessage(nChar);
  448. }
  449. }
  450. void CTelnetView::DrawCursor(CDC * pDC, BOOL pDraw)
  451. {
  452. COLORREF color;
  453. CMainFrame * frm = (CMainFrame*)GetTopLevelFrame();
  454. if(pDraw) //draw
  455. {
  456. color = cTextColor;
  457. }
  458. else //erase
  459. {
  460. color = cBackgroundColor;
  461. }
  462. CRect rect(cCursX * dtX + 2, (bufferLines-1) * dtY + 1, 
  463. cCursX * dtX + dtX - 2, (bufferLines-1) * dtY + dtY -1);
  464. pDC->FillSolidRect(rect, color);
  465. }
  466. void CTelnetView::OnSize(UINT nType, int cx, int cy) 
  467. {
  468. CScrollView::OnSize(nType, cx, cy);
  469. if(IsWindow(m_hWnd))
  470. {
  471. if(IsWindowVisible())
  472. {
  473. ScrollToPosition(CPoint(0, bufferLines * 1000)); //go way past the end
  474. }
  475. }
  476. }
  477. BOOL CTelnetView::OnEraseBkgnd(CDC* pDC) 
  478. {
  479. CRect clip;
  480. pDC->GetClipBox(clip);
  481. CMainFrame * frm = (CMainFrame*)GetTopLevelFrame();
  482. pDC->FillSolidRect(clip,cBackgroundColor);
  483. return TRUE;
  484. }