OUTPUTWND.CPP
上传用户:shgx688
上传日期:2009-12-27
资源大小:855k
文件大小:28k
源码类别:

SNMP编程

开发平台:

MultiPlatform

  1. /* 
  2. Output Window v1.0
  3. ------------------
  4.   (C) 1998/99 Ben Ashley
  5. Distribution : You are free to use this code in any program, commercial
  6.    or otherwise, providing credit is given.
  7. Modification : You are also free to modify this code to suit your needs
  8.    providing credit is still given to the original code, and
  9.    all changes are documented.  You might also consider
  10.    re-submitting it complete with modifications to 
  11.    http://www.codeguru.com, share your talent with others!!
  12. */
  13. #include "stdafx.h" // Precompiled Header
  14. #include "OutputWnd.h" // class TOutputWnd
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20. /*
  21. =================================================================
  22. TOutputWnd::TOutputWnd()
  23. TOutputWnd::~TOutputWnd()
  24. -------------------------
  25. =================================================================
  26. */
  27. TOutputWnd::TOutputWnd()
  28. {
  29. m_pFont = NULL;
  30. m_BackCol = GetSysColor( COLOR_WINDOW );
  31. m_nHead = -1;
  32. m_nLinesDone = 0;
  33. m_nDefTextCol = COLOUR_BLACK;
  34. m_bWordWrap = FALSE;
  35. m_nXOffset = 0;
  36. m_nMaxLines = 500; // Maximum of 500 entries ( default )
  37. m_nMaxWidth = 0; // Greatest width done
  38. m_nFontHeight = 0; // No Font Height
  39. // Temporary...
  40. m_ColTable[ COLOUR_WHITE ] = RGB( 255, 255, 255 );
  41. m_ColTable[ COLOUR_BLACK ] = RGB( 0, 0, 0 );
  42. m_ColTable[ COLOUR_BLUE ] = RGB( 0, 0, 128 );
  43. m_ColTable[ COLOUR_GREEN ] = RGB( 0, 128, 0 );
  44. m_ColTable[ COLOUR_LIGHTRED ] = RGB( 255, 0, 0 );
  45. m_ColTable[ COLOUR_BROWN ] = RGB( 128, 0, 0 );
  46. m_ColTable[ COLOUR_PURPLE ] = RGB( 128, 0, 128 );
  47. m_ColTable[ COLOUR_ORANGE ] = RGB( 128, 128, 0 );
  48. m_ColTable[ COLOUR_YELLOW ] = RGB( 255, 255, 0 );
  49. m_ColTable[ COLOUR_LIGHTGREEN ] = RGB( 0, 255, 0 );
  50. m_ColTable[ COLOUR_CYAN ] = RGB( 0, 128, 128 );
  51. m_ColTable[ COLOUR_LIGHTCYAN ] = RGB( 0, 255, 255 );
  52. m_ColTable[ COLOUR_LIGHTBLUE ] = RGB( 0, 0, 255 );
  53. m_ColTable[ COLOUR_PINK ] = RGB( 255, 0, 255 );
  54. m_ColTable[ COLOUR_GREY ] = RGB( 128, 128, 128 );
  55. m_ColTable[ COLOUR_LIGHTGREY ] = RGB( 192, 192, 192 );
  56. // -------------------------------------------------------------
  57. // Load the Cursor:
  58. // -------------------------------------------------------------
  59. m_hCursor = AfxGetApp()->LoadStandardCursor( IDC_IBEAM );
  60. }
  61. TOutputWnd::~TOutputWnd()
  62. {
  63. // Destroy the font we were using:
  64. if( m_pFont != NULL )
  65. delete( m_pFont );
  66. }
  67. /*
  68. =================================================================================
  69. void TOutputWnd::UpdateHScroll()
  70. void TOutputWnd::UpdateVScroll()
  71. --------------------------------
  72. Updates scroll-bar information.
  73. =================================================================================
  74. */
  75. void TOutputWnd::UpdateHScroll()
  76. {
  77. if( m_bWordWrap ) return; // No need for word-wrapped output windows
  78. CRect clientRc; GetClientRect( &clientRc );
  79. int nMax = m_nMaxWidth - clientRc.Width();
  80. if( nMax <= 0 )
  81. m_nXOffset = 0;
  82. SetScrollRange( SB_HORZ, 0, nMax );
  83. //SCROLLINFO si;
  84. //si.fMask = SIF_PAGE;
  85. //si.nPage = m_nAvgCharWidth;
  86. //SetScrollInfo( SB_HORZ, &si );
  87. };
  88. void TOutputWnd::UpdateVScroll()
  89. {
  90. SetScrollRange( SB_VERT, 0, GetLineCount() - 1 );
  91. //SCROLLINFO si;
  92. //si.fMask = SIF_PAGE;
  93. //si.nPage = GetMaxViewableLines();
  94. //SetScrollInfo( SB_VERT, &si );
  95. };
  96. /*
  97. =================================================================
  98. void TOutputWnd::RenderSingleLine( CString&, CDC*, int&, int& )
  99. ---------------------------------------------------------------
  100. Renders a single line at the specified position, and will handle
  101. the control codes accordingly.  The line passed is expected to fit
  102. , as word-wrapping code should already have been applied.
  103. =================================================================
  104. */
  105. void TOutputWnd::RenderSingleLine( CString& strLine,
  106.    CDC* pDC,
  107.    int nX,
  108.    int nY )
  109. {
  110. CRect clientRc; GetClientRect( &clientRc );
  111. CString strTemp = strLine;
  112. CString strToRender;
  113. SIZE sz;
  114. int nPos;
  115. int nWidth = 0;
  116. do
  117. {
  118. nPos = strTemp.Find( CONTROL_BYTE );
  119. if( nPos > -1 )
  120. {
  121. strToRender = strTemp.Left( nPos );
  122. if( strToRender != "" )
  123. {
  124. if( !FLAG( m_lfFont.lfPitchAndFamily, FIXED_PITCH ) )
  125. ::GetTextExtentPoint32( pDC->GetSafeHdc(), strToRender, strToRender.GetLength(), &sz );
  126. else
  127. sz.cx = strToRender.GetLength() * m_nAvgCharWidth;
  128. pDC->TextOut( nX, nY, strToRender );
  129. nX += sz.cx;
  130. nWidth += sz.cx;
  131. };
  132. COLOURCODE code;
  133. strTemp = strTemp.Mid( nPos );
  134. GetColourCodes( strTemp, &code );
  135. if( code.nFore != -1 ) pDC->SetTextColor( m_ColTable[ code.nFore ] );
  136. if( code.nBack != -1 ) pDC->SetBkColor( m_ColTable[ code.nBack ] );
  137. }
  138. else
  139. {
  140. if( !FLAG( m_lfFont.lfPitchAndFamily, FIXED_PITCH ) )
  141. ::GetTextExtentPoint32( pDC->GetSafeHdc(), strTemp, strTemp.GetLength(), &sz );
  142. else
  143. sz.cx = strTemp.GetLength() * m_nAvgCharWidth;
  144. nWidth += sz.cx;
  145. pDC->TextOut( nX, nY, strTemp );
  146. nX += sz.cx;
  147. // Pad out rest of line with solid colour:
  148. CRect solidRc( nX, nY, clientRc.right, nY + m_nFontHeight );
  149. pDC->FillSolidRect( &solidRc, m_BackCol );
  150. break;
  151. }
  152. }while( 1 );
  153. nY += m_nFontHeight;
  154. // -------------------------------------------------------------
  155. // Update Horizontal scroll bar for width ( for times when the
  156. // word wrap is OFF )
  157. // -------------------------------------------------------------
  158. if( nWidth > m_nMaxWidth && !m_bWordWrap )
  159. {
  160. m_nMaxWidth = nWidth;
  161. UpdateHScroll();
  162. };
  163. };
  164. /*
  165. =================================================================================
  166. int TOutputWnd::GetLineInfo( CString&, LINEINFO* )
  167. --------------------------------------------------
  168. Works out the bounding rectangle of a line, and fills out a 
  169. LINERECT with the necessary information to render it.  This 
  170. function will automatically strip out control codes for the
  171. purpose of measuring.
  172. =================================================================================
  173. */
  174. int TOutputWnd::GetLineInfo( CString& strLine,
  175.  CDC* pDC,
  176.  int nRight )
  177. {
  178. int nLines = 1; // Start of with 1 line
  179. // ---------------------------------------------------------
  180. // We can very quickly handle empty lines:
  181. // ---------------------------------------------------------
  182. if( strLine == "" )
  183. return( nLines ); // See, I told u it was easy.
  184. // And lets do the rest properly:
  185. int nLen = strLine.GetLength();
  186. int nOriginalLength = nLen;
  187. char* pTmp = new char[ nOriginalLength + 1 ];
  188. char ch = 0;
  189. SIZE sz;
  190. memset( pTmp, 0, nOriginalLength );
  191. int nCurrWidth = 0; // Width of current line
  192. int nPosInTemp = 0; // Current Position in temp buffer
  193. int nPosInString = 0; // Current Position in string
  194. int nSpc = 0;
  195. HDC hDC = pDC->GetSafeHdc();// Handle to the device context
  196. CString strLeftPart; // Left Part
  197. CString strRightPart; // Right Part
  198. int nLastWrap = -1; // Where we put the last wrap point
  199. COLOURCODE code;
  200. do
  201. {
  202. ch = strLine[ nPosInString ];
  203. if( ch != CONTROL_BYTE )
  204. {
  205. pTmp[ nPosInTemp ] = ch;
  206. if( !FLAG( m_lfFont.lfPitchAndFamily, FIXED_PITCH ) )
  207. ::GetTextExtentPoint32( hDC, pTmp, nPosInTemp + 1, &sz );
  208. else
  209. sz.cx = ( nPosInTemp + 1 ) * m_nAvgCharWidth;
  210. if( sz.cx >= nRight )
  211. {
  212. // Find the previous space
  213. for( int nSpc = nPosInString - 1; nSpc >= 0; nSpc -- )
  214. if( strLine[ nSpc ] == ' ' ) break;
  215. if( nSpc == 0 )
  216. nSpc = nPosInString;
  217. if( nSpc > nLastWrap )
  218. {
  219. strLeftPart = strLine.Left( nSpc );
  220. strRightPart = strLine.Mid( nSpc + 1 );
  221. strLine = strLine.Left( nSpc );
  222. nLastWrap = nSpc;
  223. strLine += WRAP_BYTE;
  224. strLine += strRightPart;
  225. nPosInString = nSpc + 1;
  226. nLen = strLine.GetLength();
  227. nLines++; // And another line
  228. };
  229. memset( pTmp, 0, nOriginalLength );
  230. nPosInTemp = 0;
  231. }
  232. else
  233. {
  234. nPosInTemp++;
  235. nPosInString++;
  236. };
  237. }
  238. else
  239. {
  240. CString strTemp = strLine.Mid( nPosInString ); // Make temp copy. dont want to modify original
  241. nPosInString += GetColourCodes( strTemp, &code );// skips correct number of bytes
  242. };
  243. }while( nPosInString < nLen );
  244. delete [] pTmp;
  245. return( nLines );
  246. };
  247. /*
  248. =================================================================
  249. int TOutputWnd::GetColourCodes( CString&, COLOURCODE* )
  250. -------------------------------------------------------
  251. Looks at the data passed ( first character must be the control
  252. byte ), and fills in the COLOURCODE structure accordingly.  This
  253. function returns the number of bytes to skip.
  254. =================================================================
  255. */
  256. int TOutputWnd::GetColourCodes( CString& strData, 
  257.     COLOURCODE* pColourCode )
  258. {
  259. ASSERT( pColourCode != NULL );
  260. ASSERT( strData.Left( 1 ) == CONTROL_BYTE );
  261. strData = strData.Mid( 1 ); // Truncate control byte
  262. int nBytesToSkip = 1;
  263. // Jump out of strData is now empty...
  264. if( strData == "" )
  265. {
  266. pColourCode->nFore = -1; // No foreground colour
  267. pColourCode->nBack = -1; // No background colour
  268. }
  269. else
  270. {
  271. // Now handle foreground and background colours:
  272. int nComma = strData.Find( "," ); // Position of comma.  Only present if background colour present
  273. if( ( nComma != -1 ) &&
  274. ( ( nComma == 1 ) ||
  275.   ( nComma == 2 && isdigit( strData[ 1 ] ) ) 
  276. )
  277.   )
  278. {
  279. CString strFore = strData.Left( nComma );
  280. nBytesToSkip += strFore.GetLength() + 1; // Includes code and comma
  281. pColourCode->nFore = atoi( strFore ); // Get Code
  282. strData = strData.Mid( nComma + 1 ); // Truncate string
  283. // Now look for backcolour:
  284. CString strBack;
  285. int nCodeLength = 1;
  286. if( strData.GetLength() >= 2 )
  287. {
  288. if( isdigit( strData[ 1 ] ) )
  289. nCodeLength++;
  290. };
  291. nBytesToSkip+= nCodeLength;
  292. strBack = strData.Left( nCodeLength );
  293. strData = strData.Mid( nCodeLength );
  294. pColourCode->nBack = atoi( strBack );
  295. }
  296. else
  297. {
  298. // No background colour present, the delimiter for this code
  299. // is the next non-numeric character...
  300. CString strFore;
  301. int nCodeLength = 1;
  302. if( strData.GetLength() >= 2 )
  303. {
  304. if( isdigit( strData[ 1 ] ) )
  305. nCodeLength++;
  306. };
  307. nBytesToSkip += nCodeLength;
  308. strFore = strData.Left( nCodeLength );
  309. strData = strData.Mid( nCodeLength );
  310. pColourCode->nFore = atoi( strFore );
  311. pColourCode->nBack = -1;
  312. };
  313. };
  314. // Return number of bytes processed:
  315. return( nBytesToSkip );
  316. };
  317. /*
  318. =================================================================
  319. void TOutputWnd::SetBuffer( CStringArray& )
  320. bool TOutputWnd::GetBuffer( CStringArray& ) const
  321. -------------------------------------------------
  322. Sets or gets the content of the buffer.  This facility allows a
  323. different part of the application to use multiple buffers with
  324. one output window.  A typical example of this kind of use is the
  325. RAW output window which uses one output window, but allows the
  326. user to switch the content.
  327. =================================================================
  328. */
  329. void TOutputWnd::SetBuffer( CStringArray& rArray )
  330. {
  331. // Copy the buffer across:
  332. m_Lines.RemoveAll();
  333. int nLines = rArray.GetUpperBound() + 1;
  334. for( int l = 0; l < nLines; l ++ )
  335. m_Lines.Add( rArray.GetAt( l ) );
  336. UpdateVScroll();
  337. // Place the head at the bottom.
  338. m_nHead = nLines - 1;
  339. // Redraw the view if necessary:
  340. if( GetSafeHwnd() )
  341. {
  342. Invalidate();
  343. UpdateHScroll();
  344. };
  345. };
  346. bool TOutputWnd::GetBuffer( CStringArray& rArray ) const
  347. {
  348. rArray.RemoveAll(); // Ensures the passed array is empty
  349. // -------------------------------------------------------------
  350. // Add the lines to the buffer that was passed:
  351. // -------------------------------------------------------------
  352. int nLines = m_Lines.GetUpperBound() + 1;
  353. for( int l = 0; l < nLines; l ++ )
  354. rArray.Add( m_Lines.GetAt( l ) );
  355. return( true );
  356. };
  357. /*
  358. =================================================================
  359. void TOutputWnd::ClearBuffer()
  360. ------------------------------
  361. Clears the entire buffer of content.
  362. =================================================================
  363. */
  364. void TOutputWnd::ClearBuffer()
  365. {
  366. m_Lines.RemoveAll();
  367. m_nMaxWidth = 0;
  368. m_nHead = -1;
  369. if( GetSafeHwnd() )
  370. {
  371. UpdateHScroll();
  372. UpdateVScroll();
  373. Invalidate();
  374. };
  375. };
  376. /*
  377. =================================================================
  378. void TOutputWnd::AddLine( CString& )
  379. ------------------------------------
  380. Adds a line to the output window.
  381. =================================================================
  382. */
  383. void TOutputWnd::AddLine( CString& strLine )
  384. {
  385. // Add to the buffer, cutting off the first ( top ) line if
  386. // necessary.
  387. m_Lines.Add( strLine );
  388. if( GetLineCount() > m_nMaxLines )
  389. {
  390. m_Lines.RemoveAt( 0 );
  391. m_nHead--;
  392. };
  393. // Update the vertical scroll bar:
  394. UpdateVScroll();
  395. // Automatically scroll down if the user is already at the
  396. // bottom...
  397. m_nHead = GetLineCount() - 1;
  398. SetHead( m_nHead );
  399. /*
  400. if( m_nHead == GetLineCount() - 2 || m_nHead == -1 )
  401. {
  402. m_nHead++;
  403. SetHead( m_nHead );
  404. }
  405. else
  406. Invalidate();
  407. */
  408. };
  409. /*
  410. =================================================================
  411. void TOutputWnd::SetFont( LOGFONT& )
  412. bool TOutputWnd::GetFont( LOGFONT& ) const
  413. ------------------------------------------
  414. Sets or returns the font used to render the output text.
  415. =================================================================
  416. */
  417. void TOutputWnd::SetFont( LOGFONT& rFont )
  418. {
  419. // Destroy the old font if necessary:
  420. if( m_pFont != NULL )
  421. {
  422. delete( m_pFont );
  423. m_pFont = NULL;
  424. };
  425. // Create the new one:
  426. m_pFont = new CFont;
  427. m_pFont->CreateFontIndirect( &rFont );
  428. memcpy( &m_lfFont, &rFont, sizeof( LOGFONT ) );
  429. // Get the Average Char Width:
  430. TEXTMETRIC tm;
  431. CDC* pDC = GetDC();
  432. CFont* pOldFont = pDC->SelectObject( m_pFont );
  433. pDC->GetTextMetrics( &tm );
  434. pDC->SelectObject( pOldFont );
  435. ReleaseDC( pDC );
  436. m_nAvgCharWidth = tm.tmAveCharWidth;
  437. m_nFontHeight = tm.tmHeight;
  438. // Redraw the display if necessary:
  439. if( GetSafeHwnd() )
  440. {
  441. UpdateHScroll(); // Page size depends on average char width
  442. Invalidate();
  443. };
  444. };
  445. bool TOutputWnd::GetFont( LOGFONT& rFont ) const
  446. {
  447. if( m_pFont != NULL )
  448. {
  449. memcpy( &rFont, &m_lfFont, sizeof( LOGFONT ) );
  450. return( true );
  451. }
  452. else
  453. return( false ); // Should never happen unless I'm stupid
  454. };
  455. /*
  456. =================================================================
  457. void TOutputWnd::SetBackColour( COLORREF )
  458. ------------------------------------------
  459. Sets the background colour.
  460. =================================================================
  461. */
  462. void TOutputWnd::SetBackColour( COLORREF col )
  463. {
  464. m_BackCol = col;
  465. // Force a repaint if we are displayed.
  466. if( GetSafeHwnd() )
  467. Invalidate();
  468. };
  469. /*
  470. =================================================================
  471. void TOutputWnd::SetHead( int )
  472. -------------------------------
  473. Sets the position of the view relative to the first line of the
  474. buffer.
  475. =================================================================
  476. */
  477. void TOutputWnd::SetHead( int nPos )
  478. {
  479. if( nPos < -1 ) nPos = -1;
  480. if( nPos > GetLineCount() - 1 ) nPos = GetLineCount() - 1;
  481. m_nHead = nPos;
  482. if( GetSafeHwnd() )
  483. {
  484. SetScrollPos( SB_VERT, m_nHead );
  485. Invalidate();
  486. };
  487. };
  488. /*
  489. =================================================================
  490. void TOutputWnd::SetMaxLines( UINT )
  491. ------------------------------------
  492. Sets the maximum amount of lines we can display.
  493. =================================================================
  494. */
  495. void TOutputWnd::SetMaxLines( UINT nLines )
  496. {
  497. };
  498. /*
  499. =================================================================
  500. UINT TOutputWnd::GetMaxViewableLines() const
  501. --------------------------------------------
  502. Based on the current font, this function returns the maximum 
  503. number of lines that can be displayed in the output window, given
  504. it's current size.
  505. =================================================================
  506. */
  507. UINT TOutputWnd::GetMaxViewableLines()
  508. {
  509. ASSERT( GetSafeHwnd() != NULL ); // Must have been created
  510. CRect clientRc; GetClientRect( &clientRc );
  511. return( clientRc.Height() / m_nFontHeight );
  512. };
  513. /*
  514. =================================================================================
  515. void TOutputWnd::SetWordWrap( bool )
  516. ------------------------------------
  517. Sets whether we word-wrap or not.
  518. =================================================================================
  519. */
  520. void TOutputWnd::SetWordWrap( bool bWrap )
  521. {
  522. m_bWordWrap = bWrap;
  523. if( GetSafeHwnd() )
  524. Invalidate();
  525. };
  526. /*
  527. =================================================================
  528. void TOutputWnd::Load( const char* )
  529. ------------------------------------
  530. Loads a text file in from disk, and puts it in to the buffer.
  531. =================================================================
  532. */
  533. void TOutputWnd::Load( const char* lpFilename )
  534. {
  535. CStringArray tmpArray; // Temporary Array
  536. CFile file;
  537. if( file.Open( lpFilename, CFile::modeRead ) )
  538. {
  539. // ---------------------------------------------------------
  540. // Read the entire file into memory
  541. // ---------------------------------------------------------
  542. int nLen = file.GetLength();
  543. char* pBuffer = new char[ nLen + 1 ];
  544. file.Read( pBuffer, nLen );
  545. pBuffer[ nLen ] = 0;
  546. CString strTemp = pBuffer;
  547. delete [] pBuffer;
  548. file.Close();
  549. // ---------------------------------------------------------
  550. // Now add it to the buffer, line by line:
  551. // ---------------------------------------------------------
  552. int nCRLF = -1;
  553. do
  554. {
  555. if( ( nCRLF = strTemp.Find( "rn" ) ) != -1 )
  556. {
  557. tmpArray.Add( strTemp.Left( nCRLF ) );
  558. strTemp = strTemp.Mid( nCRLF + 2 );
  559. }
  560. else
  561. {
  562. tmpArray.Add( strTemp );
  563. strTemp = "";
  564. };
  565. }while( strTemp != "" );
  566. SetBuffer( tmpArray );
  567. };
  568. };
  569. /*
  570. =================================================================
  571. TOutputWnd Message Map:
  572. =================================================================
  573. */
  574. BEGIN_MESSAGE_MAP( TOutputWnd, CWnd )
  575. //{{AFX_MSG_MAP(TOutputWnd)
  576. ON_WM_CREATE()
  577. ON_WM_DESTROY()
  578. ON_WM_PAINT()
  579. ON_WM_ERASEBKGND()
  580. ON_WM_VSCROLL()
  581. ON_WM_SIZE()
  582. ON_WM_HSCROLL()
  583. ON_WM_SETCURSOR()
  584. ON_WM_LBUTTONUP()
  585. ON_WM_RBUTTONDOWN()
  586. //}}AFX_MSG_MAP
  587. END_MESSAGE_MAP()
  588. /*
  589. =================================================================
  590. int TOutputWnd::OnCreate( LPCREATESTRUCT )
  591. ------------------------------------------
  592. Initializes the window members, etc.
  593. =================================================================
  594. */
  595. int TOutputWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) 
  596. {
  597. // -------------------------------------------------------------
  598. // Call base-class implementation:
  599. // -------------------------------------------------------------
  600. if( CWnd::OnCreate( lpCreateStruct ) == -1 )
  601. return( -1 );
  602. // -------------------------------------------------------------
  603. // Give ourselves the device's default fixed-width font:
  604. // -------------------------------------------------------------
  605. #ifndef _WINNT
  606. HFONT hSysFont = ( HFONT )GetStockObject( DEFAULT_GUI_FONT );
  607. #else
  608. HFONT hSysFont = ( HFONT )GetStockObject( DEVICE_DEFAULT_FONT );
  609. #endif // !_WINNT
  610. LOGFONT lf;
  611. CFont* pFont = CFont::FromHandle( hSysFont );
  612. pFont->GetLogFont( &lf );
  613. SetFont( lf );
  614. // Initialize the scroll bars:
  615. SetScrollRange( SB_VERT, 0, 0 );
  616. SetScrollPos( SB_VERT, 0 );
  617. SetScrollRange( SB_HORZ, 0, 0 );
  618. SetScrollPos( SB_HORZ, 0 );
  619. return( 0 );
  620. }
  621. /*
  622. =================================================================
  623. void TOutputWnd::OnDestroy()
  624. ----------------------------
  625. Cleans up anything we allocated during the lifetime of this 
  626. window ( namely fonts, bitmaps and device contexts )
  627. =================================================================
  628. */
  629. void TOutputWnd::OnDestroy() 
  630. {
  631. // Call base-class implementation:
  632. CWnd::OnDestroy();
  633. // TOutputWnd-specific destruction:
  634. };
  635. /*
  636. =================================================================
  637. void TOuputWnd::OnPaint()
  638. -------------------------
  639. Simply blits our memory DC to the window's DC.
  640. =================================================================
  641. */
  642. void TOutputWnd::OnPaint() 
  643.     CPaintDC dc( this );
  644. CRect clientRc; GetClientRect( &clientRc );
  645. // Initialize the draw:
  646. UINT nMaxLines = GetMaxViewableLines(); // Max number of lines in view
  647. m_nLinesDone = 0; // No Lines drawn
  648. // Initialize colours and font:
  649. CFont* pOldFont = dc.SelectObject( m_pFont );
  650. // Now draw the lines, one by one:
  651. UINT nUBound = m_Lines.GetUpperBound();
  652. if( m_nHead != -1 )
  653. {
  654. int nRunner = m_nHead;
  655. int nX = clientRc.left - m_nXOffset;
  656. int nMasterY = clientRc.bottom;
  657. int nY = nMasterY;
  658. int nPos = -1;
  659. CString strTemp;
  660. CString strLine;
  661. do
  662. {
  663. // -----------------------------------------------------
  664. // Reset Colours:
  665. // -----------------------------------------------------
  666. dc.SetBkColor( m_BackCol );
  667. dc.SetTextColor( m_ColTable[ m_nDefTextCol ] );
  668. // -----------------------------------------------------
  669. // Proceed on to the next line:
  670. // -----------------------------------------------------
  671. strTemp = m_Lines[ nRunner ];
  672. if( !m_bWordWrap )
  673. {
  674. // Life is easier if no word-wrapping is expected
  675. // of us.  ( A damn sight quicker too <g> )
  676. nMasterY -= m_nFontHeight;
  677. RenderSingleLine( strTemp, &dc, nX, nMasterY );
  678. }
  679. else
  680. {
  681. // Obtain the line info for this line.  This 
  682. // routine will insert word-wrap control byes for
  683. // proper wrapping.  It returns the number of lines
  684. // processed.
  685. nMasterY -= GetLineInfo( strTemp, &dc, clientRc.right ) * m_nFontHeight;
  686. nY = nMasterY;
  687. do
  688. {
  689. if( ( nPos = strTemp.Find( WRAP_BYTE ) ) != -1 )
  690. {
  691. RenderSingleLine( strTemp.Left( nPos ), &dc, nX, nY );
  692. strTemp = strTemp.Mid( nPos + 1 );
  693. }
  694. else
  695. {
  696. RenderSingleLine( strTemp, &dc, nX, nY );
  697. strTemp = "";
  698. };
  699. nY += m_nFontHeight;
  700. }while( strTemp != "" );
  701. };
  702. /*
  703. else
  704. {
  705.   // Obtain the line info for this line.  This 
  706.   // routine will insert word-wrap control byes for
  707.   // proper wrapping.  It returns the number of lines
  708.   // processed.
  709.   nMasterY -= GetLineInfo(strTemp, &dc, clientRc.right)*m_nFontHeight;
  710.   nY = nMasterY;
  711.   CString strCode = _T("");//[extract code (XX,XX) from strTemp];
  712.   do
  713.   {
  714. if((nPos = strTemp.Find(WRAP_BYTE)) != -1)
  715. {
  716.   RenderSingleLine(strCode+strTemp.Left(nPos), &dc, nX, nY );
  717.   strTemp = strTemp.Mid(nPos+1);
  718. }
  719. else
  720. {
  721.   RenderSingleLine(strCode+strTemp, &dc, nX, nY);
  722.   strTemp = "";
  723. };
  724. nY += m_nFontHeight;
  725.   }
  726.   while (strTemp != "");
  727. };
  728. */
  729. // -----------------------------------------------------
  730. // Go on to the next line.
  731. // -----------------------------------------------------
  732. nRunner--;
  733. }while( nRunner > -1 && nMasterY >= 0 );
  734. // Pad out any remaining area...
  735. if( nMasterY >= 0 )
  736. {
  737. CRect solidRc = clientRc;
  738. solidRc.bottom = nMasterY;
  739. dc.FillSolidRect( &solidRc, m_BackCol );
  740. };
  741. }
  742. else
  743. dc.FillSolidRect( &clientRc, m_BackCol );
  744. // Clean up:
  745. dc.SelectObject( pOldFont );
  746. }
  747. /*
  748. =================================================================
  749. BOOL TOutputWnd::OnEraseBkgnd( CDC* )
  750. -------------------------------------
  751. Simply returns TRUE as we don't use this function and we don't
  752. want a flicker.
  753. =================================================================
  754. */
  755. BOOL TOutputWnd::OnEraseBkgnd( CDC* pDC ) 
  756. {
  757. return( TRUE );
  758. }
  759. /*
  760. =================================================================
  761. void TOutputWnd::OnVScroll( UINT, UINT, CScrollBar* )
  762. -----------------------------------------------------
  763. Occurs when the user scrolls.  Our job here is to position the
  764. head.
  765. =================================================================
  766. */
  767. void TOutputWnd::OnVScroll( UINT nSBCode, 
  768.     UINT nPos, 
  769. CScrollBar* pScrollBar ) 
  770. {
  771. int nUBound = GetLineCount() - 1;
  772. CRect rectClient;
  773. GetClientRect(rectClient);
  774. int nPage = rectClient.Height()/max(m_nFontHeight,1);
  775. switch( nSBCode )
  776. {
  777. case SB_TOP:
  778. SetHead( 0 );
  779. break;
  780. case SB_BOTTOM:
  781. SetHead( nUBound );
  782. break;
  783. case SB_PAGEUP:
  784. if( m_nHead > 0)
  785. {
  786. m_nHead -= nPage;
  787. if(m_nHead<0)
  788. m_nHead = 0;
  789. SetHead( m_nHead );
  790. }
  791. break;
  792. case SB_LINEUP:
  793. if( m_nHead > 0 )
  794. {
  795. m_nHead--;
  796. SetHead( m_nHead );
  797. }
  798. break;
  799. case SB_PAGEDOWN:
  800. if( m_nHead < nUBound)
  801. {
  802. m_nHead += nUBound;
  803. if(m_nHead > nUBound)
  804. m_nHead = nUBound;
  805. SetHead( m_nHead );
  806. }
  807. break;
  808. case SB_LINEDOWN:
  809. if( m_nHead < nUBound )
  810. {
  811. m_nHead++;
  812. SetHead( m_nHead );
  813. };
  814. break;
  815. case SB_THUMBPOSITION:
  816. case SB_THUMBTRACK:
  817. SetHead( ( int )nPos );
  818. break;
  819. };
  820. CWnd::OnVScroll( nSBCode, nPos, pScrollBar );
  821. }
  822. /*
  823. =================================================================
  824. void TOutputWnd::OnHScroll( UINT, UINT, CScrollBar* )
  825. -----------------------------------------------------
  826. For Non-Wordwrapped output windows, the horizontal scroll bar
  827. can adjust the viewport so the user can see the end of the line.
  828. =================================================================
  829. */
  830. void TOutputWnd::OnHScroll( UINT nSBCode, 
  831.     UINT nPos, 
  832. CScrollBar* pScrollBar ) 
  833. {
  834. CRect clientRc; GetClientRect( &clientRc );
  835. int nMax = max(m_nMaxWidth - clientRc.Width(),0);
  836. switch( nSBCode )
  837. {
  838. case SB_TOP:
  839. m_nXOffset = 0;
  840. break;
  841. case SB_BOTTOM:
  842. m_nXOffset = nMax;
  843. break;
  844. case SB_LINEUP:
  845. {
  846. m_nXOffset -= m_nAvgCharWidth;
  847. if( m_nXOffset < 0 ) m_nXOffset = 0;
  848. break;
  849. };
  850. case SB_PAGEUP:
  851. {
  852. m_nXOffset -= clientRc.Width();//m_nAvgCharWidth;
  853. if( m_nXOffset < 0 ) m_nXOffset = 0;
  854. break;
  855. };
  856. case SB_LINEDOWN:
  857. {
  858. m_nXOffset += m_nAvgCharWidth;
  859. if( m_nXOffset > nMax ) m_nXOffset = nMax;
  860. break;
  861. };
  862. case SB_PAGEDOWN:
  863. {
  864. m_nXOffset += clientRc.Width();//m_nAvgCharWidth;
  865. if( m_nXOffset > nMax ) m_nXOffset = nMax;
  866. break;
  867. };
  868. case SB_THUMBPOSITION:
  869. case SB_THUMBTRACK:
  870. m_nXOffset = ( int )nPos;
  871. break;
  872. };
  873. SetScrollPos( SB_HORZ, m_nXOffset );
  874. Invalidate();
  875. CWnd::OnHScroll( nSBCode, nPos, pScrollBar );
  876. }
  877. /*
  878. =================================================================================
  879. void TOutputWnd::OnSize( UINT, int, int )
  880. -----------------------------------------
  881. Overidden to update the scroll bars.
  882. =================================================================================
  883. */
  884. void TOutputWnd::OnSize(UINT nType, int cx, int cy) 
  885. {
  886. CWnd ::OnSize(nType, cx, cy);
  887. if( GetSafeHwnd() )
  888. {
  889. UpdateHScroll();
  890. UpdateVScroll();
  891. };
  892. }
  893. /*
  894. =================================================================
  895. BOOL TOuputWnd::OnSetCursor( CWnd*, UINT, UINT )
  896. ------------------------------------------------
  897. Overidden to set the window cursor.
  898. =================================================================
  899. */
  900. BOOL TOutputWnd::OnSetCursor( CWnd* pWnd, 
  901.   UINT nHitTest, 
  902.   UINT message ) 
  903. {
  904. if( nHitTest != HTVSCROLL &&
  905. nHitTest != HTHSCROLL && 
  906. nHitTest != HTCAPTION)
  907. {
  908. SetCursor( m_hCursor );
  909. return( TRUE );
  910. }
  911. else
  912. return( CWnd::OnSetCursor( pWnd, nHitTest, message ) );
  913. }
  914. /*
  915. =================================================================================
  916. Mouse handlers:
  917. =================================================================================
  918. */
  919. void TOutputWnd::OnLButtonUp( UINT nFlags, CPoint point ) 
  920. {
  921. // *** Put code for notifying owner about button up ***
  922. CWnd::OnLButtonUp( nFlags, point );
  923. }
  924. void TOutputWnd::OnRButtonDown( UINT nFlags, CPoint point ) 
  925. {
  926. // *** Put code for notifying owner about Rbutton down ***
  927. CWnd::OnRButtonDown( nFlags, point );
  928. }