// ------------------------------------------------------------------------ // T O P O F F I L E // ------------------------------------------------------------------------ // // Filename - vlmeter.cpp // // Description - Vertical Linear Meter using ChartDirector // // Author - Steve Valliere // // Create Date - May 16, 2018 // // Revision History -- (QVCS Keywords) ------------------------------------ // // $Date: Thursday, May 17, 2018 11:47:36 AM $ // // $Revision: 1.1 $ // // $Log: Q:\Source\RMCS\EV11\vlmeter.dqq $ // // Added new linear meter objects // // Revision 1.1 by: seven Rev date: 5/17/2018 1:31:31 PM // work-in-progress checkpoint (program compiles & runs) // // Revision 1.0 by: seven Rev date: 5/16/2018 1:56:04 PM // Initial Revision // // $Endlog$ // // ------------------------------------------------------------------------ #define _INCLUDE_NLS #include #include #include #include #include #include typedef struct EV11LMeterStyle_s { ULONGLONG Horizontal : 1; ULONGLONG LogScale : 1; ULONGLONG HideValue : 1; ULONGLONG HideLabel : 1; ULONGLONG HideUnits : 1; } EV11LMeterStyle; #pragma comment(lib, "chartdir60.lib") // ------------------------------------------------------------------------ /* BOOL tio_SetODRegion( int tly, int tlx, int bry, int brx, TIO_OWNERDRAWFCN fcnOwnerDraw, DWORD dwOwnerData ); BOOL tio_GetODRect ( int row, int col, LPRECT pr ); */ // ------------------------------------------------------------------------ /* Required meter data: log flag scale min value alert limit value high limit value scale max value current value area background color (i.e. condition color) */ extern "C" int ev11_VLMeter( HDC hdc, RECT *rMeter, EV11LMeterStyle style, double rdMin, double rdAlert, double rdHigh, double rdMax, double rdPeakLo, double rdValue, double rdPeakHi, int bgColor, int borderColor, int exteriorColor, char *szLabel ) { double rdPlotMin ; double rdPlotAlert ; double rdPlotHigh ; double rdPlotMax ; double rdPlotValue ; double rdPlotPeakLo; double rdPlotPeakHi; int stepCount; SIZE sMeter; char szValue[64]; // stepColor Scale items: // { rdMin, GREEN, rdAlert, YELLOW, rdHigh, RED, rdMax }, count = 7 // if no ALERT, skip rdAlert, YELLOW members count = 5 // if no HIGH, skip rdHigh, RED members count = 5 // if no ALARMS, { rdMin, GREEN, rdMax } count = 3 double stepColorScale[] = {0, 0, 0, 0, 0, 0, 0}; if( style.LogScale ) { // Convert plot values from log to linear rdPlotMin = round(log10(rdMin )); rdPlotAlert = log10(rdAlert); rdPlotHigh = log10(rdHigh ); rdPlotMax = round(log10(rdMax )); rdPlotValue = log10(rdValue); rdPlotPeakLo = log10(rdPeakLo); rdPlotPeakHi = log10(rdPeakHi); } else { rdPlotMin = rdMin ; rdPlotAlert = rdAlert ; rdPlotHigh = rdHigh ; rdPlotMax = rdMax ; rdPlotValue = rdValue ; rdPlotPeakLo = rdPeakLo; rdPlotPeakHi = rdPeakHi; } if( (rdMin < rdAlert) && (rdAlert < rdHigh) && (rdHigh < rdMax) ) { // All limits present... stepColorScale[0] = rdPlotMin; stepColorScale[1] = 0x00CC00; // green stepColorScale[2] = rdPlotAlert; stepColorScale[3] = 0xCCCC00; // yellow stepColorScale[4] = rdPlotHigh; stepColorScale[5] = 0xCC0000; // red stepColorScale[6] = rdPlotMax; stepCount = 7; } else if( (rdAlert <= rdMin) || (rdHigh <= rdAlert) ) { // no alert if( (rdHigh <= rdMin) || (rdMax <= rdHigh) ) { stepColorScale[0] = rdPlotMin; stepColorScale[1] = 0x00CC00; // green stepColorScale[2] = rdPlotMax; stepCount = 3; } else { stepColorScale[0] = rdPlotMin; stepColorScale[1] = 0x00CC00; // green stepColorScale[2] = rdPlotHigh; stepColorScale[3] = 0xCC0000; // red stepColorScale[4] = rdPlotMax; stepCount = 5; } } else if( (rdHigh <= rdAlert) || (rdMax <= rdHigh) ) { // ho high if( (rdAlert <= rdMin) || (rdMax <= rdAlert) ) { stepColorScale[0] = rdPlotMin; stepColorScale[1] = 0x00CC00; // green stepColorScale[2] = rdPlotMax; stepCount = 3; } else { stepColorScale[0] = rdPlotMin; stepColorScale[1] = 0x00CC00; // green stepColorScale[2] = rdPlotAlert; stepColorScale[3] = 0xCCCC00; // yellow stepColorScale[4] = rdPlotMax; stepCount = 5; } } sMeter.cx = rMeter->right - rMeter->left; sMeter.cy = rMeter->bottom - rMeter->top; // Create a LinearMeter object of size 70 x 260 pixels with a 3-pixel thick rounded frame LinearMeter *m = new LinearMeter(sMeter.cx, sMeter.cy, bgColor, borderColor); m->setRoundedFrame(exteriorColor);//Chart::Transparent); m->setThickFrame(3); #define XC(V) MulDiv((V),sMeter.cx,70) #define YC(V) MulDiv((V),sMeter.cy,260) // Set the scale region top-left corner at (28, 30), with size of 20 x 200 pixels. The scale // labels are located on the left (default - implies vertical meter) m->setMeter(XC(28), YC(30), XC(20), YC(200)); // Set meter scale from 0 - 100, with a tick every unit m->setScale(rdPlotMin, rdPlotMax, 1); //m->setLabelStyle( "arialbd.ttf", 10 ); // Add the step color scale at the default position m->addColorScale(DoubleArray(stepColorScale, stepCount)); if( (rdMin <= rdPeakLo) && (rdPeakLo <= rdMax) ) { // Add a black (0x000000) outline pointer at the specified value m->addPointer(rdPlotPeakLo, Chart::Transparent, 0x000000); } if( (rdMin <= rdPeakHi) && (rdPeakHi <= rdMax) ) { // Add a black (0x000000) outline pointer at the specified value m->addPointer(rdPlotPeakHi, Chart::Transparent, 0x000000); } if( (rdMin <= rdValue) && (rdValue <= rdMax) ) { // Add a blue (0x0000cc) pointer at the specified value m->addPointer(rdPlotValue, 0x0000cc); // Add a text box right aligned to (235, 61). Display the value using white (0xffffff) 8pt Arial // Bold font on a black (0x000000) background with depressed rounded border. sprintf( szValue, "%.2E", rdValue ); } else if( (1.0e-19 <= rdValue) && (rdValue <= 9.99e+19) ) { // Add a text box right aligned to (235, 61). Display the value using white (0xffffff) 8pt Arial // Bold font on a black (0x000000) background with depressed rounded border. sprintf( szValue, "%.2E", rdValue ); } else { strcpy( szValue, "unknown" ); } // Add a title using white (0xffffff) 8pt Arial Bold font with a border color background m->addTitle(szLabel, "arialbd.ttf", 10, 0xffffff)->setBackground(borderColor); // Add a bottom title using white (0xffffff) 8pt Arial Bold font with a border color background // to display the value m->addTitle(Chart::Bottom, szValue, "arialbd.ttf", 10, 0xffffff )->setBackground(borderColor); // Output the chart as BMP MemBlock bmp = m->makeChart( Chart::BMP ); // The BITMAPINFOHEADER is 14 bytes offset from the beginning LPBITMAPINFO header = (LPBITMAPINFO)(bmp.data + 14); // The bitmap data LPBYTE bitData = (LPBYTE)(bmp.data) + ((LPBITMAPFILEHEADER)(bmp.data))->bfOffBits; // Output to screen device context StretchDIBits( hdc, rMeter->left, rMeter->top, header->bmiHeader.biWidth, header->bmiHeader.biHeight, 0, 0, header->bmiHeader.biWidth, header->bmiHeader.biHeight, bitData, header, DIB_RGB_COLORS, SRCCOPY ); //free up resources delete m; return 0; } // ------------------------------------------------------------------------ // E N D O F F I L E // ------------------------------------------------------------------------