
/***************************************************************************
**
**    $Header:   C:/EPSLDV1/SRC/LOG/TRCVIEW.CPP   1.28   15 Feb 1996 08:46:16   Shirley  $
**
**    $Log:   C:/EPSLDV1/SRC/LOG/TRCVIEW.CPP  $
** 
**    Rev 1.28   15 Feb 1996 08:46:16   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:01:20   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:26:46   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:42:10   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:10:46   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:11:34   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:11:54   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:31:18   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:21:38   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.19   18 Jan 1996 10:07:04   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:09:50   Shirley
** No change.
** 
**    Rev 1.17   04 Jan 1996 11:07:18   Shirley
** No change.
** 
**    Rev 1.16   30 Nov 1995 09:07:40   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:28:42   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:17:38   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:21:14   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:27:50   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:27:22   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:39:18   Shirley
** EasyPack/SLD Version 0.22
** 
**    Rev 1.7   27 Oct 1995 13:43:00   Shirley
** EasyPack/SLD Version 0.1g
** 
**    Rev 1.4   13 Oct 1995 13:22:04   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:49:40   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:56:16   Shirley
** No change.
** 
**    Rev 1.1   15 Sep 1995 09:46:06   Shirley
** EasyPack/SLDV0.1a 
** 
**    Rev 1.0   07 Sep 1995 09:54:00   Shirley
** Initial revision.
**
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  TRCVIEW.CPP
//
//  Description:The implement file for the class: CTraceView
//
//  Author:     Chris Fang
//
//  Date:       09/10/95
//
//  Modification:
//
//      1. 09/10/95, Initial version
//
//
//  Copyright (C) 1995 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

// trcview.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"					

#include "uicom.h"
#include "xview.h"
#include "trcserve.h"
#include "ctrcbuf.h"
#include "trcview.h"
#include "trcwin.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

extern STATUS AbiGetTraceLastFrame(UINT* uLastFrame);
CListTrace* pLTrace;			//for campatibility with lane' trace window.

/////////////////////////////////////////////////////////////////////////////
// CTraceView

CTraceView::CTraceView()
{                          
	if(nTraceViewOption==TRACEMODE_BUS)
		m_nColnum=6;
	else m_nColnum=3;
	m_wCurFrame=0;
	m_wLines=0;
	m_nMaxSrclen=0;
	m_nMaxInstlen=0;
	m_wCurFrame=0;
	m_wLastFrame=0;
    
    m_ColumnMode[0]=2;
    m_ColumnMode[1]=2;
    m_ColumnMode[2]=2;
    
    m_VscrollFlag=0;
    m_bVscOn=FALSE;
    
    m_pBus=new TRACE_BUSREC[33];
    m_pInst=new TRACE_INSTREC[33];
    m_pSource=new TRACE_SOURCEREC[33];
    pLTrace=new CListTrace;
}

CTraceView::~CTraceView()
{
    delete m_pBus;
    delete m_pInst;
    delete m_pSource;      
    delete pLTrace;
}                                                      

/****************************************************************************
**
**  Name: CTraceView::DrawColLine
**
**  Description: 
**
**  Parameters:
**     input:x - 
**
**     output:
**
**  Return data --
**
****************************************************************************/
void CTraceView::DrawColLine(int x)
{                
	CDC*	pDC=GetDC();
	CPen	pen(PS_DOT, 0, RGB(0, 0, 0));
	CPen*	oldpen=pDC->SelectObject(&pen);
	
	pDC->SetROP2(R2_NOT);
	pDC->MoveTo(x, 0);
	pDC->LineTo(x, m_nCyView);
	pDC->SelectObject(oldpen);
	ReleaseDC(pDC);
}

/****************************************************************************
**
**  Name: CTraceView::ReColumn
**
**  Description: calculate m_nCol1len~m_nCol3(4)len's value.
**
**  Parameters:
**     input:cx - the width of window of CTraceView
**
**     output:
**
**  Return data --
**
****************************************************************************/
#define COLFREE 5
void CTraceView::ReColumn(int cx)
{                                           
int spare;
int nCxmin;
	if(m_ColumnMode[nTraceViewOption-1]==3)				//free mode
	 	 return;
	if(nTraceViewOption==TRACEMODE_INSTRUCTION)
		m_nMaxInstlen=max(m_nMaxInstlen,11*m_nCharWidth);
	else if(nTraceViewOption==TRACEMODE_SOURCE)
	    m_nMaxSrclen=max(m_nMaxSrclen,6*m_nCharWidth);
	else if(nTraceViewOption==TRACEMODE_MIXED)
		m_nMaxSrclen=max(m_nMaxSrclen,6*m_nCharWidth);
    switch(nTraceViewOption)
    	{
    	 case TRACEMODE_BUS:
    	 	nCxmin=(5+7+4+6+10+4)*m_nCharWidth+COLFREE*6;
    	 	break;
    	 case TRACEMODE_INSTRUCTION:	
    	 	nCxmin=(5+7)*m_nCharWidth+m_nMaxInstlen+COLFREE*3;	
    	 	break;
    	 case TRACEMODE_SOURCE:
    	 	nCxmin=(5+5)*m_nCharWidth+m_nMaxSrclen+COLFREE*3;
    	 	break;
    	 case TRACEMODE_MIXED:
    	 	nCxmin=(5+7)*m_nCharWidth+m_nMaxSrclen+COLFREE*3;
    	 	break;	
    	}
    if(cx<nCxmin)				//cx is too small, so need hscroll
		{
		 spare=0;
		 m_nHscrollMaxpos=(nCxmin-cx)/m_nCharWidth+1;
    	 m_nHscrollPos=GetScrollPos(SB_HORZ);
 		 SetScrollRange(SB_HORZ, 0, m_nHscrollMaxpos, FALSE);
		 m_nHscrollPos=min(m_nHscrollPos, m_nHscrollMaxpos);
 		 SetScrollPos(SB_HORZ, m_nHscrollPos, TRUE);
 		 m_nLeftfrom=-(m_nHscrollPos*m_nCharWidth);
		 cx+=m_nHscrollMaxpos*m_nCharWidth;			//cx is the length of one line
		}
	else
		{
		 if(m_ColumnMode[nTraceViewOption-1]==1)				//center align
		 	spare=(cx-nCxmin)/m_nColnum;
		 else								//left align
		 	spare=0;
 		 SetScrollRange(SB_HORZ, 0, 0);
 		 m_nLeftfrom=0;
		}
	m_nCol1len=5*m_nCharWidth+COLFREE+spare;
	switch(nTraceViewOption)
    	{
    	 case TRACEMODE_BUS:
    	 	m_nCol2len=7*m_nCharWidth+COLFREE+spare;
    	 	m_nCol3len=4*m_nCharWidth+COLFREE+spare;
    	 	m_nCol4len=6*m_nCharWidth+COLFREE+spare;
    	 	m_nCol5len=10*m_nCharWidth+COLFREE+spare;
    	 	m_nCol6len=cx-m_nCol1len-m_nCol2len-
    	 				m_nCol3len-m_nCol4len-m_nCol5len;
    	 	break;
    	 case TRACEMODE_INSTRUCTION:
    	 	m_nCol2len=7*m_nCharWidth+COLFREE+spare;
    	 	m_nCol3len=cx-m_nCol1len-m_nCol2len;
    	 	break;
    	 case TRACEMODE_SOURCE:
    	 	m_nCol2len=5*m_nCharWidth+COLFREE+spare;
    	 	m_nCol3len=cx-m_nCol1len-m_nCol2len;	
    	 	break;
    	 case TRACEMODE_MIXED:
    	 	m_nCol2len=7*m_nCharWidth+COLFREE+spare;
    	 	m_nCol3len=cx-m_nCol1len-m_nCol2len;	
    	 	break;
    	}
}

/****************************************************************************
**
**  Name: CTraceView::Resize
**
**  Description: 1. calculate m_nCol1len~m_nCol3(4)len's value.
**               2. calculate m_nMaxlenofSrcorInst and m_wLines
**  Parameters:
**     input:cx - the width of window of CTraceView
**           cy - the height of window of CTraceView
**     output: 
**
**  Return data --
**
****************************************************************************/
void CTraceView::ReSize(int cx, int cy)
{                                           
	for(int i=0; i<4; i++)
	{
		if(m_ColumnMode[i]==3)
		{
			if(i==0)
			{	
				m_nBusCollen[5]+=cx-m_nCxView;
				m_nBusCollen[5]=max(0, m_nBusCollen[5]);
			}
			else if(i==1)
			{
				m_nInsCollen[2]+=cx-m_nCxView;
				m_nInsCollen[2]=max(0, m_nInsCollen[2]);
			}	
			else if(i==2)
			{
				m_nSrcCollen[2]+=cx-m_nCxView;
				m_nSrcCollen[2]=max(0, m_nSrcCollen[2]);
			}
			else
			{
			    m_nMixedCollen[2]+=cx-m_nCxView;
				m_nMixedCollen[2]=max(0, m_nMixedCollen[2]);
			}
		}
	}
	m_nCxView=cx;
	m_nCyView=cy;
	ASSERT(cy>=0);
	if(WORD(cy/m_nLineHeight+1)>m_wLines)
    	{
    	 m_wLines=WORD(cy/m_nLineHeight+1);
    	 PrepareData(FALSE);
    	}
    else m_wLines=WORD(cy/m_nLineHeight+1);
 	if(m_bVscOn&&m_wLastFrame<m_wLines-1)
 	{
		EnableScrollBar(SB_VERT, ESB_DISABLE_BOTH);
	 	m_bVscOn=FALSE;
 	}
 	else if(!m_bVscOn&&m_wLastFrame>=m_wLines-1)
 	{
 		EnableScrollBar(SB_VERT, ESB_ENABLE_BOTH);
	 	m_bVscOn=TRUE;
 		m_wVscrollMaxpos=max(0, int(m_wLastFrame-m_wLines/2));
 		SetScrollRange(SB_VERT, 0, (int)m_wCurFrame, FALSE);
 	}
 	CalcMaxlenofSrcorInst();
    ReColumn(cx);
}

void CTraceView::OnModechange(TRACEMODE mode)
{
RECT	rect;	
	nTraceViewOption=mode;
	if(mode==TRACEMODE_BUS)
		m_nColnum=6;
	else m_nColnum=3;
	PrepareData(TRUE);
	SetScrollPos(SB_VERT, m_wCurFrame, TRUE);
	CalcMaxlenofSrcorInst();
	if(m_ColumnMode[nTraceViewOption-1]==3)				//free mode
	{
		switch(nTraceViewOption)
		 	{
		 	 case TRACEMODE_BUS:
		 	 	m_nCol1len=m_nBusCollen[0];
		 	 	m_nCol2len=m_nBusCollen[1];
		 	 	m_nCol3len=m_nBusCollen[2];
		 	 	m_nCol4len=m_nBusCollen[3];
		 	 	m_nCol5len=m_nBusCollen[4];
		 	 	m_nCol6len=m_nBusCollen[5];
		 	 	break;
		 	 case TRACEMODE_INSTRUCTION:
		 	 	m_nCol1len=m_nInsCollen[0];
		 	 	m_nCol2len=m_nInsCollen[1];
		 	 	m_nCol3len=m_nInsCollen[2];
		 	 	break;
		 	 case TRACEMODE_SOURCE:
		 	 	m_nCol1len=m_nSrcCollen[0];
		 	 	m_nCol2len=m_nSrcCollen[1];
		 	 	m_nCol3len=m_nSrcCollen[2];
		 	 	break;
		 	 case TRACEMODE_MIXED:
		 	 	m_nCol1len=m_nMixedCollen[0];
		 	 	m_nCol2len=m_nMixedCollen[1];
		 	 	m_nCol3len=m_nMixedCollen[2];
		 	 	break;	
		 	 default:
		 	 	ASSERT(0);
		 	 	break;
		 	}
	}
	else 
	{
		GetClientRect(&rect);
		ReColumn(rect.right-rect.left);
	}	
}

/****************************************************************************
**
**  Name: CTraceView::CalcMaxlenofSrcorInst
**
**  Description: calculate m_nMaxlenofSrcorInst's value.
**
**  Parameters:
**     input:
**
**     output:
**
**  Return data: TRUE -> m_nMaxlenofSrcorInst is change;
**				 FALSE-> m_nMaxlenofSrcorInst is not change;
**
****************************************************************************/
BOOL CTraceView::CalcMaxlenofSrcorInst(void)
{                                                  
WORD i; 
int	 len, max=0;    
    switch(nTraceViewOption)
        {
         case TRACEMODE_BUS:
             return FALSE;
         case TRACEMODE_INSTRUCTION:
         	for(i=0; i<m_wTextLines; i++)
			 	{
			 	 len=strlen((const char*)m_pInst[i].instruction);
			 	 if(max<len)	max=len;
			 	} 
			 max*=m_nCharWidth;
			 if(m_nMaxInstlen!=max)
			 	{
			 	 m_nMaxInstlen=max;
			 	 return TRUE;
			 	}
			 else return FALSE;
		 case TRACEMODE_MIXED:
		 case TRACEMODE_SOURCE:
			 for(i=0; i<m_wTextLines; i++)
			 	{
			 	 len=strlen((const char*)m_pSource[i].c);
			 	 if(max<len)	max=len;
			 	} 
			 max*=m_nCharWidth;
			 if(m_nMaxSrclen!=max)
			 	{
			 	 m_nMaxSrclen=max;
			 	 return TRUE;
			 	}
			 else return FALSE;		
         default: ASSERT(0);return FALSE;	
        }
}

/****************************************************************************
**
**  Name: CTraceView::PrepareData
**
**  Description: Get data from trace server, this is the only one function
**					in trace window to call trace server.
**               Get trace info refer to:m_wLines, nTraceViewOption, 
**				 						 m_wCurFrame	
**  Parameters:
**     input: brefresh - TRUE: Force server get trace data from FW 
**                       FALSE: trace server get trace data from FW if 
**								necessary.
**     output:
**
**  Return data: 
**
**  data transfer relation:
	1. size change:  (if window height add->preparedata)
						   ->CalcMaxlrecolumn->recolumn
	2. Vscroll bar change: ->preparedata->CalcMaxlenofSrcorInst->recolumn
	
	3. mode change:        ->preparedata->CalcMaxlenofSrcorInst->recolumn
	4. refresh command:    ->preparedata->CalcMaxlenofSrcorInst->recolumn
	vscrollbar set:
	1. 	range->all in preparedata
	2.	pos->all in preparedata
****************************************************************************/
void CTraceView::PrepareData(BOOL brefresh)
{
static  WORD Prevlines=0;
UINT	utemp;
WORD	temp;
WORD    dummy=0xffff;
BOOL    bChange=FALSE;
//DWORD	time;	
	if(!(brefresh||m_VscrollFlag)&&m_wLines<=Prevlines)
	{
		if(nTraceViewOption==TRACEMODE_BUS&&
			m_wCurFrame==m_pBus[0].phisicalNo)
			return;
		else if(nTraceViewOption==TRACEMODE_INSTRUCTION&&
			m_wCurFrame==m_pInst[0].phisicalNo)
			return;
//		else if(nTraceViewOption==TRACEMODE_SOURCE&&
//			m_wCurFrame==m_pSource[0].phisicalNo)
//			return;	
	}
//	time=GetTickCount();
    if(m_wLastFrame==0||brefresh)					//initial
    {
    	if(AbiGetTraceLastFrame(&utemp))
    		utemp=0;    	
		temp=WORD(utemp);
		if(temp==0)
		{
		 	if(m_wLastFrame)
		 		GetParent()->SetWindowText("Trace[0000]");
		 	m_wLastFrame=0;
		 	m_wTextLines=0;
		 	m_bNullLine=TRUE;
//		 	EnableScrollBar(SB_VERT, ESB_DISABLE_BOTH);
		 	if(m_bVscOn)
		 	{
		 		EnableScrollBar(SB_VERT, ESB_DISABLE_BOTH);
		 		m_bVscOn=FALSE;
		 	}	
		 	return;
		}
		if(temp!=m_wLastFrame)
		{
       		char title[15];
       		wsprintf(title,"Trace[%04X]", temp);
       		GetParent()->SetWindowText(title);
		 	if(!m_bVscOn)
	 		{
	 		 	EnableScrollBar(SB_VERT, ESB_ENABLE_BOTH);
	 		 	m_bVscOn=TRUE;
	 		}	
		 	m_wLastFrame=temp;
		 	m_wVscrollMaxpos=max(0, int(m_wLastFrame-m_wLines/2));
    	 	SetScrollRange(SB_VERT, 0, (int)m_wVscrollMaxpos, FALSE);
		} 
		if (m_wCurFrame>m_wVscrollMaxpos)
	 		m_wCurFrame=m_wVscrollMaxpos;
		SetScrollPos(SB_VERT, m_wCurFrame, TRUE);
    }
    m_wTextLines=m_wLines;
    m_bNullLine=FALSE;
    BeginWaitCursor();
    switch(nTraceViewOption)
    	{
    	 case TRACEMODE_BUS:
            bChange=ListTrcDataToWnd(m_VscrollFlag, &m_wCurFrame, &dummy,
                                             &m_wTextLines, (struct FrameData*)m_pBus);
			break;
		 case TRACEMODE_INSTRUCTION:
            bChange=ListTrcInstToWnd(m_VscrollFlag, &m_wCurFrame, &dummy,
                                              &m_wTextLines, (struct FrameInst*)m_pInst);
		 	break;
		 case TRACEMODE_SOURCE:
            bChange=ListTrcCToWnd(m_VscrollFlag, &m_wCurFrame, &dummy,
                                                &m_wTextLines, (struct FrameC*)m_pSource);
		 	break;
		 case TRACEMODE_MIXED:
            bChange=ListTrcMixedToWnd(m_VscrollFlag, &m_wCurFrame, &dummy,
                                                &m_wTextLines, (struct FrameC*)m_pSource);
		 	break;
		 default: 
		 	ASSERT(0);return;
		}																			  	
	EndWaitCursor();
	m_VscrollFlag=0;
	Prevlines=m_wTextLines;
	if(!bChange)
        {
         m_wLastFrame=0;
		 m_wTextLines=0;
		 m_bNullLine=TRUE;
		 EnableScrollBar(SB_VERT, ESB_DISABLE_BOTH);
         m_bVscOn=FALSE;
         return;
        }
//m_wLines has changed.
    if(m_wTextLines!=m_wLines)
        {
         m_bNullLine=TRUE;
//       SetScrollPos(SB_VERT, m_wVscrollMaxpos, TRUE);
        } 
    return;
}

BEGIN_MESSAGE_MAP(CTraceView, CWnd)
    //{{AFX_MSG_MAP(CTraceView)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_VSCROLL()
	ON_WM_HSCROLL()
	ON_WM_RBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTraceView message handlers

int CTraceView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	m_pFather=(CTraceWindow*)GetParent();
	TEXTMETRIC tm;
	CDC* pdc=GetDC();
	pdc->SelectStockObject(ANSI_FIXED_FONT);
	pdc->GetTextMetrics(&tm);
	m_nCharWidth=tm.tmAveCharWidth;
	m_nLineHeight=tm.tmHeight+tm.tmExternalLeading+2;
	return 0;
}

void CTraceView::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
WORD	i;    
    dc.SelectStockObject(ANSI_FIXED_FONT);
    for(i=0; i<m_wTextLines; i++)
    	PaintLines(i*m_nLineHeight, i, &dc);
    if(m_bNullLine)
		{
    	 	CRect rect(0, i*m_nLineHeight,
						m_nCxView, m_nCyView);
			CBrush Brush;
			Brush.CreateSolidBrush(RGB(0xff,0xff,0xff));	//white
			dc.FillRect(&rect, &Brush);
			Brush.DeleteObject();
    	} 
	
	// Do not call CWnd::OnPaint() for painting messages
}

void CTraceView::PaintLines(int y, int lineno, CPaintDC* pdc)
{
RECT	rect;
int 	x=m_nLeftfrom;

	rect.top=y;
	rect.bottom=y+m_nLineHeight-1;
	rect.left=x;            
	rect.right=x+m_nCol1len;
	
	switch (nTraceViewOption)
	{
     case TRACEMODE_BUS:
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pBus[lineno].frameNo, 4, NULL);
    
        x= rect.left = rect.right;
        rect.right = rect.left+m_nCol2len;
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pBus[lineno].addr, 4, NULL);
    
        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol3len;
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pBus[lineno].data, 2, NULL);

        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol4len;
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pBus[lineno].status, 2, NULL);

        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol5len;
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pBus[lineno].spare, 5, NULL);
        
        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol6len;
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pBus[lineno].portdata, 2, NULL);
        
        return;
    
     case TRACEMODE_INSTRUCTION:    
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pInst[lineno].frameNo, 4, NULL);
    
        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol2len;
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pInst[lineno].addr, 4, NULL);

        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol3len;
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pInst[lineno].instruction, 
	        			strlen((char*)m_pInst[lineno].instruction), NULL);

        return;

     case TRACEMODE_SOURCE:
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pSource[lineno].frameNo, 4, NULL);
    
        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol2len;
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pSource[lineno].line, 5, NULL);

        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol3len;                   
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pSource[lineno].c, 
	        			strlen((char*)m_pSource[lineno].c), NULL);

        return;
     case TRACEMODE_MIXED:
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pSource[lineno].frameNo, 4, NULL);
    
        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol2len;
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pSource[lineno].line, 6, NULL);

        x= rect.left = rect.right;
        rect.right = rect.left + m_nCol3len;                   
        pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
	        			&rect,m_pSource[lineno].c,
	        			strlen((char*)m_pSource[lineno].c), NULL);

        return;
     default: ASSERT(0); return;
    }

}

void CTraceView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
	// TODO: Add your message handler code here and/or call default
	switch(nSBCode)
		{
	     case SB_LINEUP:
	     	if(m_wCurFrame<=0)
	     		return;
	     	m_VscrollFlag=-1;
	     	break;
	     case SB_LINEDOWN:
	     	if(m_wCurFrame>=m_wVscrollMaxpos)
	     		return;
	     	m_VscrollFlag=1;
	     	break;	
	     case SB_PAGEUP:
	     	if(m_wCurFrame<=0)
	     		return;
	     	m_VscrollFlag=-2;
	     	break;	
	     case SB_PAGEDOWN:
	     	if(m_wCurFrame>=m_wVscrollMaxpos||m_bNullLine)
	     		return;
	     	m_VscrollFlag=2;
	     	break;
	     case SB_TOP:
	     	if(m_wCurFrame<=0)
	     		return;
	     	m_wCurFrame=0;
	     	break;
	     case SB_BOTTOM:
	        if(m_wCurFrame>=m_wVscrollMaxpos)
	     		return;
	     	m_wCurFrame=m_wVscrollMaxpos;
	     	break;
	     case SB_THUMBPOSITION:
	        if(nPos==m_wCurFrame) 
		 		return;
		 	m_wCurFrame=(WORD)nPos;
		 	break;
		 default: return;
		}
	PrepareData(FALSE);
	if(CalcMaxlenofSrcorInst())
	{
		RECT	rect;
		GetClientRect(&rect);
		ReColumn(rect.right-rect.left);
	}
	m_pFather->InvalidateRect(NULL, FALSE/*TRUE*/);		//use TRUE parament is too slow
    SetScrollPos(SB_VERT, m_wCurFrame, TRUE);
//	CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CTraceView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
	// TODO: Add your message handler code here and/or call default
	int old=m_nLeftfrom;
	switch(nSBCode)
		{
		 case SB_LINERIGHT:
		 	if(m_nHscrollPos>=m_nHscrollMaxpos)
		 		return;
		 	m_nHscrollPos++;
		 	m_nLeftfrom-=m_nCharWidth;
		 	break;
		 case SB_LINELEFT:
		 	if(m_nHscrollPos<=0)
		 		return;
		 	m_nHscrollPos--;
		 	m_nLeftfrom+=m_nCharWidth;
		 	break;		
		 case SB_PAGERIGHT:
		 	if(m_nHscrollPos>=m_nHscrollMaxpos)
		 		return;
		 	m_nHscrollPos=min(m_nHscrollPos+m_nCxView/m_nCharWidth,
		 						m_nHscrollMaxpos);
		 	m_nLeftfrom=-(m_nHscrollPos*m_nCharWidth);
		 	break;
		 case SB_PAGELEFT:
		 	if(m_nHscrollPos<=0)
		 		return;
		 	m_nHscrollPos=max(m_nHscrollPos-m_nCxView/m_nCharWidth, 0);
		 	m_nLeftfrom=-(m_nHscrollPos*m_nCharWidth);
		 	break;
		 case SB_THUMBTRACK:
		 	if(nPos==(UINT)m_nHscrollPos) 
		 		return;
		 	m_nHscrollPos=nPos;
	 		m_nLeftfrom=-(m_nHscrollPos*m_nCharWidth);
			break;
		 default: return;
	    }
	SetScrollPos(SB_HORZ, m_nHscrollPos, TRUE);
	if(m_nLeftfrom!=old)		
	{
		RECT rect;
		
		rect.left=0;
		rect.right=m_nCxView+m_pFather->m_nCxVscroll;
    	rect.top=0;
    	rect.bottom=m_pFather->m_wTitleHeight;
		m_pFather->InvalidateRect(&rect);
	}	
	ScrollWindow(m_nLeftfrom-old,0);

//    CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CTraceView::OnRButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
LPARAM lParam;
   	lParam = (WORD)point.y + m_pFather->m_wTitleHeight;
    lParam <<= 16;
    lParam += (WORD)point.x;
    m_pFather->SendMessage(WM_RBUTTONDOWN, nFlags, lParam);	
	
	CWnd::OnRButtonDown(nFlags, point);
}
