File: DIFRKMTY\D_EXTERN.CPP

    1 //##############################################################################
    2 //                                                                            //
    3 // D_EXTERN.CPP                                                               //
    4 //                                                                            //
    5 // Subsystem: Diffraktometrie/ Reflektometrie                                 //
    6 //            DIE MDI-Fensterbasisklasse                                      //
    7 // Benutzung durch andere Subsysteme erforderlich: NEIN                       //
    8 //                                                                            //
    9 //##############################################################################
   10 //! Kommentierung und Aenderungen B. Buss, 2000/2001, HUB IfI
   11 
   12 #include <direct.h>
   13 
   14 #include "internls\evrythng.h" // GermanVersion
   15 #include "winresrc\rc_def.h"   // Ressourcen-IDs
   16 #pragma hdrstop
   17 
   18 #include "difrkmty\d_extern.h" // SCHNITTSTELLE für diese Datei
   19 #include "motrstrg\motrstrg.h" // für Motor-C-Interface
   20 
   21 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
   22 
   23 //! Kurvendatenbasis
   24 __declspec(dllimport) LPDataBase lpDBase;
   25 
   26 //#############################################################################
   27 // globale Typen und Konstanten
   28 //#############################################################################
   29 
   30 //! Anzahl der max. unterschiedlichen Schrittweiten (dyn. Schrittweite)
   31 const int MaxScaleCount= 10;
   32 
   33 const UINT tiles_x_achse= 5; 
   34 const UINT tiles_y_achse= 5; 
   35 
   36 const UINT Mindxpos= 200; 
   37 const UINT Maxdxpos= 700; 
   38 const UINT Mindypos= 200; 
   39 const UINT Maxdypos= 700; 
   40 
   41 const UINT XBNorm= 85; 
   42 const UINT YBNorm= 62; 
   43 
   44 //#############################################################################
   45 // sprachspezifische Konstanten
   46 //#############################################################################
   47 
   48 #ifdef GermanVersion
   49   static const char szMsgLine600[]= "Scanachse ???";
   50   static const char szMsgLine601[]= "ausserhalb des Bereichs";
   51   static const char szMsgLine604[]= "Vergleichs-Scan speichern...";
   52   static const char szMsgLine605[]= "Vergleichs-Scan (*.bk)|*.bk||";
   53   static const char szMsgLine606[]= "[Header]\nVergleichs-Scan \n";
   54   static const char szMsgLine607[]= "Linie von (%.*f, %.*f) bis (%.*f, %.*f)";
   55   static const char szMsgLine608[]= "Theta:%.*f (D:%.3f) Omega:%.*f (D:%.3f) Int.:%.*f Zeile:%d Spalte:%d";
   56   static const char szMsgLine609[]= "X:%.*f Y:%.*f Theta:%.3f Omega:%.3f Int.:%.*f Zeile:%d Spalte:%d";
   57   static const char strMessage14[]= "Datei wurde bereits gespeichert !";
   58 
   59   static const char szIntensLi[]=   "Intensitäten\nlinear skaliert";
   60   static const char szIntensLiEZ[]= "linear skaliert";
   61   static const char szIntensLo[]=   "Intensitäten\nlog10 skaliert";
   62   static const char szIntensLoEZ[]= "log10 skaliert";
63 #else 64 static const char szMsgLine600[]= "Scanaxis ???"; 65 static const char szMsgLine601[]= "out of Range"; 66 static const char szMsgLine604[]= "Save Comparison-Scan..."; 67 static const char szMsgLine605[]= "Comparison-Scan (*.bk)|*.bk||"; 68 static const char szMsgLine606[]= "[Header]\nComparison-Scan \n"; 69 static const char szMsgLine607[]= "Line from (%.*f, %.*f) to (%.*f, %.*f)"; 70 static const char szMsgLine608[]= "Theta:%.*f (D:%.3f) Omega:%.*f (D:%.3f) Int.:%.*f Row:%d Column:%d"; 71 static const char szMsgLine609[]= "X:%.*f Y:%.*f Theta:%.3f Omega:%.3f Int.:%.*f Row:%d Column:%d"; 72 static const char strMessage14[]= "File was already saved !"; 73 74 static const char szIntensLi[]= "Intensities\nlinear scaling"; 75 static const char szIntensLiEZ[]= "linear scaling"; 76 static const char szIntensLo[]= "Intensities\nlog10 scaling"; 77 static const char szIntensLoEZ[]= "log10 scaling";
78 #endif 79 80 //############################################################################## 81 // TPlotWindow 82 //############################################################################## 83 84 //! Konstruktor TPlotWindow 85 TPlotWindow::TPlotWindow(HINSTANCE aInstance) : TFileWindow(aInstance), BSource(0), MainCurve(0), SecondCurve(0), hFont(0), DragDC(0) 86 { 87 m_Dotted= FALSE; 88 m_HasFilter= FALSE; 89 m_FilterStrength= 0.0; 90 bEnablePaint= FALSE; // siehe EnablePaint() und DisablePaint() 91 WindowType= wtUnknown; 92 bMeasurementActive= FALSE; 93 bSecondaryCoor= FALSE; 94 95 //! durch einen Aufruf von set_new_handler(0) wird das traditionelle 96 //! new-Verhalten wiederhergestellt, bei dem keine Exception ausgeloest wird 97 set_new_handler(0); 98 //! xST/yST/zST darin als TScaleType (comhead.h) def. 99 LowerBound= (float)1e-1; //! gibt beim ersten Aufruf MinIntensitaet vor 100 UpperBound= (float)1e5; //! gibt beim ersten Aufruf MaxIntensitaet vor 101 102 eOutputType= otCurve; 103 104 CoorSys.xMin= 0.01; 105 CoorSys.xMax= 100.0; 106 CoorSys.xScal= sLinear; 107 CoorSys.yMax= UpperBound; 108 CoorSys.yMin= LowerBound; 109 CoorSys.yScal= sLogarithmic; 110 CoorSys.zMax= UpperBound; 111 CoorSys.zMin= LowerBound; 112 CoorSys.zScal= sLinear; 113 //! CoorSys wird in AltCoorSys gesichert 114 AltCoorSys= CoorSys; 115 bAltCoorSystem= FALSE; 116 117 bXY_Scaling= FALSE; 118 bButtonDown= FALSE; 119 120 //! Screen - Typ TScreen (m_data.h) 121 Screen.x0= 0; 122 Screen.x1= stdx - 1; 123 Screen.dx= stdx; 124 Screen.y0= 0; 125 Screen.y1= stdy - 1; 126 Screen.dy= stdy; 127 //! SecondCurve - Typ TCurve (m_curve.h) 128 SecondCurve= (TCurve *) new TCurve; 129 130 //! Font - Def. in windows.h 131 LOGFONT lf; 132 // LogFont spezifizieren... 133 memset(&lf, 0, sizeof(LOGFONT)); 134 lf.lfHeight= -13; 135 lf.lfWidth= 0; // wird automatisch entsprechend der Hoehe gesetzt 136 lf.lfWeight= 400; 137 lf.lfUnderline= FALSE; 138 lstrcpy(lf.lfFaceName, "Times New Roman"); 139 //! the CreateFontIndirect function creates a logical font that has 140 //! the characteristics specified in the specified structure 141 hFont= CreateFontIndirect(&lf); 142 143 HCURSOR hOldCursor= SetDefaultCursor( IDC_WAIT ); 144 switch ( eOutputType ) { // notify type TOutputType 145 case otReciprokeLatticeBitmap: 146 case otMatrixBitmap: 147 new TBitmapSource(this); // registriert sich selbst für dieses Fenster 148 BSource->FormatDBaseToBitmapSource(); 149 break; 150 151 default: 152 //! setze neue Koordinatensystembereiche 153 SetRanges(); 154 } 155 SetCursor(hOldCursor); // restore cursor before waiting cursor 156 157 //! setze Bool-Variable bEnablePaint auf TRUE (m_data.h) 158 EnablePaint(); 159 //! noch keine alten Daten geladen... 160 SetLoadFormat(ffUnknown); 161 strcpy(abzisse, szMsgLine600); 162 163 VisualDB.bPsd=FALSE; VisualDB.dThetaWindow= VisualDB.dMoveRelation= VisualDB.dOmegaMin= VisualDB.dOmegaMax= VisualDB.dThetaMinFirst= VisualDB.dThetaMaxFirst= VisualDB.dThetaMinLast= VisualDB.dThetaMaxLast= 0; VisualDB.fAngleRange= VisualDB.fAngleStep= 0; 164 eLoadFormat= ffUnknown; 165 xo= yo= 0; 166 167 // Motorkoordinaten nur bei AreaScan umrechnen 168 m_MotorUnit= utNone; 169 m_DetectorUnit= utNone; 170 171 // ehemalig extern-Verweise aus D_INTERN.CPP 172 tilesx= tiles_x_achse; 173 tilesy= tiles_y_achse; 174 scrolldyposmin= Mindypos; 175 scrolldyposmax= Maxdypos; 176 scrolldxposmin= Mindxpos; 177 scrolldxposmax= Maxdxpos; 178 xBorder= XBNorm; 179 yBorder= YBNorm; 180 RLdx= 400; 181 RLdy= 400; 182 bIncreasePP= FALSE; 183 MinIntensitaet= (float)1e-5; 184 MaxIntensitaet= (float)1e10; 185 mPoint1.x= mPoint1.y= mPoint2.x= mPoint2.y= 0; //! zum Aufzeichnen der Mausbewegungen beim Ziehen einer Linie mit der Maus 186 DataaquisitionActive= false; 187 }; 188 //***************************************************************************** 189 190 //! Destruktor TPlotWindow 191 TPlotWindow::~TPlotWindow() 192 { 193 //! loesche SecondCurve - Typ TCurve (m_curve.h) 194 _FREEOBJ(SecondCurve); 195 _FREEOBJ(BSource); 196 if ( hFont ) { 197 DeleteObject(hFont); 198 hFont= 0; 199 } 200 }; 201 //***************************************************************************** 202 203 BOOL TPlotWindow::New(void) 204 { 205 //! wenn ReciprokeLatticeBitmap oder MatrixBitmap dann generiere 206 //! gleich auch neue BSource - Typ TBitmapSource (m_data.h) 207 if ( eOutputType==otReciprokeLatticeBitmap || eOutputType==otMatrixBitmap ) 208 BSource->New(); 209 210 bMeasurementActive= FALSE; 211 return TFileWindow::New(); 212 } 213 //***************************************************************************** 214 215 //! berechnet neue Groesse fuer Ausgabefenster, wenn mit Mouse geaendert 216 //! keine Groessenanpassung mehr vorgesehen... 217 /* Fehler 12 218 void TPlotWindow::Size(HWND hWnd,WPARAM,LPARAM) 219 //! berechne Groeße des Screens 220 { 221 //! the GetClientRect function retrieves the coordinates 222 //! of a window's client area 223 //! hWnd - handle of window; &WndRect - address of Rect structure for 224 //! client coordinates 225 GetClientRect(hWnd,&WndRect); 226 //! nicht hBitmap (Bitmap-windows.h) und 227 //! ReciprokeLatticeBitmap oder MatrixBitmap 228 if(!::hBitmap && (eOutputType <= MatrixBitmap)) 229 { 230 //! berechne Groeße des Screens und setze Struct-Variablen 231 //! woher kommen ominoese Multiplikatoren fuer dx und dy ??? 232 Screen.dx= (WndRect.right - WndRect.left) - xBorder; 233 Screen.x0= 0; 234 Screen.x1= Screen.dx; 235 Screen.dx*= 0.8; 236 Screen.dy= (WndRect.bottom - WndRect.top) - yBorder; 237 Screen.y0= 0; 238 Screen.y1= Screen.dy; 239 Screen.dy*= 0.9; 240 } 241 }; 242 //******************************************************************************/ 243 244 //! setze neue Koordinatensystembereiche 245 void TPlotWindow::SetRanges() 246 { 247 //! nur RecipokeLatticeBitmap und MatrixBitmap haben x,y,z Koordinatensystem 248 if ( eOutputType==otReciprokeLatticeBitmap || eOutputType==otMatrixBitmap ) 249 { 250 CoorSys.xMin= 0.01; 251 CoorSys.xMax= 100.0; 252 CoorSys.yMin= 0.01; 253 CoorSys.yMax= 100.0; 254 CoorSys.zMax= UpperBound; 255 CoorSys.zMin= LowerBound; 256 } else { 257 /*Kullmann, Reinecker: ATOS-Testfall MS.2 Fehlerbehebung 258 CoorSys.xMin= 0.01; 259 CoorSys.xMax= 100.0;*/ 260 CoorSys.yMax= UpperBound; 261 CoorSys.yMin= LowerBound; 262 } 263 }; 264 //***************************************************************************** 265 266 //! behandelt Kommando: linke Maustaste wurde gedrueckt 267 //! gibt x und y Werte in der untersten Statuszeile aus, wenn linke 268 //! Maustaste kurzzeitig gedrueckt, in einem Koord.system 269 void TPlotWindow::OnLButtonDown(WPARAM, LPARAM lParam) 270 { 271 char buf[MaxString]; 272 int nk1, nk2, nk3; 273 TCoorSystem *pCoorSys; 274 275 LPCurve Scan; 276 LPCurve ScanReport; 277 float x, y, z, offset, temp_xo, ODelta, TDelta; 278 double Omega, Theta; 279 int row, column; 280 281 bButtonDown= TRUE; 282 //! the GetDC function retrieves a handle of a display device context (DC) 283 //! for the client area of the specified window 284 //! DragDC - Typ HDC (m_data.h) - Handle auf ein DC (dc.h) 285 DragDC= GetDC( GetHandle() ); 286 //! setzt den Mausfang auf das aktuelle Fenster 287 SetCapture(GetHandle()); 288 switch (eOutputType) 289 { 290 case otReciprokeLatticeBitmap: 291 case otMatrixBitmap: 292 pCoorSys= &AltCoorSys; 293 break; 294 295 default: 296 pCoorSys= &CoorSys; 297 } 298 299 /*//! switch Anweisung folgt dem, wohin, mit der Maus geklickt wurde 300 int xi, yi; 301 //! bzw welche Optionen an waren... 302 switch (eOutputType) 303 { 304 case otReciprokeLatticeBitmap: 305 case otMatrixBitmap: 306 xi= LOWORD(lParam) - xBorder; 307 break; 308 309 default: 310 xi= LOWORD(lParam) - xBorder; 311 } 312 xo= ((float)xi * pCoorSys->xSF) + pCoorSys->xMin; 313 314 315 switch (eOutputType) 316 { 317 case otReciprokeLatticeBitmap: 318 case otMatrixBitmap: 319 yi= Screen.y1 - HIWORD(lParam) - yBorder; 320 break; 321 322 default: 323 yi= Screen.y1 - HIWORD(lParam); 324 } 325 switch (pCoorSys->yScal) 326 { 327 case sLogarithmic: 328 y= yi * pCoorSys->ySF; 329 if (y > 7.0) 330 y= yi * log10(pCoorSys->yMax / pCoorSys->yMin) / Screen.dx; 331 yo= pow((float)10, y) * pCoorSys->yMin; 332 break; 333 334 case sLinear: 335 yo= (yi * pCoorSys->ySF) + pCoorSys->yMin; 336 break; 337 }*/ 338 float valueZ= 0; 339 Screen2Title(LOWORD(lParam) - xBorder, (eOutputType==otCurve) ? (Screen.y1 - HIWORD(lParam)) : (Screen.y1 - HIWORD(lParam) - yBorder), 340 xo, yo, valueZ, false); 341 342 ScanReport= lpDBase->GetScanReport(); 343 344 345 //! ThetaOffset muss in Koordinatenausgabe beruecksichtigt werden 346 if ( eOutputType==otMatrixBitmap ) 347 { 348 row= ScanReport->GetValueByValue(yo, x, y); 349 offset= GetThetaOffset(row) - VisualDB.dThetaMinFirst; 350 temp_xo= xo; 351 352 if (VisualDB.bPsd) 353 { 354 xo= xo - pCoorSys->xMin; 355 xo= xo - offset; 356 } 357 } 358 else 359 temp_xo= xo; 360 361 mPoint1.x= temp_xo; 362 mPoint1.y= yo; 363 364 //! zeige X,Y,Intensitaet,Row,Column in Statuszeile 365 //! - wenn in Koordinatensystem geklickt 366 float xMin= pCoorSys->xMin; 367 float xMax= pCoorSys->xMax; 368 if ( eOutputType!=otMatrixBitmap && !bSecondaryCoor ) { //! im Falle von Winkelbeschriftung 369 xMin= CalcValueInUnit( m_DetectorUnit, CalcValueFromUnit(m_MotorUnit, xMin) ); 370 xMax= CalcValueInUnit( m_DetectorUnit, CalcValueFromUnit(m_MotorUnit, xMax) ); 371 } 372 if ( yo>=pCoorSys->yMin && yo<=pCoorSys->yMax && 373 temp_xo>=xMin && temp_xo<=xMax ) 374 { 375 switch (eOutputType) 376 { 377 case otReciprokeLatticeBitmap: //! Zeile und Spalte im Bitmap berechnen 378 row= (yo - pCoorSys->yMin) / pCoorSys->ySF; 379 column= (xo - pCoorSys->xMin) / pCoorSys->xSF; 380 //! Omega und Theta aus dem "Daten"Feld holen 381 if ( BSource->IsDatenInited() ) 382 { 383 Omega= BSource->GetOmega(row, column); 384 Theta= BSource->GetTheta(row, column); 385 } else { 386 Omega= 0; 387 Theta= 0; 388 } 389 390 //! nur die Vorinitialisierung des "Daten"feldes abfangen 391 if ( (Omega && Theta) != row*row - column*column ) 392 { 393 //! Zeile und Spalte in der Areascan-Datenbasis holen und Pointer darauf setzen 394 row= ScanReport->GetValueByValue(Omega, x, y); 395 Scan= lpDBase->GetCurve(row); 396 //** pick out the intensity 397 column= Scan->GetValueByValue(Theta, x, y); 398 Scan->SetPP(column); 399 //! Intensitaet holen 400 Scan->PGet(x, y, z); //07.05.2004 FastP... 401 //! zur Ausgabe in der Statuszeile Thetaoffset aufaddieren 402 //! diese Unterscheidung, da 0-dim. andere Datenbasisspeicherung als 403 //! 1-dim Areascans (ThetaOffset mitgespeichert/nichtgespeichert) 404 if (VisualDB.bPsd) 405 Theta= Theta + GetThetaOffset(row); 406 } else Omega= Theta= row= column= 0; 407 break; 408 409 case otMatrixBitmap: 410 Omega= yo; 411 Theta= xo; 412 //! Zeile und Spalte in der Areascan-Datenbasis holen und Pointer darauf setzen 413 row= ScanReport->GetValueByValue(Omega, ODelta, y); 414 Scan= lpDBase->GetCurve(row); 415 //** pick out the intensity 416 column= Scan->GetValueByValue(Theta, TDelta, y); 417 Scan->SetPP(column); 418 //! Intensitaet holen 419 Scan->PGet(x, y, z); //07.05.2004 FastP... 420 xo= temp_xo; 421 break; 422 } 423 //! hier Unterscheidung nach benoetigter Genauigkeit eingebaut - Fehler 6 424 nk1= GetNachkommaStelle(pCoorSys, 1, 0); 425 nk2= GetNachkommaStelle(pCoorSys, 0, 1); 426 if (y >= 1000) 427 nk3= 0; 428 else if (y >= 100) 429 nk3= 1; 430 else if (y >= 10) 431 nk3= 2; 432 else 433 nk3= 3; 434 435 //! Standardausgabe 436 sprintf(buf, "X: %.*f Y: %.*f", nk1, temp_xo, nk2, yo); 437 if (row && column) switch (eOutputType) 438 { 439 case otReciprokeLatticeBitmap: 440 sprintf(buf, szMsgLine609, 441 nk1, xo, nk2, yo, Theta, Omega, nk3, y, row, column); 442 break; 443 444 case otMatrixBitmap: 445 sprintf(buf, szMsgLine608, 446 nk1, xo, TDelta, nk2, yo, ODelta, nk3, y, row, column); 447 break; 448 } 449 //! buf in Statuszeile anzeigen 450 SetInfo(buf); 451 } else SetInfo(szMsgLine601); 452 }; 453 //***************************************************************************** 454 455 void TPlotWindow::OnMouseMove(WPARAM, LPARAM lParam) 456 //! diese Fkt. gibt in der Statuszeile dx und dy Werte aus 457 //! wenn mit gedrueckter linker Maustaste ueber ein Koord.system gefahren wird 458 { 459 char buf[MaxString]; 460 int xi, yi, temp1, temp2; 461 float x, y; 462 TCoorSystem *pCoorSys; 463 464 //! wenn Button nicht gedrueckt gehe zurueck... 465 if ( !bButtonDown ) 466 return; 467 468 switch (eOutputType) 469 { 470 case otReciprokeLatticeBitmap: 471 case otMatrixBitmap: 472 xi= LOWORD(lParam) - xBorder; 473 yi= Screen.y1 - HIWORD(lParam) - yBorder; 474 pCoorSys= &AltCoorSys; 475 break; 476 477 default: 478 xi= LOWORD(lParam) - xBorder; 479 yi= Screen.y1 - HIWORD(lParam); 480 pCoorSys= &CoorSys; 481 } 482 //! Abzisse immer linear skaliert 483 x= (xi * pCoorSys->xSF) + pCoorSys->xMin; 484 //! Ordinate linear oder log skaliert 485 switch (pCoorSys->yScal) 486 { 487 case sLogarithmic: 488 y= yi * pCoorSys->ySF; 489 if (y > 7.0) 490 y= yi * log10(pCoorSys->yMax / pCoorSys->yMin) / Screen.dx; 491 y= pow((float)10, y) * pCoorSys->yMin; 492 break; 493 494 case sLinear: 495 y= (yi * pCoorSys->ySF) + pCoorSys->yMin; 496 break; 497 498 default: 499 y=0; 500 } 501 //! zeige dX,dY in Statuszeile - wenn in Koordinatensystem geklickt 502 if ( mPoint1.y <= pCoorSys->yMax && mPoint1.y >= pCoorSys->yMin && 503 mPoint1.x <= pCoorSys->xMax && mPoint1.x >= pCoorSys->xMin && 504 y <= pCoorSys->yMax && y >= pCoorSys->yMin && 505 x <= pCoorSys->xMax && x >= pCoorSys->xMin) 506 { 507 //! hier Unterscheidung nach benoetigter Genauigkeit eingebaut - Fehler 6 508 temp1= GetNachkommaStelle(pCoorSys, 1, 0); 509 temp2= GetNachkommaStelle(pCoorSys, 0, 1); 510 if ( DataaquisitionActive ) { //! wenn DataAquisition aktiv 511 mPoint2.x= x; 512 mPoint2.y= y; 513 sprintf(buf, szMsgLine607, 514 temp1, mPoint1.x, temp2, mPoint1.y, 515 temp1, mPoint2.x, temp2, mPoint2.y); 516 } else sprintf(buf, "dX= %.*f dY= %.*f", temp1, x - xo, temp2, y - yo); 517 //! in Statuszeile ausgeben 518 SetInfo(buf); 519 } 520 else 521 SetInfo(szMsgLine601); 522 }; 523 //***************************************************************************** 524 525 void TPlotWindow::OnLButtonUp(WPARAM, LPARAM) 526 //! nur dazu da, um das Loslassen der linken Maustaste zu registrieren 527 { 528 bButtonDown= FALSE; 529 if ( DragDC ) { 530 ReleaseDC(GetHandle(), DragDC); 531 ReleaseCapture(); 532 DragDC= 0; 533 } 534 }; 535 //***************************************************************************** 536 537 //! fuelle TKSystem mit Standardwerten 538 BOOL TPlotWindow::SetMeasurementArea(TKSystem &ks) 539 { 540 ks[0].x= 1.0; 541 ks[0].y= 1.0; 542 ks[0].Ord= 0; 543 544 ks[1].x= 10.0; 545 ks[1].y= 1.0; 546 ks[1].Ord= 1; 547 548 ks[2].x= 10.0; 549 ks[2].y= 10.0; 550 ks[2].Ord= 2; 551 552 ks[3].x= 1.0; 553 ks[3].y= 10.0; 554 ks[3].Ord= 3; 555 return TRUE; 556 }; 557 //***************************************************************************** 558 559 void TPlotWindow::OnRenderFormat(WPARAM wParam, LPARAM) 560 //! the WM_RENDERFORMAT message is sent to the clipboard owner 561 //! when a particular format with delayed rendering needs to be rendered 562 //! HANDLE SetClipboardData(uint format, HANDLE handle); 563 //! bei erfolgreicher Ausfuehrung ist der Rueckgabewert ein Handle auf die Daten 564 { 565 HANDLE hClip; 566 567 if (eOutputType==otCurve) 568 return; 569 switch (wParam) 570 { 571 case CF_BITMAP: 572 hClip= (HANDLE)BSource->CreateGDIObject(GetDC(GetHandle())); 573 SetClipboardData(CF_BITMAP, hClip); 574 break; 575 576 case CF_PALETTE: 577 hClip= (HANDLE)CreatePalette(BSource->GetPalette()); 578 SetClipboardData(CF_PALETTE, hClip); 579 break; 580 581 case CF_DIB: 582 hClip= BSource->RenderDIB(); 583 SetClipboardData(CF_DIB, hClip); 584 break; 585 } 586 }; 587 //***************************************************************************** 588 589 void TPlotWindow::OnRenderAllFormats(WPARAM, LPARAM) 590 //! the WM_RENDERALLFORMATS message is sent to the clipboard owner 591 //! when the owner application is being destroyed 592 { 593 UINT uFormat= 0; 594 595 OpenClipboard(GetHandle()); 596 // hier stand ein =, was soll das? 597 while (NULL != (uFormat= EnumClipboardFormats(uFormat))) 598 SendMessage(GetHandle(), WM_RENDERFORMAT, uFormat, 0L); 599 CloseClipboard(); 600 }; 601 //***************************************************************************** 602 603 void TPlotWindow::DoCopy(void) 604 //! Kopieren mit Hilfe der Zwischeablage - Typen: CF_DIB, CF_PALETTE 605 606 { 607 //! OpenClipboard(hWnd) - oeffnet die Zwischenablage und hindert 608 //! andere Anwendungen daran, den Inhalt der Zwischenablage zu veraendern 609 //! (Ausgabetyp ist nicht Matrix- oder RL Bitmap) oder Zwischenablage 610 //! geht nicht auf ---> denn zurueck... 611 if ( (eOutputType==otCurve) || !OpenClipboard(GetHandle()) ) 612 return; 613 614 //! EmptyClipBoard() - Leert die Zwischenablage 615 //! und gibt alle Handles auf die Daten der Zwischenablage frei 616 EmptyClipboard(); 617 618 //! SetClipBoardData(...) - setzt ein Handle auf den Datenblock 619 //! an der durch handle angezeigten Position 620 SetClipboardData(CF_DIB, NULL); 621 SetClipboardData(CF_PALETTE, NULL); 622 623 //! schließt die Zwischenablage 624 CloseClipboard(); 625 }; 626 //***************************************************************************** 627 628 void TPlotWindow::Screen2Title(float aScreenX, float aScreenY, float &resultX, float &resultY, float &resultZ, bool aChannel5Steps) { 629 TCoorSystem *pCoorSys; 630 switch (eOutputType) 631 { 632 case otReciprokeLatticeBitmap: 633 case otMatrixBitmap: 634 pCoorSys= &AltCoorSys; 635 break; 636 637 default: 638 pCoorSys= &CoorSys; 639 } 640 641 // x-Achse 642 if ( eOutputType==otMatrixBitmap && bSecondaryCoor ) { // MatrixBitmap und Winkeldarstellung 643 float xMin= MainCurve->GetMin( P_Z ); 644 float xMax= (MainCurve->GetMax( P_Z ) * pCoorSys->xMax) / (MainCurve->GetMax( P_X ) + GetThetaOffset(0)); 645 float xSF= (xMax - xMin) / Screen.dx; 646 resultX= xMin + aScreenX*xSF; 647 } else { 648 resultX= pCoorSys->xMin + aScreenX * pCoorSys->xSF; 649 if ( bSecondaryCoor ) { //! im Falle von Kanalbeschriftung 650 if ( aChannel5Steps ) { // sonst treten an x-Achse zwei identische Beschriftungen auf 651 // in 5er Schritten runden 652 long chann= long(resultX); 653 if ( chann % 5 == 0 ) /*perfekt*/; 654 else if ( (chann-1) % 5 == 0 ) chann-= 1; // na gut, Verschiebung um -1 655 else if ( (chann+1) % 5 == 0 ) chann+= 1; // na gut, Verschiebung um +1 656 else if ( (chann-2) % 5 == 0 ) chann-= 2; // na gut, Verschiebung um -2 657 else if ( (chann+2) % 5 == 0 ) chann+= 2; // na gut, Verschiebung um +2 658 resultX= chann; 659 } 660 } else if ( m_DetectorUnit!=utNone && m_MotorUnit!=utNone ) resultX= CalcValueInUnit( m_DetectorUnit, CalcValueFromUnit(m_MotorUnit, resultX) ); //! im Falle von Winkelbeschriftung 661 } 662 663 // y-Achse 664 switch (pCoorSys->yScal) 665 { 666 case sLinear: 667 resultY= pCoorSys->yMin + aScreenY*pCoorSys->ySF; 668 break; 669 670 default: 671 resultY= pCoorSys->yMin * pow((double)10, (double)(aScreenY)*pCoorSys->ySF); 672 } 673 674 // x-Achse (zweizeilige Beschriftung; nur DTN-File) 675 if (eLoadFormat == ffDtnFile) resultZ= pCoorSys->zMin + aScreenX*pCoorSys->zSF; 676 else resultZ= 0; 677 } 678 679 void TPlotWindow::GetTitleX(int i, int titlesx, char *buf, bool reduceLines) { 680 TCoorSystem *pCoorSys; 681 switch (eOutputType) 682 { 683 case otReciprokeLatticeBitmap: 684 case otMatrixBitmap: 685 pCoorSys= &AltCoorSys; 686 break; 687 688 default: 689 pCoorSys= &CoorSys; 690 } 691 692 // an der Achse darzustellende(r) Zahlenwert(e) 693 float valueX, valueY, valueZ; 694 float x= float(i) / float(tilesx)*Screen.dx; 695 Screen2Title(x, 0/*y-Achse nicht berechnen*/, 696 valueX, valueY, valueZ, fabs(pCoorSys->xMax-pCoorSys->xMin) >= tilesx*5); 697 if ( eOutputType==otMatrixBitmap && bSecondaryCoor ) Double2String(buf, valueX, 0, TRUE, _DECIMAL, _THOUSAND); // MatrixBitmap und Winkeldarstellung 698 else if ( bSecondaryCoor ) Double2String(buf, valueX, 0, TRUE, _DECIMAL, _THOUSAND); //! im Falle von Kanalbeschriftung 699 else Double2String(buf, valueX, GetNachkommaStelle(pCoorSys, 1, 0), TRUE, _DECIMAL, _THOUSAND); // sprintf(buf, "%.*f", GetNachkommaStelle(pCoorSys, 1, 0), fval); //! im Falle von Winkelbeschriftung 700 701 // dtn-Abszissenbeschr. (zweizeilige Zahlenwerte) 702 if (eLoadFormat == ffDtnFile) { 703 char buf2[MaxString]; 704 Double2String(buf2, valueZ, GetNachkommaStelle(pCoorSys, 1, 0), TRUE, _DECIMAL, _THOUSAND); // sprintf(buf, "%.*f", GetNachkommaStelle(pCoorSys, 1, 0), fval); 705 strcat(buf, "\n"); 706 strcat(buf, buf2); 707 } 708 } 709 710 void TPlotWindow::GetTitleY(int i, int titlesy, char *buf, bool reduceLines) { 711 TCoorSystem *pCoorSys; 712 switch (eOutputType) 713 { 714 case otReciprokeLatticeBitmap: 715 case otMatrixBitmap: 716 pCoorSys= &AltCoorSys; 717 break; 718 719 default: 720 pCoorSys= &CoorSys; 721 } 722 723 // an der Achse darzustellende(r) Zahlenwert(e) 724 float valueX= 0, valueY= 0, valueZ= 0; 725 float y= float(i) / float(titlesy)*Screen.dy; 726 Screen2Title(0/*x-Achse nicht berechnen*/, y, 727 valueX, valueY, valueZ, false); 728 if ( valueY==0 ) 729 Double2String(buf, 0, 2, TRUE, _DECIMAL, _THOUSAND); // sprintf(buf, "0.00"); 730 else 731 Double2String(buf, valueY, GetNachkommaStelle(pCoorSys, 0, 1), TRUE, _DECIMAL, _THOUSAND); // sprintf(buf, "%.*f", GetNachkommaStelle(pCoorSys, 0, 1), fval); 732 733 // letzte Beschriftung = Beschriftung der Ordinaten-Achse mit Skalierungstyp 734 if ( i==tilesy ) 735 if ( eOutputType==otCurve ) { 736 if ( reduceLines ) { 737 if ( pCoorSys->yScal==sLinear ) sprintf(buf, szIntensLiEZ); 738 else if ( pCoorSys->yScal==sLogarithmic ) sprintf(buf, szIntensLoEZ); 739 } else { 740 if ( pCoorSys->yScal==sLinear ) sprintf(buf, szIntensLi); 741 else if ( pCoorSys->yScal==sLogarithmic ) sprintf(buf, szIntensLo); 742 } 743 } 744 } 745 746 BOOL TPlotWindow::GetTextExtentPointEx(HDC hdc, LPCTSTR lpString, int cbString, LPSIZE lpSize) 747 { 748 BOOL result= TRUE; // falls Leerstring 749 lpSize->cx= 0; 750 lpSize->cy= 0; 751 SIZE tagS; 752 GetTextExtentPoint(hdc, "Qq", strlen("Qq"), &tagS); 753 754 char *buf= new char[ strlen(lpString)+1 ]; 755 strcpy(buf, lpString); 756 757 char *actual= strtok( buf, "\n\r" ); // erste "Zeile" auslesen 758 while ( actual ) { // ausgeben der "Zeilen" 759 SIZE tagT; 760 if ( !GetTextExtentPoint(hdc, actual, strlen(actual), &tagT) ) result= FALSE; 761 lpSize->cx= max(lpSize->cx, tagT.cx); 762 lpSize->cy+= tagS.cy; 763 actual= strtok( NULL, "\n\r" ); // nächste "Zeile" 764 } 765 766 _FREELIST(buf); 767 return result; 768 }; 769 770 771 void TPlotWindow::TextOutEx(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString, EHAlign hAlign, EVAlign vAlign) 772 { 773 char *buf= new char[ strlen(lpString)+1 ]; 774 strcpy(buf, lpString); 775 SIZE tagO; 776 GetViewportExtEx(hdc, &tagO); 777 bool bTopDown= tagO.cy>=0; // bei Sichtweise von oben nach unten: Koordinaten werden größer 778 bool bLeftRight= tagO.cx>=0; // bei Sichtweise von links nach rechts: Koordinaten werden größer 779 SIZE tagS; 780 GetTextExtentPoint(hdc, "Qq", strlen("Qq"), &tagS); 781 SIZE tagG; 782 GetTextExtentPointEx(hdc, lpString, strlen(lpString), &tagG); 783 784 int y= nYStart; 785 if ( vAlign==vaCenter ) { 786 if ( bTopDown ) y= nYStart - tagG.cy/2; 787 else y= nYStart + tagG.cy/2; 788 } else if ( vAlign==vaBottom ) { 789 if ( bTopDown ) y= nYStart - tagG.cy; 790 else y= nYStart + tagG.cy; 791 } 792 char *actual= strtok( buf, "\n\r" ); // erste "Zeile" auslesen 793 while ( actual ) { // ausgeben der "Zeilen" 794 SIZE tagT; 795 GetTextExtentPoint(hdc, actual, strlen(actual), &tagT); 796 int x= nXStart; 797 if ( hAlign==haCenter ) { 798 if ( bLeftRight ) x= nXStart - tagT.cx/2; 799 else x= nXStart + tagT.cx/2; 800 } else if ( hAlign==haRight ) { 801 if ( bLeftRight ) x= nXStart - tagT.cx; 802 else x= nXStart + tagT.cx; 803 } 804 TextOut(hdc, x, y, actual, strlen(actual)); 805 806 if ( bTopDown ) y+= tagS.cy; 807 else y-= tagS.cy; 808 actual= strtok( NULL, "\n\r" ); // nächste "Zeile" 809 } 810 811 _FREELIST(buf); 812 } 813 814 void TPlotWindow::DrawCoordinateSystem(HDC hdc) 815 //! zeichnet Koord.System - oder was soll der Name sonst :-) 816 { 817 //! der Datentyp, der das Handle auf eine physikalische Schrift repraesentiert 818 HFONT hOldFont; 819 //! der Windows-Datentyp, der Handles fuer logische Stifte repraesentiert 820 HPEN hOldPen, hPenDot, hPenBlack; 821 //! the SIZE structure specifies the width and height of a rectangle 822 SIZE tagS; 823 //! the POINT structure defines the x- and y- coordinates of a point 824 POINT egde[5]; 825 char buf[MaxString]; 826 float dist, offset; 827 int i; 828 829 CoorSys.xSF= (CoorSys.xMax - CoorSys.xMin) / Screen.dx; 830 CoorSys.ySF= (CoorSys.yMax - CoorSys.yMin) / Screen.dy; 831 832 // inquire scaling parameters 833 CoorSys.xSF= (CoorSys.xMax - CoorSys.xMin) / Screen.dx; 834 if ( eOutputType!=otCurve || CoorSys.yScal==sLinear ) CoorSys.ySF= (CoorSys.yMax - CoorSys.yMin) / Screen.dy; // Bitmaps sind nur linear skaliert 835 else CoorSys.ySF= log10(CoorSys.yMax / CoorSys.yMin) / Screen.dy; 836 837 hPenBlack= CreatePen(PS_SOLID, 2, RGB(0, 0, 0)); 838 hPenDot= CreatePen(PS_DOT, 1, RGB(0, 0, 0)); 839 hOldFont= (HFONT)SelectObject(hdc, hFont); 840 hOldPen= (HPEN)SelectObject(hdc, hPenBlack); 841 842 // wie viele Zeilen benötigt die höchste x-Achsenbeschriftung; ausführliche Beschreibung zulassen? 843 GetTextExtentPoint(hdc, "Qq", strlen("Qq"), &tagS); 844 int rowHeight= tagS.cy; 845 int rows= 1; // Beschriftung muss in so vielen Zeilen angezeigt werden, damit es keine Überschneidungen gibt 846 int heightY= 0; // so hoch sind die Beschriftungen insgesamt für das aktuelle <rows> 847 for (int reduceLinesX= 0; reduceLinesX<2; reduceLinesX++) { 848 int rowStep= 1; // wie viele Zeilen belegt die höchste Bezeichnung 849 for (i= 0; i<=tilesx; i++) { 850 GetTitleX(i, tilesx, buf, reduceLinesX!=0); 851 GetTextExtentPointEx(hdc, buf, strlen(buf), &tagS); 852 rowStep= max(rowStep, min((yBorder-2)/rowHeight, tagS.cy/rowHeight) ); // die Beschriftung darf nicht mehr als den verfügbaren Platz ver(sch)wenden 853 } 854 855 // In wie vielen Ebenen muss die X-Achse beschriftet werden, damit sich die Beschriftungen nicht überschneiden? 856 rows= 1; 857 bool ueberschneid, lastLoop= false; 858 do { 859 ueberschneid= false; 860 heightY= 0; 861 int platz= float(Screen.dx) / float(tilesx) * float(rows); // max. Pixelanzahl zwischen zwei Beschriftungen auf gleicher Ebene (wird diese Anzahl überschritten, kommt es zu Überschneidungen) 862 for (int row=0; row<rows; row++) { // jede Zeile auf Überschneidungen prüfen 863 int dy= 0; 864 int lastWid= 0; 865 for (i= 0; i<=tilesx; i++) { 866 if ( (i%rows)!=row ) continue; 867 868 // diese Beschriftung kommt in Zeile <row> 869 GetTitleX(i, tilesx, buf, reduceLinesX!=0); 870 GetTextExtentPointEx(hdc, buf, strlen(buf), &tagS); 871 int thisWid= tagS.cx; 872 if ( i!=tilesx ) thisWid/= 2; // bis auf den letzten Abschnitt (rechtsbündig) ist alles zentriert; belegt nur die halbe Breite 873 if ( lastWid+thisWid > platz-max(5, float(platz)*0.02) ) ueberschneid= true; 874 lastWid= thisWid; 875 dy= max(dy, tagS.cy); 876 } 877 heightY+= dy; 878 } 879 if ( lastLoop ) break; 880 if ( ueberschneid ) { 881 rows+= 1; 882 if ( heightY > yBorder-max(5, float(yBorder)*0.02) ) { // reicht der Platz zwischen x-Achse und sichtbarem Bereich? 883 rows= max(1, rows-1); 884 lastLoop= true; // Schleife mit neuem <rows> wiederholen und <heightX> berechnen; dann soft beenden 885 } 886 } 887 } while ( ueberschneid ); 888 if ( !ueberschneid ) break; // reduceLinesX muss nicht eingeschaltet werden 889 } 890 891 // ermitteln, ob y-Achsenbeschriftung ausführlich oder einzeilig 892 bool reduceLinesY= false; 893 int platz= float(Screen.dy-Screen.y0)/tilesy; 894 int lastHei= 0; 895 for (i= 0;i <= tilesy; i++) { 896 GetTitleY(i, tilesy, buf, false); 897 GetTextExtentPointEx(hdc, buf, strlen(buf), &tagS); 898 int thisHei= tagS.cy; 899 if ( i!=tilesy ) thisHei/= 2; // bis auf letzten Abschnitt (oben) alles mittig ausgerichtet 900 if ( lastHei+thisHei > platz-max(5, platz*0.02) ) { // ausführliche Beschreibung ist zu hoch 901 reduceLinesY= true; 902 break; 903 } 904 lastHei= thisHei; 905 } 906 907 // Rahmen zeichnen 908 egde[0].x= egde[3].x= Screen.x0; 909 egde[1].x= egde[2].x= Screen.x0 + Screen.dx; 910 egde[0].y= egde[1].y= Screen.y0; 911 egde[2].y= egde[3].y= Screen.y0 + Screen.dy; 912 egde[4]= egde[0]; 913 Polyline(hdc, egde, 5); 914 915 //************ Absizze (x) ************************************************* 916 SelectObject(hdc, hPenBlack); 917 SelectObject(hdc, hPenDot); 918 919 TCoorSystem *pCoorSys; 920 switch (eOutputType) 921 { 922 case otReciprokeLatticeBitmap: 923 case otMatrixBitmap: 924 pCoorSys= &AltCoorSys; 925 break; 926 927 default: 928 pCoorSys= &CoorSys; 929 } 930 931 //! dient zur Unterscheidung, um ThetaOffset in RawMatrix bei 932 //! Winkeldarstellung zu beruecksichtigen 933 if ( eOutputType==otMatrixBitmap && bSecondaryCoor ) 934 { 935 offset= VisualDB.dThetaMinLast - VisualDB.dThetaMinFirst; //GetThetaOffset(lpDBase->GetCNumber()-1)-GetThetaOffset(0); 936 offset= offset / pCoorSys->xSF; 937 i= 0; 938 } else { 939 offset= 0; 940 i= 1; 941 } 942 943 for (i;i < tilesx;i++) 944 { 945 //! zeichnet Verbindungslinien ein... 946 egde[0].x= Screen.x0 + i / tilesx * (Screen.dx); 947 egde[1].x= Screen.x0 + offset + i / tilesx * (Screen.dx); 948 egde[0].y= Screen.y0; 949 egde[1].y= Screen.y0 + Screen.dy; 950 951 //! falls Hilfslinien ausserhalb des Screens fallen, berechne Anstieg der Geraden 952 //! und zugehoerigen y-Wert 953 if (egde[1].x > Screen.dx + Screen.x0) 954 { 955 egde[1].x= Screen.dx + Screen.x0; 956 egde[1].y= (Screen.dx + Screen.x0 - egde[0].x) * ((Screen.dy - Screen.y0) / offset); 957 } 958 Polyline(hdc, egde, 2); 959 } 960 961 //! eingefuegt fuer dtn-File Abzissenbeschriftung 962 if (eLoadFormat == ffDtnFile) 963 pCoorSys->zSF= (pCoorSys->zMax - pCoorSys->zMin) / Screen.dx; 964 965 //! zeichnet die Markierungen an der x-Achse 966 for (i= 0; i<=tilesx; i++) 967 { 968 // Verbindungslinien und Markierungen 969 dist= i / tilesx * Screen.dx; 970 egde[0].x= egde[1].x= Screen.x0 + dist + offset; 971 egde[0].y= Screen.y0 + Screen.dy; 972 egde[1].y= Screen.y0 + Screen.dy - 5; 973 if (egde[1].x < Screen.dx + Screen.x0) 974 Polyline(hdc, egde, 2); 975 976 egde[0].x= egde[1].x= Screen.x0 + dist; 977 egde[0].y= Screen.y0 + 5; 978 egde[1].y= Screen.y0; 979 Polyline(hdc, egde, 2); 980 } 981 982 // Beschriftungen 983 int y= -yBorder/2 + heightY/2; 984 for (int r= 0; r<rows; r++) 985 { 986 int dy= 0; 987 for (i= 0; i<=tilesx; i++) if ( i%rows==r ) 988 { 989 GetTitleX(i, tilesx, buf, reduceLinesX!=0); 990 GetTextExtentPointEx(hdc, buf, strlen(buf), &tagS); 991 TextOutEx(hdc, Screen.x0 + float(i) / tilesx * Screen.dx, y - tagS.cy/2, buf, strlen(buf), (i==tilesx) ? haRight : haCenter, vaCenter); 992 dy= max(dy, tagS.cy); 993 } 994 y-= dy; 995 } 996 997 //************ Ordinate (y) ************************************************** 998 SelectObject(hdc, hPenDot); 999 for (i= 1;i < tilesy;i++) 1000 { 1001 //! zeichnet Verbindungslinien ein... 1002 egde[0].y= egde[1].y= 1 + i / tilesy * Screen.dy + Screen.y0; 1003 egde[0].x= Screen.x0; 1004 egde[1].x= Screen.x0 + Screen.dx; 1005 Polyline(hdc, egde, 2); 1006 } 1007 1008 SelectObject(hdc, hPenBlack); 1009 for (i= 0;i <= tilesy;i++) 1010 { 1011 // Markierungen 1012 dist= i / tilesy * Screen.dy; 1013 egde[0].y= egde[1].y= Screen.x0 + dist; 1014 egde[0].x= Screen.x0 + Screen.dx; 1015 egde[1].x= Screen.x0 + Screen.dx - 5; 1016 Polyline(hdc, egde, 2); 1017 1018 egde[0].x= Screen.x0 + 5; 1019 egde[1].x= Screen.x0; 1020 Polyline(hdc, egde, 2); 1021 1022 // Beschriftung 1023 GetTitleY(i, tilesy, buf, reduceLinesY); 1024 SetTextAlign(hdc, TA_LEFT); 1025 TextOutEx(hdc, -0.5*xBorder, egde[0].y, (LPSTR)buf, strlen(buf), haCenter, (i==tilesy) ? vaTop : vaCenter); 1026 } 1027 1028 //**************************************************************************** 1029 //! loesche hPenBlack,hPenDot und krame hOldPen, hOldFont wieder hervor 1030 SelectObject(hdc, hOldPen); 1031 SelectObject(hdc, hOldFont); 1032 DeleteObject(hPenBlack); 1033 DeleteObject(hPenDot); 1034 }; 1035 //***************************************************************************** 1036 1037 int TPlotWindow::GetNachkommaStelle(TCoorSystem* pCoorSys, int x, int y) 1038 //! neue Funktion, die die benoetigte Nachkommastellengenauigkeit 1039 //! berechnet und die noetigen Nachkommastellen als int zurueckliefert 1040 //! wenn x=1 dann fuer x-Achse / wenn y=1 dann fuer y-Achse 1041 //! gehoert zu Fehler 6 1042 { 1043 float fval; 1044 1045 if (y) 1046 fval= fabs(pCoorSys->yMax - pCoorSys->yMin); 1047 if (x) 1048 fval= fabs(pCoorSys->xMax - pCoorSys->xMin); 1049 1050 if (fval < 0.25) 1051 return 5; 1052 else 1053 if (fval < 1) 1054 return 4; 1055 else 1056 if (fval < 3) 1057 return 3; 1058 else 1059 return 2; 1060 }; 1061 //***************************************************************************** 1062 1063 LRESULT TPlotWindow::OnEvent ( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ) 1064 { 1065 if ( message==WM_ERASEBKGND ) return 01; // Durch die Verwendung des hMemDC und der hBitmap in DoPaint braucht der Hintergrund nicht mehr gelöscht werden, sonst flackert es. 1066 else return TFileWindow::OnEvent(hwnd, message, wParam, lParam); 1067 } 1068 //***************************************************************************** 1069 1070 LRESULT TPlotWindow::OnCommand(WPARAM wParam, LPARAM lParam) 1071 { 1072 TModalDlg *dlg; 1073 WPARAM Cmd; 1074 Cmd= GET_WM_COMMAND_ID(wParam, lParam); 1075 switch ( Cmd ) { 1076 case cm_Open: 1077 LoadOldData(); 1078 SetRanges(); 1079 return 0l; 1080 1081 case cm_SaveSecondCurve: 1082 SaveSecondCurve(); 1083 return 0l; 1084 1085 case cm_KillSecondCurve: 1086 KillSecondCurve(); 1087 return 0l; 1088 1089 case cm_FreezeCurve: 1090 FreezeCurve(); 1091 return 0l; 1092 1093 case cm_ShowCurveParam: 1094 dlg= (TCurveShowParamDlg *)new TCurveShowParamDlg(this); 1095 if ( dlg ) dlg->ExecuteDialog(GetHandle()); 1096 _FREEOBJ(dlg); 1097 UpdateWnd(); 1098 return 0l; 1099 1100 case cm_MoveScanReady: 1101 TCurve *crv= new TCurve(); 1102 //07.05.2004 crv->FastOpen(); 1103 float x, y, z; 1104 LPLONG data; 1105 data= mGetMoveScan(); 1106 long yo; 1107 yo= data[0]; 1108 int cnt; 1109 for (cnt= 0;cnt < mGetScanSize();cnt++) 1110 { 1111 x= z= cnt; 1112 y= (data[cnt] - yo); 1113 crv->PAdd(x, y, z); //07.05.2004 FastP... 1114 } 1115 //07.05.2004 crv->FastClose(); 1116 TKSProperties ksp; 1117 ksp.bLogarithmicY= FALSE; 1118 ksp.fMinX= 0.0f; 1119 ksp.fMaxX= (float)mGetScanSize() * 1.1; 1120 ksp.fMinY= 0.01f; 1121 ksp.fMaxY= (float)(data[cnt - 1] - yo) * 1.3; 1122 SetKSProperties(&ksp); 1123 PickUpData((LPARAM)(TCurve*)crv); 1124 // SendMessage(Main.hScanWindow,WM_COMMAND,cm_PlotCurve,(LPARAM)(TCurve*)crv); 1125 char Msg[MaxString]; 1126 sprintf(Msg, "MoveFinish: %ld >>> Letzter Wert: %ld", data[mGetMoveFinishIdx()] - yo, data[mGetScanSize() - 1] - yo); 1127 SetInfo(Msg); 1128 _FREEOBJ(crv); 1129 SendMessage(GetHandle(), WM_SETFOCUS, 0, 0l); 1130 return 0l; 1131 } 1132 return TFileWindow::OnCommand(wParam, lParam); 1133 } 1134 //***************************************************************************** 1135 1136 //! Paint, das von Basisklassen aufgerufen wird, wenn diese auf eine WM_PAINT- 1137 //! Botschaft reagieren 1138 void TPlotWindow::DoPaint(HDC hdc, PAINTSTRUCT *) 1139 { 1140 BOOL PaintHole= TRUE; 1141 if ( bUserPaint ) { 1142 //! nur bei bEnablePaint zeichnen 1143 if (!bEnablePaint) 1144 return; 1145 1146 //30.06.2004 bei Ausgabe auf MemDC geht nur noch PaintHole PaintHole= WholeWnd(); //! WholeWnd() gibt an, dass für dieses Paint() nicht bPaintPoint gesetzt ist 1147 bUserPaint= false; // nächster Aufruf könnte WM_PAINT sein 1148 } 1149 1150 // Bestimmen der Ausdehnung in Pixeln des Zeichen-Fensters 1151 RECT rect; 1152 GetClientRect(GetHandle(), (LPRECT)&rect); 1153 1154 // Bitmap und DC im Speicher erzeugen, dann darauf zeichnen 1155 HBITMAP hBitmap= CreateCompatibleBitmap(hdc, rect.right-rect.left, rect.bottom-rect.top); 1156 HDC hMemDC= CreateCompatibleDC(hdc); 1157 HGDIOBJ OldBitmap= SelectObject(hMemDC, hBitmap); 1158 1159 // Hintergrund löschen (bevor neues Koordinatensystem gesetzt wird!) 1160 if ( PaintHole ) { 1161 HBRUSH brush= CreateSolidBrush(RGB(255, 255, 255)); 1162 FillRect(hMemDC, &rect, brush); 1163 DeleteObject(brush); 1164 } 1165 1166 switch (eOutputType) 1167 { 1168 case otReciprokeLatticeBitmap: 1169 case otMatrixBitmap: { 1170 //! eigentliche Bitmap 1171 BSource->DrawBitmap(hMemDC, 0, -Screen.dy, Screen); 1172 //! Legende (ColorTable) 1173 BSource->DrawBitmapFrame(hMemDC, Screen); 1174 // Koordinatensystem (erst nach DrawBitmapFrame!) 1175 DrawCoordinateSystem(hMemDC); 1176 1177 // jetzt die Bitmap auf <hdc> zeichnen 1178 StretchBlt( hdc, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 1179 hMemDC, -xBorder, (rect.bottom-rect.top)-yBorder, rect.right-rect.left, -(rect.bottom-rect.top), SRCCOPY ); // BitBlt kann nicht verwendet werden, weil hMemDC eine andere Koordinatenskalierung besitzt 1180 break; 1181 } 1182 1183 //! dies und viele folgende Sachen nur im Falle von Kurve zu tun... 1184 case otCurve: 1185 if (bAltCoorSystem) 1186 { 1187 CoorSys= AltCoorSys; 1188 bAltCoorSystem= FALSE; 1189 } 1190 else 1191 //! setze neue Koordinatensystembereiche 1192 SetRanges(); 1193 1194 // Daten-Bereich festlegen 1195 Screen.dx= (rect.right - rect.left) - xBorder; 1196 Screen.x0= 0; 1197 Screen.x1= Screen.dx; 1198 Screen.dy= (rect.bottom - rect.top) - yBorder; 1199 Screen.y0= 0; 1200 Screen.y1= Screen.dy; 1201 1202 //! Koordinatenursprung und -skalierung ändern, damit die ständigen Koordinatenumrechnungen entfallen 1203 SIZE tagS; 1204 POINT tagP; 1205 SetMapMode(hMemDC, MM_ANISOTROPIC); // wir wollen die Ausdehnung der x- und y-Achse selbst bestimmen 1206 SetWindowExtEx(hMemDC, Screen.dx + xBorder, Screen.dy + yBorder, &tagS); // setze neue x- und y-Ausdehnung 1207 SetViewportExtEx(hMemDC, Screen.dx + xBorder, -(Screen.dy + yBorder), &tagS); // nur in diesem Bereich wollen wir zeichnen 1208 SetWindowOrgEx(hMemDC, 0, 0, &tagP); // folgende Koordinaten als -ursprung des Fensters 1209 SetViewportOrgEx(hMemDC, xBorder, Screen.dy, &tagP); // folgende Koordinaten als -ursprung des sichtbaren Bereiches 1210 1211 if ( PaintHole ) // Koordinatensystem zeichnen (erst nachdem neues Koordinatensystem gesetzt und CoorSys ermittelt wurde!) 1212 DrawCoordinateSystem(hMemDC); // redraw coordinate system 1213 1214 int cnt= 0; 1215 //! Windows-Datentyp, der Handles fuer logische Stifte repraesentiert 1216 HPEN hOldPen, hPen; 1217 //! 32 bit Zeiger 1218 //! the POINT structure defines the x- and y-coordinates of a point 1219 LPPOINT lpPoints; 1220 1221 //! wenn zweite Kurve nicht leer: Kurve komplett zeichnen 1222 if ( SecondCurve->GetPNumber()>1 ) //! 1 < letzter Eintrag + 1 1223 { 1224 lpPoints= (LPPOINT)new POINT[ SecondCurve->GetPNumber() ]; 1225 //! setzt ActualIdx auf pos oder auf MaxPointIdx, wenn pos>MaxPointidx 1226 //! hier ActualIdx=0 1227 SecondCurve->SetPP(); 1228 //! fuellt die Struktur lpPoints mit den Werten fuer eine Kurve... 1229 FormatCurveToPLine(SecondCurve, lpPoints, cnt); 1230 //! ...um damit spaeter dann die Kurve darzustellen 1231 hPen= CreatePen(PS_SOLID, 1, RGB(0, 0, 255)); 1232 hOldPen= (HPEN)SelectObject(hMemDC, hPen); 1233 if ( m_HasFilter ) 1234 FilterPLine(lpPoints, cnt); 1235 if ( m_Dotted ) { 1236 HBRUSH hBrush= CreateSolidBrush(RGB(0, 0, 255)); 1237 HBRUSH hOldBrush= (HBRUSH)SelectObject(hMemDC, hBrush); 1238 Dottedline(hMemDC, lpPoints, cnt); 1239 SelectObject(hMemDC, hOldBrush); 1240 DeleteObject(hBrush); 1241 } else Polyline(hMemDC, lpPoints, cnt); 1242 SelectObject(hMemDC, hOldPen); 1243 DeleteObject(hPen); 1244 _FREELIST(lpPoints); 1245 } 1246 //! wenn erste Kurve nicht leer: diese [auch] zeichnen 1247 if ( MainCurve->GetPNumber()>1 ) //! 1 < letzter Eintrag + 1 1248 { 1249 if (PaintHole) 1250 { // alle Punkte der Kurve zeichnen, dazu PP auf Index 0 setzen 1251 lpPoints= (LPPOINT)new POINT[ MainCurve->GetPNumber() ]; 1252 //! letzter ActualIdx auf Anfang 1253 MainCurve->SetPP(); 1254 } 1255 else 1256 { // nur den letzten Punkt zeichnen, Index um eine Position zurücksetzen 1257 lpPoints= (LPPOINT)new POINT [2]; 1258 //! setzt ActualIdx vor-letztes MaxPointIdx 1259 MainCurve->SetPPLast(); 1260 MainCurve->BackStep(); 1261 } 1262 //! fuellt die Struktur lpPoints mit den Werten fuer eine Kurve... 1263 FormatCurveToPLine(MainCurve, lpPoints, cnt); 1264 1265 //! ...um damit spaeter dann die Kurve darzustellen 1266 hPen= CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); 1267 hOldPen= (HPEN)SelectObject(hMemDC, hPen); 1268 if ( m_HasFilter ) 1269 FilterPLine(lpPoints, cnt); 1270 if ( m_Dotted ) { 1271 HBRUSH hBrush= CreateSolidBrush(RGB(255, 0, 0)); 1272 HBRUSH hOldBrush= (HBRUSH)SelectObject(hMemDC, hBrush); 1273 Dottedline(hMemDC, lpPoints, cnt); 1274 SelectObject(hMemDC, hOldBrush); 1275 DeleteObject(hBrush); 1276 } else Polyline(hMemDC, lpPoints, cnt); 1277 SelectObject(hMemDC, hOldPen); 1278 DeleteObject(hPen); 1279 _FREELIST(lpPoints); 1280 } 1281 1282 // jetzt die Bitmap auf <hdc> zeichnen und alles aufräumen 1283 StretchBlt( hdc, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, 1284 hMemDC, -xBorder, Screen.dy, xBorder+Screen.dx, -(yBorder+Screen.dy), SRCCOPY ); // BitBlt kann nicht verwendet werden, weil hMemDC eine andere Koordinatenskalierung besitzt 1285 break; 1286 } // switch 1287 1288 // alles aufräumen 1289 SelectObject(hMemDC, OldBitmap); 1290 DeleteObject(hBitmap); 1291 DeleteDC(hMemDC); 1292 }; 1293 //***************************************************************************** 1294 1295 void TPlotWindow::Dottedline(HDC hdc, const POINT *lppt, int cPoints) 1296 { 1297 for (int i= 0; i<cPoints; i++) { 1298 Ellipse(hdc, lppt[i].x-1, lppt[i].y-1, lppt[i].x+1, lppt[i].y+1); 1299 } 1300 } 1301 //***************************************************************************** 1302 1303 HICON TPlotWindow::GetIcon ( void ) const 1304 { 1305 return (HICON)LoadImage( GetMainInstance(), MAKEINTRESOURCE(icon_ScanWindow),IMAGE_ICON,16,16,LR_DEFAULTCOLOR); 1306 }; 1307 //***************************************************************************** 1308 1309 void TPlotWindow::SetLoadFormat(EFileFormat type) 1310 { 1311 eLoadFormat= type; 1312 }; 1313 //***************************************************************************** 1314 1315 BOOL TPlotWindow::SaveFile(EAskType ask) { 1316 char NewFilename[ _MAX_PATH ]; 1317 char dir[_MAX_DIR], drv[_MAX_DRIVE], name[_MAX_FNAME], ext[_MAX_EXT]; 1318 OFSTRUCT of; 1319 int nNumber= 0, hFile; 1320 HFILE ht; 1321 1322 //! ht= _lopen("test",READ_WRITE); 1323 ht= _lopen("test", OF_READWRITE); 1324 _lclose(ht); 1325 _chdir(szDataPath); 1326 switch (ask) 1327 { 1328 case atNoAsk: 1329 // Test ob File beschrieben werden kann 1330 _splitpath(FileName, drv, dir, name, ext); 1331 _makepath(NewFilename, "", "", name, szExtension); 1332 hFile= OpenFile(NewFilename, &of, OF_CREATE); 1333 if (hFile==HFILE_ERROR) 1334 do { 1335 sprintf(NewFilename, "%sscan%03d.%s", szDataPath, nNumber++, szExtension); 1336 hFile= OpenFile(NewFilename, &of, OF_EXIST); 1337 } while ( hFile!=HFILE_ERROR && nNumber<10000 ); 1338 _lclose(hFile); 1339 break; 1340 1341 case atNewName: 1342 sprintf(NewFilename, "*.%s", szExtension); 1343 if ( !FileSaveDialog("Sichern unter ...", szFilter, NewFilename, szDataPath) ) return FALSE; // 'Abbruch' geklickt 1344 if ( strlen(NewFilename)==0 || strcmp(NewFilename, "*")==0 ) 1345 return FALSE; 1346 break; 1347 1348 default: 1349 if (!bFileChanged) 1350 { 1351 SetInfo(strMessage14); 1352 return FALSE; 1353 } 1354 if (!bIsNewFile) 1355 { 1356 _splitpath(FileName, drv, dir, name, ext); 1357 _makepath(NewFilename, "", "", name, szExtension); 1358 } 1359 else 1360 sprintf(NewFilename, "*.%s", szExtension); 1361 if ( !FileSaveDialog("Sichern als ...", szFilter, NewFilename, szDataPath) ) return FALSE; // 'Abbruch' wurde geklickt 1362 if ( strlen(NewFilename)==0 || strcmp(NewFilename, "*")==0 ) 1363 return FALSE; 1364 } 1365 _splitpath(NewFilename, drv, dir, name, ext); 1366 _makepath(FileName, drv, dir, name, szExtension); 1367 bIsNewFile= FALSE; 1368 // bOldDataLoaded= FALSE; 1369 bFileChanged= FALSE; 1370 _chdir(szDataPath); 1371 SetTitle(); 1372 return TRUE; 1373 } 1374 // --------------------------------------------------------------------------- 1375 // 15.06.2004 Kullmann/Reinecker: neue Methode zur uebersichtlicheren Kurvendarstellung 1376 void TPlotWindow::FilterPLine(LPPOINT lpPoints, int &idx) 1377 { 1378 bool found = false; 1379 POINT FilterLevel; 1380 LPPOINT YAccumulation = (LPPOINT)new POINT[idx+1]; 1381 1382 m_FilterStrength = max(0.0, min(100.0, m_FilterStrength)); 1383 1384 for (int i = 0; i <= idx; i++) 1385 { 1386 YAccumulation[i].x = -1; // die Häufigkeit des Auftretens 1387 YAccumulation[i].y = -1; // die gemessenen Intensitaet 1388 } 1389 FilterLevel.x = -1; 1390 FilterLevel.y = -1; 1391 for (i = 0; i <= idx; i++) 1392 { 1393 found = false; 1394 // ob schon mal gezählt 1395 for (int j = 0; j <= idx; j++) 1396 { 1397 if ( lpPoints[i].y == YAccumulation[j].y ) 1398 { 1399 (YAccumulation[j].x)++; 1400 found = true; 1401 break; 1402 } 1403 } 1404 // wenn neu dann aufnehmen 1405 if (!found) 1406 { 1407 YAccumulation[i].y = lpPoints[i].y; 1408 YAccumulation[i].x = 1; 1409 } 1410 } 1411 // Niveau der groesste Haeufigkeit bestimmen 1412 for (i = 0; i <= idx; i++) 1413 { 1414 if (FilterLevel.x < YAccumulation[i].x) 1415 { 1416 FilterLevel.x = YAccumulation[i].x; 1417 FilterLevel.y = YAccumulation[i].y; 1418 }; 1419 }; 1420 float MaxAcc = FilterLevel.x; // Maximale Häufigkeit merken 1421 // optimale Haeufigkeit für Y-Wert oberhalb der groessten Haeufigkeit finden 1422 for (i = 0; i <= idx; i++) 1423 { 1424 if ( (YAccumulation[i].y > FilterLevel.y) && ((MaxAcc-((MaxAcc/100)*m_FilterStrength)) < YAccumulation[i].x) ) // naechst kleinere Haufigkeit 1425 { 1426 FilterLevel.x = YAccumulation[i].x; 1427 FilterLevel.y = YAccumulation[i].y; 1428 }; 1429 }; 1430 // alle Y-Werte auf dieses Niveau anheben 1431 for (i = 0; i <= idx; i++) 1432 if (lpPoints[i].y < FilterLevel.y) lpPoints[i].y = FilterLevel.y; 1433 }; 1434 1435 // --------------------------------------------------------------------------- 1436 // 15.06.2004 Kullmann/Reinecker: verkuerzte und korrigierte Methode zur Skalierung der Y-Werte 1437 // fuellt die Struktur lpPoints mit den Werten fuer eine Kurve 1438 void TPlotWindow::FormatCurveToPLine(TCurve *crv, LPPOINT lpPoints, int &idx) 1439 { 1440 idx = 0; 1441 float x; // x-Wert = Thetamotorwinkel 1442 float y; // y-wert = gemessene Intensitaet des Detektors in dieser Position 1443 float z; // z-wert = Kanal 1444 float offset= GetThetaOffset(0); 1445 1446 // FastPGet(x,y,z) holt Werte der Kurve und setzt Kurvenindex weiter 1447 while (crv->PGet(x, y, z)) //07.05.2004 FastP... 1448 { 1449 // wenn X-Achse mit Theta-Winkel Beschriftung 1450 if (!bSecondaryCoor) 1451 { 1452 x += offset; // Theta-Offset beruecksichtigen 1453 lpPoints[idx].x= (x - CoorSys.xMin) / CoorSys.xSF; 1454 } else lpPoints[idx].x= (z - CoorSys.xMin) / CoorSys.xSF; // Beschriftung mit Kanaelen 1455 1456 //if (fabs(z - x) == 0.0) continue; // 15.06.2004 Fehler: was soll Kanaele - Winkel bringen ??? 1457 1458 if (y > CoorSys.yMin) // Ok, Wert ist oberhalb X-Achse 1459 { 1460 if (CoorSys.yScal == sLinear) 1461 lpPoints[idx].y= (y - CoorSys.yMin) / CoorSys.ySF; 1462 else 1463 lpPoints[idx].y= log10(y / CoorSys.yMin) / CoorSys.ySF; 1464 } 1465 else // sonst auf Niveau der X-Achse setzen 1466 lpPoints[idx].y= 0; 1467 1468 if ( idx != 0 ) { 1469 if ( !m_Dotted ) { 1470 // ehem. Fehler: Bei gleichem durch Skalierung entstandenem X-Wert 1471 // wurde der Y-Wert des Vorgaengers einfach ueberschrieben. 1472 // so koennte z.B. das abs. Maximum verlorengehen!!! 1473 // Korrektur durch Abfrage 1474 if ( (lpPoints[idx - 1].x == lpPoints[idx].x) ) { 1475 lpPoints[idx - 1].y = max( lpPoints[idx - 1].y, lpPoints[idx].y ); // bei gleichen x-Werten max. y-Wert nehmen 1476 continue; 1477 } 1478 } else 1479 if ( (lpPoints[idx - 1].x == lpPoints[idx].x) && (lpPoints[idx - 1].y == lpPoints[idx].y) ) continue; // nie zwei genau gleiche Punkte in die Liste aufnehmen 1480 } 1481 idx++; 1482 }; 1483 }; 1484 // --------------------------------------------------------------------------- 1485 //! sichert Koordinatensystem in AltCoorsys 1486 //! m_main.cpp im Falle von cm_MoveScanReady 1487 void TPlotWindow::SetKSProperties(TKSProperties* ksp) 1488 { 1489 if (!ksp) 1490 return; 1491 1492 AltCoorSys.yMin= ksp->fMinY; 1493 AltCoorSys.yMax= ksp->fMaxY; 1494 AltCoorSys.xMin= ksp->fMinX; 1495 AltCoorSys.xMax= ksp->fMaxX; 1496 if (ksp->bLogarithmicY) 1497 AltCoorSys.yScal= sLogarithmic; 1498 else 1499 AltCoorSys.yScal= sLinear; 1500 1501 AltCoorSys.xScal= sLinear; // Logarithmic; geaendert, weil xST meiner Meinung nach nie Logarithmic 1502 bAltCoorSystem= TRUE; 1503 }; 1504 //***************************************************************************** 1505 1506 void TPlotWindow::PickUpData(LPARAM data) 1507 //! wird nur in m_main.cpp im Falle von cm_MoveScanReady benoetigt 1508 //! sichert Daten in der SecondCurve 1509 { 1510 *SecondCurve= *((TCurve *)data); 1511 }; 1512 //***************************************************************************** 1513 1514 //! wird aufgerufen aus dem Scan-Fenster-Menue unter Scan -> Loeschen 1515 //! bei gesendetem cm_KillSecondCurve 1516 //! setzt SecondCurve auf Initialwerte zurück (loeschen aller Messtripel) 1517 //! zeichnet Scan-Fenster neu 1518 void TPlotWindow::KillSecondCurve(void) 1519 //! SecondCurve wird mit Standardwerten ueberschrieben 1520 { 1521 SecondCurve->New(); 1522 //! Update des ClientWindows durch 1523 UpdateWnd(); 1524 }; 1525 //***************************************************************************** 1526 1527 //! wird aufgerufen aus dem Scan-Fenster-Menue unter Scan -> Fixieren 1528 //! bei gesendetem Kommando cm_FreezeCurve 1529 //! fixiert die aktuelle Hauptkurve -> setzt Pointer von SecondCurve auf MainCurve 1530 void TPlotWindow::FreezeCurve(void) 1531 //! speichert Objektzustand von MainCurve in SecondCurve 1532 { 1533 if (1 > MainCurve->GetPNumber()) 1534 return; 1535 *SecondCurve= *MainCurve; 1536 }; 1537 //***************************************************************************** 1538 1539 //! wird aufgerufen aus dem Scan-Fenster-Men' unter Scan -> Speichern 1540 //! bei gesendetem Kommando cm_SaveSecondCurve 1541 //! speichert fixierte Kurve (SecondCurve) unter auszuwaehlendem Dateinamen 1542 //! mit Extension *.bk 1543 void TPlotWindow::SaveSecondCurve(void) 1544 //! speichert die SecondCurve 1545 { 1546 char NewFilename[ _MAX_PATH ]; 1547 OFSTRUCT of; 1548 int hFile; 1549 float x, y, z; 1550 char buf[MaxString]; 1551 1552 // 'Datei Speichern'-Dialog anzeigen und ausgewählte Datei auswerten 1553 char Extension[]= "bk"; 1554 sprintf(NewFilename, "*.%s", Extension); 1555 char temp[_MAX_PATH]; 1556 strcpy(temp, szMsgLine605); // szMsgLine605 nicht direkt angeben, weil const 1557 if ( !FileSaveDialog(szMsgLine604, temp, NewFilename, "") ) return; // Abbruch wurde geklickt 1558 if ( strlen(NewFilename)==0 || strcmp(NewFilename, "*")==0 ) return; 1559 char dir[_MAX_DIR], drv[_MAX_DRIVE], name[_MAX_FNAME], ext[_MAX_EXT]; 1560 _splitpath(NewFilename, drv, dir, name, ext); 1561 _makepath(FileName, drv, dir, name, Extension); 1562 1563 //! erstellen der Datei mit ausgewaehltem Namen + Test, ob dies moeglich 1564 //! wenn nicht, Fehlermeldung + Abbruch 1565 hFile= OpenFile(FileName, &of, OF_CREATE); 1566 if ( hFile==HFILE_ERROR ) 1567 { 1568 MessageBox(sth_CannotCreateFile, "Fehler/Error", MBSTOP); 1569 return; 1570 } 1571 //! Wait-Mauszeiger setzen 1572 HCURSOR hOldCursor= SetDefaultCursor( IDC_WAIT ); 1573 1574 strcpy(buf, szMsgLine606); 1575 //! FileType mit eingefuehrt - TScanWindow.eSaveFormat= bkFile (beim Einlesen) 1576 strcat(buf, "FileType=Comparison\n"); 1577 strcat(buf, "X >> Intensity >> Z\n[Data]\n"); 1578 _lwrite(hFile, (LPSTR)buf, strlen(buf)); 1579 1580 //! an Anfang der Kurve gehen + Speicher der Punkte fixieren 1581 //! setzt ActualIdx auf 0 oder auf MaxPointIdx, wenn pos>MaxPointidx 1582 //! hier ActualIdx=0 1583 SecondCurve->SetPP(); 1584 1585 //! folgendes wird mit FastOpen aktualisiert (betrifft Klasse Curve...) 1586 //! BOOL* lpPV; // Zeiger auf Datenfeld von Validate 1587 //07.05.2004 SecondCurve->FastOpen(); 1588 1589 //! FastPGet(x,y,z) holt Werte der Kurve und setzt ActualIdx++ (m_curve.cpp) 1590 //! Kurve Tripel für Tripel auslesen und zeilenweise in der Datei ablegen 1591 while ( SecondCurve->PGet(x, y, z) ) //07.05.2004 FastP... 1592 { //! FIX Fehler 2 Diff/Refl 1593 sprintf(buf, "%.3f %.3f %.3f", x, y, z); 1594 strcat(buf, EOL); 1595 _lwrite(hFile, (LPSTR)buf, strlen(buf)); 1596 } 1597 //! Schliežen der Datei + Fixieren des Speichers der Kurve aufheben 1598 //! Wait-Mauszeiger ausschalten 1599 _lclose(hFile); 1600 //! GlobalUnlock(hMemX);GlobalUnlock(hMemY);GlobalUnlock(hMemZ); 1601 //! GlobalUnlock(hMemV);bStreamOpen= FALSE; - Fkt. FastClose(); 1602 // 07.05.2004 SecondCurve->FastClose(); 1603 SetCursor(hOldCursor); 1604 return; 1605 }; 1606