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