📄 trcview.cpp
字号:
/********************************************************************
Module : TrcView.cpp - trace buffer viewer
Written 2000,2003 by Dmitri Leman
for an article in C/C++ journal about a tracing framework.
Purpose: A part of the tracer framework.
********************************************************************/
#ifdef TRACE_ //{
#if defined WIN32
#include <windows.h>
#include <stdio.h>
#include "HTrace.h"
#elif defined(_WIN32_WCE)
#include <windows.h>
#include "resource.h"
#include "HTrace.h"
#elif defined(__linux__)
#include <unistd.h>
#include <curses.h>
#include <malloc.h>
#include <string.h>
#include <sys/time.h>
#include "HTrace.h"
//This module was ported from WIN32 to ncurses.
//Therefore, I included few declarations, which allows
//some WIN32-specific to compile under linux.
typedef WINDOW * HDC;
typedef WINDOW * HWND;
typedef int BOOL;
#define __int64 long long
typedef struct {int left, top, right, bottom;} RECT;
void DrawText(
WINDOW * p_pWindow, const char * p_pszBuffer,
int p_iNumBytes, RECT * p_pPaintRect, int p_iFlags)
{
int l_iRes =
mvwaddnstr(stdscr, 0,0, p_pszBuffer, p_iNumBytes);
wclrtobot(p_pWindow);
}
static ULONG GetTickCount()
{
clock_t l_Clock = clock();
return (ULONG)(((__int64)l_Clock) * 1000 / CLOCKS_PER_SEC);
}
#define SB_VERT 1
#define SB_THUMBTRACK 1
#define SB_LINEUP 2
#define SB_LINEDOWN 3
#define SB_PAGEUP 4
#define SB_PAGEDOWN 5
#define SB_TOP 6
#define SB_BOTTOM 7
#define _snprintf snprintf
#endif
static const char s_szCaption[] = "Trace Viewer";
static char s_szFullINIPath[_MAX_PATH];
#define MAX_ROW_LEN 256
#define NUM_EXTRA_ROWS 2
struct BufferViewer
{
LocalTraceBufferPointers * m_pBufferPointers;
HWND m_hWnd;
#ifdef WIN32
HFONT m_hFont;
int m_iFontHeight;
int m_iFontWidth;
int m_iLogicalWidthChars;
int m_iLogicalWidthPixels;
#endif
LPTSTR m_pBuffer;
int m_iBufferSize;
int m_iNumLines;
int m_iFirstPaintIndex;
int m_iNumBytesPainted;
int m_iFirstViewPosWhenPainted;
int m_iNumLinesPainted;
int m_iFirstRowLength;
int m_iTotalNumCharsWhenPainted;
int m_iScrollChanged;
int m_iScrollChangedWhenPainted;
int m_iHorzPos;
int m_iCharShownFirst;
int m_iLineOffset;
bool m_bStickToEnd;
bool m_bMoveToStartNextTime;
RECT m_ClientRect;
RECT m_PaintRect;
int m_iNumLinesInClientArea;
BufferViewer(HWND p_hWnd)
{
m_hWnd = p_hWnd;
m_pBufferPointers = NULL;
#ifdef WIN32
m_hFont = 0;
m_iFontHeight = 0;
m_iFontWidth = 0;
m_iLogicalWidthChars = 0;
m_iLogicalWidthPixels = 0;
#endif
m_pBuffer = NULL;
m_iBufferSize = 0;
m_iNumLines = 0;
m_iFirstPaintIndex = -1;
m_iNumBytesPainted = -1;
m_iFirstViewPosWhenPainted = -1;
m_iTotalNumCharsWhenPainted = -1;
m_iNumLinesPainted = 0;
m_iFirstRowLength = 0;
m_iScrollChanged = 0;
m_iScrollChangedWhenPainted = -1;
m_iHorzPos = 0;
m_iCharShownFirst = 0;
m_iLineOffset = 0;
m_bStickToEnd = true;
m_bMoveToStartNextTime = false;
m_iNumLinesInClientArea = 0;
#ifdef __linux__
m_iInvalidated = 0;
m_iScrollMin = 0;
m_iScrollMax = 0;
m_iScrollPos = 0;
m_pWndStatus = NULL;
m_pWndHelp = NULL;
#endif
}
void PaintBufferWithCopy
(
HDC p_hDC,
LPCTSTR p_pTraceBuffer,
int p_lBufferSizeChars,
int p_iFirstViewPos,
int p_iLinesOffset,
int p_iDataSizeAfterScrollPos,
int p_iDataSizeBeforeScrollPos
);
void PaintBuffer
(
int p_iFirstViewPos,
int p_iLinesOffset,
HDC p_hDC,
RECT * p_pPaintRect
);
void UpdateScrollPos();
void OnPaint();
void OnSizeChanges();
void OnTimerMessage();
void OnScrollMessage
(
int p_nScrollBarType,
int p_nScrollCode,
int p_nPos,
int p_nTrackPos,
int p_nMin,
int p_nMax
);
#ifdef __linux__
//Few more routines to allow portions of WIN32 specific
//code to run under ncurses
void InvalidateRect(HWND,RECT*,BOOL)
{
m_iInvalidated++;
}
void GetScrollRange(HWND, int, int * p_piMin,int * p_piMax)
{
*p_piMin = m_iScrollMin;
*p_piMax = m_iScrollMax;
}
void SetScrollRange(HWND, int,int p_iMin, int p_iMax,BOOL)
{
m_iScrollMin = p_iMin;
m_iScrollMax = p_iMax;
}
void SetScrollPos(HWND, int, int p_iPos,BOOL)
{
m_iScrollPos = p_iPos;
}
int m_iInvalidated;
int m_iScrollMin;
int m_iScrollMax;
int m_iScrollPos;
WINDOW * m_pWndStatus;
WINDOW * m_pWndHelp;
#endif
};//struct BufferViewer
/*-------------------------------------------------------------
FUNCTION: BufferViewer::PaintBufferWithCopy
PURPOSE: Worker routine to copy a portion of a trace buffer
to a local display buffer and paint it to the screen.
PARAMETERS:
HDC p_hDC - device context
LPCTSTR p_pTraceBuffer - the whole circular buffer
int p_lBufferSizeChars - total size of the buffer
int p_iFirstViewPos - current scroll position
int p_iLinesOffset - count p_iLinesOffset lines up or down
from the current scroll position to
find the first line to paint.
int p_iDataSizeAfterScrollPos - number of valid bytes in the
buffer before p_iCurByte
int p_iDataSizeBeforeScrollPos - number of valid bytes in the
buffer after p_iCurByte
-------------------------------------------------------------*/
void BufferViewer::PaintBufferWithCopy
(
HDC p_hDC,
LPCTSTR p_pTraceBuffer,
int p_lBufferSizeChars,
int p_iFirstViewPos,
int p_iLinesOffset,
int p_iDataSizeAfterScrollPos,
int p_iDataSizeBeforeScrollPos
)
{
int l_iSize = (m_iNumLinesInClientArea + NUM_EXTRA_ROWS) *
MAX_ROW_LEN;
if(m_iNumLines < m_iNumLinesInClientArea || !m_pBuffer)
{
//The worst uncertainty is the line width.
//We will assume MAX_ROW_LEN = 256 byte line width.
//Hopefully, most of lines will be shorter.
//If most of lines will be longer than 256,
//we will print fewer lines, than fit in window
LPTSTR l_pBuff = (LPTSTR)malloc(l_iSize*sizeof(TCHAR));
if(l_pBuff == NULL)
{
HTRACE(TG_Error,
_T("ERROR: malloc(%d) failed"), l_iSize);
return;
}
free(m_pBuffer);
m_pBuffer = l_pBuff;
m_iBufferSize = l_iSize;
m_iNumLines = m_iNumLinesInClientArea;
}//if(m_iNumLines < m_iNumLinesInClientArea)
//Now we need to copy memory from the trace buffer to the
//screen buffer.
//We need to start before the current position to find the
//beginning of the line, which contains the current
//position.
int l_iLookBack = p_iLinesOffset < -1?
(-p_iLinesOffset)*MAX_ROW_LEN : MAX_ROW_LEN;
if(l_iLookBack + p_iDataSizeAfterScrollPos < l_iSize)
{
//If we have not enough data after the scroll point,
//we need to look farther behind to avoid leaving blank
//space (basically this means that the very last line should
//be displayed at the bottom of the screen - not at the top)
l_iLookBack = l_iSize - p_iDataSizeAfterScrollPos;
}
if(l_iLookBack > p_iDataSizeBeforeScrollPos)
l_iLookBack = p_iDataSizeBeforeScrollPos;
int l_iStartFromByteWithExtra =
(p_iFirstViewPos - l_iLookBack) % p_lBufferSizeChars;
int l_iDisplaySize = p_iDataSizeAfterScrollPos + l_iLookBack;
if(l_iDisplaySize > l_iSize)
l_iDisplaySize = l_iSize;
int l_iLookForward = l_iDisplaySize;
if(l_iStartFromByteWithExtra + l_iLookForward >
p_lBufferSizeChars)
{
l_iLookForward = p_lBufferSizeChars -
l_iStartFromByteWithExtra;
memcpy(m_pBuffer, p_pTraceBuffer +
l_iStartFromByteWithExtra, l_iLookForward*sizeof(TCHAR));
//The display area continues at the beginning of buffer
memcpy(m_pBuffer + l_iLookForward, p_pTraceBuffer,
(l_iDisplaySize - l_iLookForward)*sizeof(TCHAR));
}
else
{
memcpy(m_pBuffer, p_pTraceBuffer +
l_iStartFromByteWithExtra, l_iLookForward*sizeof(TCHAR));
}
int i;
int l_iNumLines = 0;
int l_iBeginning = l_iLookBack;
//First count lines after the current byte, which is at the
//position l_iLookBack in the m_pBuffer
int l_iEnd = l_iDisplaySize;//if we will not find newlines
int l_iFirstLineEnd = l_iEnd;
for(i = l_iLookBack; i < l_iDisplaySize; i++)
{
if(m_pBuffer[i] == '\n')
{
l_iEnd = i;
if(l_iNumLines == 0)
{
l_iFirstLineEnd = i;
}
l_iNumLines++;
if(l_iNumLines >= m_iNumLinesInClientArea)
break;
}
}
//Next look back until we find the beginning of the line,
//which the current position belongs to. And look further
//back if we have not enough lines already to fill screen.
int l_iCountLinesBefore = p_iLinesOffset < 0?
-p_iLinesOffset : 1;
for(i = l_iLookBack-1; i >= 0; i--)
{
if(m_pBuffer[i] == '\n')
{
l_iBeginning = i+1;
l_iNumLines++;
if(--l_iCountLinesBefore <= 0 &&
l_iNumLines >= m_iNumLinesInClientArea)
break;
l_iFirstLineEnd = i;
}
}
if(i < 0)
{//Didn't find any newlines before the current position.
l_iBeginning = 0;
}
m_iFirstPaintIndex = l_iBeginning;
m_iNumBytesPainted = l_iEnd - l_iBeginning;
DrawText(p_hDC, m_pBuffer + m_iFirstPaintIndex,
m_iNumBytesPainted, &m_PaintRect, 0);
m_iCharShownFirst = p_iFirstViewPos - l_iLookBack + l_iBeginning;
m_iLineOffset = 0;
m_iFirstViewPosWhenPainted = m_iCharShownFirst;
m_iNumLinesPainted = l_iNumLines;
m_iFirstRowLength = 1 + l_iFirstLineEnd - l_iBeginning;
}//void BufferViewer::PaintBufferWithCopy
/*------------------------------------------------------------
FUNCTION: BufferViewer::PaintBuffer
PURPOSE: Performs actual painting of the trace buffer
PARAMETERS:
p_iFirstViewPos - current byte (between 0 and the buffer
size) to be shown at the top of the window (measured
from the initial start of writing)
p_iLinesOffset - count p_iLinesOffset lines up or down
from the current scroll position to
find the first line to paint.
------------------------------------------------------------*/
void BufferViewer::PaintBuffer
(
int p_iFirstViewPos,
int p_iLinesOffset,
HDC p_hDC,
RECT * p_pPaintRect
)
{
if(!m_pBufferPointers || !m_pBufferPointers->m_pGlobalFooter ||
!m_pBufferPointers->m_dwTextAreaSize)
return;
int l_iCharsWritten =
m_pBufferPointers->m_pGlobalFooter->m_dwNumBytesWritten /
sizeof(TCHAR);
int l_iBufferSizeChars =
m_pBufferPointers->m_dwTextAreaSize / sizeof(TCHAR);
if(p_iFirstViewPos > l_iCharsWritten)
p_iFirstViewPos = l_iCharsWritten;
//don't show empty space
LPTSTR l_pText = m_pBufferPointers->m_pTextArea;
//Decide which byte in the trace buffer corresponds to the
//scroll position. This will be the last line to be shown.
int l_iDataSizeAfterScrollPos= l_iCharsWritten - p_iFirstViewPos;
if(l_iDataSizeAfterScrollPos > l_iBufferSizeChars)
{
//The scroll position is behind the beginning of the
//valid data in the buffer (since the scroll position was
//moved there the data were overwritten).
if(m_iFirstViewPosWhenPainted == p_iFirstViewPos &&
m_iFirstPaintIndex >= 0 && m_pBuffer != NULL)
{
//Fortunately, we already have the data in the
//display buffer
DrawText(p_hDC, m_pBuffer + m_iFirstPaintIndex,
m_iNumBytesPainted, p_pPaintRect, 0);
}
else
{
DrawText(p_hDC, _T("Data Lost"), 9, p_pPaintRect, 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -