1518 lines
38 KiB
C
1518 lines
38 KiB
C
|
||
#include "perfmon.h"
|
||
#include <lmcons.h>
|
||
#include <lmerr.h>
|
||
#include <lmapibuf.h>
|
||
#include <lmwksta.h>
|
||
#include <uiexport.h>
|
||
#include <stdio.h> // for sprintf
|
||
#include <locale.h> // for setlocale
|
||
#include "utils.h"
|
||
|
||
#include "perfdata.h" // for OpenSystemPerfData
|
||
#include "alert.h" // for AlertInsertLine
|
||
#include "report.h" // for ReportInsertLine
|
||
#include "grafdata.h" // for GraphInsertLine
|
||
#include "log.h" // for OpenLog
|
||
#include "fileopen.h" // for FileGetName
|
||
#include "fileutil.h" // for FileRead etc
|
||
#include "command.h" // for PrepareMenu
|
||
#include "playback.h" // for PlayingBackLog & LogPositionSystemTime
|
||
#include "system.h"
|
||
#include "globals.h"
|
||
#include "pmemory.h" // for MemoryFree
|
||
#include "status.h" // for StatusLineReady
|
||
#include "pmhelpid.h"
|
||
|
||
// test for delimiter, end of line and non-digit characters
|
||
// used by IsNumberInUnicodeList routine
|
||
//
|
||
#define DIGIT 1
|
||
#define DELIMITER 2
|
||
#define INVALID 3
|
||
|
||
// globals used for International Date and Time formats
|
||
enum DATE_STYLE
|
||
{
|
||
YEAR_FIRST, // YYMMDD
|
||
DAY_FIRST, // DDMMYY
|
||
MONTH_FIRST // MMDDYY
|
||
} DateStyle ;
|
||
|
||
TCHAR szInternational[] = TEXT("Intl") ;
|
||
TCHAR sz1159[6] ; // AM String
|
||
TCHAR sz2359[6] ; // PM String
|
||
int iTime ; // = 0 for 12-hour format, <> 0 for 24-hour format
|
||
int YearCharCount ; // = 4 for 1990, = 2 for 90
|
||
|
||
TCHAR szDateFormat[ResourceStringLen] ;
|
||
TCHAR szTimeFormat[ResourceStringLen] ; // time format including msec
|
||
TCHAR szTimeFormat1[ResourceStringLen] ; // time format without msec
|
||
|
||
TCHAR LeadingZeroStr [] = TEXT("%02d") ;
|
||
TCHAR NoLeadingZeroStr [] = TEXT("%d") ;
|
||
|
||
TCHAR szDecimal [2] ;
|
||
TCHAR szCurrentDecimal [2] ;
|
||
|
||
#define EvalThisChar(c,d) ( \
|
||
(c == d) ? DELIMITER : \
|
||
(c == 0) ? DELIMITER : \
|
||
(c < (WCHAR)'0') ? INVALID : \
|
||
(c > (WCHAR)'9') ? INVALID : \
|
||
DIGIT)
|
||
|
||
#define SIZE_OF_BIGGEST_INTEGER 16
|
||
// #define SIZE_OF_BIGGEST_INTEGER (16*sizeof(WCHAR))
|
||
|
||
|
||
//==========================================================================//
|
||
// Typedefs //
|
||
//==========================================================================//
|
||
|
||
BOOL AddObjectToSystem ( PLINE , PPERFSYSTEM );
|
||
BOOL GetLogFileComputer (HWND hWndParent, LPTSTR lpComputerName, DWORD BufferSize) ;
|
||
|
||
|
||
HWND PerfmonViewWindow (void)
|
||
/*
|
||
Effect: Return the current data window, i.e. the window currently
|
||
visible as the client area of Perfmon. This is either a
|
||
chart, log, alert, or report window.
|
||
*/
|
||
{ // PerfmonDataWindow
|
||
switch (iPerfmonView)
|
||
{ // switch
|
||
case IDM_VIEWLOG:
|
||
return (hWndLog) ;
|
||
|
||
case IDM_VIEWALERT:
|
||
return (hWndAlert) ;
|
||
|
||
case IDM_VIEWREPORT:
|
||
return (hWndReport) ;
|
||
|
||
// case IDM_VIEWCHART:
|
||
default:
|
||
return (hWndGraph) ;
|
||
} // switch
|
||
} // PerfmonViewWindow
|
||
|
||
|
||
|
||
|
||
#define szChooseComputerLibrary TEXT("ntlanman.dll")
|
||
#define szChooseComputerFunction "I_SystemFocusDialog"
|
||
|
||
|
||
BOOL ChooseComputer (HWND hWndParent, LPTSTR lpszComputer)
|
||
/*
|
||
Effect: Display the choose Domain/Computer dialog provided by
|
||
network services. If the user selects a computer,
|
||
copy the computer name to lpszComputer and return
|
||
nonnull. If the user cancels, return FALSE.
|
||
|
||
Internals: This dialog and code is currently not an exported
|
||
routine regularly found on any user's system. Right
|
||
now, we dynamically load and call the routine.
|
||
|
||
This is definitely temporary code that will be
|
||
rewritten when NT stabilizes. The callers of this
|
||
routine, however, will not need to be modified.
|
||
|
||
Also, the Domain/Computer dialog currently allows
|
||
a domain to be selected, which we cannot use. We
|
||
therefore loop until the user cancels or selects
|
||
a computer, putting up a message if the user selects
|
||
a domain.
|
||
|
||
Assert: lpszComputer is at least MAX_SYSTEM_NAME_LENGTH + 1
|
||
characters.
|
||
*/
|
||
{ // ChooseComputer
|
||
BOOL bSuccess ;
|
||
WCHAR wszWideComputer[MAX_PATH + 3] ;
|
||
HLIBRARY hLibrary ;
|
||
LPFNI_SYSTEMFOCUSDIALOG lpfnChooseComputer ;
|
||
LONG lError ;
|
||
|
||
if (!PlayingBackLog())
|
||
{
|
||
|
||
// bring up the select network computer dialog
|
||
hLibrary = LoadLibrary (szChooseComputerLibrary) ;
|
||
if (!hLibrary || hLibrary == INVALID_HANDLE_VALUE)
|
||
{
|
||
return (FALSE) ;
|
||
}
|
||
|
||
lpfnChooseComputer = (LPFNI_SYSTEMFOCUSDIALOG)
|
||
GetProcAddress (hLibrary, szChooseComputerFunction) ;
|
||
|
||
if (!lpfnChooseComputer)
|
||
{
|
||
FreeLibrary (hLibrary) ;
|
||
return (FALSE) ;
|
||
}
|
||
|
||
lError = (*lpfnChooseComputer) (hWndParent,
|
||
FOCUSDLG_SERVERS_ONLY | FOCUSDLG_BROWSE_ALL_DOMAINS,
|
||
wszWideComputer,
|
||
sizeof(wszWideComputer) / sizeof(WCHAR),
|
||
&bSuccess,
|
||
pszHelpFile,
|
||
HC_PM_idDlgSelectNetworkComputer) ;
|
||
|
||
FreeLibrary (hLibrary) ;
|
||
}
|
||
else
|
||
{
|
||
// bring up the select Log Computer dialog
|
||
bSuccess = GetLogFileComputer (hWndParent,
|
||
wszWideComputer,
|
||
sizeof(wszWideComputer) / sizeof(WCHAR)) ;
|
||
}
|
||
|
||
if (bSuccess)
|
||
{
|
||
lstrcpy (lpszComputer, wszWideComputer) ;
|
||
}
|
||
|
||
return (bSuccess) ;
|
||
} // ChooseComputer
|
||
|
||
|
||
void SystemTimeDateString (SYSTEMTIME *pSystemTime,
|
||
LPTSTR lpszDate)
|
||
{
|
||
int wYear ;
|
||
|
||
wYear = pSystemTime->wYear ;
|
||
if (YearCharCount == 2)
|
||
{
|
||
wYear %= 100 ;
|
||
}
|
||
|
||
switch (DateStyle)
|
||
{
|
||
case YEAR_FIRST:
|
||
TSPRINTF (lpszDate, szDateFormat,
|
||
wYear, pSystemTime->wMonth, pSystemTime->wDay) ;
|
||
break ;
|
||
|
||
case DAY_FIRST:
|
||
TSPRINTF (lpszDate, szDateFormat,
|
||
pSystemTime->wDay, pSystemTime->wMonth, wYear) ;
|
||
break ;
|
||
|
||
case MONTH_FIRST:
|
||
default:
|
||
TSPRINTF (lpszDate, szDateFormat,
|
||
pSystemTime->wMonth, pSystemTime->wDay, wYear) ;
|
||
break ;
|
||
}
|
||
}
|
||
|
||
|
||
void SystemTimeTimeString (SYSTEMTIME *pSystemTime,
|
||
LPTSTR lpszTime,
|
||
BOOL bOutputMsec)
|
||
{
|
||
int iHour ;
|
||
BOOL bPM ;
|
||
|
||
if (iTime)
|
||
{
|
||
// 24 hor format
|
||
if (bOutputMsec)
|
||
{
|
||
TSPRINTF (lpszTime, szTimeFormat,
|
||
pSystemTime->wHour,
|
||
pSystemTime->wMinute,
|
||
(FLOAT)pSystemTime->wSecond +
|
||
(FLOAT)pSystemTime->wMilliseconds / (FLOAT) 1000.0) ;
|
||
}
|
||
else
|
||
{
|
||
TSPRINTF (lpszTime, szTimeFormat1,
|
||
pSystemTime->wHour,
|
||
pSystemTime->wMinute,
|
||
pSystemTime->wSecond) ;
|
||
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 12 hour format
|
||
iHour = pSystemTime->wHour ;
|
||
bPM = (iHour >= 12) ;
|
||
|
||
if (iHour > 12)
|
||
iHour -= 12 ;
|
||
else if (!iHour)
|
||
iHour = 12 ;
|
||
|
||
if (bOutputMsec)
|
||
{
|
||
TSPRINTF (lpszTime, szTimeFormat,
|
||
iHour, pSystemTime->wMinute,
|
||
(FLOAT)pSystemTime->wSecond +
|
||
(FLOAT)pSystemTime->wMilliseconds / (FLOAT) 1000.0 ,
|
||
bPM ? sz2359 : sz1159) ;
|
||
}
|
||
else
|
||
{
|
||
TSPRINTF (lpszTime, szTimeFormat1,
|
||
iHour, pSystemTime->wMinute,
|
||
pSystemTime->wSecond,
|
||
bPM ? sz2359 : sz1159) ;
|
||
}
|
||
}
|
||
}
|
||
|
||
void ShowPerfmonWindowText ()
|
||
{
|
||
LPTSTR *ppFileName ;
|
||
TCHAR szApplication [MessageLen] ;
|
||
|
||
switch (iPerfmonView)
|
||
{
|
||
case IDM_VIEWCHART:
|
||
ppFileName = &pChartFileName ;
|
||
break ;
|
||
|
||
case IDM_VIEWALERT:
|
||
ppFileName = &pAlertFileName ;
|
||
break ;
|
||
|
||
case IDM_VIEWREPORT:
|
||
ppFileName = &pReportFileName ;
|
||
break ;
|
||
|
||
case IDM_VIEWLOG:
|
||
ppFileName = &pLogFileName ;
|
||
break ;
|
||
|
||
default:
|
||
ppFileName = NULL ;
|
||
break ;
|
||
}
|
||
|
||
if (ppFileName == NULL)
|
||
{
|
||
ppFileName = &pWorkSpaceFileName ;
|
||
}
|
||
|
||
// display the name file name on the Title bar.
|
||
StringLoad (IDS_APPNAME, szApplication) ;
|
||
|
||
if (*ppFileName)
|
||
{
|
||
lstrcat (szApplication, TEXT(" - ")) ;
|
||
lstrcat (szApplication, *ppFileName) ;
|
||
}
|
||
SetWindowText (hWndMain, szApplication) ;
|
||
}
|
||
|
||
void ShowPerfmonMenu (BOOL bMenu)
|
||
{ // ShowPerfmonMenu
|
||
if (!bMenu)
|
||
{
|
||
WindowEnableTitle (hWndMain, FALSE) ;
|
||
// SetMenu(hWndMain, NULL) ;
|
||
}
|
||
else
|
||
{
|
||
WindowEnableTitle (hWndMain, TRUE) ;
|
||
switch (iPerfmonView)
|
||
{ // switch
|
||
case IDM_VIEWCHART:
|
||
SetMenu (hWndMain, hMenuChart) ;
|
||
break ;
|
||
|
||
case IDM_VIEWALERT:
|
||
SetMenu (hWndMain, hMenuAlert) ;
|
||
break ;
|
||
|
||
case IDM_VIEWLOG:
|
||
SetMenu (hWndMain, hMenuLog) ;
|
||
break ;
|
||
|
||
case IDM_VIEWREPORT:
|
||
SetMenu (hWndMain, hMenuReport) ;
|
||
break ;
|
||
} // switch
|
||
} // else
|
||
|
||
if (bMenu != Options.bMenubar)
|
||
{
|
||
PrepareMenu (GetMenu (hWndMain)) ;
|
||
}
|
||
|
||
Options.bMenubar = bMenu ;
|
||
|
||
// Show Window Text
|
||
if (bMenu)
|
||
{
|
||
ShowPerfmonWindowText () ;
|
||
}
|
||
} // ShowPerfmonMenu
|
||
|
||
|
||
|
||
void SmallFileSizeString (int iFileSize,
|
||
LPTSTR lpszFileText)
|
||
{ // SmallFileSizeString
|
||
if (iFileSize < 1000000)
|
||
TSPRINTF (lpszFileText, TEXT(" %1.1fK "), ((FLOAT) iFileSize) / 1000.0f) ;
|
||
else
|
||
TSPRINTF (lpszFileText, TEXT(" %1.1fM "), ((FLOAT) iFileSize) / 1000000.0f) ;
|
||
} // SmallFileSizeString
|
||
|
||
|
||
|
||
BOOL DoWindowDrag (HWND hWnd, LPARAM lParam)
|
||
{
|
||
POINT lPoint ;
|
||
|
||
if (!Options.bMenubar && !IsZoomed (hWndMain))
|
||
{
|
||
// convert lParam from client to screen
|
||
lPoint.x = LOWORD (lParam) ;
|
||
lPoint.y = HIWORD (lParam) ;
|
||
ClientToScreen (hWnd, &lPoint) ;
|
||
lParam = MAKELONG (lPoint.x, lPoint.y) ;
|
||
SendMessage (hWndMain, WM_NCLBUTTONDOWN, HTCAPTION, lParam) ;
|
||
return (TRUE) ;
|
||
}
|
||
else
|
||
return (FALSE) ;
|
||
}
|
||
|
||
|
||
|
||
// Filetimes are in 100NS units
|
||
#define FILETIMES_PER_SECOND 10000000
|
||
|
||
|
||
int SystemTimeDifference (SYSTEMTIME *pst1, SYSTEMTIME *pst2, BOOL bAbs)
|
||
{
|
||
LARGE_INTEGER li1, li2 ;
|
||
LARGE_INTEGER liDifference, liDifferenceSeconds ;
|
||
DWORD uRemainder ;
|
||
int RetInteger;
|
||
BOOL bNegative;
|
||
|
||
li1.HighPart = li1.LowPart = 0 ;
|
||
li2.HighPart = li2.LowPart = 0 ;
|
||
|
||
SystemTimeToFileTime (pst1, (FILETIME *) &li1) ;
|
||
SystemTimeToFileTime (pst2, (FILETIME *) &li2) ;
|
||
|
||
// check for special cases when the time can be 0
|
||
if (li2.HighPart == 0 && li2.LowPart == 0)
|
||
{
|
||
if (li1.HighPart == 0 && li1.LowPart == 0)
|
||
{
|
||
return 0 ;
|
||
}
|
||
else
|
||
{
|
||
return -INT_MAX ;
|
||
}
|
||
}
|
||
else if (li1.HighPart == 0 && li1.LowPart == 0)
|
||
{
|
||
return INT_MAX ;
|
||
}
|
||
|
||
liDifference.QuadPart = li2.QuadPart - li1.QuadPart ;
|
||
bNegative = liDifference.QuadPart < 0 ;
|
||
|
||
// add the round-off factor before doing the division
|
||
if (bNegative)
|
||
{
|
||
liDifferenceSeconds.QuadPart = (LONGLONG)(- FILETIMES_PER_SECOND / 2) ;
|
||
}
|
||
else
|
||
{
|
||
liDifferenceSeconds.QuadPart = (LONGLONG)(FILETIMES_PER_SECOND / 2) ;
|
||
}
|
||
|
||
|
||
liDifferenceSeconds.QuadPart = liDifferenceSeconds.QuadPart +
|
||
liDifference.QuadPart ;
|
||
|
||
liDifferenceSeconds.QuadPart = liDifferenceSeconds.QuadPart /
|
||
FILETIMES_PER_SECOND;
|
||
|
||
RetInteger = liDifferenceSeconds.LowPart;
|
||
|
||
if (bNegative && bAbs)
|
||
{
|
||
return (-RetInteger) ;
|
||
}
|
||
else
|
||
{
|
||
return (RetInteger) ;
|
||
}
|
||
}
|
||
|
||
|
||
BOOL InsertLine (PLINE pLine)
|
||
{ // InsertLine
|
||
|
||
BOOL bReturn = FALSE;
|
||
|
||
switch (pLine->iLineType) { // switch
|
||
case LineTypeChart:
|
||
bReturn = ChartInsertLine (pGraphs, pLine) ;
|
||
break ;
|
||
|
||
case LineTypeAlert:
|
||
bReturn = AlertInsertLine (hWndAlert, pLine) ;
|
||
break ;
|
||
|
||
case LineTypeReport:
|
||
bReturn = ReportInsertLine (hWndReport, pLine) ;
|
||
break ;
|
||
|
||
} // switch
|
||
|
||
return bReturn;
|
||
|
||
} // InsertLine
|
||
|
||
|
||
BOOL OpenWorkspace (HANDLE hFile, DWORD dwMajorVersion, DWORD dwMinorVersion)
|
||
{
|
||
DISKWORKSPACE DiskWorkspace ;
|
||
|
||
if (!FileRead (hFile, &DiskWorkspace, sizeof(DiskWorkspace)))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
if (DiskWorkspace.ChartOffset == 0 &&
|
||
DiskWorkspace.AlertOffset == 0 &&
|
||
DiskWorkspace.LogOffset == 0 &&
|
||
DiskWorkspace.ReportOffset == 0)
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
switch (dwMajorVersion)
|
||
{ // switch
|
||
case (1):
|
||
|
||
if (dwMinorVersion >= 1)
|
||
{
|
||
// setup the window position and size
|
||
DiskWorkspace.WindowPlacement.length = sizeof(WINDOWPLACEMENT);
|
||
DiskWorkspace.WindowPlacement.flags = WPF_SETMINPOSITION;
|
||
if (!SetWindowPlacement (hWndMain, &(DiskWorkspace.WindowPlacement)))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
}
|
||
|
||
// change to the view as stored in the workspace file
|
||
SendMessage (hWndMain, WM_COMMAND,
|
||
(LONG)DiskWorkspace.iPerfmonView, 0L) ;
|
||
iPerfmonView = DiskWorkspace.iPerfmonView ;
|
||
|
||
if (DiskWorkspace.ChartOffset)
|
||
{
|
||
if (FileSeekBegin(hFile, DiskWorkspace.ChartOffset) == 0xFFFFFFFF)
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
if (!OpenChart (hWndGraph,
|
||
hFile,
|
||
dwMajorVersion,
|
||
dwMinorVersion,
|
||
FALSE))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
}
|
||
if (DiskWorkspace.AlertOffset)
|
||
{
|
||
if (FileSeekBegin(hFile, DiskWorkspace.AlertOffset) == 0xffffffff)
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
if (!OpenAlert (hWndAlert,
|
||
hFile,
|
||
dwMajorVersion,
|
||
dwMinorVersion,
|
||
FALSE))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
}
|
||
if (DiskWorkspace.LogOffset)
|
||
{
|
||
if (FileSeekBegin(hFile, DiskWorkspace.LogOffset) == 0xffffffff)
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
if (!OpenLog (hWndLog,
|
||
hFile,
|
||
dwMajorVersion,
|
||
dwMinorVersion,
|
||
FALSE))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
}
|
||
if (DiskWorkspace.ReportOffset)
|
||
{
|
||
if (FileSeekBegin(hFile, DiskWorkspace.ReportOffset) == 0xffffffff)
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
if (!OpenReport (hWndReport,
|
||
hFile,
|
||
dwMajorVersion,
|
||
dwMinorVersion,
|
||
FALSE))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
}
|
||
break ;
|
||
|
||
default:
|
||
goto Exit0 ;
|
||
break ;
|
||
}
|
||
|
||
CloseHandle (hFile) ;
|
||
return (TRUE) ;
|
||
|
||
|
||
Exit0:
|
||
CloseHandle (hFile) ;
|
||
return (FALSE) ;
|
||
|
||
} // OpenWorkspace
|
||
|
||
|
||
BOOL SaveWorkspace (void)
|
||
{
|
||
DISKWORKSPACE DiskWorkspace ;
|
||
PERFFILEHEADER FileHeader ;
|
||
HANDLE hFile ;
|
||
long DiskWorkspacePosition ;
|
||
TCHAR szFileName[FilePathLen] ;
|
||
BOOL bWriteErr = TRUE ;
|
||
|
||
if (!FileGetName (PerfmonViewWindow(), IDS_WORKSPACEFILE, szFileName))
|
||
{
|
||
return (FALSE) ;
|
||
}
|
||
|
||
hFile = FileHandleCreate (szFileName) ;
|
||
if (!hFile || hFile == INVALID_HANDLE_VALUE)
|
||
{
|
||
DlgErrorBox (PerfmonViewWindow (), ERR_CANT_OPEN, szFileName) ;
|
||
return (FALSE) ;
|
||
}
|
||
|
||
memset (&FileHeader, 0, sizeof (FileHeader)) ;
|
||
lstrcpy (FileHeader.szSignature, szPerfWorkspaceSignature) ;
|
||
FileHeader.dwMajorVersion = WorkspaceMajorVersion ;
|
||
FileHeader.dwMinorVersion = WorkspaceMinorVersion ;
|
||
|
||
if (!FileWrite (hFile, &FileHeader, sizeof (PERFFILEHEADER)))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
// reserve space in the file. We will fill up info
|
||
// and write into this guy later.
|
||
memset (&DiskWorkspace, 0, sizeof(DiskWorkspace)) ;
|
||
DiskWorkspacePosition = FileTell (hFile) ;
|
||
DiskWorkspace.WindowPlacement.length = sizeof(WINDOWPLACEMENT);
|
||
if (!GetWindowPlacement (hWndMain, &(DiskWorkspace.WindowPlacement)))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
if (!FileWrite (hFile, &DiskWorkspace, sizeof (DISKWORKSPACE)))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
// put in chart data
|
||
DiskWorkspace.ChartOffset = FileTell (hFile) ;
|
||
if (!SaveChart (hWndGraph, hFile, 0))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
// put in alert data
|
||
DiskWorkspace.AlertOffset = FileTell (hFile) ;
|
||
if (!SaveAlert (hWndAlert, hFile, 0))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
// put in log data
|
||
DiskWorkspace.LogOffset = FileTell (hFile) ;
|
||
if (!SaveLog (hWndLog, hFile, 0))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
// put in report data
|
||
DiskWorkspace.ReportOffset = FileTell (hFile) ;
|
||
if (!SaveReport (hWndReport, hFile, 0))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
|
||
// put in the disk header info
|
||
DiskWorkspace.iPerfmonView = iPerfmonView ;
|
||
FileSeekBegin (hFile, DiskWorkspacePosition) ;
|
||
if (!FileWrite (hFile, &DiskWorkspace, sizeof (DISKWORKSPACE)))
|
||
{
|
||
goto Exit0 ;
|
||
}
|
||
bWriteErr = FALSE ;
|
||
|
||
Exit0:
|
||
if (bWriteErr)
|
||
{
|
||
DlgErrorBox (PerfmonViewWindow (), ERR_SETTING_FILE, szFileName) ;
|
||
}
|
||
|
||
CloseHandle (hFile) ;
|
||
return TRUE;
|
||
} // SaveWorkspace
|
||
|
||
void SetPerfmonOptions (OPTIONS *pOptions)
|
||
{
|
||
Options = *pOptions ;
|
||
ShowPerfmonMenu (Options.bMenubar) ;
|
||
SizePerfmonComponents () ;
|
||
WindowSetTopmost (hWndMain, Options.bAlwaysOnTop) ;
|
||
} // SetPerfmonOptions
|
||
|
||
void ChangeSaveFileName (LPTSTR szFileName, int iPMView)
|
||
{
|
||
LPTSTR *ppFullName = NULL;
|
||
LPTSTR *ppFileName = NULL;
|
||
BOOL errorInput = FALSE ;
|
||
TCHAR szApplication [MessageLen] ;
|
||
|
||
|
||
switch (iPMView)
|
||
{
|
||
case IDM_VIEWCHART:
|
||
ppFileName = &pChartFileName ;
|
||
ppFullName = &pChartFullFileName ;
|
||
break ;
|
||
|
||
case IDM_VIEWALERT:
|
||
ppFileName = &pAlertFileName ;
|
||
ppFullName = &pAlertFullFileName ;
|
||
break ;
|
||
|
||
case IDM_VIEWREPORT:
|
||
ppFileName = &pReportFileName ;
|
||
ppFullName = &pReportFullFileName ;
|
||
break ;
|
||
|
||
case IDM_VIEWLOG:
|
||
ppFileName = &pLogFileName ;
|
||
ppFullName = &pLogFullFileName ;
|
||
break ;
|
||
|
||
case IDM_WORKSPACE:
|
||
// not a view but a define
|
||
ppFileName = &pWorkSpaceFileName ;
|
||
ppFullName = &pWorkSpaceFullFileName ;
|
||
break ;
|
||
|
||
default:
|
||
errorInput = TRUE ;
|
||
break ;
|
||
}
|
||
|
||
if (errorInput)
|
||
{
|
||
return ;
|
||
}
|
||
|
||
// release last filename
|
||
if (*ppFullName)
|
||
{
|
||
MemoryFree (*ppFullName) ;
|
||
*ppFileName = NULL ;
|
||
*ppFullName = NULL ;
|
||
}
|
||
|
||
// allocate new file name and display it
|
||
if (szFileName && (*ppFullName = StringAllocate (szFileName)))
|
||
{
|
||
*ppFileName = ExtractFileName (*ppFullName) ;
|
||
}
|
||
|
||
if (iPerfmonView == iPMView || iPMView == IDM_WORKSPACE)
|
||
{
|
||
StatusLineReady (hWndStatus) ;
|
||
|
||
if (Options.bMenubar)
|
||
{
|
||
// display the name file name on the Title bar.
|
||
StringLoad (IDS_APPNAME, szApplication) ;
|
||
|
||
if (*ppFileName == NULL)
|
||
{
|
||
ppFileName = &pWorkSpaceFileName ;
|
||
}
|
||
|
||
if (*ppFileName)
|
||
{
|
||
lstrcat (szApplication, TEXT(" - ")) ;
|
||
lstrcat (szApplication, *ppFileName) ;
|
||
}
|
||
SetWindowText (hWndMain, szApplication) ;
|
||
}
|
||
}
|
||
} // ChangeSaveFileName
|
||
|
||
BOOL
|
||
IsNumberInUnicodeList (
|
||
IN DWORD dwNumber,
|
||
IN LPTSTR lpwszUnicodeList
|
||
)
|
||
/*++
|
||
|
||
IsNumberInUnicodeList
|
||
|
||
Arguments:
|
||
|
||
IN dwNumber
|
||
DWORD number to find in list
|
||
|
||
IN lpwszUnicodeList
|
||
Null terminated, Space delimited list of decimal numbers
|
||
|
||
Return Value:
|
||
|
||
TRUE:
|
||
dwNumber was found in the list of unicode number strings
|
||
|
||
FALSE:
|
||
dwNumber was not found in the list.
|
||
|
||
--*/
|
||
{
|
||
DWORD dwThisNumber;
|
||
WCHAR *pwcThisChar;
|
||
BOOL bValidNumber;
|
||
BOOL bNewItem;
|
||
WCHAR wcDelimiter; // could be an argument to be more flexible
|
||
|
||
if (lpwszUnicodeList == 0) return FALSE; // null pointer, # not founde
|
||
|
||
pwcThisChar = lpwszUnicodeList;
|
||
dwThisNumber = 0;
|
||
wcDelimiter = (WCHAR)' ';
|
||
bValidNumber = FALSE;
|
||
bNewItem = TRUE;
|
||
|
||
while (TRUE) {
|
||
switch (EvalThisChar (*pwcThisChar, wcDelimiter)) {
|
||
case DIGIT:
|
||
// if this is the first digit after a delimiter, then
|
||
// set flags to start computing the new number
|
||
if (bNewItem) {
|
||
bNewItem = FALSE;
|
||
bValidNumber = TRUE;
|
||
}
|
||
if (bValidNumber) {
|
||
dwThisNumber *= 10;
|
||
dwThisNumber += (*pwcThisChar - (WCHAR)'0');
|
||
}
|
||
break;
|
||
|
||
case DELIMITER:
|
||
// a delimter is either the delimiter character or the
|
||
// end of the string ('\0') if when the delimiter has been
|
||
// reached a valid number was found, then compare it to the
|
||
// number from the argument list. if this is the end of the
|
||
// string and no match was found, then return.
|
||
//
|
||
if (bValidNumber) {
|
||
if (dwThisNumber == dwNumber) return TRUE;
|
||
bValidNumber = FALSE;
|
||
}
|
||
if (*pwcThisChar == 0) {
|
||
return FALSE;
|
||
} else {
|
||
bNewItem = TRUE;
|
||
dwThisNumber = 0;
|
||
}
|
||
break;
|
||
|
||
case INVALID:
|
||
// if an invalid character was encountered, ignore all
|
||
// characters up to the next delimiter and then start fresh.
|
||
// the invalid number is not compared.
|
||
bValidNumber = FALSE;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
|
||
}
|
||
pwcThisChar++;
|
||
}
|
||
|
||
} // IsNumberInUnicodeList
|
||
|
||
BOOL
|
||
AppendObjectToValueList (
|
||
DWORD dwObjectId,
|
||
PWSTR pwszValueList
|
||
)
|
||
/*++
|
||
|
||
AppendObjectToValueList
|
||
|
||
Arguments:
|
||
|
||
IN dwNumber
|
||
DWORD number to insert in list
|
||
|
||
IN PUNICODE_STRING
|
||
pointer to unicode string structure that contains buffer that is
|
||
Null terminated, Space delimited list of decimal numbers that
|
||
may have this number appended to.
|
||
|
||
Return Value:
|
||
|
||
TRUE:
|
||
dwNumber was added to list
|
||
|
||
FALSE:
|
||
dwNumber was not added. (because it's already there or
|
||
an error occured)
|
||
|
||
--*/
|
||
{
|
||
WCHAR tempString [SIZE_OF_BIGGEST_INTEGER] ;
|
||
DWORD dwStrLen, dwNewStrLen;
|
||
LPTSTR szFormatString;
|
||
|
||
if (!pwszValueList) {
|
||
return FALSE;
|
||
}
|
||
|
||
if (IsNumberInUnicodeList(dwObjectId, pwszValueList)) {
|
||
return FALSE; // object already in list
|
||
} else {
|
||
// append the new object id the value list
|
||
// if this is the first string to enter then don't
|
||
// prefix with a space character otherwise do
|
||
|
||
szFormatString = (*pwszValueList == 0) ? TEXT("%d") : TEXT(" %d");
|
||
|
||
TSPRINTF (tempString, szFormatString, dwObjectId) ;
|
||
|
||
// see if string will fit (compare in bytes)
|
||
|
||
dwStrLen = MemorySize (pwszValueList) - sizeof (UNICODE_NULL);
|
||
|
||
dwNewStrLen = (lstrlen (pwszValueList) + lstrlen (tempString)) *
|
||
sizeof (WCHAR);
|
||
|
||
if (dwNewStrLen <= dwStrLen) {
|
||
lstrcat (pwszValueList, tempString);
|
||
return TRUE;
|
||
} else {
|
||
SetLastError (ERROR_OUTOFMEMORY);
|
||
return FALSE;
|
||
}
|
||
}
|
||
}
|
||
|
||
BOOL
|
||
AddObjectToSystem (
|
||
PLINE pLine,
|
||
PPERFSYSTEM pFirstSystem
|
||
)
|
||
{
|
||
PPERFSYSTEM pSystem;
|
||
|
||
if ((ARGUMENT_PRESENT (pLine)) && (ARGUMENT_PRESENT(pFirstSystem))) {
|
||
pSystem = SystemGet (pFirstSystem, pLine->lnSystemName);
|
||
|
||
if (pSystem) {
|
||
return AppendObjectToValueList (
|
||
pLine->lnObject.ObjectNameTitleIndex,
|
||
pSystem->lpszValue);
|
||
} else {
|
||
return FALSE;
|
||
}
|
||
} else {
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
BOOL
|
||
RemoveObjectsFromSystem (
|
||
PPERFSYSTEM pSystem
|
||
)
|
||
{
|
||
DWORD dwBufferSize = 0;
|
||
|
||
if (ARGUMENT_PRESENT (pSystem)) {
|
||
// don't do foreign computers
|
||
if (pSystem->lpszValue && (_wcsnicmp(pSystem->lpszValue, L"Foreign", 7) != 0)){
|
||
dwBufferSize = MemorySize (pSystem->lpszValue);
|
||
|
||
memset (pSystem->lpszValue, 0, dwBufferSize);
|
||
return TRUE;
|
||
} else {
|
||
return FALSE;
|
||
}
|
||
} else {
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
}
|
||
|
||
BOOL
|
||
BuildValueListForSystems (
|
||
PPERFSYSTEM pSystemListHead,
|
||
PLINE pLineListHead
|
||
)
|
||
/*++
|
||
|
||
BuildValueListForSystem
|
||
|
||
Abstract:
|
||
|
||
Walks down line list and builds the list of objects to query from
|
||
that system containing that line.
|
||
|
||
Arguments:
|
||
|
||
pSystemListHead
|
||
|
||
head of system linked list
|
||
each system will have it's "Value Name" list appended
|
||
|
||
pLineListHead
|
||
|
||
head of line list that will be searched for creating the new
|
||
valuelist.
|
||
|
||
|
||
Return Value:
|
||
|
||
|
||
--*/
|
||
{
|
||
|
||
PPERFSYSTEM pSystem; // system that contains current line
|
||
PLINE pThisLine; // current line
|
||
|
||
if ((ARGUMENT_PRESENT (pLineListHead)) && (ARGUMENT_PRESENT(pSystemListHead))) {
|
||
// clear system entries:
|
||
for (pSystem = pSystemListHead; pSystem; pSystem = pSystem->pSystemNext) {
|
||
if (pSystem && pSystem->FailureTime == 0) {
|
||
RemoveObjectsFromSystem (pSystem);
|
||
}
|
||
}
|
||
|
||
// add new enties
|
||
|
||
for (pThisLine = pLineListHead; pThisLine; pThisLine = pThisLine->pLineNext) {
|
||
|
||
pSystem = SystemGet (pSystemListHead, pThisLine->lnSystemName);
|
||
if (pSystem && pSystem->FailureTime == 0) {
|
||
AppendObjectToValueList (
|
||
pThisLine->lnObject.ObjectNameTitleIndex,
|
||
pSystem->lpszValue);
|
||
|
||
}
|
||
}
|
||
return TRUE;
|
||
} else { // argument(s) missing
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
// define in Addline.c
|
||
extern PLINESTRUCT pLineEdit ;
|
||
#define bEditLine (pLineEdit != NULL)
|
||
|
||
BOOL
|
||
SetSystemValueNameToGlobal (
|
||
PPERFSYSTEM pSystem
|
||
)
|
||
{
|
||
|
||
if (!bEditLine && ARGUMENT_PRESENT(pSystem)) {
|
||
if (pSystem->lpszValue && RemoveObjectsFromSystem(pSystem)) {
|
||
if (pSystem->lpszValue && (_wcsnicmp(pSystem->lpszValue, L"Foreign",7) != 0)){
|
||
// don't change foreign computer strings
|
||
lstrcpy (
|
||
pSystem->lpszValue,
|
||
TEXT("Global")) ;
|
||
}
|
||
return TRUE;
|
||
} else {
|
||
return FALSE;
|
||
}
|
||
} else {
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
BOOL
|
||
RemoveUnusedSystems (
|
||
PPERFSYSTEM pSystemHead,
|
||
PLINE pLineHead
|
||
)
|
||
/*++
|
||
|
||
walks system list and removes systems with no lines from list
|
||
|
||
--*/
|
||
{
|
||
PPERFSYSTEM pSystem;
|
||
PPERFSYSTEM pLastSystem;
|
||
PLINE pLine;
|
||
BOOL bSystemFound;
|
||
|
||
pLastSystem = NULL;
|
||
|
||
if ((ARGUMENT_PRESENT (pLineHead)) && (ARGUMENT_PRESENT(pSystemHead))) {
|
||
for (pSystem = pSystemHead;
|
||
pSystem != NULL;
|
||
pLastSystem = pSystem, pSystem = pSystem->pSystemNext) {
|
||
|
||
if (pSystem) {
|
||
bSystemFound = FALSE;
|
||
// walk lines to see if this system has a line
|
||
for (pLine = pLineHead; pLine; pLine = pLine->pLineNext) {
|
||
// if system in line is this system, then bailout
|
||
if (strsame (pLine->lnSystemName, pSystem->sysName)) {
|
||
bSystemFound = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!bSystemFound) { // delete this unused system
|
||
|
||
// fix pointers
|
||
if (pLastSystem)
|
||
pLastSystem->pSystemNext = pSystem->pSystemNext;
|
||
|
||
SystemFree (pSystem, TRUE);
|
||
|
||
// set pointer back to a valid structure
|
||
pSystem = pLastSystem;
|
||
if (pSystem == NULL)
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
void CreatePerfmonSystemObjects ()
|
||
{
|
||
ColorBtnFace = GetSysColor (COLOR_BTNFACE) ;
|
||
hBrushFace = CreateSolidBrush (ColorBtnFace) ;
|
||
hPenHighlight = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_BTNHIGHLIGHT)) ;
|
||
hPenShadow = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_BTNSHADOW)) ;
|
||
SetClassLongPtr (hWndMain, GCLP_HBRBACKGROUND, (LONG_PTR)hBrushFace);
|
||
}
|
||
|
||
void DeletePerfmonSystemObjects ()
|
||
{
|
||
if (hBrushFace)
|
||
{
|
||
DeleteBrush (hBrushFace) ;
|
||
hBrushFace = 0 ;
|
||
}
|
||
if (hPenHighlight)
|
||
{
|
||
DeletePen (hPenHighlight) ;
|
||
hPenHighlight = 0 ;
|
||
}
|
||
if (hPenShadow)
|
||
{
|
||
DeletePen (hPenShadow) ;
|
||
hPenShadow = 0 ;
|
||
}
|
||
}
|
||
|
||
// This routine count the number of the same charatcer in the input string
|
||
int SameCharCount (LPTSTR pInputString)
|
||
{
|
||
int Count = 0 ;
|
||
TCHAR InputChar = *pInputString ;
|
||
|
||
if (InputChar)
|
||
{
|
||
while (InputChar == *pInputString)
|
||
{
|
||
Count ++ ;
|
||
pInputString ++ ;
|
||
}
|
||
}
|
||
return (Count) ;
|
||
}
|
||
|
||
// create the format to be used in SystemTimeDateString()
|
||
BOOL CreateDateFormat (LPTSTR pShortDate)
|
||
{
|
||
int iIndex ;
|
||
int iDayCount ;
|
||
int iMonthCount ;
|
||
int DateSeparatorCount ;
|
||
TCHAR szDateSeparator [10] ;
|
||
BOOL bFirstLeading, bSecondLeading, bThirdLeading ;
|
||
|
||
// get the date format based on the first char
|
||
if (*pShortDate == TEXT('M') || *pShortDate == TEXT('m'))
|
||
{
|
||
DateStyle = MONTH_FIRST ;
|
||
}
|
||
else if (*pShortDate == TEXT('D') || *pShortDate == TEXT('d'))
|
||
{
|
||
DateStyle = DAY_FIRST ;
|
||
}
|
||
else if (*pShortDate == TEXT('Y') || *pShortDate == TEXT('y'))
|
||
{
|
||
DateStyle = YEAR_FIRST ;
|
||
}
|
||
else
|
||
{
|
||
// bad format
|
||
return FALSE ;
|
||
}
|
||
|
||
bFirstLeading = bSecondLeading = bThirdLeading = FALSE ;
|
||
|
||
switch (DateStyle)
|
||
{
|
||
case YEAR_FIRST:
|
||
// YYYY-MM-DD
|
||
YearCharCount = SameCharCount (pShortDate) ;
|
||
pShortDate += YearCharCount ;
|
||
DateSeparatorCount = SameCharCount (pShortDate) ;
|
||
|
||
// get the separator string
|
||
for (iIndex = 0; iIndex < DateSeparatorCount; iIndex ++)
|
||
{
|
||
szDateSeparator [iIndex] = *pShortDate++ ;
|
||
}
|
||
szDateSeparator [iIndex] = TEXT('\0') ;
|
||
|
||
iMonthCount = SameCharCount (pShortDate) ;
|
||
pShortDate += iMonthCount + DateSeparatorCount ;
|
||
iDayCount = SameCharCount (pShortDate) ;
|
||
|
||
if (YearCharCount == 2)
|
||
{
|
||
bFirstLeading = TRUE ;
|
||
}
|
||
|
||
if (iMonthCount == 2)
|
||
{
|
||
bSecondLeading = TRUE ;
|
||
}
|
||
|
||
if (iDayCount == 2)
|
||
{
|
||
bThirdLeading = TRUE ;
|
||
}
|
||
|
||
break ;
|
||
|
||
case MONTH_FIRST:
|
||
// MM-DD-YYYY
|
||
iMonthCount = SameCharCount (pShortDate) ;
|
||
pShortDate += iMonthCount ;
|
||
DateSeparatorCount = SameCharCount (pShortDate) ;
|
||
|
||
// get the separator string
|
||
for (iIndex = 0; iIndex < DateSeparatorCount; iIndex ++)
|
||
{
|
||
szDateSeparator [iIndex] = *pShortDate++ ;
|
||
}
|
||
szDateSeparator [iIndex] = TEXT('\0') ;
|
||
|
||
iDayCount = SameCharCount (pShortDate) ;
|
||
pShortDate += iMonthCount + DateSeparatorCount ;
|
||
YearCharCount = SameCharCount (pShortDate) ;
|
||
|
||
|
||
if (iMonthCount == 2)
|
||
{
|
||
bFirstLeading = TRUE ;
|
||
}
|
||
|
||
if (iDayCount == 2)
|
||
{
|
||
bSecondLeading = TRUE ;
|
||
}
|
||
|
||
if (YearCharCount == 2)
|
||
{
|
||
bThirdLeading = TRUE ;
|
||
}
|
||
|
||
break ;
|
||
|
||
case DAY_FIRST:
|
||
// DD-MM-YYYY
|
||
iDayCount = SameCharCount (pShortDate) ;
|
||
pShortDate += iDayCount ;
|
||
DateSeparatorCount = SameCharCount (pShortDate) ;
|
||
|
||
// get the separator string
|
||
for (iIndex = 0; iIndex < DateSeparatorCount; iIndex ++)
|
||
{
|
||
szDateSeparator [iIndex] = *pShortDate++ ;
|
||
}
|
||
szDateSeparator [iIndex] = TEXT('\0') ;
|
||
|
||
iMonthCount = SameCharCount (pShortDate) ;
|
||
pShortDate += iMonthCount + DateSeparatorCount ;
|
||
YearCharCount = SameCharCount (pShortDate) ;
|
||
|
||
if (iDayCount == 2)
|
||
{
|
||
bFirstLeading = TRUE ;
|
||
}
|
||
|
||
if (iMonthCount == 2)
|
||
{
|
||
bSecondLeading = TRUE ;
|
||
}
|
||
|
||
if (YearCharCount == 2)
|
||
{
|
||
bThirdLeading = TRUE ;
|
||
}
|
||
|
||
break ;
|
||
}
|
||
|
||
// now generate the date format
|
||
lstrcpy (szDateFormat, bFirstLeading ? LeadingZeroStr : NoLeadingZeroStr) ;
|
||
lstrcat (szDateFormat, szDateSeparator) ;
|
||
lstrcat (szDateFormat, bSecondLeading ? LeadingZeroStr : NoLeadingZeroStr) ;
|
||
lstrcat (szDateFormat, szDateSeparator) ;
|
||
lstrcat (szDateFormat, bThirdLeading ? LeadingZeroStr : NoLeadingZeroStr) ;
|
||
|
||
return TRUE ;
|
||
}
|
||
|
||
BOOL CreateTimeFormat (LPTSTR pTimeSeparator, int iLeadingZero)
|
||
{
|
||
// create the format to be used in SystemTimeTimeString
|
||
if (iLeadingZero)
|
||
{
|
||
lstrcpy (szTimeFormat, LeadingZeroStr) ;
|
||
}
|
||
else
|
||
{
|
||
lstrcpy (szTimeFormat, NoLeadingZeroStr) ;
|
||
}
|
||
|
||
lstrcat (szTimeFormat, pTimeSeparator) ;
|
||
lstrcat (szTimeFormat, LeadingZeroStr) ;
|
||
lstrcat (szTimeFormat, pTimeSeparator) ;
|
||
// lstrcat (szTimeFormat, LeadingZeroStr) ;
|
||
|
||
// Duplicate the format without the msec field (for export use)
|
||
lstrcpy (szTimeFormat1, szTimeFormat) ;
|
||
|
||
// for the msec
|
||
lstrcat (szTimeFormat, TEXT("%02.1f")) ;
|
||
|
||
// for sec without msec
|
||
lstrcat (szTimeFormat1, TEXT("%02d")) ;
|
||
|
||
if (iTime == 0)
|
||
{
|
||
lstrcat (szTimeFormat, TEXT(" %s ")) ;
|
||
lstrcat (szTimeFormat1, TEXT(" %s ")) ;
|
||
}
|
||
|
||
return TRUE ;
|
||
} // CreateTimeFormats
|
||
|
||
BOOL GetInternational()
|
||
{
|
||
TCHAR szShortDate[40] ;
|
||
TCHAR szTime[40] ; // time separator
|
||
DWORD RetCode ;
|
||
int iTLZero = 0 ; // = 0 for no leading zero, <> 0 for leading zero
|
||
CHAR aLanguageStr [2] ;
|
||
LPSTR pRetStr ;
|
||
LPTSTR lpStr ;
|
||
|
||
// read the data from the win.ini (which i smapped to registry)
|
||
RetCode = GetProfileString(szInternational,
|
||
TEXT("sShortDate"), szShortDate, szShortDate, sizeof(szShortDate)/sizeof(TCHAR));
|
||
|
||
if (RetCode)
|
||
{
|
||
RetCode = GetProfileString(szInternational,
|
||
TEXT("sTime"), szTime, szTime, sizeof(szTime)/sizeof(TCHAR));
|
||
}
|
||
|
||
|
||
if (RetCode)
|
||
{
|
||
iTime = GetProfileInt(szInternational, TEXT("iTime"), iTime);
|
||
iTLZero = GetProfileInt(szInternational, TEXT("iTLZero"), iTLZero);
|
||
|
||
GetProfileString(szInternational, TEXT("sDecimal"), szDecimal, szDecimal, sizeof(szDecimal)/sizeof(TCHAR));
|
||
|
||
if (iTime == 0)
|
||
{
|
||
// get the AM PM strings for 12-hour format.
|
||
// These two strings could be NULL.
|
||
sz1159[0] = sz2359[0] = TEXT('\0') ;
|
||
GetProfileString(szInternational,
|
||
TEXT("s1159"), sz1159, sz1159, sizeof(sz1159)/sizeof(TCHAR));
|
||
|
||
GetProfileString(szInternational,
|
||
TEXT("s2359"), sz2359, sz2359, sizeof(sz2359)/sizeof(TCHAR));
|
||
}
|
||
}
|
||
|
||
// create the two formats
|
||
if (RetCode)
|
||
{
|
||
RetCode = (DWORD) CreateDateFormat (szShortDate) ;
|
||
}
|
||
|
||
if (RetCode)
|
||
{
|
||
RetCode = (DWORD) CreateTimeFormat (szTime, iTLZero) ;
|
||
}
|
||
|
||
// use the system default language numeric
|
||
aLanguageStr[0] = '\0' ;
|
||
pRetStr = setlocale(LC_NUMERIC, aLanguageStr);
|
||
|
||
// get current decimal point used by C-runtime
|
||
TSPRINTF (szShortDate, TEXT("%f"), (FLOAT)1.0) ;
|
||
lpStr = szShortDate ;
|
||
|
||
szCurrentDecimal [0] = TEXT('\0') ;
|
||
|
||
while (*lpStr != TEXT('\0'))
|
||
{
|
||
if (*lpStr == TEXT('1'))
|
||
{
|
||
lpStr++ ;
|
||
szCurrentDecimal [0] = *lpStr ;
|
||
break ;
|
||
}
|
||
lpStr++ ;
|
||
}
|
||
|
||
if (szCurrentDecimal[0] == TEXT('\0'))
|
||
{
|
||
szCurrentDecimal [0] = TEXT('.') ;
|
||
}
|
||
|
||
return (RetCode != 0) ;
|
||
} // GetInternational
|
||
|
||
|
||
// this routine is called to get the date/time formats either
|
||
// for the resource or from the registry.
|
||
void GetDateTimeFormats ()
|
||
{
|
||
PALERT pAlert ;
|
||
PLOG pLog ;
|
||
if (!GetInternational())
|
||
{
|
||
// GetInternational failed, then get default formats from resource
|
||
iTime = 0 ;
|
||
DateStyle = MONTH_FIRST ;
|
||
YearCharCount = 4 ;
|
||
StringLoad (IDS_S1159, sz1159) ;
|
||
StringLoad (IDS_S2359, sz2359) ;
|
||
StringLoad (IDS_TIME_FORMAT, szTimeFormat) ;
|
||
StringLoad (IDS_SHORT_DATE_FORMAT, szDateFormat) ;
|
||
}
|
||
WindowInvalidate (PerfmonViewWindow()) ;
|
||
|
||
// reset all the field taht may be affected by the
|
||
// language numberic changes
|
||
|
||
pAlert = AlertData (hWndMain) ;
|
||
pLog = LogData (hWndMain) ;
|
||
|
||
if (pAlert)
|
||
{
|
||
DialogSetInterval (hWndAlert, IDD_ALERTINTERVAL, pAlert->iIntervalMSecs) ;
|
||
}
|
||
|
||
if (pLog)
|
||
{
|
||
DialogSetInterval (hWndLog, IDD_LOGINTERVAL, pLog->iIntervalMSecs) ;
|
||
}
|
||
} // GetDateTimeFormats
|
||
|
||
void ConvertDecimalPoint (LPTSTR lpFloatPointStr)
|
||
{
|
||
if (szCurrentDecimal[0] == szDecimal[0])
|
||
{
|
||
// no need to convert anything
|
||
return ;
|
||
}
|
||
|
||
while (*lpFloatPointStr)
|
||
{
|
||
if (*lpFloatPointStr == szCurrentDecimal[0])
|
||
{
|
||
*lpFloatPointStr = szDecimal[0] ;
|
||
break ;
|
||
}
|
||
++lpFloatPointStr ;
|
||
}
|
||
} // ConvertDecimalPoint
|
||
|
||
void ReconvertDecimalPoint (LPTSTR lpFloatPointStr)
|
||
{
|
||
if (szCurrentDecimal[0] == szDecimal[0])
|
||
{
|
||
// no need to convert anything
|
||
return ;
|
||
}
|
||
|
||
while (*lpFloatPointStr)
|
||
{
|
||
if (*lpFloatPointStr == szDecimal[0])
|
||
{
|
||
*lpFloatPointStr = szCurrentDecimal[0] ;
|
||
break ;
|
||
}
|
||
++lpFloatPointStr ;
|
||
}
|
||
} // ReconvertDecimalPoint
|
||
|
||
|