File: MANJUST\MJ_GUI.CPP

    1 //#############################################################################
    2 //                                                                           //
    3 // MJ_GUI.CPP                                                                //
    4 //                                                                           //
    5 // Subsystem : neue Manuelle Justage / Oberfläche                            //
    6 // Benutung durch andere Subsysteme erforderlich: JA                         //
    7 //---------------------------------------------------------------------------//
    8 // Autoren: Thomas Kullmann, Günther Reinecker                               //
    9 // Stand  : 21.04.2002                                                       //
   10 //                                                                           //
   11 //#############################################################################
   12 
   13 #include "internls\evrythng.h" // GermanVersion
   14 #include "winresrc\rc_def.h"   // Ressourcen-IDs
   15 #include "help\help_def.h"     // Help-IDs
   16 #include <assert.h> // assert()
   17 
   18 #include "manjust\mj_gui.h" // SCHNITTSTELLE für diese Datei
   19 
   20 //--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--//--||--\\--||--
   21 
   22 extern HINSTANCE hModuleInstance;
   23 
   24 //#############################################################################
   25 // sprachspezifische Konstanten
   26 //#############################################################################
   27 
   28 static const char _NODRIVE[]= "-"; // sprachunabhängige Kennzeichung für "kein Antrieb" in der ini-Datei
   29 
   30 static const UINT USR_OTHERCONTROLS= WM_USER + 100;
   31 static const UINT USR_TB_CONTROLS= WM_USER + 102;
   32 static const UINT USR_TB_KINDOFMOVE= WM_USER + 103;
   33 static const UINT USR_TB_STARTSTOP= WM_USER + 104;
   34 static const UINT USR_TB_MOTIONPARAM= WM_USER + 105;
   35 static const UINT USR_TB_POSITIONS= WM_USER + 106;
   36 static const UINT USR_TB_OFFSET= WM_USER + 107;
   37 static const UINT USR_TB_UNITS= WM_USER + 108;
   38 static const UINT USR_TB_CONTROLSENABLE= WM_USER + 109;
   39 static const UINT USR_TB_MOTORLISTENABLE= WM_USER + 110;
   40 static const UINT USR_TB_KINDOFMOVEENABLE= WM_USER + 111;
   41 static const UINT USR_TB_STARTSTOPENABLE= WM_USER + 112;
   42 static const UINT USR_TB_MOTIONPARAMENABLE= WM_USER + 113;
   43 static const UINT USR_TB_POSITIONSENABLE= WM_USER + 114;
   44 static const UINT USR_TB_OFFSETENABLE= WM_USER + 115;
   45 static const UINT USR_TB_MOTORCHANGED= WM_USER + 116;
   46 
   47 //#############################################################################
   48 // TManJustageDlg
   49 //#############################################################################
   50 
   51 //*****************************************************************************
   52 // KONSTRUKTOR-DESTRUKTOR
   53 //*****************************************************************************
   54 
   55 TManJustageDlg::TManJustageDlg ( void ) : TModalDlg( "MANUALADJUSTMENTDLG", GetMainInstance() ), m_lnkManJustage( 0 ), m_lnkTimer( 0 ), m_Selection( 0 )
   56 {
   57         m_lnkManJustage= new TManJustage(); //POLLING, d.h. KEINE Referenz auf uns übergeben
   58         m_lnkTimer= new TInterfaceTimer( this, 100 ); //Observer, d.h. Timer benachrichtigt uns
   59 
   60         // enthält für jeden Teilbereich, welcher Index zuletzt ausgewählt war
   61         m_Selection= new UINT[ TB_Count() ];
   62         for (UINT i= 0; i < TB_Count(); i++)
   63                 m_Selection[i]= m_lnkManJustage->GetMotorCount() + 1; // bislang ist nichts ausgewählt (sonst keine Änderung bei SetSelection und Aktualisierung bleibt aus)
   64 
   65         m_Parallel= IniReadBool(GetCFile(), "ManualAdjustment", "Parallel", TRUE);
   66         m_StateRefresh= IniReadBool(GetCFile(), "ManualAdjustment", "StateRefresh", TRUE);
   67         m_DisplayNoActionMsg= IniReadBool(GetCFile(), "ManualAdjustment", "DisplayNoActionMsg", FALSE);
   68 };
   69 //-----------------------------------------------------------------------------
   70 
   71 TManJustageDlg::~TManJustageDlg ( void )
   72 {
   73         IniWriteBool(GetCFile(), "ManualAdjustment", "Parallel", m_Parallel);
   74         IniWriteBool(GetCFile(), "ManualAdjustment", "StateRefresh", m_StateRefresh);
   75         IniWriteBool(GetCFile(), "ManualAdjustment", "DisplayNoActionMsg", m_DisplayNoActionMsg);
   76         _FREEOBJ( m_Selection );
   77         _FREEOBJ( m_lnkManJustage );
   78         _FREEOBJ( m_lnkTimer );
   79 };
   80 
   81 //*****************************************************************************
   82 // EREIGNISSE DER BASISKLASSE
   83 //*****************************************************************************
   84 
   85 BOOL TManJustageDlg::Dlg_OnInit ( HWND, HWND, LPARAM )
   86 {
   87         m_lnkManJustage->BeginUpdate();
   88         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
   89         while ( TB_Next(tb) )
   90         { // alle drei Teilbereiche
   91                 UINT i; // zum Durchsuchen der Liste der verfügbaren Antriebe
   92 
   93                 // Antriebs-Auswahllisten mit verfügbaren Antrieb und "kein Antrieb" füllen
   94                 BOOL bValid;
   95                 for (i= 0; i < m_lnkManJustage->GetMotorCount(); i++)
   96                         CtrlAddString( GetResId(tb, riMotorList), m_lnkManJustage->GetMotorName(i, bValid) );
   97                 CtrlAddString( GetResId(tb, riMotorList), sth_mj_NoMotor );
   98 
   99                 // Bezeichnung des zuletzt verwendeten Antriebs aus ini-Datei laden, _NODRIVE ("-"= kein Antrieb) oder "" (erster Aufruf dieses Dialogfensters)
  100                 char tbName[ 13 ]; // Teilbereich<Ziffer> + Nullterminierung
  101                 TB_GetName( tb, tbName );
  102                 char mName[ _MAXLENCHARACTERISTIC + 1 ]; // + Nullterminierung
  103                 IniReadString( mName, GetCFile(), "ManualAdjustment", tbName, "", _MAXLENCHARACTERISTIC );
  104 
  105                 // Index des auszuwählenden Antriebs ermitteln
  106                 int mSel;
  107                 if ( strcmp(mName, _NODRIVE) != 0 )
  108                 {
  109                         // Index des zuletzt ausgewählten Antriebs ermitteln; Antrieb darf nicht mehrfach angezeigt werden
  110                         if ( strcmp(mName, "") == 0 )
  111                                 mSel= -1; // -1 <--> erster Aufruf dieses Dialogfensters
  112                         else
  113                                 mSel= m_lnkManJustage->GetMotorIdx( mName ); // -1 <--> Antrieb ist nicht mehr vorhanden
  114                         if ( Selection2TB(mSel) != ETB(0) )
  115                                 mSel= -1; // Antrieb wird bereits angezeigt
  116                         // falls der Index noch nicht feststeht UND der Antrieb noch nicht angezeigt wird: wähle den ersten verfügbaren Antrieb, der noch nicht angezeigt wird
  117                         for (i= 0; i < m_lnkManJustage->GetMotorCount(); i++)
  118                                 if ( (mSel == -1) && (Selection2TB(i) == (ETB)0) && (CanSetSelection(tb,i)) )
  119                                         mSel= i;
  120                         if ( mSel == -1 )
  121                                 mSel= m_lnkManJustage->GetMotorCount(); // kein "erster verfügbarer Antrieb": wähle "kein Antrieb"
  122                 }
  123                 else
  124                         mSel= m_lnkManJustage->GetMotorCount(); // "kein Antrieb", darf auch mehrfach angezeigt werden
  125 
  126                 // Antrieb auswählen, Inhalt der Steuerelemente im Teilbereich aktualisieren, freigeben bzw. sperren und ausgrauen
  127                 SetSelection( tb, mSel );
  128         };
  129 
  130         // Halbwertsbreite beschriften und Steuerelemenete (außerhalb der Teilbereiche) freigeben bzw. sperren und ausgrauen
  131         Notice( USR_OTHERCONTROLS, (ETB)0 );
  132         m_lnkManJustage->EndUpdate();
  133 
  134         // Beschriftung von '<Psd>-Offset...'
  135         BOOL bValid;
  136         LPCSTR dName= m_lnkManJustage->GetDetectorName( bValid );
  137         CtrlSetFormat( cm_PsdOffset, sth_mj_PsdOffset, dName );
  138 
  139         // HotKey's für Betriebsarten in den Teilbereichen UND zum Wechseln zwischen den Teilbereichen (nur Win32)
  140         LoadHotKeys( LoadAccelerators(GetMainInstance(), MAKEINTRESOURCE(ACC_ManualAdjustment)) ); // Accelerator aus Ressourcen laden
  141         return TRUE;
  142 };
  143 //-----------------------------------------------------------------------------
  144 
  145 LRESULT TManJustageDlg::OnEvent ( HWND aWnd, UINT aId, WPARAM wParam, LPARAM lParam )
  146 {
  147         if ( TBasicDialog::OnEvent(aWnd, aId, wParam, lParam) )
  148                 return TRUE; // Botschaft verarbeitet
  149         switch ( aId )
  150         { // die folgenden Nachrichten erlauben das Füllen und Freigeben bzw. Sperren und Ausgrauen der Steuerelemente im Hintergrund
  151                 case USR_OTHERCONTROLS:
  152                         OtherControls();
  153                         return TRUE; // Botschaft wurde verarbeitet
  154 
  155                 case USR_TB_CONTROLS:
  156                         OnTB_Controls( (ETB)wParam, (BOOL)lParam );
  157                         return TRUE; // Botschaft wurde verarbeitet
  158 
  159                 case USR_TB_KINDOFMOVE:
  160                         OnTB_KindOfMove( (ETB)wParam, (BOOL)lParam );
  161                         return TRUE; // Botschaft wurde verarbeitet
  162 
  163                 case USR_TB_STARTSTOP:
  164                         OnTB_StartStop( (ETB)wParam, (BOOL)lParam );
  165                         return TRUE; // Botschaft wurde verarbeitet
  166 
  167                 case USR_TB_MOTIONPARAM:
  168                         OnTB_MotionParam( (ETB)wParam, (BOOL)lParam );
  169                         return TRUE; // Botschaft wurde verarbeitet
  170 
  171                 case USR_TB_POSITIONS:
  172                         OnTB_Positions( (ETB)wParam, (BOOL)lParam );
  173                         return TRUE; // Botschaft wurde verarbeitet
  174 
  175                 case USR_TB_OFFSET:
  176                         OnTB_Offset( (ETB)wParam, (BOOL)lParam );
  177                         return TRUE; // Botschaft wurde verarbeitet
  178 
  179                 case USR_TB_UNITS:
  180                         OnTB_Units( (ETB)wParam );
  181                         return TRUE; // Botschaft wurde verarbeitet
  182 
  183                 case USR_TB_CONTROLSENABLE:
  184                         OnTB_ControlsEnable( (ETB)wParam );
  185                         return TRUE; // Botschaft wurde verarbeitet
  186 
  187                 case USR_TB_MOTORLISTENABLE:
  188                         OnTB_MotorListEnable( (ETB)wParam );
  189                         return TRUE; // Botschaft wurde verarbeitet
  190                 
  191                 case USR_TB_KINDOFMOVEENABLE:
  192                         OnTB_KindOfMoveEnable( (ETB)wParam );
  193                         return TRUE; // Botschaft wurde verarbeitet
  194                 
  195                 case USR_TB_STARTSTOPENABLE:
  196                         OnTB_StartStopEnable( (ETB)wParam );
  197                         return TRUE; // Botschaft wurde verarbeitet
  198                 
  199                 case USR_TB_MOTIONPARAMENABLE:   // Spezialfall: siehe Notice()
  200                         OnTB_MotionParamEnable( (ETB)wParam );
  201                         return TRUE; // Botschaft wurde verarbeitet
  202                 
  203                 case USR_TB_POSITIONSENABLE:
  204                         OnTB_PositionsEnable( (ETB)wParam );
  205                         return TRUE; // Botschaft wurde verarbeitet
  206                 
  207                 case USR_TB_OFFSETENABLE:
  208                         OnTB_OffsetEnable( (ETB)wParam );
  209                         return TRUE; // Botschaft wurde verarbeitet
  210 
  211                 case USR_TB_MOTORCHANGED:
  212                         TB_MotorChanged( (ETB)wParam );
  213                         return TRUE; // Botschaft wurde verarbeitet
  214         }
  215         return FALSE; // Botschaft nicht verarbeitet
  216 };
  217 //-----------------------------------------------------------------------------
  218 
  219 void TManJustageDlg::Dlg_OnCommand ( HWND aHWnd, int aId, HWND aCtrlWnd, UINT aCode )
  220 {
  221         if ( aCode==ONENTER ) return;
  222         // prüfe zuerst die Steuerelemente in den Teilbereichen, diese wurden in drei Gruppen eingeteilt:
  223         // LINKS: Auswahlliste Antrieb, Betriebsarten
  224         // MITTE: Start/ Stop und Betriebsarten, wenn [ENTER] gedrückt wurde
  225         // RECHTS: Relative Null setzen, aufheben; Offset setzen
  226         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
  227         while ( TB_Next(tb) )
  228         {
  229                 if (  ( (TB_CheckLeft(tb, aId)) || (TB_CheckMiddle(tb, aId)) || (TB_CheckRight(tb, aId)) ) ||
  230                            ( (aCode == ONEXIT) && (TB_CheckExit(tb, aId)) )  )
  231                         return; // Botschaft verarbeitet
  232         }
  233 
  234         // prüfe dann die Steuerelemente außerhalb der Teilbereiche
  235         switch ( aId )
  236         {
  237                 case cm_PsdOffset:
  238                         OnPsdOffset();
  239                         return; // Botschaft verarbeitet
  240 
  241                 case cm_HwbMeasure:
  242                         if ( !m_lnkManJustage->IsMeasuring() )
  243                         { // dann starten
  244                                 if ( m_lnkManJustage->DoStartMeasure( GetHandle() ) )
  245                                         m_lnkTimer->StartTimerIm(); // wenn Makroverarbeitung gestartet sorgt der Timer für Bildschirmaktualisierung
  246                                 else
  247                                         OnNoAction(); // Messung kann nicht gestartet werden
  248                         }
  249                         else if ( m_lnkManJustage->DoStopMeasure() )
  250                                 m_lnkTimer->Immediately(); // Makroverarbeitung stoppen: der Timer stoppt automatisch, wenn nichts mehr zu überwachen ist
  251                         else
  252                                 OnNoAction(); // Messung kann nicht gestoppt werden
  253                         return; // Botschaft verarbeitet
  254 
  255                 case cm_ChooseTB:   // Tastenkombination "Ctrl+Tab"
  256                         OnChooseTB();
  257                         return; // Botschaft verarbeitet
  258 
  259                 case cm_Help:
  260                         WinHelp(GetHandle(), GetHelpFile(), HELP_CONTEXT, Help_ManualAdjustmentDlg);
  261                         return; // Botschaft verarbeitet
  262                         
  263                 case cm_CounterSet: // Aktualisieren des Detektorfensters
  264                         m_lnkManJustage->UpdateDetector();
  265                         return; // Botschaft verarbeitet
  266 
  267                 case IDOK:
  268                         return; // [ENTER]-Botschaft ignorieren; SONST schließt sich das Dialogfenster
  269 
  270                 default:
  271                         TModalDlg::Dlg_OnCommand( aHWnd, aId, aCtrlWnd, aCode );
  272         };
  273 };
  274 //-----------------------------------------------------------------------------
  275 
  276 void TManJustageDlg::Dlg_OnHScrollBar ( HWND, HWND aCtrl, UINT aCode, int aPos )
  277 {
  278         BOOL bValid;
  279         // in welchem Teilbereich wurde die Bildlaufleiste benutzt?
  280         ETB tb= ETB(0); // "unbekannte Bildlaufleiste"
  281         ETB tblist= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
  282         while ( TB_Next(tblist) )
  283                 if ( aCtrl == GetCtrl(tblist, riRelativePos) )
  284                         tb= tblist; // alle drei Teilbereiche
  285 
  286         // welcher Index ist in dem Teilbereich ausgewählt?
  287         UINT mSel= TB2Selection( tb ); // ggf. GetMotorCount(), d.h.
  288         EMotionType mt= m_lnkManJustage->GetMotionType( mSel, bValid );
  289         if ( !bValid )
  290                 return; // "unbekannter Teilbereich" oder "kein Antrieb"
  291 
  292         // Spezialfall: Direktbetrieb
  293         if ( mt == mtDirect )
  294         {
  295                 if ( (aCode != SB_THUMBTRACK) && (aCode != SB_ENDSCROLL) )
  296                         MessageBox( sth_mj_NoScroll, sth_mj_ErrTitle, MBSTOP ); // THUMBTRACK und SB_ENDSCROLL werden ausgeschlossen, nach einer Interaktion des Anwenders erscheinen sonst mehrere Meldungsfenster
  297                 return; //Steuerung nur im Fahr- und Schrittbetrieb
  298         }
  299 
  300         // aufwärts, merkwürdig ist die widersprüchliche Benennung der Scrollcodes
  301         if ( ( (aCode == SB_LINEDOWN) || (aCode == SB_PAGEDOWN) ) || (aCode == SB_BOTTOM) || ( (aCode == SB_THUMBPOSITION) && (aPos > ScrollBar_GetPos(aCtrl)) ) )
  302         {
  303                 if ( mt == mtDrive )
  304                 {
  305                         if ( m_lnkManJustage->DoDrive(mSel, dUp) )
  306                                 m_lnkTimer->StartTimerIm();
  307                         else
  308                                 OnNoAction(); // Fahrbetrieb nicht möglich
  309                 }
  310                 if ( mt == mtStep )
  311                 {
  312                         if ( m_lnkManJustage->DoStep(mSel, dUp) )
  313                                 m_lnkTimer->StartTimerIm();
  314                         else
  315                                 MessageBeep( -1); // Schrittbetrieb nicht möglich
  316                 }
  317         }
  318 
  319         // abwärts, merkwürdig ist die widersprüchliche Benennung der Scrollcodes
  320         if ( ( (aCode == SB_LINEUP) || (aCode == SB_PAGEUP) ) || (aCode == SB_TOP) || ( (aCode == SB_THUMBPOSITION) && (aPos < ScrollBar_GetPos(aCtrl)) ) )
  321         {
  322                 if ( mt == mtDrive )
  323                 {
  324                         if ( m_lnkManJustage->DoDrive(mSel, dDown) )
  325                                 m_lnkTimer->StartTimerIm();
  326                         else
  327                                 OnNoAction(); // Fahrbetrieb nicht möglich
  328                 }
  329                 if ( mt == mtStep )
  330                 {
  331                         if ( m_lnkManJustage->DoStep(mSel, dDown) )
  332                                 m_lnkTimer->StartTimerIm();
  333                         else
  334                                 MessageBeep( -1); // Schrittbetrieb nicht möglich
  335                 }
  336         }
  337 
  338         //Fahrbetrieb: Bewegung endet, wenn [Maus-]Taste losgelassen wird (Bildlaufpfeil nicht mehr gedrückt wird)
  339         if ( (aCode == SB_ENDSCROLL) && (mt == mtDrive) )
  340         {
  341                 if ( m_lnkManJustage->DoStop(mSel) )
  342                         m_lnkTimer->Immediately(); // Bewegung stoppen: der Timer stoppt automatisch, wenn nichts mehr zu aktualisieren ist
  343                 else
  344                         OnNoAction(); // Stoppen der Bewegung im Fahrbetrieb nicht möglich
  345         }
  346 };
  347 //-----------------------------------------------------------------------------
  348 
  349 void TManJustageDlg::LeaveDialog ( void )
  350 {
  351         m_lnkManJustage->DoStopEverything();
  352 };
  353 
  354 //*****************************************************************************
  355 // EREIGNISSE
  356 //*****************************************************************************
  357 
  358 void TManJustageDlg::OnTimer ( TBasicTimer *const )
  359 {
  360         BOOL bValid;
  361         BOOL bStopTimer= TRUE; //Standard: alles ruht, Timer wird nicht mehr benötigt
  362 
  363         m_lnkManJustage->BeginUpdate();
  364         BOOL isMeasuring= m_lnkManJustage->IsMeasuring();
  365         BOOL kzMeasuring= m_lnkManJustage->GetKzMeasuring();
  366         // zuerst prüfen wir was die Antriebe machen; aber nur wenn KEIN Makro verarbeitet wird (Makroverarbeitung == alle Antriebe reserviert für Bewegung)
  367         // nur die Antriebe in den Teilbereichen überprüfen
  368         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
  369         if ( !isMeasuring )
  370                 while ( TB_Next(tb) )
  371                 { //05.02.2003 wir prüfen nicht mehr alle Antriebe, sondern nur die angezeigten in den Teilbereichen
  372                         int i= TB2Selection(tb); // dieser Antrieb wird angezeigt
  373                         if ( i == m_lnkManJustage->GetMotorCount() )
  374                                 continue; // kein Antrieb ist ausgewählt
  375                         BOOL isMoving= m_lnkManJustage->IsMoving(i, bValid);
  376                         BOOL kzMoving= m_lnkManJustage->GetKzMoving(i, bValid);
  377                         // seit dem letzten OnTimer wurde dieser Antrieb gestartet
  378                         if ( (isMoving) && (!kzMoving) && (bValid) )
  379                         {
  380                                 bStopTimer= FALSE; // die Bewegung dieses Antriebs weiter verfolgen
  381                                 m_lnkManJustage->SetKzMoving( i, TRUE ); // jetzt hat auch die Oberfläche erfahren, dass der Antrieb gestartet wurde
  382                                 OnMotionStarts( i );
  383 
  384                                 // der Antrieb ist immernoch in Bewegung
  385                         }
  386                         else if ( (isMoving) && (kzMoving) && (bValid) )
  387                         {
  388                                 bStopTimer= FALSE; // die Bewegung dieses Antriebs weiter verfolgen
  389                                 OnMotionProgress( i );
  390 
  391                                 // seit dem letzten OnTimer hat dieser Antrieb gestoppt
  392                         }
  393                         else if ( (!isMoving) && (kzMoving) && (bValid) )
  394                         {
  395                                 // diesen Antrieb brauchen wir nicht weiter überwachen
  396                                 m_lnkManJustage->SetKzMoving( i, FALSE ); // jetzt hat auch die Oberfläche erfahren, dass der Antrieb gestoppt wurde
  397                                 OnMotionStops( i );
  398                         }
  399                 }
  400 
  401         // dann noch die Makroverarbeitung prüfen
  402         // seit dem letzten OnTimer wurde die Makroverarbeitung gestartet
  403         if ( (isMeasuring) && (!kzMeasuring) )
  404         {
  405                 bStopTimer= FALSE; // die Makroverarbeitung wollen wir weiter verfolgen
  406                 OnMeasureStarts();
  407         }
  408         else if ( (isMeasuring) && (kzMeasuring) )
  409         { // das Makro läuft immernoch
  410                 bStopTimer= FALSE; // die Makroverarbeitung wollen wir weiter verfolgen
  411                 OnMeasureProgress();
  412         }
  413         else if ( (!isMeasuring) && (kzMeasuring) )
  414         { // seit dem letzten OnTimer hat die Makroverarbeitung gestoppt
  415                 OnMeasureStops(); 
  416                 // Makroverarbeitung nicht weiter überwachen
  417         } 
  418         m_lnkManJustage->EndUpdate();
  419         if (bStopTimer)
  420                 m_lnkTimer->StopTimer(); // wenn alle Antriebe stehen und kein Makro verarbeitet wird
  421 };
  422 //-----------------------------------------------------------------------------
  423 
  424 void TManJustageDlg::OnMotionStarts ( const UINT aSel )
  425 {
  426         ETB tb= Selection2TB(aSel);
  427         if ( tb == (ETB)0 )
  428                 return;
  429 
  430         OnTB_ControlsEnable( tb ); // zuerst die Steuerelemente freigeben bzw. sperren und ausgrauen
  431         Notice( USR_TB_STARTSTOP, tb ); // "Start" mit "Stop" beschriften
  432         Notice( USR_OTHERCONTROLS, (ETB)0 ); // Steuerelemente außerhalb der Teilbereiche
  433 };
  434 //-----------------------------------------------------------------------------
  435 
  436 void TManJustageDlg::OnMotionProgress ( const UINT aSel )
  437 {
  438         ETB tb= Selection2TB(aSel);
  439         if ( tb != (ETB)0 )
  440                 OnTB_Positions( tb, FALSE ); // Notice( USR_TB_POSITIONS, Selection2TB(aSel) ); ist zu langsam
  441 };
  442 //-----------------------------------------------------------------------------
  443 
  444 void TManJustageDlg::OnMotionStops ( const UINT aSel )
  445 {
  446         ETB tb= Selection2TB(aSel);
  447         if ( tb == (ETB)0 )
  448                 return;
  449 
  450         OnTB_ControlsEnable( tb ); // zuerst die Steuerelemente freigeben bzw. sperren und ausgrauen
  451         Notice( USR_TB_POSITIONS, tb ); // Positionen aktualisieren
  452         Notice( USR_TB_STARTSTOP, tb ); // "Stop" mit "Start" beschriften
  453         Notice( USR_OTHERCONTROLS, (ETB)0 ); // Steuerelemente außerhalb der Teilbereiche
  454 };
  455 //-----------------------------------------------------------------------------
  456 
  457 void TManJustageDlg::OnMeasureStarts ( void )
  458 {
  459         m_lnkManJustage->SetKzMeasuring( TRUE ); // jetzt hat auch die Oberfläche erfahren, dass die Makroverarbeitung gestartet wurde
  460 
  461         // "Halbwertsbreite wird gemessen..." anzeigen
  462         CtrlSetText( id_HwbState, sth_mj_IsMeasuring );
  463 
  464         // alle Steuerelemente aktualisieren, sperren und ausgrauen
  465         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
  466         while ( TB_Next(tb) )
  467         { // alle drei Teilbereiche
  468                 Notice( USR_TB_STARTSTOP, tb ); // "Start" mit "Stop" beschriften
  469                 Notice( USR_TB_CONTROLSENABLE, tb ); // alle Steuerelemente speeren
  470         }
  471         Notice( USR_OTHERCONTROLS, (ETB)0 );
  472 };
  473 //-----------------------------------------------------------------------------
  474 
  475 void TManJustageDlg::OnMeasureProgress ( void )
  476 {
  477         // Fortschritt zeigen
  478         int idx, count;
  479         char *progress= new char [ MaxString + 1 ]; //siehe TCmd::GetShowData (und abgeleitete Klassen)
  480         if ( !m_lnkManJustage->GetMeasureProgress(idx, progress, count) ) {
  481                 _FREELIST(progress);
  482                 return; // Messung ist bereits beendet
  483         }
  484 
  485         CtrlSetFormat( id_HwbState, sth_mj_Progress, idx + 1, count, progress );
  486         _FREELIST(progress);
  487 };
  488 //-----------------------------------------------------------------------------
  489 
  490 void TManJustageDlg::OnMeasureStops ( void )
  491 {
  492         m_lnkManJustage->SetKzMeasuring( FALSE ); // jetzt hat auch die Oberfläche erfahren, dass die Makroverarbeitung gestoppt hat oder wurde
  493 
  494         BOOL bValid;
  495         // Wert der Halbwertsbreitenmessung anzeigen
  496         if ( !m_lnkManJustage->IsMeasureReset() )
  497         { // Makroverarbeitung und Messung erfolgreich beendet
  498                 double hwb= m_lnkManJustage->GetMeasureHwb();
  499                 char *value= new char[ _MAXLENDOUBLE + 1 ]; // Double-Werte haben max. 50 Zeichen + Nullterminierung
  500                 Double2String( value, hwb, m_lnkManJustage->GetDigits( m_lnkManJustage->GetHwbAxis(), bValid ), FALSE, _DECIMAL); // wenn zu viele Nachkommastellen: Rest abschneiden
  501                 LPCSTR unit= m_lnkManJustage->GetUnit( m_lnkManJustage->GetMotorIdx(m_lnkManJustage->GetHwbAxis()), bValid );
  502 
  503                 MessageBeep( -1 );
  504                 CtrlSetFormat( id_HwbState, sth_mj_MeasureValue, value, unit ); 
  505                 _FREELIST(value);
  506                 char buf[MaxString+1];
  507                 CtrlGetText( id_HwbState, buf, MaxString);
  508                 SetInfo( buf );
  509                 // Messung wurde abgebrochen
  510         }
  511         else
  512                 CtrlSetText( id_HwbState, sth_mj_MeasureInterrupted );
  513 
  514         // alle Steuerelemente aktualisieren, freigeben bzw. sperren und ausgrauen
  515         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
  516         while ( TB_Next(tb) )
  517         { // alle drei Teilbereiche
  518                 Notice( USR_TB_POSITIONS, tb );  // Positionen aktualisieren
  519                 Notice( USR_TB_STARTSTOP, tb ); // "Stop" mit "Start" beschriften
  520                 Notice( USR_TB_CONTROLSENABLE, tb ); // alle Steuerelemente speeren
  521         }
  522         Notice( USR_OTHERCONTROLS, (ETB)0 );
  523 };
  524 
  525 //*****************************************************************************
  526 // Verhalten aller Steuerelemente außerhalb der Teilbereiche
  527 //*****************************************************************************
  528 
  529 void TManJustageDlg::OnPsdOffset ( void )
  530 {
  531         int idx= m_lnkManJustage->GetDetectorAxisIdx();
  532         if ( !m_lnkManJustage->CanSetOffset(idx) )
  533         { // PSD-Offsetdialog nur anzeigen wenn wir dürfen; includes m_lnkManJustage->HasDetectorAxis()
  534                 OnNoAction();
  535                 return;
  536         }
  537 
  538         //Dialog anzeigen
  539         TModalDlg *dlg= new TPsdOffsetDlg( idx, m_lnkManJustage );
  540         if ( dlg ) dlg->ExecuteDialog( GetHandle() );
  541         _FREEOBJ(dlg);
  542 
  543         m_lnkManJustage->BeginUpdate();
  544         // ALLE Teilbereiche aktualisieren, wir wissen nicht wo <_PSDAXIS> angezeigt wird
  545         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
  546         while ( TB_Next(tb) )
  547         {
  548                 Notice( USR_TB_POSITIONS, tb );    // Positionen aktualisieren,
  549                 Notice( USR_TB_OFFSET, tb, TRUE ); // Steuerelemnete für Relative Null, Offset freigeben bzw. sperren und ausgrauen; ggf. "OFFSET" anzeigen
  550         }
  551         m_lnkManJustage->EndUpdate();
  552 };
  553 //-----------------------------------------------------------------------------
  554 
  555 void TManJustageDlg::OnChooseTB ( void )
  556 {
  557         // wir ermitteln welcher Teilbereich derzeit fokussiert ist und fokusieren die Antriebsauswahlliste des nächsten Teilbereichs (nach dem dritten folgt der erste)
  558         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
  559         while ( TB_Next(tb) )
  560                 if ( (CtrlHasFocus(GetResId(tb, riMotorList))) || (CtrlHasFocus(GetResId(tb, riDirectMode))) || (CtrlHasFocus(GetResId(tb, riDriveMode))) || (CtrlHasFocus(GetResId(tb, riStepMode))) || (CtrlHasFocus(GetResId(tb, riStart))) ||
  561                                 (CtrlHasFocus(GetResId(tb, riRelativePos))) || (CtrlHasFocus(GetResId(tb, riAngleDest))) || (CtrlHasFocus(GetResId(tb, riSpeed))) || (CtrlHasFocus(GetResId(tb, riStepWidth))) ||
  562                                 (CtrlHasFocus(GetResId(tb, riSetRelativeZero))) || (CtrlHasFocus(GetResId(tb, riResetRelativeZero))) || (CtrlHasFocus(GetResId(tb, riAngle))) || (CtrlHasFocus(GetResId(tb, riOffset))) )
  563                 {
  564                         if ( !TB_Next(tb) )
  565                                 break; // der letzte Teilbereich ist fokussiert: siehe nach der while-Schleife
  566                         CtrlSetFocus( GetResId(tb, riMotorList) );
  567                         return; // gefunden
  568                 }
  569         // Steuerelement nicht innerhalb der ersten beiden Teilbereiche, also im dritten oder außerhalb: fokussiere den ersten Teilbereich
  570         tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
  571         TB_Next(tb);
  572         CtrlSetFocus( GetResId(tb, riMotorList) );
  573 };
  574 //-----------------------------------------------------------------------------
  575 
  576 void TManJustageDlg::OnNoAction ( void )
  577 {
  578         if ( !m_DisplayNoActionMsg )
  579                 return;
  580 
  581         SetFocus(NULL); // <kein Steuerelement> fokussieren, sonst erscheint die Meldung u.U. mehrfach
  582         MessageBox( sth_mj_NoAction, sth_mj_ErrTitle, MBINFO );
  583 };
  584 
  585 //*****************************************************************************
  586 // Verhalten aller Steuerelemente innerhalb der Teilbereiche
  587 //*****************************************************************************
  588 
  589 BOOL TManJustageDlg::TB_CheckLeft ( const ETB aTB, const int aId )
  590 {
  591         // Auswahlliste Antrieb
  592         if ( aId == GetResId(aTB, riMotorList) )
  593         {
  594                 // weil der Regressionstest SENDMESSAGE zum Auswählen des Antriebs verwendet, wartet ATOS auf return TRUE; d.h. die Meldung "Antrieb ist bereits ausgewählt" wäre nicht testbar
  595                 // Verarbeitung der riMotorList-Botschaft deshalb quasiparallel
  596                 Notice( USR_TB_MOTORCHANGED, aTB );
  597                 return TRUE; // Botschaft verarbeitet
  598         }
  599 
  600         // Betriebsart
  601         EMotionType mt= (EMotionType)0;
  602         if ( aId == GetResId(aTB, riDirectMode) )
  603                 mt= mtDirect;
  604         if ( aId == GetResId(aTB, riDriveMode) )
  605                 mt= mtDrive;
  606         if ( aId == GetResId(aTB, riStepMode) )
  607                 mt= mtStep;
  608         if ( mt != (EMotionType)0 )
  609         { // NUR wenn eines der Betriebsarten-Optionsfelder
  610                 BOOL bValid= m_lnkManJustage->SetMotionType( TB2Selection(aTB), mt );
  611                 Notice( USR_TB_STARTSTOPENABLE, aTB );   // "Start" freigeben (Direktbetrieb) bzw. sperren und ausgrauen
  612                 Notice( USR_TB_KINDOFMOVE, aTB, TRUE );  // Betriebsart auswählen und freigeben bzw. sperren und ausgrauen
  613                 Notice( USR_TB_MOTIONPARAMENABLE, aTB ); // Bewegungsparameter freigeben bzw. sperren und ausgrauen
  614                 if ( bValid )
  615                 { // wenn die Betriebsart wirklich gesetzt wurde, entsprechenden Bewegungsparameter fokusieren (Eingabe hier sofort möglich)
  616                         if ( mt == mtDirect )
  617                                 CtrlSetFocus( GetResId(aTB, riAngleDest) );
  618                         if ( mt == mtDrive )
  619                                 CtrlSetFocus( GetResId(aTB, riSpeed) );
  620                         if ( mt == mtStep )
  621                                 CtrlSetFocus( GetResId(aTB, riStepWidth) );
  622                 }
  623                 else
  624                         OnNoAction();
  625                 return TRUE; // Botschaft verarbeitet
  626         };
  627         return FALSE; // Botschaft NICHT verarbeitet
  628 };
  629 //-----------------------------------------------------------------------------
  630 
  631 BOOL TManJustageDlg::TB_CheckMiddle ( const ETB aTB, const int aId )
  632 {
  633         BOOL bValid;
  634         EMotionType mt= m_lnkManJustage->GetMotionType( TB2Selection(aTB), bValid );
  635         if ( aId == GetResId(aTB, riStart) )
  636         { // Start bzw. Stop
  637                 TB_StartStopClicked( aTB );
  638                 return TRUE; // Botschaft verarbeitet
  639         };
  640 
  641         // [ENTER] wurde gedrückt
  642         if ( aId == IDOK )
  643         {
  644                 if ( CtrlHasFocus(GetResId(aTB, riAngleDest)) )
  645                 { // [ENTER] bei Sollposition
  646                         CtrlSetFocus( GetResId(aTB, riStart) ); // Versuch Start fokussieren (beim Verlassen wird TB_CheckExit gerufen)
  647                         return TRUE; // Botschaft verarbeitet
  648                 }
  649                 if ( CtrlHasFocus(GetResId(aTB, riSpeed)) )
  650                 { // [ENTER] bei Geschwindigkeit
  651                         if ( mt==mtDrive && bValid ) CtrlSetFocus( GetResId(aTB, riRelativePos) ); // Versuch Bildlaufleiste fokussieren wenn Fahrbetrieb (beim Verlassen wird TB_CheckExit gerufen)
  652                         else if ( mt==mtDirect && bValid ) CtrlSetFocus( GetResId(aTB, riStart) ); // Versuch Start fokussieren wenn Direktbetrieb (beim Verlassen wird TB_CheckExit gerufen)
  653                         return TRUE; // Botschaft verarbeitet
  654                 }
  655                 if ( CtrlHasFocus(GetResId(aTB, riStepWidth)) )
  656                 { // [ENTER] bei Schrittweite
  657                         CtrlSetFocus( GetResId(aTB, riRelativePos) ); // Versuch Bildlaufleiste fokussieren (beim Verlassen wird TB_CheckExit gerufen)
  658                         return TRUE; // Botschaft verarbeitet
  659                 }
  660                 if ( CtrlHasFocus(GetResId(aTB, riStart)) )
  661                 { // Start bzw. Stop
  662                         TB_StartStopClicked( aTB );
  663                         return TRUE; // Botschaft verarbeitet
  664                 }
  665         }
  666         return FALSE; // Botschaft nicht verarbeitet
  667 };
  668 //-----------------------------------------------------------------------------
  669 
  670 BOOL TManJustageDlg::TB_CheckRight ( const ETB aTB, const int aId )
  671 {
  672         int mSel= TB2Selection(aTB); // den ausgewählten Antrieb in diesem Teilbereich ermitteln
  673         // Setzen/ Aufheben der Relativen Null und Offset
  674         if ( aId == GetResId(aTB, riSetRelativeZero) )
  675         {
  676                 if ( !m_lnkManJustage->SetRelativeZero(mSel) )
  677                         OnNoAction(); // Relative Null konnte nicht gesetzt werden
  678 
  679                 Notice( USR_TB_POSITIONS, aTB );    // Positionen aktualisieren
  680                 Notice( USR_TB_OFFSET, aTB, TRUE ); // Steuerelemente für Offset, Relative Null setzen und aufheben freigeben bzw. sperren und ausgrauen; ggf. <_HASOFFSET> anzeigen
  681                 return TRUE; // Botschaft verarbeitet
  682         }
  683         if ( aId == GetResId(aTB, riResetRelativeZero) )
  684         {
  685                 if ( !m_lnkManJustage->ResetRelativeZero(mSel) )
  686                         OnNoAction(); // Relative Null konnte nicht aufgehoben werden
  687 
  688                 Notice( USR_TB_POSITIONS, aTB );    // Positionen aktualisieren
  689                 Notice( USR_TB_OFFSET, aTB, TRUE ); // Steuerelemente für Offset, Relative Null setzen und aufheben freigeben bzw. sperren und ausgrauen; ggf. <_HASOFFSET> anzeigen
  690                 return TRUE; // Botschaft verarbeitet
  691         }
  692         if ( aId == GetResId(aTB, riOffset) )
  693         {
  694                 if ( !m_lnkManJustage->CanSetOffset(mSel) )
  695                 { // Offset darf nicht definiert werden
  696                         OnNoAction();
  697                         return TRUE;
  698                 }
  699 
  700                 // Motoroffset-Dialog anzeigen
  701                 TModalDlg *dlg= new TMotorOffsetDlg( mSel, m_lnkManJustage );
  702                 if ( dlg ) dlg->ExecuteDialog( GetHandle() );
  703                 _FREEOBJ(dlg);
  704 
  705                 Notice( USR_TB_POSITIONS, aTB );    // Positionen aktualisieren
  706                 Notice( USR_TB_OFFSET, aTB, TRUE ); // Steuerelemente für Offset, Relative Null setzen und aufheben freigeben bzw. sperren und ausgrauen; ggf. "Offset" anzeigen
  707                 return TRUE; // Botschaft verarbeitet
  708         }
  709         return FALSE; // Botschaft NICHT verarbeitet
  710 };
  711 //-----------------------------------------------------------------------------
  712 
  713 BOOL TManJustageDlg::TB_CheckExit ( const ETB aTB, const int aId )
  714 {
  715         if ( aId == GetResId(aTB, riAngleDest) )
  716         {
  717                 TB_AngleDestEntered( aTB );
  718                 return TRUE;
  719         }
  720         else if ( aId == GetResId(aTB, riSpeed) )
  721         {
  722                 TB_SpeedEntered( aTB );
  723                 return TRUE;
  724         }
  725         else if ( aId == GetResId(aTB, riStepWidth) )
  726         {
  727                 TB_StepWidthEntered( aTB );
  728                 return TRUE;
  729         }
  730         else
  731                 return FALSE;
  732 };
  733 
  734 //*****************************************************************************
  735 // Verhalten für ausgewählter Steuerelemente innerhalb der Teilbereiche
  736 //*****************************************************************************
  737 
  738 void TManJustageDlg::TB_StartStopClicked ( const ETB aTB )
  739 {
  740         BOOL bValid;
  741         if ( !m_lnkManJustage->IsMeasuring() )
  742         { // SONST darf sich nicht's ändern
  743                 int mSel= TB2Selection(aTB); // den ausgewählten Antrieb in diesem Teilbereich ermitteln
  744                 if ( (!m_lnkManJustage->IsMoving(mSel, bValid)) && (bValid) )
  745                 { // dann starten
  746                         if ( m_lnkManJustage->DoDirect(mSel) )
  747                                 m_lnkTimer->StartTimerIm(); // wenn Bewegung gestartet wird sorgt der Timer für die Bildschirmaktualisierung
  748                         else
  749                                 OnNoAction(); // Direktbetrieb kann nicht gestartet werden
  750                 }
  751                 else if ( m_lnkManJustage->DoStop(mSel) )
  752                         m_lnkTimer->Immediately(); // Bewegung stoppen: der Timer stoppt automatisch, wenn nichts mehr zu aktualisieren ist
  753                 else
  754                         OnNoAction(); // beliebige Bewegung konnte nicht gestoppt werden
  755         }
  756 };
  757 //-----------------------------------------------------------------------------
  758 
  759 void TManJustageDlg::TB_AngleDestEntered ( const ETB aTB )
  760 {
  761         BOOL bValid, bSuccess= TRUE;
  762         int mSel= TB2Selection(aTB); // den ausgewählten Antrieb in diesem Teilbereich ermitteln
  763         UINT iDigits= m_lnkManJustage->GetDigits( mSel, bValid ); //Nachkommastellen schonmal im vorhinein ermitteln
  764         if ( (m_lnkManJustage->IsIndexValid(mSel)) && (!m_lnkManJustage->IsMeasuring()) )
  765         { // SONST darf sich nichts ändern
  766                 TAngle value= CtrlGetDouble( GetResId(aTB, riAngleDest), iDigits, _DECIMAL, bValid );
  767                 bSuccess= ( (bValid) && (m_lnkManJustage->SetAngleDest(mSel, value)) );
  768         }
  769         OnTB_MotionParam( aTB, FALSE ); // Bewegungsparameter immer aktualisieren (wenn der gewünschte Wert nicht in die Funktionalität übernommen wurde); Notice ist zu langsam
  770         if ( !bSuccess )
  771                 OnNoAction();
  772 };
  773 //-----------------------------------------------------------------------------
  774 
  775 void TManJustageDlg::TB_SpeedEntered ( const ETB aTB )
  776 {
  777         BOOL bValid, bSuccess= TRUE;
  778         int mSel= TB2Selection(aTB); // den ausgewählten Antrieb in diesem Teilbereich ermitteln
  779         UINT iDigits= m_lnkManJustage->GetDigits( mSel, bValid ); //Nachkommastellen schonmal im vorhinein ermitteln
  780         if ( (m_lnkManJustage->IsIndexValid(mSel)) && (!m_lnkManJustage->IsMeasuring()) )
  781         { // SONST darf sich nichts ändern
  782                 EMotionType mt= m_lnkManJustage->GetMotionType( mSel, bValid );
  783                 TAngle value= CtrlGetDouble( GetResId(aTB, riSpeed), iDigits, _DECIMAL, bValid );
  784                 bSuccess= ( (bValid) && (m_lnkManJustage->SetSpeed(mSel, value)) );
  785         }
  786         OnTB_MotionParam( aTB, FALSE ); // Bewegungsparameter immer aktualisieren (wenn der gewünschte Wert nicht in die Funktionalität übernommen wurde); Notice ist zu langsam
  787         if ( !bSuccess )
  788                 OnNoAction();
  789 };
  790 //-----------------------------------------------------------------------------
  791 
  792 void TManJustageDlg::TB_StepWidthEntered ( const ETB aTB )
  793 {
  794         BOOL bValid, bSuccess= TRUE;
  795         int mSel= TB2Selection(aTB); // den ausgewählten Antrieb in diesem Teilbereich ermitteln
  796         UINT iDigits= m_lnkManJustage->GetDigits( mSel, bValid ); //Nachkommastellen schonmal im vorhinein ermitteln
  797         if ( (m_lnkManJustage->IsIndexValid(mSel)) && (!m_lnkManJustage->IsMeasuring()) )
  798         { // SONST darf sich nichts ändern
  799                 TAngle value= CtrlGetDouble( GetResId(aTB, riStepWidth), iDigits + 1, _DECIMAL, bValid ); // plus eine Nachkommastelle
  800                 bSuccess= ( (bValid) && (m_lnkManJustage->SetAngleWidth(mSel, value)) );
  801         }
  802         OnTB_MotionParam( aTB, FALSE ); // Bewegungsparameter immer aktualisieren (wenn der gewünschte Wert nicht in die Funktionalität übernommen wurde); Notice ist zu langsam
  803         if ( !bSuccess )
  804                 OnNoAction();
  805 };
  806 //-----------------------------------------------------------------------------
  807 
  808 void TManJustageDlg::TB_MotorChanged ( const ETB aTB )
  809 {
  810         // während der Halbwertsbreitenmessung darf kein anderer Antrieb ausgewählt werden
  811         int sel= TB2Selection(aTB); // Index des zuvor ausgewählten Antriebs ermitteln; ggf. GetMotorCount() - d.h. 'kein Antrieb'
  812         if ( m_lnkManJustage->IsMeasuring() )
  813         { // während der Halbwertsbreitenmessung wird der zuletzt ausgewählte Antrieb wieder ausgewählt
  814                 SetSelection( aTB, sel );
  815                 OnNoAction();
  816                 return; // fertig
  817         }
  818 
  819         // welcher Index wurde ausgewählt, hat sich was geändert?
  820         int mSel= CtrlGetSel( GetResId(aTB, riMotorList) );
  821 
  822         // Geschwindigkeitsoptimierung: Wenn Block bei DetermineMoving wieder einkommentiert wurde, kann dieser Block auch wieder auskommentiert werden.
  823         // während sich der Antrieb bewegt, darf kein anderer ausgewählt werden
  824         BOOL bValid= FALSE;
  825         if ( (mSel!=sel) && (m_lnkManJustage->IsMoving(sel, bValid)) ) {
  826                 SetSelection( aTB, sel );
  827                 MessageBox( sth_mj_DontChange, sth_mj_ErrTitle, MBSTOP );
  828                 return; // Abbruch
  829         } 
  830 
  831         // versuchen neuen Antrieb auszuwählen und Inhalt der Steuerelemente aktualisieren und Steuerelemenete freigeben bzw. sperren und ausgrauen
  832         if ( SetSelection(aTB, mSel) )
  833                 return; // Antrieb erfolgreich ausgewählt
  834 
  835         // zuvor ausgewählten Antrieb wieder herstellen (damit ist die Dopplung beseitigt) und anschließend Meldungsfenster ausgeben
  836         // !!! Reihenfolge ist unbedingt zu beachten, SONST erscheint die Meldung mehrfach
  837         SetSelection( aTB, sel );
  838 
  839         char *stDoubleMotor= LoadString(sth_mj_DoubleMotor);
  840         char *msg= new char[ strlen(stDoubleMotor) + _MAXLENCHARACTERISTIC + 1 ]; //max. Länge einer Antriebsbezeichnung nicht vergessen
  841         sprintf( msg, stDoubleMotor, m_lnkManJustage->GetMotorName(mSel, bValid) );
  842         _FREELIST(stDoubleMotor);
  843 
  844         MessageBox( msg, sth_mj_ErrTitle, MBSTOP );
  845         _FREELIST(msg);
  846 };
  847 
  848 //*****************************************************************************
  849 // quasiparallele Aktualisierung (Inhalt und Zustand) aller Steuerelemente
  850 //*****************************************************************************
  851 
  852 void TManJustageDlg::Notice( const int aCommand, const ETB aTB, const BOOL aEnableDisable )
  853 {
  854         if ( (aCommand == USR_TB_MOTORCHANGED) ||   // immer quasiparallel, wegen ATOS
  855                         ((m_Parallel) && (aCommand != USR_TB_MOTIONPARAMENABLE)) )
  856                 PostMessage( GetHandle(), aCommand, aTB, aEnableDisable ); // quasiparallele Verarbeitung (USR_TB_MOTIONPARAMENABLE NIE quasiparallel)
  857         else
  858                 OnEvent( GetHandle(), aCommand, aTB, aEnableDisable ); // quasiparallele Verarbeitung ist zu langsam (Eingabefelder können z.B. fokussiert werden bevor sie freigegeben werden)
  859 };
  860 //-----------------------------------------------------------------------------
  861 
  862 void TManJustageDlg::OnTB_Controls ( const ETB aTB, const BOOL aEnableDisable )
  863 {
  864         m_lnkManJustage->BeginUpdate();
  865         if ( aEnableDisable )
  866                 Notice( USR_TB_CONTROLSENABLE, aTB ); // ZUERST freigeben bzw. sperren und ausgrauen
  867 
  868         Notice( USR_TB_POSITIONS, aTB );
  869         Notice( USR_TB_KINDOFMOVE, aTB );
  870         Notice( USR_TB_STARTSTOP, aTB );
  871         Notice( USR_TB_MOTIONPARAM, aTB );
  872         Notice( USR_TB_OFFSET, aTB );
  873 
  874         // gültiger Referenzpunktlauf?
  875         UINT sel= TB2Selection(aTB);
  876         BOOL bValid;
  877         if ( (!m_lnkManJustage->IsCalibrated(sel, bValid)) && (bValid) )
  878                 CtrlSetText( GetResId(aTB, riRefPoint), sth_mj_NoRefPoint ); // bei "kein Antrieb" ==> !bValid
  879         else
  880                 CtrlSetText( GetResId(aTB, riRefPoint), sth_mj_HasRefPoint );
  881         m_lnkManJustage->EndUpdate();
  882 };
  883 //-----------------------------------------------------------------------------
  884 
  885 void TManJustageDlg::OnTB_KindOfMove ( const ETB aTB, const BOOL aEnableDisable )
  886 {
  887         BOOL bValid;
  888         EMotionType mt= m_lnkManJustage->GetMotionType( TB2Selection(aTB), bValid ); // wenn die Betriebsart nicht ermittelt werden konnte (bValid==FALSE), wird mtDirect zurückgegeben
  889         if ( bValid )
  890         { // entweder Direkt-/ Fahr- oder Schrittbetrieb auswählen
  891                 CtrlSetChecked( GetResId(aTB, riDirectMode), mt == mtDirect );
  892                 CtrlSetChecked( GetResId(aTB, riDriveMode), mt == mtDrive );
  893                 CtrlSetChecked( GetResId(aTB, riStepMode), mt == mtStep );
  894         }
  895         if ( aEnableDisable )
  896                 Notice( USR_TB_KINDOFMOVEENABLE, aTB );
  897 };
  898 //-----------------------------------------------------------------------------
  899 
  900 void TManJustageDlg::OnTB_StartStop ( const ETB aTB, const BOOL aEnableDisable )
  901 {
  902         BOOL bValid;
  903         BOOL moves= m_lnkManJustage->IsMoving(TB2Selection(aTB), bValid);
  904         if ( bValid )
  905         { // Start/ Stop?
  906                 if ( (moves) && (!m_lnkManJustage->IsMeasuring()) )
  907                         CtrlSetText( GetResId(aTB, riStart), sth_mj_Stop );
  908                 else
  909                         CtrlSetText( GetResId(aTB, riStart), sth_mj_Start );
  910         }
  911         if ( aEnableDisable )
  912                 Notice( USR_TB_STARTSTOPENABLE, aTB );
  913 };
  914 //-----------------------------------------------------------------------------
  915 
  916 void TManJustageDlg::OnTB_MotionParam ( const ETB aTB, const BOOL aEnableDisable )
  917 {
  918         BOOL bValid;
  919         UINT mSel= TB2Selection( aTB );
  920         UINT iDigits= m_lnkManJustage->GetDigits(mSel, bValid); // wenn die Nachkommastellengenauigkeit nicht ermittelt werden (bValid==FALSE), wird 2 zurückgegeben
  921         if ( bValid )
  922         { // Bewegungsparameter (Sollposition auch bei TB_Positions)
  923                 CtrlSetDouble( GetResId(aTB, riAngleDest), m_lnkManJustage->GetAngleDest(mSel, bValid), iDigits, _DECIMAL ); // siehe auch OnTB_Positions
  924                 CtrlSetDouble( GetResId(aTB, riSpeed), m_lnkManJustage->GetSpeed(mSel, bValid), iDigits, _DECIMAL );
  925                 CtrlSetDouble( GetResId(aTB, riStepWidth), m_lnkManJustage->GetAngleWidth(mSel, bValid), iDigits + 1, _DECIMAL );
  926         }
  927         if ( aEnableDisable )
  928                 Notice( USR_TB_MOTIONPARAMENABLE, aTB );
  929 };
  930 //-----------------------------------------------------------------------------
  931 
  932 void TManJustageDlg::OnTB_Positions ( const ETB aTB, const BOOL aEnableDisable )
  933 {
  934         SCROLLINFO scrInfo;
  935         scrInfo.cbSize= sizeof(SCROLLINFO);
  936         scrInfo.fMask= SIF_POS | SIF_RANGE;
  937 
  938         BOOL bValid;
  939         UINT mSel= TB2Selection( aTB );
  940         UINT iDigits= m_lnkManJustage->GetDigits( mSel, bValid );
  941         if ( bValid )
  942         { // Sollposition und Min-, Act-, Maxposition
  943                 CtrlSetDouble( GetResId(aTB, riAngleDest), m_lnkManJustage->GetAngleDest(mSel, bValid), iDigits, _DECIMAL ); // siehe bei OnTB_MotionParam
  944 
  945                 // Min-, Act-, Maxposition auslesen
  946                 TAngle angleMin= m_lnkManJustage->GetAngleMin( mSel, bValid );
  947                 TAngle angle= m_lnkManJustage->GetAngle( mSel, bValid );
  948                 TAngle angleMax= m_lnkManJustage->GetAngleMax( mSel, bValid );
  949 
  950                 // Min-, Act-, Maxposition aktualisieren
  951                 CtrlSetDouble( GetResId(aTB, riRelativePosMin), angleMin, iDigits, _DECIMAL );
  952                 CtrlSetDouble( GetResId(aTB, riAngle), angle, iDigits, _DECIMAL );
  953                 CtrlSetDouble( GetResId(aTB, riRelativePosMax), angleMax, iDigits, _DECIMAL );
  954 
  955                 // Bildlaufleiste aktualisieren
  956                 int posMin, pos, posMax;
  957                 ScrollbarCalculate( angleMin, angle, angleMax, posMin, pos, posMax );
  958                 scrInfo.nPos= pos;
  959                 scrInfo.nMin= posMin;
  960                 scrInfo.nMax= posMax;
  961                 SetScrollInfo(GetCtrl(aTB, riRelativePos),SB_CTL,&scrInfo,TRUE);
  962         }
  963         if ( aEnableDisable )
  964                 Notice( USR_TB_POSITIONSENABLE, aTB );
  965 };
  966 //-----------------------------------------------------------------------------
  967 
  968 void TManJustageDlg::OnTB_Offset ( const ETB aTB, const BOOL aEnableDisable )
  969 {
  970         BOOL bValid;
  971         BOOL offset= m_lnkManJustage->HasOffset(TB2Selection(aTB), bValid);
  972         if ( bValid )
  973         { // "OFFSET" definiert ?
  974                 if ( offset )
  975                         CtrlSetText( GetResId(aTB, riOffsetState), sth_mj_HasOffset );
  976                 else
  977                         CtrlSetText( GetResId(aTB, riOffsetState), sth_mj_NoOffset );
  978         }
  979         if ( aEnableDisable )
  980                 Notice( USR_TB_OFFSETENABLE, aTB );
  981 };
  982 //-----------------------------------------------------------------------------
  983 
  984 void TManJustageDlg::OnTB_Units ( const ETB aTB )
  985 {
  986         BOOL bValid;
  987         LPCSTR unit= m_lnkManJustage->GetUnit( TB2Selection(aTB), bValid );
  988         if ( bValid )
  989         { // Auslesen der Einheit erfolgreich ?
  990                 char *stSec= LoadString(sth_mj_Sec);
  991                 char *unitSec= new char[ strlen(unit) + strlen(stSec) + 1 ]; //+ Nullterminierung
  992                 strcpy( unitSec, unit );
  993                 strcat( unitSec, stSec );
  994                 _FREELIST(stSec);
  995 
  996                 CtrlSetText( GetResId(aTB, riRelativePosUnit), unit );
  997                 CtrlSetText( GetResId(aTB, riAngleDestUnit), unit );
  998                 CtrlSetText( GetResId(aTB, riSpeedUnit), unitSec );
  999                 CtrlSetText( GetResId(aTB, riStepWidthUnit), unit );
 1000                 CtrlSetText( GetResId(aTB, riAngleUnit), unit );
 1001                 _FREELIST(unitSec);
 1002         }
 1003 };
 1004 //-----------------------------------------------------------------------------
 1005 
 1006 void TManJustageDlg::OnTB_ControlsEnable ( const ETB aTB )
 1007 {
 1008   m_lnkManJustage->BeginUpdate();
 1009         Notice( USR_TB_MOTORLISTENABLE, aTB );
 1010         Notice( USR_TB_STARTSTOPENABLE, aTB );
 1011         Notice( USR_TB_KINDOFMOVEENABLE, aTB );
 1012         Notice( USR_TB_MOTIONPARAMENABLE, aTB );
 1013         Notice( USR_TB_POSITIONSENABLE, aTB );
 1014         Notice( USR_TB_OFFSETENABLE, aTB );
 1015   m_lnkManJustage->EndUpdate();
 1016 };
 1017 //-----------------------------------------------------------------------------
 1018 
 1019 void TManJustageDlg::OnTB_MotorListEnable ( const ETB aTB ) const
 1020 {
 1021         // Antriebs-Auswahlliste
 1022         CtrlSetEnabled( GetResId(aTB, riMotorList), (!m_StateRefresh) || (!m_lnkManJustage->IsMeasuring()) ); // nur während der Halbwertsbreitenmessung inaktiv (während der Bewegung und bei "kein Antrieb" freigeben)
 1023 };
 1024 //-----------------------------------------------------------------------------
 1025 
 1026 void TManJustageDlg::OnTB_KindOfMoveEnable ( const ETB aTB ) const
 1027 {
 1028         BOOL bValid;
 1029         UINT mSel= TB2Selection( aTB );
 1030         BOOL enable= (!m_StateRefresh) || (!m_lnkManJustage->IsMoving(mSel, bValid)) && (bValid); // bei "kein Antrieb" kann nichts ausgewählt werden
 1031         CtrlSetEnabled( GetResId(aTB, riDirectMode), enable );
 1032         CtrlSetEnabled( GetResId(aTB, riDriveMode), enable );
 1033         CtrlSetEnabled( GetResId(aTB, riStepMode), enable );
 1034 };
 1035 //-----------------------------------------------------------------------------
 1036 
 1037 void TManJustageDlg::OnTB_StartStopEnable ( const ETB aTB ) const
 1038 {
 1039         UINT mSel= TB2Selection( aTB );
 1040         CtrlSetEnabled( GetResId(aTB, riStart), (!m_StateRefresh) || (m_lnkManJustage->CanDoDirect(mSel)) || (m_lnkManJustage->CanDoStop(mSel)) ); // bei "kein Antrieb" kann weder gestartet noch gestoppt werden
 1041 };
 1042 //-----------------------------------------------------------------------------
 1043 
 1044 void TManJustageDlg::OnTB_MotionParamEnable ( const ETB aTB ) const
 1045 {
 1046         UINT mSel= TB2Selection( aTB );
 1047         // Sollposition auch bei TB_PositionsEnable
 1048         CtrlSetEnabled( GetResId(aTB, riAngleDest), (!m_StateRefresh) || (m_lnkManJustage->CanSetAngleDest(mSel)) ); // bei "kein Antrieb" kann nichts eingegeben werden
 1049         CtrlSetEnabled( GetResId(aTB, riSpeed), (!m_StateRefresh) || (m_lnkManJustage->CanSetSpeed(mSel)) ); // bei "kein Antrieb" kann nichts eingegeben werden
 1050         CtrlSetEnabled( GetResId(aTB, riStepWidth), (!m_StateRefresh) || (m_lnkManJustage->CanSetAngleWidth(mSel)) ); // bei "kein Antrieb" kann nichts eingegeben werden
 1051 };
 1052 //-----------------------------------------------------------------------------
 1053 
 1054 void TManJustageDlg::OnTB_PositionsEnable ( const ETB aTB ) const
 1055 {
 1056         UINT mSel= TB2Selection( aTB );
 1057         // Sollposition auch bei TB_MotionParamEnable
 1058         CtrlSetEnabled( GetResId(aTB, riAngleDest), (!m_StateRefresh) || (m_lnkManJustage->CanSetAngleDest(mSel)) ); // bei "kein Antrieb" kann nichts eingegeben werden
 1059         // Min-, Act- und Maxposition sind und bleiben gesperrt und ausgegraut
 1060         // Bildlaufleiste
 1061         CtrlSetEnabled( GetResId(aTB, riRelativePos), (!m_StateRefresh) || (!m_lnkManJustage->IsMeasuring()) && (m_lnkManJustage->IsIndexValid(mSel)) ); // bei "kein Antrieb" oder Makroverarbeitung sperren und ausgrauen; im Direktbetrieb erscheint eine Fehlermeldung
 1062 };
 1063 //-----------------------------------------------------------------------------
 1064 
 1065 void TManJustageDlg::OnTB_OffsetEnable ( const ETB aTB ) const
 1066 {
 1067         UINT mSel= TB2Selection( aTB );
 1068         BOOL canSet= (!m_StateRefresh) || (m_lnkManJustage->CanSetOffset(mSel));
 1069         CtrlSetEnabled( GetResId(aTB, riSetRelativeZero), canSet ); // bei "kein Antrieb" kann die Null nicht gesetzt werden
 1070         CtrlSetEnabled( GetResId(aTB, riResetRelativeZero), (!m_StateRefresh) || (m_lnkManJustage->CanResetRelativeZero(mSel)) ); // bei "kein Antrieb" kann die Null nicht aufgehoben werden
 1071         CtrlSetEnabled( GetResId(aTB, riOffset), canSet ); // bei "kein Antrieb" kann die Null nicht aufgehoben werden
 1072 };
 1073 //-----------------------------------------------------------------------------
 1074 
 1075 void TManJustageDlg::OtherControls ( void ) const
 1076 {
 1077         if ( m_lnkManJustage->IsMeasuring() )
 1078                 CtrlSetText( cm_HwbMeasure, sth_mj_StopMeasure );
 1079         else
 1080                 CtrlSetText( cm_HwbMeasure, sth_mj_StartMeasure );
 1081 
 1082         int idx= m_lnkManJustage->GetDetectorAxisIdx();
 1083         CtrlSetEnabled( cm_PsdOffset, (!m_StateRefresh) || (m_lnkManJustage->CanSetOffset(idx)) ); // includes m_lnkManJustage->HasDetectorAxis()
 1084         CtrlSetEnabled( cm_HwbMeasure, (!m_StateRefresh) || (m_lnkManJustage->CanDoStartMeasure()) || (m_lnkManJustage->CanDoStopMeasure()) );
 1085 };
 1086 
 1087 //*****************************************************************************
 1088 // Verwaltung der Teilbereiche
 1089 //*****************************************************************************
 1090 
 1091 UINT TManJustageDlg::TB2Selection ( const ETB aTB ) const
 1092 {
 1093         int idx= TB_GetId(aTB);
 1094         if ( idx != -1 )
 1095                 return m_Selection[ idx ];
 1096         else
 1097                 return m_lnkManJustage->GetMotorCount(); // unbekannter Teilbereich: "kein Antrieb"
 1098 };
 1099 //-----------------------------------------------------------------------------
 1100 
 1101 ETB TManJustageDlg::Selection2TB( const UINT aSel ) const
 1102 {
 1103         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
 1104         while ( TB_Next(tb) )
 1105                 if ( TB2Selection(tb) == aSel )
 1106                         return tb; // gefunden (!!! "kein Antrieb" kann auch in mehreren Teilbereichen angezeigt werden)
 1107         return (ETB) 0; // irgends angezeigt
 1108 };
 1109 //-----------------------------------------------------------------------------
 1110 
 1111 BOOL TManJustageDlg::CanSetSelection ( const ETB aTB, const UINT aSel ) const
 1112 {
 1113         // Status der Halbwertsbreitenmessung darf hier NICHT berücksichtigt werden, sonst kann SetSelection(...) während der Messung den Antrieb nicht wiederherstellen!!!
 1114         if ( !m_lnkManJustage->IsIndexValid(aSel) )
 1115                 return TRUE; // "kein Antrieb" darf mehrfach angezeigt werden
 1116 
 1117         // der ausgewählte Index darf nicht bereits in einem anderen Teilbereich angezeigt werden
 1118         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
 1119         while ( TB_Next(tb) ) {
 1120                 if ( (TB2Selection(tb)==aSel) && (tb!=aTB) ) return FALSE; 
 1121 
 1122                 // Geschwindigkeitsoptimierung: Wenn Bock bei DetermineMoving wieder einkommentiert wurde, kann dieser Block auch wieder auskommentiert werden.
 1123                 // Partnerantriebe dürfen nicht gleichzeitig sichtbar sein
 1124                 int df= m_lnkManJustage->GetMotorIdx(DF);
 1125                 int dc= m_lnkManJustage->GetMotorIdx(DC);
 1126                 if ( (aSel==df) && (TB2Selection(tb)==dc) && (tb!=aTB) ) return FALSE;
 1127                 if ( (aSel==dc) && (TB2Selection(tb)==df) && (tb!=aTB) ) return FALSE;
 1128         }
 1129         return TRUE; // Index darf ausgewählt werden
 1130 };
 1131 //-----------------------------------------------------------------------------
 1132 
 1133 BOOL TManJustageDlg::SetSelection ( const ETB aTB, const UINT aSel )
 1134 {
 1135         UINT sel= min( aSel, m_lnkManJustage->GetMotorCount() ); // im Zweifelsfall: "kein Antrieb"
 1136         if ( !CanSetSelection( aTB, sel ) )
 1137                 return FALSE; // Antrieb darf nicht doppelt ausgewählt werden
 1138 
 1139         // Antrieb in Auswahlliste auswählen und Auswahl merken
 1140         CtrlSetSel( GetResId(aTB, riMotorList), sel ); // Antrieb auswählen (auch wenn KEINE Änderung!!!)
 1141         if ( m_Selection[ TB_GetId(aTB) ] == sel )
 1142                 return TRUE; // keine Änderung: weder speichern noch aktualisieren
 1143 
 1144         // ausgewählten Antriebs in der ini-Datei speichern
 1145         m_Selection[ TB_GetId(aTB) ]= sel;
 1146         BOOL bValid;
 1147         char *mName= new char[ _MAXLENCHARACTERISTIC + 1 ];
 1148         if ( !m_lnkManJustage->IsIndexValid(sel) )
 1149                 strcpy(mName, _NODRIVE); // "kein Antrieb"
 1150         else
 1151                 strcpy(mName, m_lnkManJustage->GetMotorName(sel, bValid));
 1152         char tbName[ 12 + 1 ]; // "Teilbereich<Nummer des Teilbereichs, beginnend bei 1>" + Nullterminierung
 1153         TB_GetName( aTB, tbName );
 1154         IniWriteString( GetCFile(), "ManualAdjustment", tbName, mName );
 1155         _FREELIST(mName);
 1156 
 1157   m_lnkManJustage->BeginUpdate();
 1158         // Teilbereich aktualisieren
 1159         Notice( USR_TB_CONTROLS, aTB, TRUE ); // Steuerelemente mit Inhalt füllen und freigeben bzw. sperren und ausgrauen
 1160         Notice( USR_TB_UNITS, aTB ); // Einheiten anzeigen; wenn diese nicht ermittelt werden konnte (weil "kein Antrieb" angezeigt wird), wird diese auch nicht angezeigt
 1161   m_lnkManJustage->EndUpdate();
 1162         m_lnkTimer->StartTimerIm(); //05.02.2003 Antrieb könnte sich bewegen (KzMoving setzen, Oberfl. ist schon aktualisiert)
 1163         return TRUE; // erfolgreich
 1164 };
 1165 //-----------------------------------------------------------------------------
 1166 
 1167 HWND TManJustageDlg::GetCtrl ( const ETB aTB, const ERessourceId aCtrl ) const
 1168 {
 1169         return TBasicDialog::Ctrl( GetResId(aTB, aCtrl) );
 1170 };
 1171 //-----------------------------------------------------------------------------
 1172 
 1173 int TManJustageDlg::GetResId ( const ETB aTB, const ERessourceId aCtrl )
 1174 {
 1175         // zugunsten einer dreifachen Ausführungsgeschwindigkeit musste hier nach Teilbereichen unterscheiden werden
 1176         if ( aTB == tb1 )
 1177         {
 1178                 switch ( aCtrl )
 1179                 {
 1180                         case riMotorList:
 1181                                 return id_p1_MotorList;
 1182 
 1183                         case riStart:
 1184                                 return cm_p1_Start;
 1185 
 1186                         case riSetRelativeZero:
 1187                                 return cm_p1_SetRelativeZero;
 1188 
 1189                         case riResetRelativeZero:
 1190                                 return cm_p1_ResetRelativeZero;
 1191                         
 1192                         case riOffset:
 1193                                 return cm_p1_Offset;
 1194                         
 1195                         case riDirectMode:
 1196                                 return id_p1_DirectMode;
 1197                         
 1198                         case riDriveMode:
 1199                                 return id_p1_DriveMode;
 1200                         
 1201                         case riStepMode:
 1202                                 return id_p1_StepMode;
 1203                         
 1204                         case riAngleDest:
 1205                                 return id_p1_AngleDest;
 1206                         
 1207                         case riSpeed:
 1208                                 return id_p1_Speed;
 1209                         
 1210                         case riStepWidth:
 1211                                 return id_p1_StepWidth;
 1212                         
 1213                         case riAngle:
 1214                                 return id_p1_Angle;
 1215                         
 1216                         case riOffsetState:
 1217                                 return id_p1_OffsetState;
 1218                         
 1219                         case riRelativePos:
 1220                                 return id_p1_RelativePos;
 1221                         
 1222                         case riRelativePosMin:
 1223                                 return txt_p1_RelativePosMin;
 1224                         
 1225                         case riRelativePosMax:
 1226                                 return txt_p1_RelativePosMax;
 1227                         
 1228                         case riAngleDestUnit:
 1229                                 return txt_p1_AngleDestUnit;
 1230                         
 1231                         case riSpeedUnit:
 1232                                 return txt_p1_SpeedUnit;
 1233                         
 1234                         case riStepWidthUnit:
 1235                                 return txt_p1_StepWidthUnit;
 1236                         
 1237                         case riAngleUnit:
 1238                                 return txt_p1_AngleUnit;
 1239                         
 1240                         case riRelativePosUnit:
 1241                                 return txt_p1_RelativePosUnit;
 1242                         
 1243                         case riRefPoint:
 1244                                 return txt_p1_RefPoint;
 1245                 }
 1246         }
 1247         else if ( aTB == tb2 )
 1248         {
 1249                 switch ( aCtrl )
 1250                 {
 1251                         case riMotorList:
 1252                                 return id_p2_MotorList;
 1253                         
 1254                         case riStart:
 1255                                 return cm_p2_Start;
 1256                         
 1257                         case riSetRelativeZero:
 1258                                 return cm_p2_SetRelativeZero;
 1259                         
 1260                         case riResetRelativeZero:
 1261                                 return cm_p2_ResetRelativeZero;
 1262                         
 1263                         case riOffset:
 1264                                 return cm_p2_Offset;
 1265                         
 1266                         case riDirectMode:
 1267                                 return id_p2_DirectMode;
 1268                         
 1269                         case riDriveMode:
 1270                                 return id_p2_DriveMode;
 1271                         
 1272                         case riStepMode:
 1273                                 return id_p2_StepMode;
 1274                         
 1275                         case riAngleDest:
 1276                                 return id_p2_AngleDest;
 1277                         
 1278                         case riSpeed:
 1279                                 return id_p2_Speed;
 1280                         
 1281                         case riStepWidth:
 1282                                 return id_p2_StepWidth;
 1283                         
 1284                         case riAngle:
 1285                                 return id_p2_Angle;
 1286                         
 1287                         case riOffsetState:
 1288                                 return id_p2_OffsetState;
 1289                         
 1290                         case riRelativePos:
 1291                                 return id_p2_RelativePos;
 1292                         
 1293                         case riRelativePosMin:
 1294                                 return txt_p2_RelativePosMin;
 1295                         
 1296                         case riRelativePosMax:
 1297                                 return txt_p2_RelativePosMax;
 1298                         
 1299                         case riAngleDestUnit:
 1300                                 return txt_p2_AngleDestUnit;
 1301                         
 1302                         case riSpeedUnit:
 1303                                 return txt_p2_SpeedUnit;
 1304                         
 1305                         case riStepWidthUnit:
 1306                                 return txt_p2_StepWidthUnit;
 1307                         
 1308                         case riAngleUnit:
 1309                                 return txt_p2_AngleUnit;
 1310                         
 1311                         case riRelativePosUnit:
 1312                                 return txt_p2_RelativePosUnit;
 1313                         
 1314                         case riRefPoint:
 1315                                 return txt_p2_RefPoint;
 1316                 }
 1317         }
 1318         else if ( aTB == tb3 )
 1319         {
 1320                 switch ( aCtrl )
 1321                 {
 1322                         case riMotorList:
 1323                                 return id_p3_MotorList;
 1324                         
 1325                         case riStart:
 1326                                 return cm_p3_Start;
 1327                         
 1328                         case riSetRelativeZero:
 1329                                 return cm_p3_SetRelativeZero;
 1330                         
 1331                         case riResetRelativeZero:
 1332                                 return cm_p3_ResetRelativeZero;
 1333                         
 1334                         case riOffset:
 1335                                 return cm_p3_Offset;
 1336                         
 1337                         case riDirectMode:
 1338                                 return id_p3_DirectMode;
 1339                         
 1340                         case riDriveMode:
 1341                                 return id_p3_DriveMode;
 1342                         
 1343                         case riStepMode:
 1344                                 return id_p3_StepMode;
 1345                         
 1346                         case riAngleDest:
 1347                                 return id_p3_AngleDest;
 1348                         
 1349                         case riSpeed:
 1350                                 return id_p3_Speed;
 1351                         
 1352                         case riStepWidth:
 1353                                 return id_p3_StepWidth;
 1354                         
 1355                         case riAngle:
 1356                                 return id_p3_Angle;
 1357                         
 1358                         case riOffsetState:
 1359                                 return id_p3_OffsetState;
 1360                         
 1361                         case riRelativePos:
 1362                                 return id_p3_RelativePos;
 1363                         
 1364                         case riRelativePosMin:
 1365                                 return txt_p3_RelativePosMin;
 1366                         
 1367                         case riRelativePosMax:
 1368                                 return txt_p3_RelativePosMax;
 1369                         
 1370                         case riAngleDestUnit:
 1371                                 return txt_p3_AngleDestUnit;
 1372                         
 1373                         case riSpeedUnit:
 1374                                 return txt_p3_SpeedUnit;
 1375                         
 1376                         case riStepWidthUnit:
 1377                                 return txt_p3_StepWidthUnit;
 1378                         
 1379                         case riAngleUnit:
 1380                                 return txt_p3_AngleUnit;
 1381                         
 1382                         case riRelativePosUnit:
 1383                                 return txt_p3_RelativePosUnit;
 1384                         
 1385                         case riRefPoint:
 1386                                 return txt_p3_RefPoint;
 1387                 }
 1388         };
 1389         return -1; //unbekannter Teilbereich oder unbekannte Ressourcen-ID
 1390 };
 1391 
 1392 //*****************************************************************************
 1393 // zur Verwaltung der Teilbereiche
 1394 //*****************************************************************************
 1395 
 1396 BOOL TManJustageDlg::TB_Next ( ETB &aTB )
 1397 {
 1398         switch ( aTB )
 1399         {
 1400                 case (ETB)0:
 1401                         aTB= tb1;
 1402                         return TRUE;
 1403 
 1404                 case tb1:
 1405                         aTB= tb2;
 1406                         return TRUE;
 1407 
 1408                 case tb2:
 1409                         aTB= tb3;
 1410                         return TRUE;
 1411 
 1412                 default:
 1413                         return FALSE; // nach tb3 gehts nicht mehr weiter
 1414         }
 1415 };
 1416 //-----------------------------------------------------------------------------
 1417 
 1418 UINT TManJustageDlg::TB_Count ( void )
 1419 {
 1420         UINT result= 0;
 1421         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
 1422         while ( TB_Next(tb) )
 1423                 result++;
 1424         return result;
 1425 };
 1426 //-----------------------------------------------------------------------------
 1427 
 1428 UINT TManJustageDlg::TB_GetId ( const ETB aTB )
 1429 {
 1430         UINT result= 0; // beginnend bei 0
 1431         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
 1432         while ( TB_Next(tb) )
 1433         {
 1434                 if ( tb == aTB )
 1435                         return result;
 1436                 result++;
 1437         }
 1438         return -1; // unbekannter Teilbereich
 1439 };
 1440 //-----------------------------------------------------------------------------
 1441 
 1442 void TManJustageDlg::TB_GetName ( const ETB aTB, LPSTR aReturn )
 1443 {
 1444         strcpy( aReturn, "" ); // unbekannter Teilbereich, falls nicht gefunden
 1445         ETB tb= (ETB)0; // nur so gibt TB_Next beim ersten Aufruf tb1 zurück
 1446         while ( TB_Next(tb) )
 1447                 if ( aTB == tb )
 1448                         sprintf( aReturn, "Section%d", TB_GetId(aTB) + 1 ); // nicht abhängig von GermanVersion, weil Eintrag aus der ini-Datei
 1449 };
 1450 
 1451 //*****************************************************************************
 1452 // Winkelwerte für Bildlaufleiste umrechnen
 1453 //*****************************************************************************
 1454 
 1455 void TManJustageDlg::ScrollbarCalculate ( const TAngle angleMin, const TAngle angle, const TAngle angleMax,
 1456                 int &posMin, int &pos, int &posMax )
 1457 {
 1458         posMin= 0;
 1459         float skale;
 1460         try 
 1461         {
 1462                 skale= (float) ( 32000 / (angleMax - angleMin)); 
 1463         } 
 1464         catch (...) 
 1465         {
 1466                 skale= 0;
 1467         }       
 1468         pos= (int)( (angle - angleMin) * skale );
 1469         posMax= (int)( (angleMax - angleMin) * skale );
 1470 };
 1471 
 1472 //#############################################################################
 1473 // TMotorOffsetDlg
 1474 //#############################################################################
 1475 
 1476 //-----------------------------------------------------------------------------
 1477 // Konstruktor
 1478 
 1479 TMotorOffsetDlg::TMotorOffsetDlg ( const UINT aIdx, TManJustage *aManJustage ) : TModalDlg ( "MOTOROFFSETDLG", GetMainInstance() )
 1480 {
 1481         BOOL bValid= FALSE;
 1482         //Aufrufer muss sicherstellen, dass gültige Referenzen übergeben werden
 1483         assert( aManJustage );
 1484         m_lnkManJustage= aManJustage;
 1485         assert( m_lnkManJustage->IsIndexValid(aIdx) );
 1486         m_Idx= aIdx;
 1487         m_Digits= m_lnkManJustage->GetDigits(m_Idx, bValid); // Nachkommastellen lesen
 1488 };
 1489 //-----------------------------------------------------------------------------
 1490 // Initialisierung
 1491 
 1492 BOOL TMotorOffsetDlg::Dlg_OnInit ( HWND, HWND, LPARAM )
 1493 {
 1494         BOOL bValid= FALSE;
 1495         // Titelleiste des Dialogfensters
 1496         LPCSTR mName= m_lnkManJustage->GetMotorName( m_Idx, bValid );
 1497 
 1498         char *stMotorOffsetTitle= LoadString( sth_mj_MotorOffsetTitle );
 1499         char *title= new char[ strlen(stMotorOffsetTitle) + _MAXLENCHARACTERISTIC + 1 ]; // + Nullterminierung
 1500         sprintf( title, stMotorOffsetTitle, mName );
 1501         _FREELIST(stMotorOffsetTitle);
 1502 
 1503         SetWindowText( GetHandle(), title );
 1504         _FREELIST(title);
 1505         // Einheiten anzeigen
 1506         LPCSTR unit= m_lnkManJustage->GetUnit( m_Idx, bValid );
 1507         CtrlSetText( txt_AngleUnit, unit );
 1508         CtrlSetText( txt_OffsetUnit, unit );
 1509         CtrlSetText( txt_AngleDestUnit, unit );
 1510         CtrlSetText( txt_OffsetDestUnit, unit );
 1511         // aktuelle Position und aktueller Offset anzeigen
 1512         CtrlSetDouble( id_Angle, m_lnkManJustage->GetAngle(m_Idx, bValid), m_Digits, _DECIMAL);
 1513         CtrlSetDouble( id_Offset, m_lnkManJustage->GetOffset(m_Idx, bValid), m_Digits, _DECIMAL);
 1514         // zu Beginn immer Winkeleingabe aktiviert
 1515         ChooseAngleMode( TRUE );
 1516         // Offset von 0 anzeigen
 1517         CtrlSetDouble( id_AngleDest, m_lnkManJustage->GetAngle(m_Idx, bValid), m_Digits, _DECIMAL);
 1518         CalcValue(FALSE);
 1519         return TRUE;
 1520 };
 1521 
 1522 //-----------------------------------------------------------------------------
 1523 // Eingabeverarbeitung
 1524 
 1525 void TMotorOffsetDlg::Dlg_OnCommand ( HWND aHWnd, int aId, HWND aCtrlWnd, UINT aCode )
 1526 {
 1527         switch ( aId )
 1528         {
 1529                 case id_AngleMode:
 1530                 case id_OffsetMode:   // entweder Winkel ODER Offset-Eingabe freigegeben,
 1531                         ChooseAngleMode( aId == id_AngleMode );
 1532                         return;
 1533 
 1534                 case id_AngleDest:
 1535                 case id_OffsetDest:   // Eingabefelder 'neuer Winkel' und 'Offset'
 1536                         if ( aCode == ONEXIT )
 1537                                 CalcValue(FALSE);
 1538                         return;
 1539 
 1540                 case IDOK:   // Eingabebestätigung [ENTER]
 1541                         if ( (CtrlHasFocus(id_AngleDest)) || (CtrlHasFocus(id_OffsetDest)) )
 1542                         {
 1543                                 if ( CalcValue(FALSE) )
 1544                                         CtrlSetFocus( IDOK );
 1545                                 return; // verarbeitet
 1546                                 // bei 'OK' Werte übernehmen
 1547                         }
 1548                         else if ( (CtrlHasFocus(IDOK)) && (!CalcValue(TRUE)) )
 1549                                 return; // nur bei gültiger Eingabe weiter bei default (Dialg schließen)
 1550                         // hier kein break, sondern TModalDlg::Dlg_OnCommand
 1551 
 1552                 default:
 1553                         TModalDlg::Dlg_OnCommand( aHWnd, aId, aCtrlWnd, aCode );
 1554         };
 1555 };
 1556 //-----------------------------------------------------------------------------
 1557 // Wechsel der Eingabemöglichkeit
 1558 
 1559 void TMotorOffsetDlg::ChooseAngleMode( BOOL aAngleMode )
 1560 {
 1561         CtrlSetChecked( id_AngleMode, aAngleMode );
 1562         CtrlSetChecked( id_OffsetMode, !aAngleMode );
 1563         CtrlSetEnabled( id_AngleDest, IsAngleMode() );
 1564         CtrlSetEnabled( id_OffsetDest, !IsAngleMode() );
 1565         if ( IsAngleMode() )
 1566                 CtrlSetFocus( id_AngleDest );
 1567         else
 1568                 CtrlSetFocus( id_OffsetDest );
 1569 };
 1570 //-----------------------------------------------------------------------------
 1571 // lokale Berechnung von Offset oder Winkel, Übernahme wenn Parameter==TRUE
 1572 
 1573 BOOL TMotorOffsetDlg::CalcValue( BOOL aTakeOver )
 1574 {
 1575         BOOL bValid= FALSE;
 1576         int inputResId= 0, outputResId= 0;
 1577         if ( IsAngleMode() )
 1578         { // neuer Winkel eingegeben
 1579                 inputResId= id_AngleDest;
 1580                 outputResId= id_OffsetDest;
 1581         }
 1582         else
 1583         { // neuer Offset eingegeben
 1584                 inputResId= id_OffsetDest;
 1585                 outputResId= id_AngleDest;
 1586         };
 1587         TAngle inputValue= CtrlGetDouble( inputResId, m_Digits, _DECIMAL, bValid );
 1588         if (!bValid)
 1589                 return FALSE; // wenn Fehler beim lesen dann raus
 1590 
 1591         TAngle outputValue= 0.0;
 1592         if ( IsAngleMode() )
 1593                 outputValue= m_lnkManJustage->CalcOffsetFromAngle(m_Idx, inputValue);
 1594         else
 1595                 outputValue= m_lnkManJustage->CalcAngleFromOffset(m_Idx, inputValue);
 1596         if ( aTakeOver )
 1597         { // TRUE <--> Übernahme
 1598                 if ( IsAngleMode() )
 1599                         m_lnkManJustage->SetOffset(m_Idx, outputValue);
 1600                 else
 1601                         m_lnkManJustage->SetOffset(m_Idx, inputValue);
 1602         };
 1603         CtrlSetDouble( inputResId, inputValue, m_Digits, _DECIMAL);
 1604         CtrlSetDouble( outputResId, outputValue, m_Digits, _DECIMAL);
 1605         return TRUE;
 1606 };
 1607 //-----------------------------------------------------------------------------
 1608 
 1609 BOOL TMotorOffsetDlg::IsAngleMode ( void )
 1610 {
 1611         return CtrlIsChecked( id_AngleMode );
 1612 };
 1613 
 1614 //#############################################################################
 1615 // TPsdOffsetDlg
 1616 //#############################################################################
 1617 
 1618 //-----------------------------------------------------------------------------
 1619 // KONSTRUKTOR-DESTRUKTOR
 1620 
 1621 TPsdOffsetDlg::TPsdOffsetDlg ( const UINT aIdx, TManJustage *aManJustage ) : TModalDlg ( "PSDOFFSETDLG", GetMainInstance() )
 1622 {
 1623         BOOL bValid= FALSE;
 1624         // Aufrufer muss sicherstellen, dass gültige Referenzen übergeben werden
 1625         assert( aManJustage );
 1626         assert( aManJustage->GetDetector() ); // eindim. Detektor (z.B. PSD) vorhanden?
 1627         m_lnkManJustage= aManJustage;
 1628         assert( m_lnkManJustage->IsIndexValid(aIdx) );
 1629         m_Idx= aIdx;
 1630         m_Digits= m_lnkManJustage->GetDigits(m_Idx, bValid); // Nachkommastellen lesen
 1631         m_PSDDigits= m_lnkManJustage->GetDetectorDigits(bValid); // Kanalbreite Nachkommastellen lesen
 1632 };
 1633 
 1634 //-----------------------------------------------------------------------------
 1635 // EREIGNISSE DER BASISKLASSE
 1636 
 1637 BOOL TPsdOffsetDlg::Dlg_OnInit ( HWND, HWND, LPARAM )
 1638 {
 1639         BOOL bValid= FALSE;
 1640         //Titelleiste des Dialogfensters
 1641         LPCSTR dName= m_lnkManJustage->GetDetectorName( bValid );
 1642 
 1643         char *stPsdOffsetTitle= LoadString( sth_mj_PsdOffsetTitle );
 1644         char *title= new char[ strlen(stPsdOffsetTitle) + _MAXLENCHARACTERISTIC + 1 ]; // + Nullterminierung
 1645         sprintf( title, stPsdOffsetTitle, dName );
 1646         _FREELIST(stPsdOffsetTitle);
 1647 
 1648         SetWindowText( GetHandle(), title );
 1649         _FREELIST(title);
 1650         // Beschriftung von "Offset für <Psd>"
 1651         LPCSTR mName= m_lnkManJustage->GetMotorName( m_Idx, bValid );
 1652 
 1653         char *stPsdActPos= LoadString( sth_mj_PsdActPos );
 1654         title= new char[ strlen(stPsdActPos) + _MAXLENCHARACTERISTIC + 1 ]; // + Nullterminierung
 1655         sprintf( title, stPsdActPos, mName );
 1656         _FREELIST(stPsdActPos);
 1657         
 1658         CtrlSetText(txt_PsdAngle, title);
 1659         _FREELIST(title);
 1660 
 1661         //Beschriftung von "<Psd>-Kaneloffset"
 1662         char *stPsdOffsetDest= LoadString( sth_mj_PsdOffsetDest );
 1663         title= new char[ strlen(stPsdOffsetDest) + _MAXLENCHARACTERISTIC + 1 ]; // + Nullterminierung
 1664         sprintf( title, stPsdOffsetDest, dName );
 1665         _FREELIST(stPsdOffsetDest);
 1666         CtrlSetText(txt_PsdOffsetDest, title);
 1667         _FREELIST(title);
 1668         
 1669         // Einheiten anzeigen
 1670         LPCSTR unit= m_lnkManJustage->GetUnit( m_Idx, bValid );
 1671         CtrlSetText( txt_PsdAngleUnit, unit );
 1672         CtrlSetText( txt_PsdAnglePerChannelUnit, unit );
 1673         CtrlSetText( txt_PsdOffsetDestUnit, unit );
 1674         CtrlSetText( txt_PsdAngleDestUnit, unit );
 1675         // aktuelle Position und Winkel/Kanal anzeigen
 1676         CtrlSetDouble( id_PsdAngle, m_lnkManJustage->GetAngle(m_Idx, bValid), m_Digits, _DECIMAL);
 1677         CtrlSetDouble( id_PsdAnglePerChannel, m_lnkManJustage->GetAnglePerChannel(), m_PSDDigits, _DECIMAL);
 1678         // aktuellen Kanal anzeigen
 1679         CtrlSetLong( id_ChannelDest, m_lnkManJustage->GetChannel());
 1680         CalcValue(FALSE);
 1681         return TRUE;
 1682 };
 1683 //-----------------------------------------------------------------------------
 1684 
 1685 void TPsdOffsetDlg::Dlg_OnCommand ( HWND aHWnd, int aId, HWND aCtrlWnd, UINT aCode )
 1686 {
 1687         switch ( aId )
 1688         {
 1689                 case id_ChannelDest:   // Eingabefelder 'neu zugeordneter Kanal'
 1690                         if ( aCode == ONEXIT )
 1691                                 CalcValue(FALSE);
 1692                         return;
 1693 
 1694                 case IDOK:   // Eingabebestätigung [ENTER]
 1695                         if ( CtrlHasFocus(id_ChannelDest) )
 1696                         {
 1697                                 if ( CalcValue(FALSE) )
 1698                                         CtrlSetFocus( IDOK );
 1699                                 return; // verarbeitet
 1700                                 // bei 'OK' Werte übernehmen
 1701                         }
 1702                         else if ( (CtrlHasFocus(IDOK)) && (!CalcValue(TRUE)) )
 1703                                 return; // nur bei gültiger Eingabe weiter bei default (Dialg schließen)
 1704                         // hier kein break, sondern TModalDlg::Dlg_OnCommand
 1705 
 1706                 default:
 1707                         TModalDlg::Dlg_OnCommand( aHWnd, aId, aCtrlWnd, aCode );
 1708         };
 1709 };
 1710 //-----------------------------------------------------------------------------
 1711 // lokale Berechnung von PSD-Offset und Thetaposition, Übernahme wenn Parameter==TRUE
 1712 
 1713 BOOL TPsdOffsetDlg::CalcValue ( BOOL aTakeOver )
 1714 {
 1715         BOOL bValid= FALSE;
 1716         int inputValue= CtrlGetLong( id_ChannelDest, bValid );
 1717         if (!bValid)
 1718                 return FALSE; // wenn Fehler beim lesen dann raus
 1719 
 1720         TAngle OffsetValue= m_lnkManJustage->CalcChannelOffset( inputValue );
 1721         TAngle AngleValue= m_lnkManJustage->CalcChannelAngle( inputValue );
 1722         if ( aTakeOver )
 1723                 m_lnkManJustage->SetChannel( inputValue ); // TRUE <--> Übernahme
 1724         CtrlSetLong( id_ChannelDest, inputValue );
 1725         CtrlSetDouble( id_PsdOffsetDest, OffsetValue, m_PSDDigits, _DECIMAL);
 1726         CtrlSetDouble( id_PsdAngleDest, AngleValue, m_Digits, _DECIMAL);
 1727         return TRUE;
 1728 };
 1729 //-----------------------------------------------------------------------------
 1730 // LastLine
 1731