/* FUNCTION: PacketizeFile DATE: 12/2/2015 REVISIONS: v2 - updates the "sent message" window by reading the file DESIGNER: Dylan & Thomas & Allen PROGRAMMER: Dylan INTERFACE: DWORD PacketizeFile(HANDLE fileToBeRead) HANDLE fileToBeRead : the file to read in order to create packets RETURNS: the number of bytes read from the file NOTES: It is the caller's responsibility to ensure that the handle refers to a valid file that is opened for reading. */ DWORD PacketizeFile(HANDLE fileToBeRead) { DWORD bytesRead; DWORD totalBytes = GetFileSize(fileToBeRead, NULL); DWORD bytesToRead = (totalBytes > MAX_READ ? MAX_READ : totalBytes); DWORD totalBytesRead = 0; TCHAR readResult[MAX_READ + 1] = { 0 }; ZeroMemory(Result, 8000000); SetFilePointer(fileToBeRead, NULL, NULL, FILE_BEGIN); // as long as the whole file is not read, attempt to read the remaining file while (totalBytesRead < totalBytes) { if (!ReadFile(fileToBeRead, readResult, bytesToRead, &bytesRead, NULL)) { // error check DWORD err = GetLastError(); OutputDebugString("ReadFile failed\n"); if (GetLastError() == ERROR_NOACCESS) OutputDebugString("NO ACCESS"); return bytesRead; } else { // PROCESS FILE strcat_s(Result, readResult); totalBytesRead += bytesRead; } } UpdateWindowFromFile(hSend, fileToBeRead); packetsCreated = CreatePackets(Result, packetBuffer); SetStatistics(); return bytesRead; }
void NowPlayingWidget::SetTrackInfo (const MediaInfo& info) { const bool isNull = info.Title_.isEmpty () && info.Artist_.isEmpty (); Ui_.TrackInfoLayout_->setEnabled (!isNull); Ui_.SimilarView_->setVisible (!isNull); const QString& unknown = isNull ? QString () : tr ("unknown"); auto str = [&unknown] (const QString& str) { return str.isNull () ? unknown : ("<strong>") + str + ("</strong>"); }; Ui_.ArtistName_->setText (str (info.Artist_)); Ui_.AlbumName_->setText (str (info.Album_)); Ui_.TrackName_->setText (str (info.Title_)); const auto& genres = info.Genres_.join (" / "); Ui_.Genres_->setText ("<em>" + genres + "</em>"); SetStatistics (info.LocalPath_); }
CPLErr GS7BGRasterBand::ScanForMinMaxZ() { GS7BGDataset* poGDS = reinterpret_cast<GS7BGDataset*>(poDS); double *pafRowVals = (double *)VSI_MALLOC2_VERBOSE( nRasterXSize, sizeof(double)); if( pafRowVals == NULL ) { return CE_Failure; } double dfNewMinZ = DBL_MAX; double dfNewMaxZ = -DBL_MAX; int nNewMinZRow = 0; int nNewMaxZRow = 0; /* Since we have to scan, lets calc. statistics too */ double dfSum = 0.0; double dfSum2 = 0.0; unsigned long nValuesRead = 0; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { CPLErr eErr = IReadBlock( 0, iRow, pafRowVals ); if( eErr != CE_None ) { VSIFree( pafRowVals ); return CE_Failure; } pafRowMinZ[iRow] = FLT_MAX; pafRowMaxZ[iRow] = -FLT_MAX; for( int iCol=0; iCol<nRasterXSize; iCol++ ) { if( pafRowVals[iCol] == poGDS->dfNoData_Value ) continue; if( pafRowVals[iCol] < pafRowMinZ[iRow] ) pafRowMinZ[iRow] = pafRowVals[iCol]; if( pafRowVals[iCol] > pafRowMinZ[iRow] ) pafRowMaxZ[iRow] = pafRowVals[iCol]; dfSum += pafRowVals[iCol]; dfSum2 += pafRowVals[iCol] * pafRowVals[iCol]; nValuesRead++; } if( pafRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = pafRowMinZ[iRow]; nNewMinZRow = iRow; } if( pafRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = pafRowMaxZ[iRow]; nNewMaxZRow = iRow; } } VSIFree( pafRowVals ); if( nValuesRead == 0 ) { dfMinZ = 0.0; dfMaxZ = 0.0; nMinZRow = 0; nMaxZRow = 0; return CE_None; } dfMinZ = dfNewMinZ; dfMaxZ = dfNewMaxZ; nMinZRow = nNewMinZRow; nMaxZRow = nNewMaxZRow; double dfMean = dfSum / nValuesRead; double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean)); SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev ); return CE_None; }
CPLErr VRTSourcedRasterBand::ComputeStatistics( int bApproxOK, double *pdfMin, double *pdfMax, double *pdfMean, double *pdfStdDev, GDALProgressFunc pfnProgress, void *pProgressData ) { if( nSources != 1 ) return GDALRasterBand::ComputeStatistics( bApproxOK, pdfMin, pdfMax, pdfMean, pdfStdDev, pfnProgress, pProgressData ); if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* If we have overview bands, use them for statistics. */ /* -------------------------------------------------------------------- */ if( bApproxOK && GetOverviewCount() > 0 && !HasArbitraryOverviews() ) { GDALRasterBand *poBand; poBand = GetRasterSampleOverview( GDALSTAT_APPROX_NUMSAMPLES ); if( poBand != this ) return poBand->ComputeStatistics( FALSE, pdfMin, pdfMax, pdfMean, pdfStdDev, pfnProgress, pProgressData ); } /* -------------------------------------------------------------------- */ /* Try with source bands. */ /* -------------------------------------------------------------------- */ if ( bAntiRecursionFlag ) { CPLError( CE_Failure, CPLE_AppDefined, "VRTSourcedRasterBand::ComputeStatistics() called recursively on the same band. " "It looks like the VRT is referencing itself." ); return CE_Failure; } bAntiRecursionFlag = TRUE; double dfMin = 0.0, dfMax = 0.0, dfMean = 0.0, dfStdDev = 0.0; CPLErr eErr = papoSources[0]->ComputeStatistics(GetXSize(), GetYSize(), bApproxOK, &dfMin, &dfMax, &dfMean, &dfStdDev, pfnProgress, pProgressData); if (eErr != CE_None) { eErr = GDALRasterBand::ComputeStatistics(bApproxOK, pdfMin, pdfMax, pdfMean, pdfStdDev, pfnProgress, pProgressData); bAntiRecursionFlag = FALSE; return eErr; } bAntiRecursionFlag = FALSE; SetStatistics( dfMin, dfMax, dfMean, dfStdDev ); /* -------------------------------------------------------------------- */ /* Record results. */ /* -------------------------------------------------------------------- */ if( pdfMin != NULL ) *pdfMin = dfMin; if( pdfMax != NULL ) *pdfMax = dfMax; if( pdfMean != NULL ) *pdfMean = dfMean; if( pdfStdDev != NULL ) *pdfStdDev = dfStdDev; return CE_None; }
/* FUNCTION: CreateUI DATE: 12/2/2015 REVISIONS: v1 DESIGNER: Dylan PROGRAMMER: Dylan INTERFACE: BOOL CreateUI(HINSTANCE hInst) HINSTANCE hInst : instance on to which the UI elements are created RETURNS: TRUE if all the UI elements are created, FALSE otherwise NOTES: It is the caller's responsibility to ensure that this function is called at the appropriate time (i.e. when UI elements can be created). */ BOOL CreateUI(HINSTANCE hInst) { WNDCLASSEX Wcl; enq[0] = ENQ; ack[0] = ACK; if ((hComm = CreateFile(TEXT("COM1"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE) { OutputDebugString("Failed to open COM port\n"); } else { } // create the main window class Wcl.cbSize = sizeof(WNDCLASSEX); Wcl.style = CS_HREDRAW | CS_VREDRAW; Wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION); // large icon Wcl.hIconSm = NULL; // use small version of large icon Wcl.hCursor = LoadCursor(NULL, IDC_ARROW); // cursor style Wcl.lpfnWndProc = WndProc; Wcl.hInstance = hInst; Wcl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //white background Wcl.lpszClassName = Name; Wcl.lpszMenuName = TEXT("ASN4MENU"); // The menu Class Wcl.cbClsExtra = 0; // no extra memory needed Wcl.cbWndExtra = 0; if (!RegisterClassEx(&Wcl)) { OutputDebugString("Failed to register Wcl"); return FALSE; } // show ui hMain = CreateWindow(Name, Name, WS_OVERLAPPEDWINDOW, 10, 10, 800, 600, NULL, NULL, hInst, NULL); if (!(hBtnConnect = CreateWindow("BUTTON", "Send File", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, BTN_XSTART, BTN_YSTART, BTN_WIDTH, BTN_HEIGHT, hMain, (HMENU)ASN_OPN, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hBtnQuit = CreateWindow("BUTTON", "Quit", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, BTN_XSTART, BTN_YSTART + BTN_HEIGHT + BTN_BUFFER, BTN_WIDTH, BTN_HEIGHT, hMain, (HMENU)ASN_QUIT, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hSend = CreateWindow("EDIT", "Sent File", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | ES_MULTILINE, 0, 0, 400, 250, hMain, (HMENU)NULL, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hSendEnq = CreateWindow("BUTTON", "Send ENQ", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, BTN_XSTART, BTN_YSTART + (BTN_HEIGHT + BTN_BUFFER) * 2, BTN_WIDTH, BTN_HEIGHT, hMain, (HMENU)ASN_ENQ, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hReceive = CreateWindow("EDIT", "Received File", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 0, 250, 400, 250, hMain, (HMENU)NULL, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } if (!(hStats = CreateWindow("STATIC", "Statistics", WS_VISIBLE | WS_CHILD | WS_BORDER, BTN_XSTART + BTN_WIDTH + BTN_BUFFER, BTN_YSTART, 200, 200, hMain, (HMENU)NULL, (HINSTANCE)GetWindowLong(hMain, GWL_HINSTANCE), NULL))) { return FALSE; } cc.dwSize = sizeof(COMMCONFIG); cc.wVersion = 0x100; if (!GetCommConfig(hComm, &cc, &cc.dwSize)) { OutputDebugString("Could not get CommConfig\n"); return FALSE; } if ((hThrd = CreateThread(NULL, 0, ReadFromPort, (LPVOID)hComm, 0, &threadId)) == NULL) { //failure OutputDebugString("Failed to start read thread\n"); } else { OutputDebugString("Thread created\n"); } SetStatistics(); return TRUE; }
/* FUNCTION: ReadFromPort DATE: 11/28/2015 REVISIONS: v4 12/2/2015 - wait state added DESIGNER: Allen & Dylan & Thomas PROGRAMMER: Allen & Dylan INTERFACE: static DWORD WINAPI ReadFromPort(LPVOID lpParam) LPVOID lpParam : parameter passed to the thread; intended to be a communications handle RETURNS: 1 NOTES: This function is intended to be called on a separate thread. It has the event driven code to monitor the serial port for INCOMING communications. It will send messages to the main window (via WndProc) for OUTGOING communications. */ static DWORD WINAPI ReadFromPort(LPVOID lpParam) { OVERLAPPED overlapped = { 0 }; HANDLE hnd = 0; BOOL fWaitingOnRead = FALSE; overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); CHAR buffer[PACKETLENGTH] = ""; DWORD dwEvent; SetCommMask(lpParam, EV_RXCHAR); while (true) { switch (state) { // Waiting for ENQ ACKnowledgment case WENQACK: if (!fWaitingOnRead) { if (!WaitCommEvent(lpParam, &dwEvent, &overlapped)) { if (GetLastError() == ERROR_IO_PENDING) { fWaitingOnRead = TRUE; } } } else { if (Wait(overlapped.hEvent, TIMEOUT)) { if (!ReadFile(lpParam, buffer, 1, NULL, &overlapped)) { WaitForSingleObject(overlapped.hEvent, TIMEOUT); }; OutputDebugString("Finished reading in WENQACK\n"); if (buffer[0] == ACK) { SendMessage(hMain, WM_COMMAND, ACK_REC, NULL); } else { OutputDebugString("Was not ACK, was "); OutputDebugString(buffer); OutputDebugString("\n"); state = WAIT; } fWaitingOnRead = FALSE; } else { state = IDLE; } } break; // Waiting for ACKnowledgment for a packet case WACK: if (!fWaitingOnRead) { if (!WaitCommEvent(lpParam, &dwEvent, &overlapped)) { if (GetLastError() == ERROR_IO_PENDING) { fWaitingOnRead = TRUE; } } } else { if (Wait(overlapped.hEvent, TIMEOUT)) { ReadFile(lpParam, &buffer, 1, NULL, &overlapped); if (buffer[0] == ACK) { SendMessage(hMain, WM_COMMAND, ACK_REC, NULL); buffer[0] = 0; } fWaitingOnRead = FALSE; } else { state = WAIT; } } break; // a backoff state, can only become a receiver for some time case WAIT: // default state, can move to sending or receiving case IDLE: if (!fWaitingOnRead) { if ((state == WAIT || state == IDLE) && !WaitCommEvent(lpParam, &dwEvent, &overlapped)) { if (GetLastError() == ERROR_IO_PENDING) { fWaitingOnRead = TRUE; } } } else { if ((state == WAIT || state == IDLE) && Wait(overlapped.hEvent, TIMEOUT)) { ReadFile(lpParam, &buffer, 1, NULL, &overlapped); if (buffer[0] == ENQ) { startWriting(); SendAck(lpParam); finishWriting(); state = RECEIVING; } // this is what you call a hack to get around race conditions else if ((state == WENQACK || state == WACK) && buffer[0] == ACK) { SendMessage(hMain, WM_COMMAND, ACK_REC, NULL); } fWaitingOnRead = FALSE; } else { state = IDLE; } } break; // anticipating a packet case RECEIVING: if (!fWaitingOnRead) { if (!WaitCommEvent(lpParam, &dwEvent, &overlapped)) { if (GetLastError() == ERROR_IO_PENDING) { fWaitingOnRead = TRUE; } } } else { if (Wait(overlapped.hEvent, INFINITE)) { receiveBuffer = ReceivePacket(lpParam, overlapped); if (ErrorCheck(receiveBuffer) || 1) { //DoNonReadingStuff(receiveBuffer); Depacketize(receiveBuffer); startWriting(); SendAck(lpParam); finishWriting(); packetsReceived++; SetStatistics(); // open the file for writing and reading hnd = CreateFile(FileName, FILE_APPEND_DATA | GENERIC_WRITE | GENERIC_READ, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); startWriting(); if (WritePacketToFile(receiveBuffer, hnd)) { UpdateWindowFromFile(hReceive, hnd); } finishWriting(); CloseHandle(hnd); fWaitingOnRead = FALSE; state = IDLE; buffer[0] = 0; free(receiveBuffer); } } else { state = IDLE; } } break; } // if a packet is in the queue and the process is in idle, attempt to send if (state == IDLE && packetBuffer[currentPacket][0] != 0) { SendMessage(hMain, WM_COMMAND, ASN_ENQ, NULL); } } return 1; }
/* FUNCTION: WndProc DATE: 12/2/2015 REVISIONS: v3 - changed all IO operations to overlapped DESIGNER: Dylan & Allen & Thomas PROGRAMMER: Dylan & Allen INTERFACE: LRESULT CALLBACK WndProc (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) HWND hwnd : handle to the the main window UINT Message : message sent from the message loop to the window WPARAM wParam : parameters to the message LPARAM lParam : parameters to the message RETURNS: The default window procedure or 0 NOTES: Handles all button presses from the main window as well as events from the serial port reading thread */ LRESULT CALLBACK WndProc (HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { switch (Message) { case WM_CREATE: break; case WM_COMMAND: switch (LOWORD(wParam)) { case ASN_ENQ: if (state != IDLE && state != WAIT) { OutputDebugString("ENQ but not idling\n"); break; } startWriting(); // send ENQ to the serial port and assume it never fails WriteFile(hComm, enq, 1, NULL, &OVERLAPPED()); state = WENQACK; OutputDebugString("ENQ sent\n"); finishWriting(); break; case ASN_SET: startWriting(); if (!CommConfigDialog(TEXT("com1"), hMain, &cc)) { return FALSE; } else { SetCommConfig(hComm, &cc, cc.dwSize); PurgeComm(hComm, PURGE_RXCLEAR); } finishWriting(); break; case ASN_CON: OpenFileDialog(); break; case ASN_CLR: ClearTextBoxes(); break; case ASN_QUIT: PostQuitMessage(0); break; case ASN_HLP: break; case ASN_OPN: OpenFileDialog(); break; case ACK_REC: if (state != WACK && state != WENQACK) { OutputDebugString("ACK received but not waiting for ACK before sending a packet\n"); break; } if (state == WENQACK) { OutputDebugString("ACK received\n"); acksReceived++; SetStatistics(); if (packetBuffer[currentPacket][0] != 0) { OVERLAPPED overlapped = { 0 }; overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); startWriting(); if (!WriteFile(hComm, packetBuffer[currentPacket++], PACKETLENGTH, NULL, &overlapped)) { WaitForSingleObject(overlapped.hEvent, TIMEOUT); } OutputDebugString("Sent a packet\n"); packetsSent++; SetStatistics(); // ENQ the line to send the next packet // THIS SHOULD BE REPLACED BY THE APPROPRIATE PRIORTIY PROTOCOL /* if (packetBuffer[currentPacket][0] != 0) { WriteFile(hComm, enq, 1, NULL, NULL); } */ finishWriting(); } OutputDebugString("Going to WACK state\n"); state = WACK; break; } if (state == WACK) { OutputDebugString("Packet confirmed received\n"); OutputDebugString("Going to WAIT state\n"); state = WAIT; packsAcked++; acksReceived++; SetStatistics(); } break; } break; // end WM_COMMAND case WM_CHAR: break; case WM_SIZE: break; case WM_DESTROY: // Terminate program PostQuitMessage(0); break; default: return DefWindowProc(hwnd, Message, wParam, lParam); } return 0; }
CPLErr GSAGRasterBand::ScanForMinMaxZ() { double *padfRowValues = (double *)VSIMalloc2( nBlockXSize, sizeof(double) ); if( padfRowValues == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate memory for grid row values.\n" ); return CE_Failure; } double dfNewMinZ = DBL_MAX; double dfNewMaxZ = -DBL_MAX; int nNewMinZRow = 0; int nNewMaxZRow = 0; /* Since we have to scan, lets calc. statistics too */ double dfSum = 0.0; double dfSum2 = 0.0; unsigned long nValuesRead = 0; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { CPLErr eErr = IReadBlock( 0, iRow, padfRowValues ); if( eErr != CE_None ) { VSIFree( padfRowValues ); return eErr; } padfRowMinZ[iRow] = DBL_MAX; padfRowMaxZ[iRow] = -DBL_MAX; for( int iCell=0; iCell<nRasterXSize; iCell++ ) { if( AlmostEqual(padfRowValues[iCell], GSAGDataset::dfNODATA_VALUE) ) continue; if( padfRowValues[iCell] < padfRowMinZ[iRow] ) padfRowMinZ[iRow] = padfRowValues[iCell]; if( padfRowValues[iCell] > padfRowMaxZ[iRow] ) padfRowMaxZ[iRow] = padfRowValues[iCell]; dfSum += padfRowValues[iCell]; dfSum2 += padfRowValues[iCell] * padfRowValues[iCell]; nValuesRead++; } if( padfRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = padfRowMinZ[iRow]; nNewMinZRow = iRow; } if( padfRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = padfRowMaxZ[iRow]; nNewMaxZRow = iRow; } } VSIFree( padfRowValues ); if( nValuesRead == 0 ) { dfMinZ = 0.0; dfMaxZ = 0.0; nMinZRow = 0; nMaxZRow = 0; return CE_None; } dfMinZ = dfNewMinZ; dfMaxZ = dfNewMaxZ; nMinZRow = nNewMinZRow; nMaxZRow = nNewMaxZRow; double dfMean = dfSum / nValuesRead; double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean)); SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev ); return CE_None; }
CPLErr GSBGRasterBand::ScanForMinMaxZ() { float *pafRowVals = (float *)VSIMalloc2( nRasterXSize, 4 ); if( pafRowVals == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate row buffer to scan grid file.\n" ); return CE_Failure; } double dfNewMinZ = DBL_MAX; double dfNewMaxZ = -DBL_MAX; int nNewMinZRow = 0; int nNewMaxZRow = 0; /* Since we have to scan, lets calc. statistics too */ double dfSum = 0.0; double dfSum2 = 0.0; unsigned long nValuesRead = 0; for( int iRow=0; iRow<nRasterYSize; iRow++ ) { CPLErr eErr = IReadBlock( 0, iRow, pafRowVals ); if( eErr != CE_None ) { VSIFree( pafRowVals ); return CE_Failure; } pafRowMinZ[iRow] = FLT_MAX; pafRowMaxZ[iRow] = -FLT_MAX; for( int iCol=0; iCol<nRasterXSize; iCol++ ) { if( pafRowVals[iCol] == GSBGDataset::fNODATA_VALUE ) continue; if( pafRowVals[iCol] < pafRowMinZ[iRow] ) pafRowMinZ[iRow] = pafRowVals[iCol]; if( pafRowVals[iCol] > pafRowMinZ[iRow] ) pafRowMaxZ[iRow] = pafRowVals[iCol]; dfSum += pafRowVals[iCol]; dfSum2 += pafRowVals[iCol] * pafRowVals[iCol]; nValuesRead++; } if( pafRowMinZ[iRow] < dfNewMinZ ) { dfNewMinZ = pafRowMinZ[iRow]; nNewMinZRow = iRow; } if( pafRowMaxZ[iRow] > dfNewMaxZ ) { dfNewMaxZ = pafRowMaxZ[iRow]; nNewMaxZRow = iRow; } } VSIFree( pafRowVals ); if( nValuesRead == 0 ) { dfMinZ = 0.0; dfMaxZ = 0.0; nMinZRow = 0; nMaxZRow = 0; return CE_None; } dfMinZ = dfNewMinZ; dfMaxZ = dfNewMaxZ; nMinZRow = nNewMinZRow; nMaxZRow = nNewMaxZRow; double dfMean = dfSum / nValuesRead; double dfStdDev = sqrt((dfSum2 / nValuesRead) - (dfMean * dfMean)); SetStatistics( dfMinZ, dfMaxZ, dfMean, dfStdDev ); return CE_None; }