File: SWINTRAC\M_DEVICE.CPP

    1 // m_device.cpp
    2 // (C) 1993,1994 by Heiko Damerow
    3 // MPG AG "Röntgenbeugung an Schichtstrukturen"
    4 
    5 #include "utils\u_utils.h"
    6 #include "winresrc\rc_def.h" // Ressourcen-IDs
    7 #pragma hdrstop
    8 
    9 #include "swintrac\m_dlg.h" // für TCounterWindow
   10 #include "detecuse\detecuse.h"
   11 
   12 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
   13 
   14 TCounterWindow *TCounterWindow::s_Singleton= 0;
   15 
   16 //******************************************************************************
   17 //******** Anwender-Schnittstelle **********************************************
   18 //******** Methoden für das Zähler-Fenster *************************************
   19 TCounterWindow::TCounterWindow(HINSTANCE aInstance, TDetector *detectorParam) : TMDIWindow(aInstance), IField(0, 0.0) // 31.04.2004 MEMCORRECT (verwende IField), hMemG(0)
   20 {
   21         if ( detectorParam == 0 )
   22                 Sensor= TDetectorManager::DetectorManager().GetDetector();
   23         else
   24                 Sensor= detectorParam;
   25 
   26         Sensor->SetCounterWnd(NULL);
   27         if ( s_Singleton ) _FREEOBJ(s_Singleton);
   28         s_Singleton= this;
   29 
   30         // Aussehen des Fensters festlegen
   31         bShowAsDigital= TRUE;
   32         bQuiteOpen= FALSE;
   33         eScaleType= sLinear;
   34         bAnalogSwitchOn= TRUE;
   35         bWindowWillBeOpen= TRUE;
   36         bWriteLogFile= FALSE;
   37         fData= 100.0;
   38         fThickness= 10.0;
   39         fHight= 200.0;
   40         // Größe der Historien-Schlange
   41         nBarCount= 40;
   42         nIdx= -1;
   43         fMaxIntensity= 14000.1f;
   44         hBrushRed= CreateSolidBrush(RGB(255, 0, 0));
   45         hBrushWhite= CreateSolidBrush(RGB(0, 0, 0));
   46         hBrushBlack= CreateSolidBrush(RGB(255, 255, 255));
   47         hBrushOC= CreateSolidBrush(RGB(0, 255, 127));
   48         hPen= CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
   49         strcpy(FontName, "");
   50 
   51         //! erstellen der Menüeintraege 
   52         hHoleMenu= LoadMenu(GetMainInstance(), MAKEINTRESOURCE(menu_Counter));
   53     // Fix für PopupMenüs aus Ressourcen (Dummy Popup)
   54     TheMenu= GetSubMenu(hHoleMenu, 0); 
   55 };
   56 
   57 TCounterWindow::~TCounterWindow()
   58 {       
   59         char buf[MaxString];
   60         RECT rc, rcm;
   61 
   62         if (bQuiteOpen)
   63         {
   64                 Sensor->MeasureStop();
   65                 Sensor->SetCounterWnd(NULL);
   66         }
   67 
   68         GetWindowRect(GetFrameHandle(), &rcm);
   69         GetWindowRect(GetHandle(), &rc);
   70         sprintf(buf, "%d", rc.left - rcm.left - 4);
   71         WritePrivateProfileString("Counter", "xo", buf, GetCFile());
   72         sprintf(buf, "%d", rc.top - rcm.top - 42);
   73         WritePrivateProfileString("Counter", "yo", buf, GetCFile());
   74         sprintf(buf, "%d", rc.right - rc.left);
   75         WritePrivateProfileString("Counter", "dx", buf, GetCFile());
   76         sprintf(buf, "%d", rc.bottom - rc.top);
   77         WritePrivateProfileString("Counter", "dy", buf, GetCFile());
   78         DeleteObject(hBrushWhite);
   79         DeleteObject(hBrushRed);
   80         DeleteObject(hBrushBlack);
   81         DeleteObject(hBrushOC);
   82         DeleteObject(hPen);
   83 
   84         s_Singleton= 0;
   85 
   86         /* 31.04.2004 MEMCORRECT (verwende IField) if ( hMemG ) HeapFree(GetProcessHeap(),0,hMemG);
   87         hMemG= 0;*/
   88 };
   89 
   90 BOOL TCounterWindow::CanOpen(void)
   91 {
   92         char buf[MaxString];
   93 
   94         if (!TMDIWindow::CanOpen())
   95                 return FALSE;
   96 
   97         if (Sensor->GetCounterWnd())
   98         {
   99                 sprintf(buf, "Es ist bereits ein darstellendes Fenster geöffnet!");
  100                 MessageBox((LPSTR)buf, "Fehler", MBINFO);
  101                 return FALSE;
  102         }
  103 
  104         return TRUE;
  105 };
  106 
  107 void TCounterWindow::OnCreate()
  108 {
  109         int value;
  110 
  111         bQuiteOpen= TRUE;
  112         Sensor->MeasureStop();
  113         Sensor->SetCounterWnd( GetHandle() );
  114         Sensor->SetParameters();
  115         Sensor->MeasureStart();
  116         GetPrivateProfileString( "Counter", "font", "Times New Roman", FontName,
  117                                                          MaxString, GetCFile());
  118         nBarCount= GetPrivateProfileInt("Counter", "BarNumber", 40, GetCFile());
  119 
  120         WndRect.left= GetPrivateProfileInt("Counter", "xo", 500, GetCFile());
  121         WndRect.top= GetPrivateProfileInt("Counter", "yo", 400, GetCFile());
  122         value= GetPrivateProfileInt("Counter", "dx", 170, GetCFile());
  123         WndRect.right= WndRect.left + value;
  124         value= GetPrivateProfileInt("Counter", "dy", 50, GetCFile());
  125         WndRect.bottom= WndRect.top + value;
  126 
  127 
  128         // 31.04.2004 MEMCORRECT (verwende IField) hMemG= (HGLOBAL)HeapAlloc(GetProcessHeap(),0,nBarCount * sizeof(float));
  129         IField.SetCount( nBarCount );
  130 
  131 
  132         SetWindowPos( GetHandle(), NULL, WndRect.left, WndRect.top,
  133                                   WndRect.right - WndRect.left, WndRect.bottom - WndRect.top, SWP_NOZORDER );
  134         SetTitle();
  135 };
  136 
  137 void TCounterWindow::OnSize(WPARAM, LPARAM)
  138 {
  139         char buf[MaxString];
  140 
  141         if (bWindowWillBeOpen)
  142                 bWindowWillBeOpen= FALSE;
  143         else
  144                 GetWindowRect(GetHandle(), &WndRect);
  145 
  146         GetClientRect(GetHandle(), &ClientRect);
  147 
  148         sprintf(buf, "%d", nBarCount);
  149 
  150         WritePrivateProfileString("Counter", "BarNumber", buf, GetCFile());
  151 };
  152 
  153 BOOL TCounterWindow::SetTitle()
  154 {
  155         strcpy(m_Title, "Zähler: ");
  156         strcat(m_Title, Sensor->GetCharacteristic());
  157         return TMDIWindow::SetTitle();
  158 };
  159 
  160 LRESULT TCounterWindow::OnCommand(WPARAM wParam, LPARAM lParam)
  161 {
  162         TModalDlg *dlg;
  163         WPARAM Cmd;
  164         Cmd= GET_WM_COMMAND_ID(wParam, lParam);
  165         switch (Cmd)
  166         {
  167                 case cm_ShowCounterParam:
  168                         dlg= new TCounterShowParamDlg(this);
  169                         if ( dlg ) dlg->ExecuteDialog(GetHandle());
  170                         _FREEOBJ(dlg);
  171                         return 0l;
  172 
  173                 case cm_Logging:
  174                         SetupLogging();
  175                         return 0l;
  176 
  177                 case cm_ShowDigital:
  178                         bShowAsDigital= TRUE;
  179                         return 0l;
  180 
  181                 case cm_ShowAnalog:
  182                         bShowAsDigital= FALSE;
  183                         return 0l;
  184         }
  185         return TMDIWindow::OnCommand(wParam, lParam);
  186 }
  187 
  188 void TCounterWindow::CounterSetRequest(LPARAM)
  189 {
  190         float temp= 0;
  191         int res= Sensor->GetIntegral(temp);
  192         if ( (res==R_OK) || (res==R_SoftOverflow) ) ShowCounterSetRequest(temp);
  193         else ShowCounterSetRequest(fData); // bei Hardoverflow
  194 };
  195 
  196 void TCounterWindow::ShowCounterSetRequest(float aIntegral)
  197 {
  198         FILE *hFile;
  199         char buf[MaxString];
  200         fData= aIntegral;
  201 
  202         if (bWriteLogFile)
  203         {
  204                 sprintf(buf, "device%d.log", Sensor->GetId());
  205                 hFile= fopen(buf, "at");
  206                 sprintf(buf, "%.3f\n", fData);
  207                 fwrite(buf, 1, strlen(buf), hFile);
  208                 fclose(hFile);
  209         }
  210 
  211         if (bShowAsDigital)
  212                 UpdateWnd();
  213         else
  214                 UpdateWnd( ptPaintPoint );
  215 
  216         if (!Sensor->GetControlWnd())
  217                 Sensor->MeasureStart();
  218 };
  219 
  220 void TCounterWindow::SetupLogging(void)
  221 {
  222         FILE *hFile;
  223         char buf[MaxString];
  224 
  225         SYSTEMTIME t;
  226 
  227         bWriteLogFile= !bWriteLogFile;
  228 
  229         if (bWriteLogFile)
  230         {
  231                 GetLocalTime(&t);
  232                 sprintf(buf, "device%d.log", Sensor->GetId());
  233                 hFile= fopen(buf, "at");
  234                 sprintf(buf, "Logging Detector%d starts at %02i.%02i.%i %2d:%02d\n",
  235                                 Sensor->GetId(), t.wDay, t.wMonth, t.wYear, t.wHour, t.wMinute);
  236                 fwrite(buf, 1, strlen(buf), hFile);
  237                 fclose(hFile);
  238         }
  239 };
  240 
  241 void TCounterWindow::OnPopupMenuInit(WPARAM, LPARAM lParam)
  242 {
  243         TDetectorManager::DetectorManager().SetDetector(Sensor);
  244         CheckMenuItem(TheMenu, cm_ShowDigital, bShowAsDigital ? MF_CHECKED : MF_UNCHECKED);
  245         CheckMenuItem(TheMenu, cm_ShowAnalog, bShowAsDigital ? MF_UNCHECKED : MF_CHECKED);
  246         CheckMenuItem(TheMenu, cm_Logging, bWriteLogFile ? MF_CHECKED : MF_UNCHECKED);
  247 };
  248 
  249 void TCounterWindow::OnFocus(void)
  250 {
  251         TDetectorManager::DetectorManager().SetDetector(Sensor);
  252 };
  253 
  254 void TCounterWindow::OnLButtonDown(WPARAM, LPARAM)
  255 {};
  256 
  257 void TCounterWindow::DoPaint(HDC hdc, PAINTSTRUCT *)
  258 {
  259   char buf[MaxString];
  260   HDC hMemDC;
  261   HBITMAP hOldBitmap, hBitmap;
  262   HFONT hOldFont, hFont;
  263   int yp, xp;
  264   int xclient, yclient, i;
  265   LOGFONT lf;
  266   SIZE size;
  267   POINT point;
  268 
  269   if (!WholeWnd()) {
  270     if (bShowAsDigital) return;
  271     
  272     // Definition des logischen Zeichen-Fensters
  273     SetMapMode(hdc, MM_ANISOTROPIC);
  274     
  275     // Koordinatenursprung setzen
  276     SetWindowExtEx(hdc, ClientRect.right - ClientRect.left, ClientRect.bottom - ClientRect.top, &size);
  277     SetWindowOrgEx(hdc, 0, 0, &point);
  278     SetViewportExtEx(hdc, ClientRect.right - ClientRect.left, -(ClientRect.bottom - ClientRect.top), &size);
  279     SetViewportOrgEx(hdc, 0, ClientRect.bottom - ClientRect.top, &point);
  280 
  281     
  282     // 31.04.2004 MEMCORRECT (verwende IField) IField= (HPFLOAT)GlobalLock(hMemG);    
  283         
  284         SelectObject(hdc, hPen);
  285     SelectObject(hdc, hBrushRed);
  286     if (nIdx >= 0) Rectangle(hdc, nIdx*fThickness, IField[nIdx]*fHight, (nIdx + 1)*fThickness, 0);
  287     if (++nIdx >= nBarCount) nIdx= 0;
  288     
  289     IField[nIdx]= fData;
  290     
  291     // Zeichnen des letzten Wertes als Säule in schwarz
  292     SelectObject(hdc, hBrushBlack);
  293     
  294     Rectangle(hdc, nIdx*fThickness, ClientRect.bottom - ClientRect.top, (nIdx + 2)*fThickness, IField[nIdx]*fHight);
  295     SelectObject(hdc, hBrushWhite);
  296     Rectangle(hdc, nIdx*fThickness, IField[nIdx]*fHight, (nIdx + 2)*fThickness, 0);
  297     sprintf(buf, "Intensität:  %.1f", IField[nIdx]);
  298     SetInfo(buf);
  299 
  300 
  301     // 31.04.2004 MEMCORRECT (verwende IField) GlobalUnlock(hMemG);
  302 
  303 
  304     return;
  305   }
  306 
  307   if (bShowAsDigital) {
  308     bAnalogSwitchOn= TRUE;
  309     xclient= ClientRect.right - ClientRect.left;
  310     yclient= ClientRect.bottom - ClientRect.top;
  311     SetMapMode(hdc, MM_TEXT);
  312     
  313     // MemDC erzeugen und auswählen
  314     hMemDC= CreateCompatibleDC(hdc);
  315     hBitmap= CreateCompatibleBitmap(hdc, xclient, yclient);
  316     hOldBitmap= (HBITMAP)SelectObject(hMemDC, hBitmap);
  317 
  318     // auszugebende Zeichenkette erstellen
  319     if (fabs(fData) > 10000) sprintf(buf, "%.0f", fData);
  320     else if (fabs(fData) > 1000) sprintf(buf, "%.1f", fData);
  321     else sprintf(buf, "%.2f", fData);
  322 
  323     //Schriftskalierung berechnen (neu Kullmann+Reinecker)
  324     GetTextExtentPoint(hMemDC, buf, strlen(buf), &size);
  325     float scaleX= (float)xclient / max(1.0f, (float)size.cx); // DIV0 verhindern
  326     float scaleY= (float)yclient / max(1.0f, (float)size.cy); // DIV0 verhindern
  327 
  328     // Font erstellen und auswählen
  329     memset(&lf, 0, sizeof(LOGFONT));
  330     lf.lfHeight= (int) ( size.cy*min(scaleX, scaleY) ); // neu Kullmann+Reinecker: yclient ersetzt durch Skalierung
  331     lf.lfWidth= 0;
  332     lf.lfWeight= 200;
  333     lf.lfUnderline= FALSE;
  334     strcpy(lf.lfFaceName, FontName);
  335     hFont= CreateFontIndirect(&lf);
  336     hOldFont= (HFONT)SelectObject(hMemDC, hFont);
  337 
  338     // Zeichnen der Daten
  339     GetTextExtentPoint(hMemDC, buf, strlen(buf), &size);
  340     xp= xclient - size.cx; // horizontal rechtsbündig
  341     yp= yclient / 2 - size.cy / 2; // vertikal zentiert
  342     TextOut(hMemDC, xp, yp, (LPSTR)buf, strlen(buf));    
  343     BitBlt(hdc, xp, yp, size.cx, size.cy, hMemDC, xp, yp, SRCCOPY); // PatBlt(hMemDC,0,0,xclient,yclient,WHITENESS);
  344 
  345     // DC wiederherstellen
  346     SelectObject(hMemDC, hOldFont);
  347     DeleteObject(hFont);
  348     SelectObject(hMemDC, hOldBitmap);
  349     DeleteObject(hBitmap);
  350     DeleteDC(hMemDC);
  351   } else { // !bShowAsDigital
  352     // 31.04.2004 MEMCORRECT (verwende IField) IField= (HPFLOAT)GlobalLock(hMemG);
  353 
  354           
  355     if (bAnalogSwitchOn) {
  356       for (nIdx= 0;nIdx < nBarCount; nIdx++) IField[nIdx]= 0.0;      
  357       nIdx= -1;
  358       bAnalogSwitchOn= FALSE;
  359       fHight= (ClientRect.bottom - ClientRect.top) / fMaxIntensity * 0.9;
  360     };
  361     
  362     fThickness= (ClientRect.right - ClientRect.left) / nBarCount;
  363     SetMapMode(hdc, MM_ANISOTROPIC);
  364     SetWindowExtEx( hdc, ClientRect.right - ClientRect.left, ClientRect.bottom - ClientRect.top, &size);
  365     SetWindowOrgEx(hdc, 0, 0, &point);
  366     SetViewportExtEx( hdc, ClientRect.right - ClientRect.left, -(ClientRect.bottom - ClientRect.top), &size);
  367     SetViewportOrgEx(hdc, 0, ClientRect.bottom - ClientRect.top, &point);
  368     
  369     // Zeichnen der aktuellen Werte in Rot
  370     SelectObject(hdc, hPen);
  371     SelectObject(hdc, hBrushRed);
  372     for (i= 0;i < nBarCount;i++) Rectangle(hdc, i*fThickness, 0, (i + 1)*fThickness, IField[i]*fHight);
  373 
  374     
  375     // 31.04.2004 MEMCORRECT (verwende IField) GlobalUnlock(hMemG);
  376   }
  377 };
  378 
  379 //******************************************************************************
  380 TCounterShowParamDlg::TCounterShowParamDlg(TCounterWindow *cwnd)
  381                 : TModalDlg("CounterShowParam", GetMainInstance() )
  382 {
  383         CounterWnd= cwnd;
  384 };
  385 
  386 
  387 BOOL TCounterShowParamDlg::Dlg_OnInit(HWND hwnd, HWND hwndCtl, LPARAM lParam)
  388 {
  389         char buf[MaxString];
  390 
  391         SetFocus(GetDlgItem(GetHandle(), IDOK));
  392         CheckDlgButton(GetHandle(), id_ShowAsLog, (CounterWnd->eScaleType == sLogarithmic));
  393         sprintf(buf, "%.1f", CounterWnd->fMaxIntensity);
  394         SetDlgItemText(GetHandle(), id_MaxIntensity, (LPSTR)buf);
  395         sprintf(buf, "%u", CounterWnd->nBarCount);
  396         SetDlgItemText(GetHandle(), id_BarNumber, (LPSTR)buf);
  397         return TRUE;
  398 };
  399 
  400 BOOL TCounterShowParamDlg::CanClose(void)
  401 {
  402         float value_f;
  403         short value_s;
  404         char buf[MaxString];
  405 
  406         if (!IsDlgButtonChecked(GetHandle(), id_ShowAsLog))
  407                 CounterWnd->eScaleType= sLinear;
  408         else
  409                 CounterWnd->eScaleType= sLogarithmic;
  410 
  411         GetDlgItemText(GetHandle(), id_MaxIntensity, (LPSTR)buf, 10);
  412 
  413         value_f= atof(buf);
  414 
  415         if ((value_f < 2e5) && (value_f > 0.0))
  416                 CounterWnd->fMaxIntensity= value_f;
  417         else
  418         {
  419                 CounterWnd->fMaxIntensity= 2.6e4;
  420                 sprintf(buf, "%.1f", CounterWnd->fMaxIntensity);
  421                 SetDlgItemText(GetHandle(), id_MaxIntensity, (LPSTR)buf);
  422                 return FALSE;
  423         }
  424 
  425         GetDlgItemText(GetHandle(), id_BarNumber, (LPSTR)buf, 10);
  426         value_s= (short)atoi(buf);
  427 
  428         if (CounterWnd->nBarCount == value_s)
  429                 return TRUE;
  430 
  431         if ((value_s < 140) && (value_s > 0))
  432         {
  433                 CounterWnd->nBarCount= value_s;
  434                 // Änderung des belegten Speichers notwendig
  435                 CounterWnd->Sensor->MeasureStop();
  436 
  437 
  438                 // 31.04.2004 MEMCORRECT (verwende IField) HeapReAlloc(GetProcessHeap(),0, CounterWnd->hMemG, CounterWnd->nBarCount*sizeof(float));
  439                 CounterWnd->IField.SetCount( CounterWnd->nBarCount );
  440 
  441 
  442                 CounterWnd->nIdx= 0;
  443                 CounterWnd->Sensor->MeasureStart();
  444                 sprintf(buf, "%u", CounterWnd->nBarCount);
  445                 SetDlgItemText(GetHandle(), id_BarNumber, (LPSTR)buf);
  446         }
  447         else
  448         {
  449                 sprintf(buf, "%u", CounterWnd->nBarCount);
  450                 SetDlgItemText(GetHandle(), id_BarNumber, (LPSTR)buf);
  451                 return FALSE;
  452         }
  453 
  454         return TRUE;
  455 };
  456 
  457 // __LastLine__
  458 
  459