2213 lines
58 KiB
C
2213 lines
58 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* Report.c - This file contains the report window handler. Some of the
|
||
|
* support routines are in RptFct.c
|
||
|
*
|
||
|
* Microsoft Confidential
|
||
|
* Copyright (c) 1992-1993 Microsoft Corporation
|
||
|
*
|
||
|
* Author -
|
||
|
*
|
||
|
* Hon-Wah Chan
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include "perfmon.h"
|
||
|
#include <stdio.h> // for sprintf
|
||
|
#include <string.h> // for strncpy
|
||
|
#include "report.h" // Exported declarations for this file
|
||
|
|
||
|
#include "addline.h" // for AddLine, EditLine
|
||
|
#include "perferr.h" // for PostError
|
||
|
#include "fileutil.h" // for FileHandleCreate
|
||
|
#include "line.h" // for LineAppend
|
||
|
#include "pmemory.h" // for MemoryXXX (mallloc-type) routines
|
||
|
#include "perfdata.h" // for UpdateLines
|
||
|
#include "perfmops.h" // for DoWindowDrag
|
||
|
#include "playback.h" // for PlaybackLines, PlayingBackLog
|
||
|
#include "system.h" // for SystemGet
|
||
|
#include "utils.h"
|
||
|
#include "menuids.h" // for IDM_VIEWREPORT
|
||
|
#include "fileopen.h" // for FileGetName
|
||
|
#include "counters.h" // for CounterEntry
|
||
|
|
||
|
|
||
|
//==========================================================================//
|
||
|
// Local Data //
|
||
|
//==========================================================================//
|
||
|
|
||
|
TCHAR szSystemFormat [ResourceStringLen] ;
|
||
|
TCHAR szObjectFormat [ResourceStringLen] ;
|
||
|
|
||
|
|
||
|
//=============================//
|
||
|
// Report Class //
|
||
|
//=============================//
|
||
|
|
||
|
|
||
|
TCHAR szReportWindowClass[] = TEXT("PerfRpt") ;
|
||
|
#define dwReportClassStyle (CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS)
|
||
|
#define iReportClassExtra (0)
|
||
|
#define iReportWindowExtra (0)
|
||
|
#define dwReportWindowStyle (WS_CHILD | WS_VSCROLL | WS_HSCROLL)
|
||
|
|
||
|
|
||
|
#define szValuePlaceholder TEXT("-999999999.999")
|
||
|
#define szValueLargeHexPlaceholder TEXT(" xBBBBBBBBDDDDDDDD")
|
||
|
|
||
|
#define szHexFormat TEXT("x%08lX")
|
||
|
#define szLargeHexFormat TEXT("x%08lX%08lX")
|
||
|
#define szLargeValueFormat TEXT("%12.0f")
|
||
|
#define eStatusLargeValueMax ((FLOAT) 999999999.0)
|
||
|
#define szValueFormat TEXT("%12.3f")
|
||
|
|
||
|
|
||
|
//==========================================================================//
|
||
|
// Local Functions //
|
||
|
//==========================================================================//
|
||
|
|
||
|
|
||
|
PREPORT AllocateReportData (HWND hWndReport)
|
||
|
{
|
||
|
PREPORT pReport ;
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
|
||
|
pReport->hWnd = hWndReport ;
|
||
|
pReport->iStatus = iPMStatusClosed ;
|
||
|
pReport->bManualRefresh = FALSE ;
|
||
|
pReport->bModified = FALSE ;
|
||
|
|
||
|
pReport->Visual.iColorIndex = 0 ;
|
||
|
pReport->Visual.iWidthIndex = -1 ;
|
||
|
pReport->Visual.iStyleIndex = -1 ;
|
||
|
|
||
|
pReport->iIntervalMSecs = iDefaultReportIntervalSecs * 1000 ;
|
||
|
pReport->pSystemFirst = NULL ;
|
||
|
pReport->pLineFirst = NULL ;
|
||
|
|
||
|
pReport->CurrentItemType = REPORT_TYPE_NOTHING ;
|
||
|
pReport->CurrentItem.pLine = NULL ;
|
||
|
|
||
|
return (pReport) ;
|
||
|
} // AllocateReportData
|
||
|
|
||
|
|
||
|
void FreeReportData (PREPORT pReport)
|
||
|
{ // FreeReportData
|
||
|
} // FreeReportData
|
||
|
|
||
|
|
||
|
|
||
|
BOOL LineCounterRemove (PPLINE ppLineFirst,
|
||
|
PLINE pLineRemove)
|
||
|
{
|
||
|
PLINE pLine ;
|
||
|
|
||
|
if (*ppLineFirst == pLineRemove)
|
||
|
{
|
||
|
*ppLineFirst = (*ppLineFirst)->pLineCounterNext ;
|
||
|
return (TRUE) ;
|
||
|
}
|
||
|
|
||
|
for (pLine = *ppLineFirst ;
|
||
|
pLine->pLineCounterNext ;
|
||
|
pLine = pLine->pLineCounterNext)
|
||
|
{ // for
|
||
|
if (pLine->pLineCounterNext == pLineRemove)
|
||
|
{
|
||
|
pLine->pLineCounterNext = pLineRemove->pLineCounterNext ;
|
||
|
return (TRUE) ;
|
||
|
} // if
|
||
|
} // for
|
||
|
|
||
|
return (FALSE) ;
|
||
|
} // LineCounterRemove
|
||
|
|
||
|
|
||
|
|
||
|
void DrawCounter (HDC hDC, PREPORT pReport,
|
||
|
PCOUNTERGROUP pCounterGroup)
|
||
|
{ // DrawCounter
|
||
|
|
||
|
RECT Rect ;
|
||
|
|
||
|
|
||
|
if (!pCounterGroup->pLineFirst)
|
||
|
return ;
|
||
|
|
||
|
SelectFont (hDC, pReport->hFont) ;
|
||
|
TextOut (hDC, xCounterMargin, pCounterGroup->yLine,
|
||
|
pCounterGroup->pLineFirst->lnCounterName,
|
||
|
lstrlen (pCounterGroup->pLineFirst->lnCounterName)) ;
|
||
|
|
||
|
if (pCounterGroup == pReport->CurrentItem.pCounter)
|
||
|
{
|
||
|
ReportCounterRect (pReport, pCounterGroup, &Rect) ;
|
||
|
DrawFocusRect (hDC, &Rect) ;
|
||
|
}
|
||
|
|
||
|
} // DrawCounter
|
||
|
|
||
|
|
||
|
void DrawObject (HDC hDC, PREPORT pReport,
|
||
|
POBJECTGROUP pObjectGroup)
|
||
|
{ // DrawObject
|
||
|
TCHAR szLine [LongTextLen] ;
|
||
|
PCOUNTERGROUP pCounterGroup ;
|
||
|
PCOLUMNGROUP pColumnGroup ;
|
||
|
|
||
|
if (!pObjectGroup->pCounterGroupFirst)
|
||
|
{
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
SelectFont (hDC, pReport->hFontHeaders) ;
|
||
|
|
||
|
SetTextAlign (hDC, TA_RIGHT) ;
|
||
|
|
||
|
for (pColumnGroup = pObjectGroup->pColumnGroupFirst ;
|
||
|
pColumnGroup ;
|
||
|
pColumnGroup = pColumnGroup->pColumnGroupNext)
|
||
|
{ // for
|
||
|
// Draw Parent
|
||
|
if (pColumnGroup->lpszParentName)
|
||
|
TextOut (hDC,
|
||
|
ValueMargin (pReport) +
|
||
|
pColumnGroup->xPos + pColumnGroup->xWidth,
|
||
|
pObjectGroup->yFirstLine - pReport->yLineHeight,
|
||
|
pColumnGroup->lpszParentName,
|
||
|
lstrlen (pColumnGroup->lpszParentName)) ;
|
||
|
|
||
|
// Draw Instance
|
||
|
if (pColumnGroup->lpszInstanceName)
|
||
|
{
|
||
|
TextOut (hDC,
|
||
|
ValueMargin (pReport) +
|
||
|
pColumnGroup->xPos + pColumnGroup->xWidth,
|
||
|
pObjectGroup->yFirstLine,
|
||
|
pColumnGroup->lpszInstanceName,
|
||
|
lstrlen (pColumnGroup->lpszInstanceName)) ;
|
||
|
}
|
||
|
|
||
|
if (pColumnGroup == pReport->CurrentItem.pColumn)
|
||
|
{
|
||
|
RECT Rect ;
|
||
|
|
||
|
ReportColumnRect (pReport, pColumnGroup, &Rect) ;
|
||
|
DrawFocusRect (hDC, &Rect) ;
|
||
|
}
|
||
|
|
||
|
} // for
|
||
|
SetTextAlign (hDC, TA_LEFT) ;
|
||
|
|
||
|
TSPRINTF (szLine, szObjectFormat, pObjectGroup->lpszObjectName) ;
|
||
|
TextOut (hDC,
|
||
|
xObjectMargin, pObjectGroup->yFirstLine,
|
||
|
szLine, lstrlen (szLine)) ;
|
||
|
|
||
|
if (pObjectGroup == pReport->CurrentItem.pObject)
|
||
|
{
|
||
|
RECT Rect ;
|
||
|
|
||
|
ReportObjectRect (pReport, pObjectGroup, &Rect) ;
|
||
|
DrawFocusRect (hDC, &Rect) ;
|
||
|
}
|
||
|
|
||
|
SelectFont (hDC, pReport->hFont) ;
|
||
|
|
||
|
for (pCounterGroup = pObjectGroup->pCounterGroupFirst ;
|
||
|
pCounterGroup ;
|
||
|
pCounterGroup = pCounterGroup->pCounterGroupNext)
|
||
|
{ // for
|
||
|
DrawCounter (hDC, pReport, pCounterGroup) ;
|
||
|
} // for
|
||
|
|
||
|
} // DrawObject
|
||
|
|
||
|
|
||
|
void DrawSystem (HDC hDC, PREPORT pReport, PSYSTEMGROUP pSystemGroup)
|
||
|
{ // DrawSystem
|
||
|
TCHAR szLine [LongTextLen] ;
|
||
|
POBJECTGROUP pObjectGroup ;
|
||
|
|
||
|
SelectFont (hDC, pReport->hFontHeaders) ;
|
||
|
|
||
|
if (!pSystemGroup->pObjectGroupFirst)
|
||
|
return ;
|
||
|
|
||
|
SetTextAlign (hDC, TA_LEFT) ;
|
||
|
TSPRINTF (szLine, szSystemFormat, pSystemGroup->lpszSystemName) ;
|
||
|
TextOut (hDC,
|
||
|
xSystemMargin, pSystemGroup->yFirstLine,
|
||
|
szLine, lstrlen (szLine)) ;
|
||
|
|
||
|
if (pSystemGroup == pReport->CurrentItem.pSystem)
|
||
|
{
|
||
|
RECT Rect ;
|
||
|
|
||
|
ReportSystemRect (pReport, pSystemGroup, &Rect) ;
|
||
|
DrawFocusRect (hDC, &Rect) ;
|
||
|
}
|
||
|
|
||
|
for (pObjectGroup = pSystemGroup->pObjectGroupFirst ;
|
||
|
pObjectGroup ;
|
||
|
pObjectGroup = pObjectGroup->pObjectGroupNext)
|
||
|
{ // for
|
||
|
DrawObject (hDC, pReport, pObjectGroup) ;
|
||
|
} // for
|
||
|
} // DrawSystem
|
||
|
|
||
|
void DrawReportValue (HDC hDC, PREPORT pReport, PLINE pLine)
|
||
|
{ // DrawReportValue
|
||
|
TCHAR szValue [20] ;
|
||
|
FLOAT eValue ;
|
||
|
RECT rectValue ;
|
||
|
|
||
|
// skip until we have collect enough samples for the first data
|
||
|
if (pLine->bFirstTime == 0)
|
||
|
{
|
||
|
eValue = CounterEntry (pLine) ;
|
||
|
if (pLine->lnCounterType == PERF_COUNTER_RAWCOUNT_HEX ||
|
||
|
pLine->lnCounterType == PERF_COUNTER_LARGE_RAWCOUNT_HEX)
|
||
|
{
|
||
|
if (pLine->lnCounterType == PERF_COUNTER_RAWCOUNT_HEX ||
|
||
|
pLine->lnaCounterValue[0].HighPart == 0)
|
||
|
{
|
||
|
TSPRINTF (szValue,
|
||
|
szHexFormat,
|
||
|
pLine->lnaCounterValue[0].LowPart) ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TSPRINTF (szValue,
|
||
|
szLargeHexFormat,
|
||
|
pLine->lnaCounterValue[0].HighPart,
|
||
|
pLine->lnaCounterValue[0].LowPart) ;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TSPRINTF (szValue,
|
||
|
(eValue > eStatusLargeValueMax) ?
|
||
|
szLargeValueFormat : szValueFormat,
|
||
|
eValue) ;
|
||
|
ConvertDecimalPoint (szValue) ;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// draw "- - - -"
|
||
|
lstrcpy(szValue, DashLine);
|
||
|
}
|
||
|
|
||
|
ReportLineValueRect (pReport, pLine, &rectValue) ;
|
||
|
|
||
|
ExtTextOut (hDC,
|
||
|
rectValue.right - 2, rectValue.top,
|
||
|
ETO_CLIPPED | ETO_OPAQUE,
|
||
|
&rectValue,
|
||
|
szValue, lstrlen (szValue), NULL) ;
|
||
|
|
||
|
if (pReport->CurrentItemType == REPORT_TYPE_LINE &&
|
||
|
pLine == pReport->CurrentItem.pLine)
|
||
|
{
|
||
|
DrawFocusRect (hDC, &rectValue) ;
|
||
|
}
|
||
|
} // DrawReportValue
|
||
|
|
||
|
|
||
|
void DrawReportValues (HDC hDC, PREPORT pReport)
|
||
|
{
|
||
|
PSYSTEMGROUP pSystemGroup ;
|
||
|
POBJECTGROUP pObjectGroup ;
|
||
|
PCOUNTERGROUP pCounterGroup ;
|
||
|
PLINE pLine ;
|
||
|
|
||
|
SelectFont (hDC, pReport->hFont) ;
|
||
|
SetTextAlign (hDC, TA_RIGHT) ;
|
||
|
|
||
|
for (pSystemGroup = pReport->pSystemGroupFirst ;
|
||
|
pSystemGroup ;
|
||
|
pSystemGroup = pSystemGroup->pSystemGroupNext)
|
||
|
{ // for System...
|
||
|
for (pObjectGroup = pSystemGroup->pObjectGroupFirst ;
|
||
|
pObjectGroup ;
|
||
|
pObjectGroup = pObjectGroup->pObjectGroupNext)
|
||
|
{ // for Object...
|
||
|
for (pCounterGroup = pObjectGroup->pCounterGroupFirst ;
|
||
|
pCounterGroup ;
|
||
|
pCounterGroup = pCounterGroup->pCounterGroupNext)
|
||
|
{ // for Counter...
|
||
|
for (pLine = pCounterGroup->pLineFirst ;
|
||
|
pLine ;
|
||
|
pLine = pLine->pLineCounterNext)
|
||
|
{ // for Line...
|
||
|
DrawReportValue (hDC, pReport, pLine) ;
|
||
|
} // for Line...
|
||
|
} // for Counter...
|
||
|
} // for Object
|
||
|
} // for System...
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void DrawReportHeaders (HDC hDC, PREPORT pReport)
|
||
|
{ // DrawReportHeaders
|
||
|
PSYSTEMGROUP pSystemGroup ;
|
||
|
|
||
|
for (pSystemGroup = pReport->pSystemGroupFirst ;
|
||
|
pSystemGroup ;
|
||
|
pSystemGroup = pSystemGroup->pSystemGroupNext)
|
||
|
{ // for
|
||
|
DrawSystem (hDC, pReport, pSystemGroup) ;
|
||
|
} // for
|
||
|
} // DrawReportHeaders
|
||
|
|
||
|
|
||
|
void DrawReport (HDC hDC, PREPORT pReport)
|
||
|
{
|
||
|
SetBkColor (hDC, GetSysColor(COLOR_WINDOW)) ;
|
||
|
DrawReportHeaders (hDC, pReport) ;
|
||
|
//UpdateLines (&(pReport->pSystemFirst), pReport->pLineFirst) ;
|
||
|
DrawReportValues (hDC, pReport) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void SetLinePosition (HDC hDC,
|
||
|
PREPORT pReport,
|
||
|
POBJECTGROUP pObjectGroup,
|
||
|
PLINE pLine)
|
||
|
{ // SetLinePositions
|
||
|
PCOLUMNGROUP pColumnGroup ;
|
||
|
|
||
|
pColumnGroup = GetColumnGroup (pReport, pObjectGroup, pLine) ;
|
||
|
if (!pColumnGroup)
|
||
|
{
|
||
|
pLine->xReportPos = 0 ;
|
||
|
pLine->iReportColumn = -1 ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pLine->xReportPos = pColumnGroup->xPos ;
|
||
|
pLine->iReportColumn = pColumnGroup->ColumnNumber ;
|
||
|
}
|
||
|
} // SetLinePosition
|
||
|
|
||
|
|
||
|
void SetCounterPositions (HDC hDC,
|
||
|
PREPORT pReport,
|
||
|
POBJECTGROUP pObjectGroup,
|
||
|
PCOUNTERGROUP pCounterGroup,
|
||
|
int yLine)
|
||
|
{ // SetCounterPositions
|
||
|
PLINE pLine ;
|
||
|
int yPos ;
|
||
|
|
||
|
|
||
|
if (!pCounterGroup->pLineFirst)
|
||
|
return ;
|
||
|
|
||
|
yPos = pCounterGroup->yLine ;
|
||
|
|
||
|
SelectFont (hDC, pReport->hFontHeaders) ;
|
||
|
|
||
|
for (pLine = pCounterGroup->pLineFirst ;
|
||
|
pLine ;
|
||
|
pLine = pLine->pLineCounterNext)
|
||
|
{ // for
|
||
|
SetLinePosition (hDC, pReport, pObjectGroup, pLine) ;
|
||
|
pLine->yReportPos = yPos ;
|
||
|
} // for
|
||
|
} // SetCounterPositions
|
||
|
|
||
|
|
||
|
void SetColumnPositions (HDC hDC,
|
||
|
PREPORT pReport,
|
||
|
POBJECTGROUP pObjectGroup)
|
||
|
{ // SetColumnPositions
|
||
|
int xPos ;
|
||
|
PCOLUMNGROUP pColumnGroup ;
|
||
|
|
||
|
xPos = 0 ;
|
||
|
for (pColumnGroup = pObjectGroup->pColumnGroupFirst ;
|
||
|
pColumnGroup ;
|
||
|
pColumnGroup = pColumnGroup->pColumnGroupNext)
|
||
|
{ // for
|
||
|
pColumnGroup->xWidth = max (max (pColumnGroup->ParentNameTextWidth,
|
||
|
pColumnGroup->InstanceNameTextWidth),
|
||
|
pReport->xValueWidth) ;
|
||
|
pColumnGroup->xPos = xPos ;
|
||
|
pColumnGroup->yFirstLine = pObjectGroup->yFirstLine ;
|
||
|
xPos += (pColumnGroup->xWidth + xColumnMargin) ;
|
||
|
} // for
|
||
|
} // SetColumnPositions
|
||
|
|
||
|
|
||
|
void SetObjectPositions (HDC hDC,
|
||
|
PREPORT pReport,
|
||
|
POBJECTGROUP pObjectGroup,
|
||
|
int yLine)
|
||
|
/*
|
||
|
Effect: Determine and set the logical coordinates for the
|
||
|
object pObject within the report pReport.
|
||
|
|
||
|
For each instance x counter, determine the appropriate
|
||
|
column, adding a column description to the object if
|
||
|
needed.
|
||
|
|
||
|
Called By: SetSystemPositions only.
|
||
|
|
||
|
See Also: SetSystemPositions, SetCounterPositions, ColumnGroup.
|
||
|
*/
|
||
|
{ // SetObjectPositions
|
||
|
PCOUNTERGROUP pCounterGroup ;
|
||
|
int yPos ;
|
||
|
PLINE pLine ;
|
||
|
|
||
|
// check if there is parnet name for this object type
|
||
|
// if so, need to add extra space for the parent name
|
||
|
if (pObjectGroup->pCounterGroupFirst)
|
||
|
{
|
||
|
pCounterGroup = pObjectGroup->pCounterGroupFirst ;
|
||
|
pLine = pCounterGroup->pLineFirst ;
|
||
|
if (pLine && LineParentName(pLine))
|
||
|
{
|
||
|
pObjectGroup->yFirstLine += yLine ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SetColumnPositions (hDC, pReport, pObjectGroup) ;
|
||
|
|
||
|
yPos = pObjectGroup->yFirstLine + yLine ;
|
||
|
|
||
|
for (pCounterGroup = pObjectGroup->pCounterGroupFirst ;
|
||
|
pCounterGroup ;
|
||
|
pCounterGroup = pCounterGroup->pCounterGroupNext)
|
||
|
{ // for
|
||
|
pCounterGroup->yLine = yPos + yLine ;
|
||
|
|
||
|
SetCounterPositions (hDC, pReport, pObjectGroup, pCounterGroup, yLine) ;
|
||
|
|
||
|
yPos = pCounterGroup->yLine ;
|
||
|
} // for
|
||
|
|
||
|
pObjectGroup->yLastLine = yPos + yLine ;
|
||
|
} // SetObjectPositions
|
||
|
|
||
|
|
||
|
void SetSystemPositions (HDC hDC,
|
||
|
PREPORT pReport,
|
||
|
PSYSTEMGROUP pSystemGroup,
|
||
|
int yLine)
|
||
|
{ // SetSystemPositions
|
||
|
POBJECTGROUP pObjectGroup ;
|
||
|
int yPos ;
|
||
|
|
||
|
yPos = pSystemGroup->yFirstLine ;
|
||
|
|
||
|
for (pObjectGroup = pSystemGroup->pObjectGroupFirst ;
|
||
|
pObjectGroup ;
|
||
|
pObjectGroup = pObjectGroup->pObjectGroupNext)
|
||
|
{ // for
|
||
|
pObjectGroup->yFirstLine = yPos + yLine ;
|
||
|
|
||
|
SetObjectPositions (hDC, pReport, pObjectGroup, yLine) ;
|
||
|
|
||
|
yPos = pObjectGroup->yLastLine ;
|
||
|
} // for
|
||
|
|
||
|
pSystemGroup->yLastLine = yPos + yLine ;
|
||
|
} // SetSystemPositions
|
||
|
|
||
|
|
||
|
void static SetScrollRanges (HWND hWnd)
|
||
|
{ // SetScrollRanges
|
||
|
PREPORT pReport ;
|
||
|
RECT rectClient ;
|
||
|
int xWidth, yHeight ;
|
||
|
|
||
|
GetClientRect (hWnd, &rectClient) ;
|
||
|
xWidth = rectClient.right - rectClient.left ;
|
||
|
yHeight = rectClient.bottom - rectClient.top ;
|
||
|
|
||
|
pReport = ReportData (hWnd) ;
|
||
|
|
||
|
SetScrollRange (hWnd, SB_VERT,
|
||
|
0, max (0, pReport->yHeight - yHeight),
|
||
|
TRUE) ;
|
||
|
SetScrollRange (hWnd, SB_HORZ,
|
||
|
0, max (0, pReport->xWidth - xWidth),
|
||
|
TRUE) ;
|
||
|
} // SetScrollRanges
|
||
|
|
||
|
//==========================================================================//
|
||
|
// Message Handlers //
|
||
|
//==========================================================================//
|
||
|
|
||
|
|
||
|
void static OnCreate (HWND hWnd)
|
||
|
{ // OnCreate
|
||
|
HDC hDC ;
|
||
|
PREPORT pReport ;
|
||
|
|
||
|
pReport = AllocateReportData (hWnd) ;
|
||
|
if (!pReport)
|
||
|
return ;
|
||
|
|
||
|
pReport->hFont = hFontScales ;
|
||
|
pReport->hFontHeaders = hFontScalesBold ;
|
||
|
|
||
|
pReport->pLineFirst = NULL ;
|
||
|
pReport->pSystemFirst = NULL ;
|
||
|
|
||
|
pReport->pSystemGroupFirst = NULL ;
|
||
|
|
||
|
hDC = GetDC (hWnd) ;
|
||
|
|
||
|
SelectFont (hDC, pReport->hFont) ;
|
||
|
|
||
|
|
||
|
pReport->yLineHeight = FontHeight (hDC, TRUE) ;
|
||
|
pReport->xValueWidth = TextWidth (hDC, szValuePlaceholder) ;
|
||
|
ReleaseDC (hWnd, hDC) ;
|
||
|
|
||
|
pReport->xWidth = 0 ;
|
||
|
pReport->yHeight = 0 ;
|
||
|
|
||
|
StringLoad (IDS_SYSTEMFORMAT, szSystemFormat) ;
|
||
|
StringLoad (IDS_OBJECTFORMAT, szObjectFormat) ;
|
||
|
} // OnCreate
|
||
|
|
||
|
|
||
|
void static OnPaint (HWND hWnd)
|
||
|
{
|
||
|
HDC hDC ;
|
||
|
PAINTSTRUCT ps ;
|
||
|
PREPORT pReport ;
|
||
|
|
||
|
|
||
|
|
||
|
pReport = ReportData (hWnd) ;
|
||
|
|
||
|
hDC = BeginPaint (hWnd, &ps) ;
|
||
|
//hDC = hReportDC ;
|
||
|
SetWindowOrgEx (hDC,
|
||
|
GetScrollPos (hWnd, SB_HORZ),
|
||
|
GetScrollPos (hWnd, SB_VERT),
|
||
|
NULL) ;
|
||
|
|
||
|
DrawReport (hDC, pReport) ;
|
||
|
|
||
|
EndPaint (hWnd, &ps) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
void static UpdateReportValues (PREPORT pReport)
|
||
|
/*
|
||
|
Effect: Redraw all the visible report values of pReport.
|
||
|
Since drawing the values completely covers any
|
||
|
previous values, there is no need to erase (or flicker)
|
||
|
between updating values.
|
||
|
|
||
|
Called By: ReportTimer, OnVScroll, OnHScroll.
|
||
|
*/
|
||
|
{ // UpdateReportValues
|
||
|
HDC hDC ;
|
||
|
|
||
|
hDC = GetDC (pReport->hWnd) ;
|
||
|
|
||
|
SetBkColor (hDC, GetSysColor(COLOR_WINDOW)) ;
|
||
|
SetWindowOrgEx (hDC,
|
||
|
GetScrollPos (pReport->hWnd, SB_HORZ),
|
||
|
GetScrollPos (pReport->hWnd, SB_VERT),
|
||
|
NULL) ;
|
||
|
|
||
|
DrawReportValues (hDC, pReport) ;
|
||
|
ReleaseDC (pReport->hWnd, hDC) ;
|
||
|
|
||
|
} // UpdateReportValues
|
||
|
|
||
|
|
||
|
|
||
|
void static OnHScroll (HWND hWnd,
|
||
|
int iScrollCode,
|
||
|
int iScrollNewPos)
|
||
|
{ // OnHScroll
|
||
|
PREPORT pReport ;
|
||
|
int iScrollAmt, iScrollPos, iScrollRange ;
|
||
|
int iScrollLo ;
|
||
|
RECT rectClient ;
|
||
|
int xWidth ;
|
||
|
|
||
|
pReport = ReportData (hWnd) ;
|
||
|
|
||
|
GetClientRect (hWnd, &rectClient) ;
|
||
|
xWidth = rectClient.right - rectClient.left ;
|
||
|
|
||
|
if (pReport->xWidth <= xWidth)
|
||
|
{
|
||
|
// no horz scroll bar, forget it
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
iScrollPos = GetScrollPos (hWnd, SB_HORZ) ;
|
||
|
|
||
|
GetScrollRange (hWnd, SB_HORZ, &iScrollLo, &iScrollRange) ;
|
||
|
|
||
|
|
||
|
switch (iScrollCode)
|
||
|
{
|
||
|
case SB_LINEUP:
|
||
|
iScrollAmt = - Report.yLineHeight ;
|
||
|
break ;
|
||
|
|
||
|
case SB_LINEDOWN:
|
||
|
iScrollAmt = Report.yLineHeight ;
|
||
|
break ;
|
||
|
|
||
|
case SB_PAGEUP:
|
||
|
iScrollAmt = - (rectClient.right - rectClient.left) / 2 ;
|
||
|
break ;
|
||
|
|
||
|
case SB_PAGEDOWN:
|
||
|
iScrollAmt = (rectClient.right - rectClient.left) / 2 ;
|
||
|
break ;
|
||
|
|
||
|
case SB_THUMBPOSITION:
|
||
|
iScrollAmt = iScrollNewPos - iScrollPos ;
|
||
|
break ;
|
||
|
|
||
|
default:
|
||
|
iScrollAmt = 0 ;
|
||
|
} // switch
|
||
|
|
||
|
iScrollAmt = PinInclusive (iScrollAmt,
|
||
|
-iScrollPos,
|
||
|
iScrollRange - iScrollPos) ;
|
||
|
if (iScrollAmt)
|
||
|
{
|
||
|
iScrollPos += iScrollAmt ;
|
||
|
ScrollWindow (hWnd, -iScrollAmt, 0, NULL, NULL) ;
|
||
|
SetScrollPos (hWnd, SB_HORZ, iScrollPos, TRUE) ;
|
||
|
UpdateWindow (hWnd) ;
|
||
|
#if 0
|
||
|
UpdateReportValues (pReport) ;
|
||
|
#endif
|
||
|
}
|
||
|
} // OnHScroll
|
||
|
|
||
|
|
||
|
|
||
|
void static OnVScroll (HWND hWnd,
|
||
|
int iScrollCode,
|
||
|
int iScrollNewPos)
|
||
|
{ // OnVScroll
|
||
|
PREPORT pReport ;
|
||
|
int iScrollAmt, iScrollPos, iScrollRange ;
|
||
|
int iScrollLo ;
|
||
|
RECT rectClient ;
|
||
|
|
||
|
pReport = ReportData (hWnd) ;
|
||
|
|
||
|
iScrollPos = GetScrollPos (hWnd, SB_VERT) ;
|
||
|
GetScrollRange (hWnd, SB_VERT, &iScrollLo, &iScrollRange) ;
|
||
|
|
||
|
GetClientRect (hWnd, &rectClient) ;
|
||
|
|
||
|
switch (iScrollCode)
|
||
|
{
|
||
|
case SB_LINEUP:
|
||
|
iScrollAmt = - Report.yLineHeight ;
|
||
|
break ;
|
||
|
|
||
|
case SB_LINEDOWN:
|
||
|
iScrollAmt = Report.yLineHeight ;
|
||
|
break ;
|
||
|
|
||
|
case SB_PAGEUP:
|
||
|
iScrollAmt = - (rectClient.bottom - rectClient.top) / 2 ;
|
||
|
break ;
|
||
|
|
||
|
case SB_PAGEDOWN:
|
||
|
iScrollAmt = (rectClient.bottom - rectClient.top) / 2 ;
|
||
|
break ;
|
||
|
|
||
|
case SB_THUMBPOSITION:
|
||
|
iScrollAmt = iScrollNewPos - iScrollPos ;
|
||
|
break ;
|
||
|
|
||
|
default:
|
||
|
iScrollAmt = 0 ;
|
||
|
} // switch
|
||
|
|
||
|
iScrollAmt = PinInclusive (iScrollAmt,
|
||
|
-iScrollPos,
|
||
|
iScrollRange - iScrollPos) ;
|
||
|
if (iScrollAmt)
|
||
|
{
|
||
|
iScrollPos += iScrollAmt ;
|
||
|
ScrollWindow (hWnd, 0, -iScrollAmt, NULL, NULL) ;
|
||
|
SetScrollPos (hWnd, SB_VERT, iScrollPos, TRUE) ;
|
||
|
|
||
|
// WindowInvalidate (hWnd) ;
|
||
|
UpdateWindow (hWnd) ;
|
||
|
#if 0
|
||
|
UpdateReportValues (pReport) ;
|
||
|
#endif
|
||
|
}
|
||
|
} // OnVScroll
|
||
|
|
||
|
void static OnKeyDown (HWND hWnd, DWORD wParam)
|
||
|
{
|
||
|
switch (wParam)
|
||
|
{
|
||
|
case VK_UP:
|
||
|
OnVScroll (hWnd, SB_LINEUP, 0) ;
|
||
|
break ;
|
||
|
|
||
|
case VK_DOWN:
|
||
|
OnVScroll (hWnd, SB_LINEDOWN, 0) ;
|
||
|
break ;
|
||
|
|
||
|
case VK_LEFT:
|
||
|
OnHScroll (hWnd, SB_LINEUP, 0) ;
|
||
|
break ;
|
||
|
|
||
|
case VK_RIGHT:
|
||
|
OnHScroll (hWnd, SB_LINEDOWN, 0) ;
|
||
|
break ;
|
||
|
|
||
|
case VK_PRIOR:
|
||
|
OnVScroll (hWnd, SB_PAGEUP, 0) ;
|
||
|
break ;
|
||
|
|
||
|
case VK_NEXT:
|
||
|
OnVScroll (hWnd, SB_PAGEDOWN, 0) ;
|
||
|
break ;
|
||
|
}
|
||
|
} // OnKeyDown
|
||
|
|
||
|
|
||
|
LRESULT APIENTRY ReportWndProc (HWND hWnd,
|
||
|
WORD wMsg,
|
||
|
DWORD wParam,
|
||
|
LONG lParam)
|
||
|
{ // ReportWndProc
|
||
|
BOOL bCallDefProc ;
|
||
|
LRESULT lReturnValue ;
|
||
|
|
||
|
bCallDefProc = FALSE ;
|
||
|
lReturnValue = 0L ;
|
||
|
|
||
|
switch (wMsg)
|
||
|
{ // switch
|
||
|
case WM_CREATE:
|
||
|
OnCreate (hWnd) ;
|
||
|
break ;
|
||
|
|
||
|
case WM_LBUTTONDOWN:
|
||
|
|
||
|
if (!OnReportLButtonDown (hWnd, LOWORD (lParam), HIWORD (lParam)))
|
||
|
{
|
||
|
// mouse click do not hit on any entries, see if we
|
||
|
// need to drag Perfmon
|
||
|
if (!(Options.bMenubar))
|
||
|
{
|
||
|
DoWindowDrag (hWnd, lParam) ;
|
||
|
}
|
||
|
}
|
||
|
break ;
|
||
|
|
||
|
case WM_LBUTTONDBLCLK:
|
||
|
SendMessage (hWndMain, WM_LBUTTONDBLCLK, wParam, lParam) ;
|
||
|
break ;
|
||
|
|
||
|
case WM_PAINT:
|
||
|
OnPaint (hWnd) ;
|
||
|
break ;
|
||
|
|
||
|
case WM_SIZE:
|
||
|
SetScrollRanges (hWnd) ;
|
||
|
break ;
|
||
|
|
||
|
case WM_HSCROLL:
|
||
|
OnHScroll (hWnd, LOWORD (wParam), HIWORD (wParam)) ;
|
||
|
break ;
|
||
|
|
||
|
case WM_VSCROLL:
|
||
|
OnVScroll (hWnd, LOWORD (wParam), HIWORD (wParam)) ;
|
||
|
break ;
|
||
|
|
||
|
case WM_TIMER:
|
||
|
ReportTimer (hWnd, FALSE) ;
|
||
|
break ;
|
||
|
|
||
|
case WM_KEYDOWN:
|
||
|
OnKeyDown (hWnd, wParam) ;
|
||
|
break ;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
KillTimer (hWnd, ReportTimerID) ;
|
||
|
break ;
|
||
|
|
||
|
default:
|
||
|
bCallDefProc = TRUE ;
|
||
|
} // switch
|
||
|
|
||
|
|
||
|
if (bCallDefProc)
|
||
|
lReturnValue = DefWindowProc (hWnd, wMsg, wParam, lParam) ;
|
||
|
|
||
|
return (lReturnValue);
|
||
|
} // ReportWndProc
|
||
|
|
||
|
|
||
|
|
||
|
//==========================================================================//
|
||
|
// Exported Functions //
|
||
|
//==========================================================================//
|
||
|
|
||
|
#if 0
|
||
|
PREPORT ReportData (HWND hWndReport)
|
||
|
{
|
||
|
return (&Report) ;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void SetReportTimer (PREPORT pReport)
|
||
|
{
|
||
|
if (pReport->iStatus == iPMStatusCollecting)
|
||
|
KillTimer (pReport->hWnd, ReportTimerID) ;
|
||
|
|
||
|
SetTimer (pReport->hWnd, ReportTimerID,
|
||
|
pReport->iIntervalMSecs , NULL) ;
|
||
|
pReport->iStatus = iPMStatusCollecting ;
|
||
|
}
|
||
|
|
||
|
|
||
|
void ClearReportTimer (PREPORT pReport)
|
||
|
{
|
||
|
pReport->iStatus = iPMStatusClosed ;
|
||
|
KillTimer (pReport->hWnd, ReportTimerID) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL ReportInitializeApplication (void)
|
||
|
{ // ReportInitializeApplication
|
||
|
BOOL bSuccess ;
|
||
|
WNDCLASS wc ;
|
||
|
|
||
|
//=============================//
|
||
|
// Register ReportWindow class //
|
||
|
//=============================//
|
||
|
|
||
|
|
||
|
wc.style = dwReportClassStyle ;
|
||
|
wc.lpfnWndProc = (WNDPROC) ReportWndProc ;
|
||
|
wc.hInstance = hInstance ;
|
||
|
wc.cbClsExtra = iReportWindowExtra ;
|
||
|
wc.cbWndExtra = iReportClassExtra ;
|
||
|
wc.hIcon = NULL ;
|
||
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
|
||
|
// wc.hbrBackground = GetStockObject (WHITE_BRUSH) ;
|
||
|
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
|
||
|
wc.lpszMenuName = NULL ;
|
||
|
wc.lpszClassName = szReportWindowClass ;
|
||
|
|
||
|
bSuccess = RegisterClass (&wc) ;
|
||
|
|
||
|
|
||
|
//=============================//
|
||
|
// Register Child classes //
|
||
|
//=============================//
|
||
|
|
||
|
return (bSuccess) ;
|
||
|
} // ReportInitializeApplication
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
HWND CreateReportWindow (HWND hWndParent)
|
||
|
/*
|
||
|
Effect: Create the graph window. This window is a child of
|
||
|
hWndMain and is a container for the graph data,
|
||
|
graph label, graph legend, and graph status windows.
|
||
|
|
||
|
Note: We dont worry about the size here, as this window
|
||
|
will be resized whenever the main window is resized.
|
||
|
|
||
|
*/
|
||
|
{
|
||
|
return (CreateWindow (szReportWindowClass, // window class
|
||
|
NULL, // caption
|
||
|
dwReportWindowStyle, // style for window
|
||
|
0, 0, // initial position
|
||
|
0, 0, // initial size
|
||
|
hWndParent, // parent
|
||
|
NULL, // menu
|
||
|
hInstance, // program instance
|
||
|
NULL)) ; // user-supplied data
|
||
|
} // CreateReportWindow
|
||
|
|
||
|
|
||
|
|
||
|
void SetReportPositions (HDC hDC,
|
||
|
PREPORT pReport)
|
||
|
{
|
||
|
PSYSTEMGROUP pSystemGroup ;
|
||
|
int yLine ;
|
||
|
int yPos ;
|
||
|
|
||
|
|
||
|
// pReport->xMaxCounterWidth = 0 ;
|
||
|
|
||
|
yLine = pReport->yLineHeight ;
|
||
|
yPos = 2 * yLine ;
|
||
|
|
||
|
for (pSystemGroup = pReport->pSystemGroupFirst ;
|
||
|
pSystemGroup ;
|
||
|
pSystemGroup = pSystemGroup->pSystemGroupNext)
|
||
|
{ // for
|
||
|
pSystemGroup->yFirstLine = yPos + yLine ;
|
||
|
|
||
|
SetSystemPositions (hDC, pReport, pSystemGroup, yLine) ;
|
||
|
|
||
|
yPos = pSystemGroup->yLastLine ;
|
||
|
} // for
|
||
|
|
||
|
pReport->yHeight = yPos ;
|
||
|
|
||
|
SetScrollRanges (pReport->hWnd) ;
|
||
|
} // SetReportPositions
|
||
|
|
||
|
|
||
|
|
||
|
void PlaybackReport (HWND hWndReport)
|
||
|
{ // PlaybackReport
|
||
|
PREPORT pReport ;
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
|
||
|
PlaybackLines (pReport->pSystemFirst,
|
||
|
pReport->pLineFirst,
|
||
|
PlaybackLog.StartIndexPos.iPosition) ;
|
||
|
PlaybackLines (pReport->pSystemFirst,
|
||
|
pReport->pLineFirst,
|
||
|
PlaybackLog.StopIndexPos.iPosition) ;
|
||
|
} // PlaybackReport
|
||
|
|
||
|
|
||
|
BOOL CurrentReportItem (HWND hWndReport)
|
||
|
{ // CurrentReportItem
|
||
|
PREPORT pReport ;
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
if (!pReport)
|
||
|
return (FALSE) ;
|
||
|
|
||
|
return (pReport->CurrentItemType != REPORT_TYPE_NOTHING) ;
|
||
|
} // CurrentReportItem
|
||
|
|
||
|
|
||
|
|
||
|
BOOL AddReport (HWND hWndParent)
|
||
|
{
|
||
|
PREPORT pReport ;
|
||
|
LPTSTR pCurrentSystem ;
|
||
|
POBJECTGROUP pParentObject ;
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
|
||
|
if (pReport->CurrentItemType == REPORT_TYPE_LINE)
|
||
|
{
|
||
|
pCurrentSystem = pReport->CurrentItem.pLine->lnSystemName ;
|
||
|
}
|
||
|
else if (pReport->CurrentItemType == REPORT_TYPE_SYSTEM)
|
||
|
{
|
||
|
pCurrentSystem = pReport->CurrentItem.pSystem->lpszSystemName ;
|
||
|
}
|
||
|
else if (pReport->CurrentItemType == REPORT_TYPE_OBJECT)
|
||
|
{
|
||
|
pCurrentSystem = pReport->CurrentItem.pObject->pParentSystem->lpszSystemName ;
|
||
|
}
|
||
|
else if (pReport->CurrentItemType == REPORT_TYPE_COLUMN)
|
||
|
{
|
||
|
pParentObject = pReport->CurrentItem.pColumn->pParentObject ;
|
||
|
pCurrentSystem = pParentObject->pParentSystem->lpszSystemName ;
|
||
|
}
|
||
|
else if (pReport->CurrentItemType == REPORT_TYPE_COUNTER)
|
||
|
{
|
||
|
pParentObject = pReport->CurrentItem.pCounter->pParentObject ;
|
||
|
pCurrentSystem = pParentObject->pParentSystem->lpszSystemName ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pCurrentSystem = NULL ;
|
||
|
}
|
||
|
|
||
|
|
||
|
return (AddLine (hWndParent,
|
||
|
&(pReport->pSystemFirst),
|
||
|
&(pReport->Visual),
|
||
|
pCurrentSystem,
|
||
|
LineTypeReport)) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL ToggleReportRefresh (HWND hWnd)
|
||
|
{ // ToggleReportRefresh
|
||
|
PREPORT pReport ;
|
||
|
|
||
|
pReport = ReportData (hWnd) ;
|
||
|
|
||
|
if (pReport->bManualRefresh)
|
||
|
SetReportTimer (pReport) ;
|
||
|
else
|
||
|
ClearReportTimer (pReport) ;
|
||
|
|
||
|
pReport->bManualRefresh = !pReport->bManualRefresh ;
|
||
|
return (pReport->bManualRefresh) ;
|
||
|
} // ToggleReportRefresh
|
||
|
|
||
|
BOOL ReportRefresh (HWND hWnd)
|
||
|
{ // ReportRefresh
|
||
|
PREPORT pReport ;
|
||
|
|
||
|
pReport = ReportData (hWnd) ;
|
||
|
|
||
|
return (pReport->bManualRefresh) ;
|
||
|
} // ReportRefresh
|
||
|
|
||
|
|
||
|
|
||
|
void ReportTimer (HWND hWnd, BOOL bForce)
|
||
|
{
|
||
|
PREPORT pReport ;
|
||
|
|
||
|
pReport = ReportData (hWnd) ;
|
||
|
|
||
|
if (PlayingBackLog () || !pReport)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (bForce || !pReport->bManualRefresh)
|
||
|
{ // if
|
||
|
UpdateLines (&(pReport->pSystemFirst), pReport->pLineFirst) ;
|
||
|
if (iPerfmonView == IDM_VIEWREPORT && !bPerfmonIconic)
|
||
|
{
|
||
|
// only need to draw the data when we are viewing it...
|
||
|
UpdateReportValues (pReport) ;
|
||
|
}
|
||
|
} // if
|
||
|
} // ReportTimer
|
||
|
|
||
|
BOOL SaveReport (HWND hWndReport, HANDLE hInputFile, BOOL bGetFileName)
|
||
|
{
|
||
|
PREPORT pReport ;
|
||
|
PLINE pLine ;
|
||
|
HANDLE hFile ;
|
||
|
DISKREPORT DiskReport ;
|
||
|
PERFFILEHEADER FileHeader ;
|
||
|
TCHAR szFileName [256] ;
|
||
|
BOOL newFileName = FALSE ;
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
if (!pReport)
|
||
|
{
|
||
|
return (FALSE) ;
|
||
|
}
|
||
|
|
||
|
if (hInputFile)
|
||
|
{
|
||
|
// use the input file handle if it is available
|
||
|
// this is the case for saving workspace data
|
||
|
hFile = hInputFile ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pReportFullFileName)
|
||
|
{
|
||
|
lstrcpy (szFileName, pReportFullFileName) ;
|
||
|
}
|
||
|
if (bGetFileName || pReportFullFileName == NULL)
|
||
|
{
|
||
|
if (!FileGetName (hWndReport, IDS_REPORTFILE, szFileName))
|
||
|
{
|
||
|
return (FALSE) ;
|
||
|
}
|
||
|
newFileName = TRUE ;
|
||
|
}
|
||
|
|
||
|
hFile = FileHandleCreate (szFileName) ;
|
||
|
|
||
|
if (hFile && newFileName)
|
||
|
{
|
||
|
ChangeSaveFileName (szFileName, IDM_VIEWREPORT) ;
|
||
|
}
|
||
|
else if (!hFile)
|
||
|
{
|
||
|
DlgErrorBox (hWndReport, ERR_CANT_OPEN, szFileName) ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if (!hFile)
|
||
|
return (FALSE) ;
|
||
|
|
||
|
|
||
|
if (!hInputFile)
|
||
|
{
|
||
|
memset (&FileHeader, 0, sizeof (FileHeader)) ;
|
||
|
lstrcpy (FileHeader.szSignature, szPerfReportSignature) ;
|
||
|
FileHeader.dwMajorVersion = ReportMajorVersion ;
|
||
|
FileHeader.dwMinorVersion = ReportMinorVersion ;
|
||
|
|
||
|
if (!FileWrite (hFile, &FileHeader, sizeof (PERFFILEHEADER)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DiskReport.Visual = pReport->Visual ;
|
||
|
DiskReport.bManualRefresh = pReport->bManualRefresh ;
|
||
|
DiskReport.dwIntervalSecs = pReport->iIntervalMSecs ;
|
||
|
DiskReport.dwNumLines = NumLines (pReport->pLineFirst) ;
|
||
|
DiskReport.perfmonOptions = Options ;
|
||
|
|
||
|
if (!FileWrite (hFile, &DiskReport, sizeof (DISKREPORT)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
for (pLine = pReport->pLineFirst ;
|
||
|
pLine ;
|
||
|
pLine = pLine->pLineNext)
|
||
|
{ // for
|
||
|
if (!WriteLine (pLine, hFile))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
} // for
|
||
|
|
||
|
if (!hInputFile)
|
||
|
{
|
||
|
CloseHandle (hFile) ;
|
||
|
}
|
||
|
|
||
|
return (TRUE) ;
|
||
|
|
||
|
Exit0:
|
||
|
if (!hInputFile)
|
||
|
{
|
||
|
CloseHandle (hFile) ;
|
||
|
|
||
|
// only need to report error if not workspace
|
||
|
DlgErrorBox (hWndReport, ERR_SETTING_FILE, szFileName) ;
|
||
|
}
|
||
|
return (FALSE) ;
|
||
|
} // SaveReport
|
||
|
|
||
|
|
||
|
void ReportAddAction (PREPORT pReport)
|
||
|
{
|
||
|
HDC hDC ;
|
||
|
|
||
|
//=============================//
|
||
|
// Calculate report positions //
|
||
|
//=============================//
|
||
|
|
||
|
hDC = GetDC (hWndReport) ;
|
||
|
SetReportPositions (hDC, pReport) ;
|
||
|
ReleaseDC (hWndReport, hDC) ;
|
||
|
|
||
|
if (PlayingBackLog ())
|
||
|
{
|
||
|
PlaybackReport (hWndReport) ;
|
||
|
}
|
||
|
else if (pReport->iStatus == iPMStatusClosed)
|
||
|
{
|
||
|
SetReportTimer (pReport) ;
|
||
|
}
|
||
|
|
||
|
WindowInvalidate (hWndReport) ;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL OpenReportVer1 (HANDLE hFile,
|
||
|
DISKREPORT *pDiskReport,
|
||
|
PREPORT pReport,
|
||
|
DWORD dwMinorVersion)
|
||
|
{
|
||
|
HDC hDC ;
|
||
|
|
||
|
pReport->Visual = pDiskReport->Visual ;
|
||
|
pReport->iIntervalMSecs = pDiskReport->dwIntervalSecs ;
|
||
|
if (dwMinorVersion < 3)
|
||
|
{
|
||
|
// convert this to msec
|
||
|
pReport->iIntervalMSecs *= 1000 ;
|
||
|
}
|
||
|
pReport->bManualRefresh = pDiskReport->bManualRefresh ;
|
||
|
|
||
|
bDelayAddAction = TRUE ;
|
||
|
ReadLines (hFile, pDiskReport->dwNumLines,
|
||
|
&(pReport->pSystemFirst), &(pReport->pLineFirst), IDM_VIEWREPORT) ;
|
||
|
|
||
|
if (pReport->pLineFirst)
|
||
|
{
|
||
|
// set focus on the first line
|
||
|
pReport->CurrentItem.pLine = pReport->pLineFirst ;
|
||
|
pReport->CurrentItemType = REPORT_TYPE_LINE ;
|
||
|
}
|
||
|
bDelayAddAction = FALSE ;
|
||
|
|
||
|
//=============================//
|
||
|
// Calculate report positions //
|
||
|
//=============================//
|
||
|
|
||
|
hDC = GetDC (hWndReport) ;
|
||
|
SetReportPositions (hDC, pReport) ;
|
||
|
ReleaseDC (hWndReport, hDC) ;
|
||
|
|
||
|
if (PlayingBackLog ())
|
||
|
|
||
|
{
|
||
|
PlaybackReport (hWndReport) ;
|
||
|
}
|
||
|
else if (pReport->iStatus == iPMStatusClosed)
|
||
|
{
|
||
|
SetReportTimer (pReport) ;
|
||
|
}
|
||
|
|
||
|
WindowInvalidate (hWndReport) ;
|
||
|
|
||
|
return (TRUE) ;
|
||
|
} // OpenReportVer1
|
||
|
|
||
|
|
||
|
|
||
|
BOOL OpenReport (HWND hWndReport,
|
||
|
HANDLE hFile,
|
||
|
DWORD dwMajorVersion,
|
||
|
DWORD dwMinorVersion,
|
||
|
BOOL bReportFile)
|
||
|
{
|
||
|
PREPORT pReport ;
|
||
|
DISKREPORT DiskReport ;
|
||
|
BOOL bSuccess = TRUE ;
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
if (!pReport)
|
||
|
{
|
||
|
bSuccess = FALSE ;
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
if (!FileRead (hFile, &DiskReport, sizeof (DISKREPORT)))
|
||
|
{
|
||
|
bSuccess = FALSE ;
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
|
||
|
switch (dwMajorVersion)
|
||
|
{
|
||
|
case (1):
|
||
|
|
||
|
SetHourglassCursor() ;
|
||
|
|
||
|
ResetReportView (hWndReport) ;
|
||
|
|
||
|
OpenReportVer1 (hFile, &DiskReport, pReport, dwMinorVersion) ;
|
||
|
|
||
|
// change to report view if we are opening a
|
||
|
// report file
|
||
|
if (bReportFile && iPerfmonView != IDM_VIEWREPORT)
|
||
|
{
|
||
|
SendMessage (hWndMain, WM_COMMAND, (LONG)IDM_VIEWREPORT, 0L) ;
|
||
|
}
|
||
|
|
||
|
if (iPerfmonView == IDM_VIEWREPORT)
|
||
|
{
|
||
|
SetPerfmonOptions (&DiskReport.perfmonOptions) ;
|
||
|
}
|
||
|
|
||
|
SetArrowCursor() ;
|
||
|
|
||
|
break ;
|
||
|
} // switch
|
||
|
|
||
|
Exit0:
|
||
|
|
||
|
if (bReportFile)
|
||
|
{
|
||
|
CloseHandle (hFile) ;
|
||
|
}
|
||
|
|
||
|
return (bSuccess) ;
|
||
|
} // OpenReport
|
||
|
|
||
|
void ResetReportView (HWND hWndReport)
|
||
|
{ // ResetReportView
|
||
|
PREPORT pReport ;
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
|
||
|
if (!pReport)
|
||
|
{
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
ChangeSaveFileName (NULL, IDM_VIEWREPORT) ;
|
||
|
|
||
|
if (pReport->pSystemGroupFirst)
|
||
|
{
|
||
|
ResetReport (hWndReport) ;
|
||
|
}
|
||
|
} // ResetReportView
|
||
|
|
||
|
|
||
|
void ResetReport (HWND hWndReport)
|
||
|
{ // ResetReport
|
||
|
PREPORT pReport ;
|
||
|
PSYSTEMGROUP pSystemGroup, pSystemGroupDelete ;
|
||
|
POBJECTGROUP pObjectGroup, pObjectGroupDelete ;
|
||
|
PCOUNTERGROUP pCounterGroup, pCounterGroupDelete ;
|
||
|
HDC hDC ;
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
if (!pReport)
|
||
|
return ;
|
||
|
|
||
|
ClearReportTimer (pReport) ;
|
||
|
|
||
|
pSystemGroup = pReport->pSystemGroupFirst ;
|
||
|
while (pSystemGroup)
|
||
|
{
|
||
|
pObjectGroup = pSystemGroup->pObjectGroupFirst ;
|
||
|
while (pObjectGroup)
|
||
|
{
|
||
|
pCounterGroup = pObjectGroup->pCounterGroupFirst ;
|
||
|
while (pCounterGroup)
|
||
|
{
|
||
|
pCounterGroupDelete = pCounterGroup ;
|
||
|
pCounterGroup = pCounterGroup->pCounterGroupNext ;
|
||
|
MemoryFree (pCounterGroupDelete) ;
|
||
|
} // while pCounter...
|
||
|
|
||
|
pObjectGroupDelete = pObjectGroup ;
|
||
|
pObjectGroup = pObjectGroup->pObjectGroupNext ;
|
||
|
ColumnGroupRemove (pObjectGroupDelete->pColumnGroupFirst) ;
|
||
|
MemoryFree (pObjectGroupDelete->lpszObjectName) ;
|
||
|
MemoryFree (pObjectGroupDelete) ;
|
||
|
} // while pObject
|
||
|
|
||
|
pSystemGroupDelete = pSystemGroup ;
|
||
|
pSystemGroup = pSystemGroup->pSystemGroupNext ;
|
||
|
MemoryFree (pSystemGroupDelete->lpszSystemName) ;
|
||
|
MemoryFree (pSystemGroupDelete) ;
|
||
|
} // while pSystem...
|
||
|
|
||
|
FreeLines (pReport->pLineFirst) ;
|
||
|
pReport->pLineFirst = NULL ;
|
||
|
|
||
|
FreeSystems (pReport->pSystemFirst) ;
|
||
|
pReport->pSystemFirst = NULL ;
|
||
|
|
||
|
pReport->pSystemGroupFirst = NULL ;
|
||
|
pReport->CurrentItemType = REPORT_TYPE_NOTHING ;
|
||
|
pReport->CurrentItem.pLine = NULL ;
|
||
|
|
||
|
// reset scrolling ranges
|
||
|
pReport->xWidth = 0 ;
|
||
|
pReport->yHeight = 0 ;
|
||
|
pReport->xMaxCounterWidth = 0 ;
|
||
|
hDC = GetDC (hWndReport) ;
|
||
|
SetReportPositions (hDC, pReport) ;
|
||
|
|
||
|
SelectFont (hDC, pReport->hFont) ;
|
||
|
pReport->xValueWidth = TextWidth (hDC, szValuePlaceholder) ;
|
||
|
|
||
|
ReleaseDC (hWndReport, hDC) ;
|
||
|
|
||
|
WindowInvalidate (hWndReport) ;
|
||
|
} // ResetReport
|
||
|
|
||
|
void ClearReportDisplay (HWND hWndReport)
|
||
|
{ // ResetReport
|
||
|
PREPORT pReport ;
|
||
|
PLINE pLine;
|
||
|
|
||
|
if (PlayingBackLog())
|
||
|
{
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
if (!pReport || !pReport->pLineFirst)
|
||
|
return ;
|
||
|
|
||
|
for (pLine = pReport->pLineFirst ;
|
||
|
pLine ;
|
||
|
pLine = pLine->pLineNext)
|
||
|
{
|
||
|
// reset the new data counts
|
||
|
pLine->bFirstTime = 2 ;
|
||
|
}
|
||
|
|
||
|
// re-draw the values
|
||
|
UpdateReportValues (pReport) ;
|
||
|
|
||
|
} // ClearReportDisplay
|
||
|
|
||
|
//=========================================
|
||
|
// we don't print. we just export
|
||
|
//
|
||
|
// if need printing, define KEEP_PRINT
|
||
|
//=========================================
|
||
|
#ifdef KEEP_PRINT
|
||
|
BOOL PrintReportDisplay (HDC hDC,
|
||
|
PREPORT pReport)
|
||
|
{
|
||
|
SetReportPositions (hDC, pReport) ;
|
||
|
DrawReport (hDC, pReport) ;
|
||
|
return TRUE ;
|
||
|
} // PrintReportDisplay
|
||
|
|
||
|
|
||
|
|
||
|
BOOL PrintReport (HWND hWndParent,
|
||
|
HWND hWndReport)
|
||
|
{
|
||
|
PREPORT pReport ;
|
||
|
HDC hDC ;
|
||
|
int xPageWidth ;
|
||
|
int yPageHeight ;
|
||
|
int xValueWidth ;
|
||
|
|
||
|
HFONT hFont, hFontHeaders ;
|
||
|
int yLineHeight ;
|
||
|
|
||
|
pReport = ReportData (hWndReport) ;
|
||
|
if (!pReport)
|
||
|
return (FALSE) ;
|
||
|
|
||
|
hDC = PrintDC () ;
|
||
|
if (!hDC)
|
||
|
{
|
||
|
PostError () ;
|
||
|
return (FALSE) ;
|
||
|
}
|
||
|
|
||
|
xPageWidth = GetDeviceCaps (hDC, HORZRES) ;
|
||
|
yPageHeight = GetDeviceCaps (hDC, VERTRES) ;
|
||
|
|
||
|
|
||
|
StartJob (hDC, TEXT("Performance Monitor Report")) ;
|
||
|
StartPage (hDC) ;
|
||
|
|
||
|
|
||
|
hFont = pReport->hFont ;
|
||
|
hFontHeaders = pReport->hFontHeaders ;
|
||
|
yLineHeight = pReport->yLineHeight ;
|
||
|
xValueWidth = pReport->xValueWidth ;
|
||
|
|
||
|
pReport->hFont = hFontPrinterScales ;
|
||
|
pReport->hFontHeaders = hFontPrinterScalesBold ;
|
||
|
|
||
|
SelectFont (hDC, pReport->hFont) ;
|
||
|
pReport->yLineHeight = FontHeight (hDC, TRUE) ;
|
||
|
|
||
|
pReport->xValueWidth = TextWidth (hDC, szValuePlaceholder) ;
|
||
|
|
||
|
PrintReportDisplay (hDC, pReport) ;
|
||
|
|
||
|
EndPage (hDC) ;
|
||
|
EndJob (hDC) ;
|
||
|
|
||
|
DeleteDC (hDC) ;
|
||
|
|
||
|
|
||
|
pReport->hFont = hFont ;
|
||
|
pReport->hFontHeaders = hFontHeaders ;
|
||
|
pReport->yLineHeight = yLineHeight ;
|
||
|
|
||
|
pReport->xValueWidth = xValueWidth ;
|
||
|
|
||
|
hDC = GetDC (hWndReport) ;
|
||
|
SetReportPositions (hDC, pReport) ;
|
||
|
ReleaseDC (hWndReport, hDC) ;
|
||
|
|
||
|
return (FALSE) ;
|
||
|
} // PrintReport
|
||
|
|
||
|
// we don't print. we just export
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
BOOL ReportInsertLine (HWND hWnd, PLINE pLine)
|
||
|
/*
|
||
|
Effect: Insert the line pLine into the data structures for the
|
||
|
Report of window hWnd. The line is added to the list of
|
||
|
lines, and also added to the report structure in the
|
||
|
appropriate System, Object, and Counter.
|
||
|
|
||
|
Returns: Whether the function was successful. If this function
|
||
|
returns FALSE, the line was not added.
|
||
|
*/
|
||
|
{ // ReportInsertLine
|
||
|
HDC hDC ;
|
||
|
PREPORT pReport ;
|
||
|
PSYSTEMGROUP pSystemGroup ;
|
||
|
POBJECTGROUP pObjectGroup ;
|
||
|
PCOUNTERGROUP pCounterGroup ;
|
||
|
PLINE pLineEquivalent ;
|
||
|
int OldCounterWidth ;
|
||
|
BOOL bNewCounterGroup ;
|
||
|
|
||
|
pReport = ReportData (hWnd) ;
|
||
|
pReport->bModified = TRUE ;
|
||
|
|
||
|
pLineEquivalent = FindEquivalentLine (pLine, pReport->pLineFirst) ;
|
||
|
if (pLineEquivalent)
|
||
|
{
|
||
|
if (bMonitorDuplicateInstances) {
|
||
|
pLine->dwInstanceIndex = pLineEquivalent->dwInstanceIndex + 1;
|
||
|
} else {
|
||
|
return (FALSE) ;
|
||
|
}
|
||
|
}
|
||
|
//=============================//
|
||
|
// Add line, line's system //
|
||
|
//=============================//
|
||
|
|
||
|
LineAppend (&pReport->pLineFirst, pLine) ;
|
||
|
SystemAdd (&pReport->pSystemFirst, pLine->lnSystemName, hWnd) ;
|
||
|
|
||
|
|
||
|
//=============================//
|
||
|
// Find correct spot; add line //
|
||
|
//=============================//
|
||
|
|
||
|
pSystemGroup = GetSystemGroup (pReport, pLine->lnSystemName) ;
|
||
|
pObjectGroup = GetObjectGroup (pSystemGroup, pLine->lnObjectName) ;
|
||
|
pCounterGroup = GetCounterGroup (pObjectGroup,
|
||
|
pLine->lnCounterDef.CounterNameTitleIndex,
|
||
|
&bNewCounterGroup,
|
||
|
pLine->lnCounterName);
|
||
|
|
||
|
if (!pCounterGroup)
|
||
|
return (FALSE) ;
|
||
|
|
||
|
LineCounterAppend (&pCounterGroup->pLineFirst, pLine) ;
|
||
|
|
||
|
//=============================//
|
||
|
// Calculate report positions //
|
||
|
//=============================//
|
||
|
hDC = GetDC (hWnd) ;
|
||
|
SelectFont (hDC, pReport->hFontHeaders) ;
|
||
|
|
||
|
if (bNewCounterGroup)
|
||
|
{
|
||
|
// re-calc. the max. counter group width
|
||
|
OldCounterWidth = pReport->xMaxCounterWidth ;
|
||
|
pReport->xMaxCounterWidth =
|
||
|
max (pReport->xMaxCounterWidth,
|
||
|
TextWidth (hDC, pLine->lnCounterName)) ;
|
||
|
if (OldCounterWidth < pReport->xMaxCounterWidth)
|
||
|
{
|
||
|
// adjust the report width with the new counter width
|
||
|
pReport->xWidth +=
|
||
|
(pReport->xMaxCounterWidth - OldCounterWidth);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pLine->lnCounterType == PERF_COUNTER_LARGE_RAWCOUNT_HEX)
|
||
|
{
|
||
|
SelectFont (hDC, pReport->hFont) ;
|
||
|
pReport->xValueWidth = TextWidth (hDC, szValueLargeHexPlaceholder) ;
|
||
|
}
|
||
|
|
||
|
if (!bDelayAddAction)
|
||
|
{
|
||
|
SetReportPositions (hDC, pReport) ;
|
||
|
}
|
||
|
ReleaseDC (hWnd, hDC) ;
|
||
|
|
||
|
pReport->CurrentItem.pLine = pLine ;
|
||
|
pReport->CurrentItemType = REPORT_TYPE_LINE ;
|
||
|
|
||
|
if (!bDelayAddAction)
|
||
|
{
|
||
|
if (PlayingBackLog ())
|
||
|
{
|
||
|
PlaybackReport (hWndReport) ;
|
||
|
}
|
||
|
else if (pReport->iStatus == iPMStatusClosed)
|
||
|
{
|
||
|
SetReportTimer (pReport) ;
|
||
|
}
|
||
|
|
||
|
WindowInvalidate (hWnd) ;
|
||
|
}
|
||
|
return (TRUE) ;
|
||
|
} // ReportInsertLine
|
||
|
|
||
|
|
||
|
BOOL ExportComputerName (HANDLE hFile, PSYSTEMGROUP pSystemGroup)
|
||
|
{
|
||
|
int StringLen ;
|
||
|
BOOL bWriteSuccess = TRUE ;
|
||
|
CHAR TempBuff [LongTextLen] ;
|
||
|
TCHAR UnicodeBuff [LongTextLen] ;
|
||
|
|
||
|
// export computer name
|
||
|
strcpy (TempBuff, LineEndStr) ;
|
||
|
strcat (TempBuff, LineEndStr) ;
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
TSPRINTF (UnicodeBuff, szSystemFormat, pSystemGroup->lpszSystemName) ;
|
||
|
ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
|
||
|
strcat (TempBuff, LineEndStr) ;
|
||
|
|
||
|
if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
|
||
|
{
|
||
|
bWriteSuccess = FALSE ;
|
||
|
}
|
||
|
|
||
|
return (bWriteSuccess) ;
|
||
|
} // ExportComputerName
|
||
|
|
||
|
#define WRITE_FILE_TIME 2
|
||
|
BOOL ExportObjectName (HANDLE hFile, POBJECTGROUP pObjectGroup, int *pColNum)
|
||
|
{
|
||
|
int StringLen ;
|
||
|
BOOL bNeedToExport ;
|
||
|
BOOL bWriteSuccess = TRUE ;
|
||
|
PCOLUMNGROUP pColumnGroup ;
|
||
|
int ParentNum, InstanceNum ;
|
||
|
int TimeToWrite ;
|
||
|
CHAR TempBuff [512] ;
|
||
|
TCHAR UnicodeBuff [512] ;
|
||
|
|
||
|
ParentNum = InstanceNum = 0 ;
|
||
|
|
||
|
if (pColNum)
|
||
|
{
|
||
|
*pColNum = 0 ;
|
||
|
}
|
||
|
|
||
|
// export object name
|
||
|
strcpy (TempBuff, LineEndStr) ;
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
TSPRINTF (UnicodeBuff, szObjectFormat, pObjectGroup->lpszObjectName) ;
|
||
|
ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
|
||
|
strcat (TempBuff, LineEndStr) ;
|
||
|
|
||
|
if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
|
||
|
TimeToWrite = 0 ;
|
||
|
|
||
|
// export column group
|
||
|
if (pObjectGroup->pColumnGroupFirst)
|
||
|
{
|
||
|
strcpy (TempBuff, pDelimiter) ;
|
||
|
strcat (TempBuff, pDelimiter) ;
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
|
||
|
bNeedToExport = FALSE ;
|
||
|
|
||
|
// export Parent Names
|
||
|
for (pColumnGroup = pObjectGroup->pColumnGroupFirst ;
|
||
|
pColumnGroup ;
|
||
|
pColumnGroup = pColumnGroup->pColumnGroupNext)
|
||
|
{ // for
|
||
|
|
||
|
if (pColumnGroup->lpszParentName)
|
||
|
{
|
||
|
ParentNum++ ;
|
||
|
bNeedToExport = TRUE ;
|
||
|
ConvertUnicodeStr (&TempBuff[StringLen],
|
||
|
pColumnGroup->lpszParentName) ;
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
}
|
||
|
|
||
|
strcat (&TempBuff[StringLen], pDelimiter) ;
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
|
||
|
// check if we need to export this line before it is filled up
|
||
|
TimeToWrite++ ;
|
||
|
if (TimeToWrite > WRITE_FILE_TIME)
|
||
|
{
|
||
|
if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
TimeToWrite = 0 ;
|
||
|
StringLen = 0 ;
|
||
|
TempBuff[0] = TEXT('\0') ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// write the line delimiter
|
||
|
strcpy (&TempBuff[StringLen], LineEndStr) ;
|
||
|
if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
if (!bNeedToExport)
|
||
|
{
|
||
|
ParentNum = 0 ;
|
||
|
}
|
||
|
|
||
|
|
||
|
// setup to export Instances
|
||
|
strcpy (TempBuff, pDelimiter) ;
|
||
|
strcat (TempBuff, pDelimiter) ;
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
bNeedToExport = FALSE ;
|
||
|
TimeToWrite = 0 ;
|
||
|
|
||
|
// export Instance Names
|
||
|
for (pColumnGroup = pObjectGroup->pColumnGroupFirst ;
|
||
|
pColumnGroup ;
|
||
|
pColumnGroup = pColumnGroup->pColumnGroupNext)
|
||
|
{ // for
|
||
|
|
||
|
if (pColumnGroup->lpszInstanceName)
|
||
|
{
|
||
|
InstanceNum++ ;
|
||
|
bNeedToExport = TRUE ;
|
||
|
ConvertUnicodeStr (&TempBuff[StringLen],
|
||
|
pColumnGroup->lpszInstanceName) ;
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
}
|
||
|
|
||
|
strcat (&TempBuff[StringLen], pDelimiter) ;
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
|
||
|
// check if we need to export this line before it is filled up
|
||
|
TimeToWrite++ ;
|
||
|
if (TimeToWrite > WRITE_FILE_TIME)
|
||
|
{
|
||
|
if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
TimeToWrite = 0 ;
|
||
|
StringLen = 0 ;
|
||
|
TempBuff[0] = TEXT('\0') ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// write the line delimiter
|
||
|
strcpy (&TempBuff[StringLen], LineEndStr) ;
|
||
|
if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
if (!bNeedToExport)
|
||
|
{
|
||
|
InstanceNum = 0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pColNum)
|
||
|
{
|
||
|
*pColNum = max (ParentNum, InstanceNum) ;
|
||
|
}
|
||
|
|
||
|
return (TRUE) ;
|
||
|
|
||
|
Exit0:
|
||
|
return (FALSE) ;
|
||
|
|
||
|
} // ExportObjectName
|
||
|
|
||
|
BOOL ExportLineName (HANDLE hFile, PLINE pLine, int *pExportCounterName)
|
||
|
{
|
||
|
FLOAT eValue ;
|
||
|
int StringLen ;
|
||
|
BOOL bWriteSuccess = TRUE ;
|
||
|
CHAR TempBuff [LongTextLen] ;
|
||
|
TCHAR UnicodeBuff [LongTextLen] ;
|
||
|
|
||
|
|
||
|
strcpy (TempBuff, pDelimiter) ;
|
||
|
|
||
|
if (*pExportCounterName)
|
||
|
{
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
ConvertUnicodeStr (&TempBuff[StringLen], pLine->lnCounterName) ;
|
||
|
strcat (TempBuff, pDelimiter) ;
|
||
|
*pExportCounterName = FALSE ;
|
||
|
}
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
|
||
|
if (pLine->bFirstTime == 0)
|
||
|
{
|
||
|
eValue = CounterEntry (pLine) ;
|
||
|
|
||
|
if (pLine->lnCounterType == PERF_COUNTER_RAWCOUNT_HEX ||
|
||
|
pLine->lnCounterType == PERF_COUNTER_LARGE_RAWCOUNT_HEX)
|
||
|
{
|
||
|
if (pLine->lnCounterType == PERF_COUNTER_RAWCOUNT_HEX ||
|
||
|
pLine->lnaCounterValue[0].HighPart == 0)
|
||
|
{
|
||
|
TSPRINTF (UnicodeBuff,
|
||
|
szHexFormat,
|
||
|
pLine->lnaCounterValue[0].LowPart) ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TSPRINTF (UnicodeBuff,
|
||
|
szLargeHexFormat,
|
||
|
pLine->lnaCounterValue[0].HighPart,
|
||
|
pLine->lnaCounterValue[0].LowPart) ;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TSPRINTF (UnicodeBuff,
|
||
|
(eValue > eStatusLargeValueMax) ?
|
||
|
szLargeValueFormat : szValueFormat,
|
||
|
eValue) ;
|
||
|
ConvertDecimalPoint (UnicodeBuff) ;
|
||
|
}
|
||
|
ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// export "----" for unstable values
|
||
|
strcat (&TempBuff[StringLen], "----");
|
||
|
}
|
||
|
|
||
|
// write the line value
|
||
|
if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
return (TRUE) ;
|
||
|
|
||
|
|
||
|
Exit0:
|
||
|
return (FALSE) ;
|
||
|
} // ExportLineName
|
||
|
|
||
|
|
||
|
// This routine is need to insert the line values into its
|
||
|
// column location. It is needed because not all the instances (columns)
|
||
|
// are available for the same line.
|
||
|
void SaveColumnLineData (PLINE pLine, LPSTR pColumnLineData)
|
||
|
{
|
||
|
FLOAT eValue ;
|
||
|
LPSTR pColumnLine ;
|
||
|
CHAR TempBuff [LongTextLen] ;
|
||
|
TCHAR UnicodeBuff [LongTextLen] ;
|
||
|
|
||
|
if (!pColumnLineData || pLine->iReportColumn < 0)
|
||
|
{
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
// find the offset into the pColumnLineData buffer for current line
|
||
|
pColumnLine = pColumnLineData + pLine->iReportColumn * ShortTextLen ;
|
||
|
|
||
|
if (pLine->bFirstTime == 0)
|
||
|
{
|
||
|
eValue = CounterEntry (pLine) ;
|
||
|
|
||
|
|
||
|
if (pLine->lnCounterType == PERF_COUNTER_RAWCOUNT_HEX ||
|
||
|
pLine->lnCounterType == PERF_COUNTER_LARGE_RAWCOUNT_HEX)
|
||
|
{
|
||
|
if (pLine->lnCounterType == PERF_COUNTER_RAWCOUNT_HEX ||
|
||
|
pLine->lnaCounterValue[0].HighPart == 0)
|
||
|
{
|
||
|
TSPRINTF (UnicodeBuff,
|
||
|
szHexFormat,
|
||
|
pLine->lnaCounterValue[0].LowPart) ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TSPRINTF (UnicodeBuff,
|
||
|
szLargeHexFormat,
|
||
|
pLine->lnaCounterValue[0].HighPart,
|
||
|
pLine->lnaCounterValue[0].LowPart) ;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
TSPRINTF (UnicodeBuff,
|
||
|
(eValue > eStatusLargeValueMax) ?
|
||
|
szLargeValueFormat : szValueFormat,
|
||
|
eValue) ;
|
||
|
ConvertDecimalPoint (UnicodeBuff) ;
|
||
|
}
|
||
|
ConvertUnicodeStr (TempBuff, UnicodeBuff) ;
|
||
|
strncpy (pColumnLine, TempBuff, ShortTextLen) ;
|
||
|
*(pColumnLine + ShortTextLen - 1) = '\0' ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// export "----" for unstable values
|
||
|
strcpy (pColumnLine, "----");
|
||
|
}
|
||
|
} // SaveColumnLineData
|
||
|
|
||
|
BOOL ExportColumnLineData (HANDLE hFile,
|
||
|
int ColumnTotal,
|
||
|
PCOUNTERGROUP pCounterGroup,
|
||
|
LPSTR pColumnLineData)
|
||
|
{
|
||
|
int iIndex ;
|
||
|
int StringLen ;
|
||
|
CHAR TempBuff [LongTextLen] ;
|
||
|
LPSTR pCurrentLineData ;
|
||
|
|
||
|
// export the counter name
|
||
|
strcpy (TempBuff, pDelimiter) ;
|
||
|
StringLen = strlen (TempBuff) ;
|
||
|
ConvertUnicodeStr (&TempBuff[StringLen], pCounterGroup->pLineFirst->lnCounterName) ;
|
||
|
strcat (TempBuff, pDelimiter) ;
|
||
|
if (!FileWrite (hFile, TempBuff, strlen(TempBuff)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
// go thru each column and export the line value if it has been stored
|
||
|
for (iIndex = 0, pCurrentLineData = pColumnLineData ;
|
||
|
iIndex < ColumnTotal ;
|
||
|
iIndex++, pCurrentLineData += ShortTextLen )
|
||
|
{
|
||
|
if (*pCurrentLineData != 0)
|
||
|
{
|
||
|
// data available for this column
|
||
|
if (!FileWrite (hFile, pCurrentLineData, strlen(pCurrentLineData)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!FileWrite (hFile, pDelimiter, strlen(pDelimiter)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!FileWrite (hFile, LineEndStr, strlen(LineEndStr)))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
return (TRUE) ;
|
||
|
|
||
|
|
||
|
Exit0:
|
||
|
return (FALSE) ;
|
||
|
|
||
|
} // ExportColumnLineData
|
||
|
|
||
|
void ExportReport (void)
|
||
|
{
|
||
|
HANDLE hFile = 0 ;
|
||
|
PREPORT pReport ;
|
||
|
PSYSTEMGROUP pSystemGroup ;
|
||
|
POBJECTGROUP pObjectGroup ;
|
||
|
PCOUNTERGROUP pCounterGroup ;
|
||
|
PLINE pLine ;
|
||
|
BOOL bExportComputer ;
|
||
|
BOOL bExportObject ;
|
||
|
BOOL bExportCounterName ;
|
||
|
int ColumnTotal = 0 ;
|
||
|
LPSTR pColumnLineData = NULL ;
|
||
|
LPTSTR pFileName = NULL ;
|
||
|
INT ErrCode = 0 ;
|
||
|
|
||
|
if (!(pReport = ReportData (hWndReport)))
|
||
|
{
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
// see if there is anything to export..
|
||
|
if (!(pReport->pSystemGroupFirst))
|
||
|
{
|
||
|
return ;
|
||
|
}
|
||
|
|
||
|
SetHourglassCursor() ;
|
||
|
|
||
|
if (ErrCode = ExportFileOpen (hWndReport, &hFile,
|
||
|
pReport->iIntervalMSecs, &pFileName))
|
||
|
{
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
if (!pFileName)
|
||
|
{
|
||
|
// the case when user cancel
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
// export each system group
|
||
|
|
||
|
for (pSystemGroup = pReport->pSystemGroupFirst ;
|
||
|
pSystemGroup ;
|
||
|
pSystemGroup = pSystemGroup->pSystemGroupNext)
|
||
|
{ // for System...
|
||
|
|
||
|
bExportComputer = TRUE ;
|
||
|
|
||
|
for (pObjectGroup = pSystemGroup->pObjectGroupFirst ;
|
||
|
pObjectGroup ;
|
||
|
pObjectGroup = pObjectGroup->pObjectGroupNext)
|
||
|
{ // for Object...
|
||
|
|
||
|
bExportObject = TRUE ;
|
||
|
|
||
|
for (pCounterGroup = pObjectGroup->pCounterGroupFirst ;
|
||
|
pCounterGroup ;
|
||
|
pCounterGroup = pCounterGroup->pCounterGroupNext)
|
||
|
{ // for Counter...
|
||
|
|
||
|
bExportCounterName = TRUE ;
|
||
|
|
||
|
// Column data buffer has been allocated for this object type,
|
||
|
// zero out the buffer and prepare for next round.
|
||
|
|
||
|
if (pColumnLineData)
|
||
|
{
|
||
|
memset (pColumnLineData, 0, ColumnTotal * ShortTextLen) ;
|
||
|
}
|
||
|
|
||
|
for (pLine = pCounterGroup->pLineFirst ;
|
||
|
pLine ;
|
||
|
pLine = pLine->pLineCounterNext)
|
||
|
{ // for Line...
|
||
|
|
||
|
if (bExportComputer)
|
||
|
{
|
||
|
// only need to do this for the first object
|
||
|
bExportComputer = FALSE ;
|
||
|
if (!ExportComputerName (hFile, pSystemGroup))
|
||
|
{
|
||
|
ErrCode = ERR_EXPORT_FILE ;
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bExportObject)
|
||
|
{
|
||
|
// only need to do this for the first counter group
|
||
|
bExportObject = FALSE ;
|
||
|
if (!ExportObjectName (hFile, pObjectGroup, &ColumnTotal))
|
||
|
{
|
||
|
ErrCode = ERR_EXPORT_FILE ;
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
|
||
|
if (ColumnTotal > 1)
|
||
|
{
|
||
|
// special case to setup a column array and export
|
||
|
// the line values later
|
||
|
pColumnLineData = MemoryAllocate (ColumnTotal * ShortTextLen) ;
|
||
|
if (!pColumnLineData)
|
||
|
{
|
||
|
ErrCode = ERR_EXPORT_FILE ;
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (ColumnTotal > 1)
|
||
|
{
|
||
|
// save the line value into its column & export later
|
||
|
SaveColumnLineData (pLine, pColumnLineData) ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// simple case, export the line now
|
||
|
if (!ExportLineName (hFile, pLine, &bExportCounterName))
|
||
|
{
|
||
|
ErrCode = ERR_EXPORT_FILE ;
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
}
|
||
|
} // for Line...
|
||
|
|
||
|
if (!bExportCounterName)
|
||
|
{
|
||
|
// export the line end
|
||
|
if (!FileWrite (hFile, LineEndStr, strlen(LineEndStr)))
|
||
|
{
|
||
|
ErrCode = ERR_EXPORT_FILE ;
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pColumnLineData)
|
||
|
{
|
||
|
// now, do the actual export
|
||
|
if (!ExportColumnLineData (hFile,
|
||
|
ColumnTotal,
|
||
|
pCounterGroup,
|
||
|
pColumnLineData))
|
||
|
{
|
||
|
ErrCode = ERR_EXPORT_FILE ;
|
||
|
goto Exit0 ;
|
||
|
}
|
||
|
}
|
||
|
} // for Counter...
|
||
|
|
||
|
// done with the object, done with the buffer
|
||
|
if (pColumnLineData)
|
||
|
{
|
||
|
MemoryFree (pColumnLineData) ;
|
||
|
ColumnTotal = 0 ;
|
||
|
pColumnLineData = NULL ;
|
||
|
}
|
||
|
} // for Object
|
||
|
|
||
|
|
||
|
} // for System...
|
||
|
|
||
|
Exit0:
|
||
|
|
||
|
SetArrowCursor() ;
|
||
|
|
||
|
if (pColumnLineData)
|
||
|
{
|
||
|
MemoryFree (pColumnLineData) ;
|
||
|
}
|
||
|
|
||
|
if (hFile)
|
||
|
{
|
||
|
CloseHandle (hFile) ;
|
||
|
}
|
||
|
|
||
|
if (pFileName)
|
||
|
{
|
||
|
if (ErrCode)
|
||
|
{
|
||
|
DlgErrorBox (hWndGraph, ErrCode, pFileName) ;
|
||
|
}
|
||
|
|
||
|
MemoryFree (pFileName) ;
|
||
|
}
|
||
|
|
||
|
} // ExportReport
|
||
|
|
||
|
|
||
|
|