#include "rc_def.h"
#include "comhead.h"
#pragma hdrstop

// m_dlg.cpp
// (C) 1993,1994 by Heiko Damerow MPG AG "Roentgenbeugung"
// Definition verschiedener Dialog-Prozeduren

#include "m_devcom.h"
#include "m_steerg.h"
#include "m_dlg.h"
#include "m_layer.h"
#include "c_layer.h"

// variables related to continuous scan's
TCScanParam CScan;

//*** verschiedene Macros *****************************************************
extern TMain     Main;
extern TSteering Steering;
extern LPDList   lpDList;
extern BOOL      bManualMovesCorrected;

//*****************************************************************************
TGetData::TGetData( LPSTR dt, int* dr ) : TModalDlg("GetData")
{
  dataref = dr;
  strcpy( datatext, dt );
};

BOOL TGetData::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM lParam )
{
  char buf[30];

  TModalDlg::Dlg_OnInit( hwnd, hwndCtl, lParam );
  itoa( *dataref, buf, 10 );
  SetDlgItemText( hwnd, id_GetDataText, datatext );
  SetDlgItemText( hwnd, id_GetDataValue, buf );
  return TRUE;
};

BOOL TGetData::CanClose( void )
{
  char buf[30];

  GetDlgItemText( GetHandle(), id_GetDataValue, buf, 29 );
  *dataref = atoi( buf );
  return TRUE;
};

BOOL TMain::GetDataDlg( LPSTR text, int *val )
{
  int dref;
  TModalDlg* dlg;

  dref  = *val;
  dlg  = (TGetData *)new TGetData( text, &dref );
  dlg->ExecuteDialog( hWndFrame );
  *val  = dref;
  delete dlg;
  return TRUE;
};

//***** Dialog fuer die Einstellungen des Psd *********************************
TPsdParameters::TPsdParameters() : TModelessDlg("PsdParameter")
{
};

#pragma argsused
BOOL TPsdParameters::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM lParam )
{
  if (!lpDList->IsDeviceValid( PsdDevice ))
  {
    FORWARD_WM_COMMAND( hwnd, IDCANCEL, hwndCtl, 0, PostMessage );
    return FALSE;
  }
  Device = (TPsd*)lpDList->DP( lpDList->GetIdByName( PsdDevice ) );
  // Initialisieren der Parameterfenster
  EnableWindow( GetDlgItem( hwnd, id_StepWidth ), FALSE );
  EnableWindow( GetDlgItem( hwnd, id_AngleRange ), FALSE );

  FORWARD_WM_COMMAND( hwnd, cm_ParamSet, hwndCtl, 0, SendMessage );
  SetFocus( GetDlgItem( hwnd, id_AddedChannels ) );
  return TRUE;
};

void TPsdParameters::Dlg_OnCommand( HWND hwnd, int id, HWND hwndCtl,
    UINT codeNotify )
{
  char buf[MaxString];
  UINT her, ler;

  switch ( id )
  {
    case cm_ParamSet:
    sprintf( buf, "%.2f", Device->GetAngleRange() );
    SetDlgItemText( hwnd, id_AngleRange, (LPSTR)buf );
    sprintf( buf, "%d", Device->nAddedChannels );
    SetDlgItemText( hwnd, id_AddedChannels, (LPSTR)buf );
    sprintf( buf, "%.2f", Device->fAngleStep );
    SetDlgItemText( hwnd, id_StepWidth, (LPSTR)buf );
    Device->GetEnergyRange( ler, her );
    sprintf( buf, "%d", her );
    SetDlgItemText( hwnd, id_UpperLevel, (LPSTR)buf );
    sprintf( buf, "%d", ler );
    SetDlgItemText( hwnd, id_LowerLevel, (LPSTR)buf );

    sprintf( buf, "%d", Device->nMaxChannel );
    SetDlgItemText( hwnd, id_PositionMax, (LPSTR)buf );
    sprintf( buf, "%d", Device->nMinChannel );
    SetDlgItemText( hwnd, id_PositionMin, (LPSTR)buf );
    CheckDlgButton( hwnd, id_EnergyControl, Device->bHVRegelung );
    CheckDlgButton( hwnd, id_LeftConnectedZero, Device->bReadLeftFirst );
    break;

    case cm_InitializePsd:
    if (CanClose())
      if (R_OK != Device->PsdInit())
        SetInfo("Init Psd failed.");
    FORWARD_WM_COMMAND( hwnd, cm_ParamSet, 0, 0, SendMessage );
    break;

    case cm_ClearEnergyData:
    MessageBox( GetFocus(), "Zur Zeit nicht unterstuetzt !", "Message",
        MBINFO );
    break;

    case cm_SetEnergyRange:
    GetDlgItemText( hwnd, id_UpperLevel, buf, MaxString );
    her = atoi( buf );
    GetDlgItemText( hwnd, id_LowerLevel, buf, MaxString );
    ler = atoi( buf );
    if (R_OK != Device->SetEnergyRange( ler, her ))
    {
      FORWARD_WM_COMMAND( hwnd, cm_ParamSet, 0, 0, PostMessage );
      SetInfo("SetEnergy Range failed.");
    }
    break;

    case cm_SetPositionRange:
    GetDlgItemText( hwnd, id_PositionMax, buf, MaxString );
    Device->nMaxChannel = atoi( buf );
    GetDlgItemText( hwnd, id_PositionMin, buf, MaxString );
    Device->nMinChannel = atoi( buf );
    break;

    default:
    TModelessDlg::Dlg_OnCommand( hwnd, id, hwndCtl, codeNotify );
  }
};

BOOL TPsdParameters::CanClose( void )
{
  int val_i, store_i;
  int her, ler;
  BOOL bFailure = FALSE, id = 0;

  FORWARD_WM_COMMAND( GetHandle(), cm_SetPositionRange, 0, 0, SendMessage );
  Device->bHVRegelung = IsDlgButtonChecked( GetHandle(), id_EnergyControl );
  Device->bReadLeftFirst = IsDlgButtonChecked( GetHandle(),
      id_LeftConnectedZero );
  val_i = store_i = GetDlgItemInt( GetHandle(), id_AddedChannels, (LPINT)&id,
      FALSE );
  val_i = max( 1, val_i );
  val_i = min( (int)( 0.1 * Device->GetChannelNumber() ), val_i );
  if (store_i != val_i)
    bFailure &= TRUE;
  Device->SetAddedChannels( val_i );
  her = GetDlgItemInt( GetHandle(), id_UpperLevel, &her, FALSE );
  ler = GetDlgItemInt( GetHandle(), id_LowerLevel, &ler, FALSE );
  if (R_OK != Device->SetEnergyRange( ler, her ))
    return FALSE;
  return TRUE;
};

BOOL TPsdParameters::LeaveDialog( void )
{
  return TRUE;
};

//********* Direkte Eingabe von Kommandos *******************
TExecuteCmd::TExecuteCmd():TModalDlg("ExecuteCmd")
{
  ExecutionId = 0;
};

BOOL TExecuteCmd::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM lParam )
{
  TModalDlg::Dlg_OnInit( hwnd, hwndCtl, lParam );
  nMotor = mlGetAxis();
  SetDlgItemText( hwnd, cm_RotateMotor, mGetAxisName() );
  SetFocus( GetDlgItem( hwnd, id_CommandLine ) );
  return TRUE;
};

void TExecuteCmd::Dlg_OnCommand( HWND hwnd, int id, HWND hwndCtl,
    UINT codeNotify )
{
  static int i = 0;
  HWND hwndCmd = GetDlgItem( hwnd, id_Response );
  char cmd[MaxString + 1];
  char *lpszToken;

  switch ( id )
  {
    case IDOK:
    GetDlgItemText( hwnd, id_CommandLine, cmd, 34 );
    strcat( cmd, "\r" );
    if (R_OK == mExecuteCmd( cmd ))
    {
      lpszToken = strtok( cmd, "\n\3\r" );
      while ( lpszToken )
      {
        if (strlen( lpszToken ) > 1)
          ComboBox_AddString( hwndCmd, lpszToken );
        lpszToken = strtok( NULL, "\n\3\r" );
      }
    }
    break;

    case cm_RotateMotor:
    mlSetAxis( 1 + mlGetAxis() );
    SetDlgItemText( hwnd, cm_RotateMotor, (LPSTR)mGetAxisName() );
    SetFocus( GetDlgItem( hwnd, id_CommandLine ) );
    break;

    default:
    TModalDlg::Dlg_OnCommand( hwnd, id, hwndCtl, codeNotify );
  }
};

BOOL TExecuteCmd::LeaveDialog( void )
{
  return TRUE;
};

//*****************************************************************************
//*****************************************************************************
TMeasurementParam::TMeasurementParam() : TModalDlg("MeasurementParam")
{
};

BOOL TMeasurementParam::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM lParam )
{
  char buf[MaxString];

  TModalDlg::Dlg_OnInit( hwnd, hwndCtl, lParam );
  SetFocus( GetDlgItem( hwnd, IDOK ) );
  sprintf( buf, "%s", Main.Target );
  SetDlgItemText( hwnd, id_TargetName, buf );
  sprintf( buf, "%s", Main.TargetBulk );
  SetDlgItemText( hwnd, id_TargetBulk, buf );
  sprintf( buf, "%.3f", Main.WaveLength );
  SetDlgItemText( hwnd, id_WaveLength, buf );
  sprintf( buf, "%s", Main.User );
  SetDlgItemText( hwnd, id_Scientist, buf );
  sprintf( buf, "%d", Main.Current );
  SetDlgItemText( hwnd, id_BeamCurrent, buf );
  sprintf( buf, "%d", Main.Voltage );
  SetDlgItemText( hwnd, id_BeamVoltage, buf );
  GetHKL( Main.Reflection, buf );
  SetDlgItemText( hwnd, id_Reflection, buf );
  GetHKL( Main.Orientation, buf );
  SetDlgItemText( hwnd, id_Orientation, buf );
  SetDlgItemText( hwnd, id_Text, Main.Comment );
  return TRUE;
};

BOOL TMeasurementParam::CanClose( void )
{
  char buf[MaxString];
  BOOL fl;

  GetDlgItemText( GetHandle(), id_TargetName, buf, MaxString );
  strcpy( Main.Target, buf );
  GetDlgItemText( GetHandle(), id_TargetBulk, buf, MaxString );
  strcpy( Main.TargetBulk, buf );
  GetDlgItemText( GetHandle(), id_Reflection, buf, MaxString );
  SetHKL( Main.Reflection, buf );
  GetDlgItemText( GetHandle(), id_Orientation, buf, MaxString );
  SetHKL( Main.Orientation, buf );
  GetDlgItemText( GetHandle(), id_WaveLength, buf, MaxString );
  Main.WaveLength = atof( buf );
  GetDlgItemText( GetHandle(), id_Scientist, buf, MaxString );
  strcpy( Main.User, buf );
  Main.Current = GetDlgItemInt( GetHandle(), id_BeamCurrent, &fl, FALSE );
  Main.Voltage = GetDlgItemInt( GetHandle(), id_BeamVoltage, &fl, FALSE );
  SetStaticInfo("");
  GetDlgItemText( GetHandle(), id_Text, Main.Comment, 2*MaxString );
  return TRUE;
};

//*********** Dialog Manuelle Justage *****************************************
//********** Steuerung des Probentellers ueber den Winkel *********************
#ifdef GermanVersion
TAngleControl::TAngleControl( void ):TModalDlg("AngleControl")
#else
TAngleControl::TAngleControl( void ):TModalDlg("AngleControlEng")
#endif
{
  bMoveActive = FALSE;
  AskTime     = 100;
  bLongMove   = FALSE;
  bMeasureHwb = FALSE;
  bStepMode   = TRUE;
  MoveSpeed   = new float [mlGetAxisNumber()];
};

// Routine fuer die Behandlung von WM_INITDIALOG
BOOL TAngleControl::Dlg_OnInit( HWND hwnd, HWND hwndCtl, LPARAM lParam )
{
  int cnt;

  // Initialisierungs-Routine der Basisklasse
  TModalDlg::Dlg_OnInit( hwnd, hwndCtl, lParam );
  // speichern der Motoren-ID; (via DLL-Interface)
  nMotor = mlGetAxis();
  // speichern eines pointers auf ein device (counter)
  Sensor = lpDList->DP();
  // speichern von handles auf Dialogelemente
  BarHandle = GetDlgItem( hwnd, id_Bar );
  hMotorList = GetDlgItem( hwnd, id_ChooseMotor );
  // (de)aktivieren der Eingabefelder (D, V) je nach Betriebsart
  EnableWindow( GetDlgItem( hwnd, id_AngleWidth ), bStepMode );
  EnableWindow( GetDlgItem( hwnd, id_SpeedValue ), !bStepMode );
  // wenn kein Motor fuer bestimmte Achse entspr. button deaktivieren
  if (!mlIsAxisValid( Omega ))
  {
    // Beugung Fein, Halbwertsbereite messen
    EnableWindow( GetDlgItem( hwnd, cm_SetFine ), FALSE );
    EnableWindow( GetDlgItem( hwnd, cm_MeasureHWB ), FALSE );
  }
  if (!mlIsAxisValid( Psi ))
    // Tilt
    EnableWindow( GetDlgItem( hwnd, cm_SetTilt ), FALSE );
  if (!Steering.GetMacroById( InquireHwb ))
    // ???
    EnableWindow( GetDlgItem( hwnd, cm_MeasureHWB ), FALSE );
  if (!mlIsAxisValid( Collimator ))
    // Collimator
    EnableWindow( GetDlgItem( hwnd, cm_SetCollimator ), FALSE );
  // check: "fahren" = Negation von "schrittbetrieb"
  CheckDlgButton( hwnd, id_LongMoveMode, !bStepMode );
  // fuellen der 'MotorenListe' mit den 'Namen' der Motoren
  cnt = 0;
  while ( cnt < mlGetAxisNumber() )
  {
    mlSetAxis( cnt++ );
    ComboBox_AddString( hMotorList, mGetAxisName() );
  }
  // Ausloesen einer WM_TIMER-message in AskTime (100) Sekunden
  // wird in OnTimer behandelt
  SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
  // Sichern der Motor-Einstellungen (u.a.) in der Objektvariablen MoveSpeed
  for (cnt = 0; cnt < mlGetAxisNumber(); cnt++)
  {
    mlSetAxis( cnt );
    mPushSettings();
    MoveSpeed[cnt] = mGetValue( Speed );
  }
  // (re)aktivieren des motors
  mlSetAxis( nMotor );
  // schickt sich selbst 2 CM_Messages; zu behandeln in On_Command
  FORWARD_WM_COMMAND( hwnd, cm_MotorInit, hwndCtl, 0, SendMessage );
  FORWARD_WM_COMMAND( hwnd, cm_ParamSet, hwndCtl, 0, SendMessage );
  // ???
  bMoveActive = TRUE;
  SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
  return TRUE;
};

#define TestCall  KillTimer(GetHandle(), TimerIdInformation);          \
         if (Motor->IsMoveFinish())                                    \
         {                                                             \
           if (!Motor->GetAngle(1))                                    \
           {                                                           \
             SetCursor(LoadCursor(NULL, IDC_WAIT));                    \
             SetTimer(GetHandle(), TimerIdInformation, AskTime, NULL); \
             return TRUE;                                              \
           }                                                           \
           bLongMove = FALSE;                                          \
           Motor->dAngleNew = Motor->dAngle;                           \
           sprintf(buf, Motor->pOFmt(), Motor->dAngleNew);             \
           SetDlgItemText(GetHandle(), id_NewAngle, (LPSTR)buf);       \
           sprintf(buf, Motor->pOFmt(), Motor->dAngle);                \
           SetDlgItemText(GetHandle(), id_Angle, (LPSTR)buf);          \
           SetScrollPos(BarHandle, SB_CTL, GetBarPos(), TRUE);         \
           bMoveActive = FALSE;                                        \
           SetCursor(LoadCursor(NULL, IDC_ARROW));                     \
         }                                                             \
         else                                                          \
         {                                                             \
           if (bLongMove)                                              \
           {                                                           \
             Motor->GetAngle(0);                                       \
             sprintf(buf, Motor->pOFmt(), Motor->dAngle);              \
             SetDlgItemText(GetHandle(), id_Angle, (LPSTR)buf);        \
             SetScrollPos(BarHandle, SB_CTL, GetBarPos(), TRUE);       \
           }                                                           \
           SetCursor(LoadCursor(NULL, IDC_WAIT));                      \
         }                                                             \
 

void TAngleControl::Dlg_OnTimer( HWND hwnd, UINT id )
{
  char buf[MaxString];
  double dDistance;

  switch ( id )
  {
    case TimerIdInformation:
    KillTimer( hwnd, TimerIdInformation );
    if (mIsMoveFinish())
    {
      if (!mGetDistance( dDistance ))
      {
        SetCursor( LoadCursor( NULL, IDC_WAIT ) );
        SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
        return;
      }
      bLongMove = FALSE;
      sprintf( buf, mGetDF(), dDistance );
      SetDlgItemText( hwnd, id_NewAngle, (LPSTR)buf );
      SetDlgItemText( hwnd, id_Angle, (LPSTR)buf );
      SetScrollPos( BarHandle, SB_CTL, GetBarPos(), TRUE );
      bMoveActive = FALSE;
      SetFocus( BarHandle );
      SetCursor( LoadCursor( NULL, IDC_ARROW ) );
    }
    else
    {
      if (bLongMove)
      {
        sprintf( buf, mGetDF(), mGetDistanceProcess() );
        SetDlgItemText( hwnd, id_Angle, buf );
      }
      SetCursor( LoadCursor( NULL, IDC_WAIT ) );
      SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
    }
  }
};

void TAngleControl::Dlg_OnCommand( HWND hwnd, int id, HWND hwndCtl,
    UINT codeNotify )
{
  static HWND hDlgItem;
  long        varl = 0;
  int         idx;
  char        buf[MaxString];

  switch ( id )
  {
    case cm_ParamSet:
    if (mIsDistanceRelative())
      EnableWindow( GetDlgItem( hwnd, cm_CancelRelativeZero ), TRUE );
    else
      EnableWindow( GetDlgItem( hwnd, cm_CancelRelativeZero ), FALSE );
    sprintf( buf, mGetDF(), mGetValue( Distance ) );
    SetDlgItemText( hwnd, id_Angle, (LPSTR)buf );
    SetDlgItemText( hwnd, id_NewAngle, (LPSTR)buf );
    ComboBox_SelectString( hMotorList, 0, mGetAxisName( ) );
    SetDlgItemText( hwnd, id_Unit, mGetAxisUnit() );
    SetDlgItemText( hwnd, id_StepUnit, mGetAxisUnit() );
    // Initialisieren des Motor-Scroll-Bar´s
    SetScrollRange( BarHandle, SB_CTL, GetBarEgde( LEFT ), GetBarEgde( RIGHT ),
        TRUE );
    SetFocus( BarHandle );
    break;

    case cm_SetAngleZero:
    if (bMoveActive)
      break;
    mSetRelativeZero( YES, mGetValue( Distance ) );
    if (mIsDistanceRelative())
      EnableWindow( GetDlgItem( hwnd, cm_CancelRelativeZero ), TRUE );
    else
      EnableWindow( GetDlgItem( hwnd, cm_CancelRelativeZero ), FALSE );
    bMoveActive = bLongMove = TRUE;
    mPushSettings();
    SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
    SetFocus( BarHandle );
    break;

    case cm_CancelRelativeZero:
    if (bMoveActive)
      break;
    mSetRelativeZero( NO, 0.0 );
    bMoveActive = bLongMove = TRUE;
    SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
    EnableWindow( GetDlgItem( hwnd, cm_CancelRelativeZero ), FALSE );
    SetFocus( BarHandle );
    break;

    case cm_MotorInit:
    // Fuer Moduswechsel,  Shortcuts und Motorwechsel
    EnableWindow( GetDlgItem( hwnd, id_AngleWidth ), bStepMode );
    EnableWindow( GetDlgItem( hwnd, id_SpeedValue ), !bStepMode );
    CheckDlgButton( hwnd, id_StepMode, bStepMode );
    if (bStepMode)
      mSetValue( Speed, 10000.0 );
    else
      mSetValue( Speed, MoveSpeed[nMotor] );
    sprintf( buf, mGetSF(), mGetValue( Width ) );
    SetDlgItemText( hwnd, id_AngleWidth, (LPSTR)buf );
    sprintf( buf, mGetDF(), (float)mGetValue( Speed ) );
    SetDlgItemText( hwnd, id_SpeedValue, (LPSTR)buf );
    mActivateDrive();
    if (bManualMovesCorrected)
      mSetCorrectionState( ON );
    //####################################################################
    // Fuer Ueberpruefung der Kalibrierungskurven Correction aktivieren
    //####################################################################
    // Initialisieren des Positions-Eingabefenster's
    bMoveActive = TRUE;
#ifdef GermanVersion
    if (mIsCalibrated())
      sprintf( buf, "Manuelle Justage" );
    else
      sprintf( buf, "Manuelle Justage : Kein gueltiger Referenzpunktlauf" );
#else
    if (mIsCalibrated())
      sprintf( buf, "Manual Adjustment" );
    else
      sprintf( buf, "Manual Adjustment : No valid Reference Point" );
#endif
    SetWindowText( hwnd, (LPCSTR)buf );
    SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
    break;

    case id_StepMode:
    if (bMoveActive)
      break;
    if (!bStepMode)
    {
      bStepMode = TRUE;
      SendMessage( hwnd, WM_COMMAND, cm_MotorInit, 0 );
      SetFocus( BarHandle );
    }
    else
    {
      // Focus auf Eingabefeld setzen
      SetFocus( GetDlgItem( hwnd, id_AngleWidth ) );
      hDlgItem = GetDlgItem( hwnd, id_AngleWidth );
    }
    break;

    case id_LongMoveMode:
    if (bStepMode)
    {
      bStepMode = FALSE;
      FORWARD_WM_COMMAND( hwnd, cm_MotorInit, 0, 0, SendMessage );
      SetFocus( BarHandle );
    }
    else
    {
      // Focus auf Eingabefeld setzen
      hDlgItem = GetDlgItem( hwnd, id_SpeedValue );
      ReplyMessage( varl );
      SetFocus( GetDlgItem( hwnd, id_SpeedValue ) );
    }
    break;

    case cm_MeasureHWB:
    if (bMeasureHwb)
    {
      // Messung abbrechen
      bMeasureHwb = FALSE;
      Steering.ToggleInterrupt();
#ifdef GermanVersion
      SetWindowText( GetDlgItem( hwnd, cm_MeasureHWB ),
          "&Halbwertsbreite messen" );
#else
      SetWindowText( GetDlgItem( hwnd, cm_MeasureHWB ), "Measure &Halfwidth" );
#endif
      mlSetAxis( nMotor );
      SendMessage( hwnd, WM_COMMAND, cm_MotorInit, 0 );
      SendMessage( hwnd, WM_COMMAND, cm_ParamSet, 0 );
      bMoveActive = TRUE;
      SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
      break;
    }
    if (bMoveActive)
      break;
    bMeasureHwb = TRUE;
    bMoveActive = TRUE;
    Steering.Reset();
    Steering.StartUp( hwnd, nMotor, Sensor->GetId() );
    Steering.Visualising( 1, 0, 0, 0, 0, 0 );
#ifdef GermanVersion
    SetWindowText( GetDlgItem( hwnd, cm_MeasureHWB ), "&Messung abbrechen" );
#else
    SetWindowText( GetDlgItem( hwnd, cm_MeasureHWB ), "Skip &Measurement" );
#endif
    Steering.StartMacroExecution( Steering.GetMacroById( InquireHwb ), hwnd );
    break;

    case cm_CounterSet:
    Sensor->UpdateDisplay();
    Steering.DeviceRequest();
    break;

    case cm_SteeringReady:
    mlSetAxis( nMotor );
    FORWARD_WM_COMMAND( hwnd, cm_MotorInit, 0, 0, SendMessage );
    FORWARD_WM_COMMAND( hwnd, cm_ParamSet, 0, 0, SendMessage );
    bMoveActive = TRUE;
    SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
    MessageBeep( 0 );
    bMeasureHwb = FALSE;
#ifdef GermanVersion
    sprintf( buf, "HWB = %.2f Sekunden", Steering.fHWB );
    SetInfo( buf );
    SetWindowText( GetDlgItem( hwnd, cm_MeasureHWB ),
        "&Halbwertsbreite messen" );
#else
    sprintf( buf, "HWB = %.2f arcsec", Steering.fHWB );
    SetInfo( buf );
    SetWindowText( GetDlgItem( hwnd, cm_MeasureHWB ), "Measure &Halfwidth" );
#endif
    break;

    case id_ChooseMotor:
    switch ( codeNotify )
    {
      case CBN_SELCHANGE:
      idx = ComboBox_GetCurSel( hMotorList );
      if ((nMotor != idx) && (idx != CB_ERR))
      {
        nMotor = idx;
        mlSetAxis( nMotor );
        FORWARD_WM_COMMAND( hwnd, cm_ParamSet, 0, 0, SendMessage );
        FORWARD_WM_COMMAND( hwnd, cm_MotorInit, 0, 0, PostMessage );
      }
    }
    break;

    case cm_RotateMotor:
    if (bMoveActive)
      break;
    if (!hDlgItem)
      break;
    mlSetAxis( ++nMotor );
    nMotor = mlGetAxis();
    FORWARD_WM_COMMAND( hwnd, cm_ParamSet, 0, 0, SendMessage );
    FORWARD_WM_COMMAND( hwnd, cm_MotorInit, 0, 0, PostMessage );
    break;

    case cm_SetFine:
    if (bMoveActive)
      break;
    mlSetAxis( mlGetIdByName( Omega ) );
    nMotor = mlGetAxis();
    FORWARD_WM_COMMAND( hwnd, cm_ParamSet, 0, 0, SendMessage );
    FORWARD_WM_COMMAND( hwnd, cm_MotorInit, 0, 0, PostMessage );
    break;

    case cm_SetTilt:
    if (bMoveActive)
      break;
    mlSetAxis( mlGetIdByName( Psi ) );
    nMotor = mlGetAxis();
    FORWARD_WM_COMMAND( hwnd, cm_ParamSet, 0, 0, SendMessage );
    FORWARD_WM_COMMAND( hwnd, cm_MotorInit, 0, 0, PostMessage );
    break;

    case cm_SetCollimator:
    if (bMoveActive)
      break;
    mlSetAxis( mlGetIdByName( Collimator ) );
    nMotor = mlGetAxis();
    FORWARD_WM_COMMAND( hwnd, cm_ParamSet, 0, 0, SendMessage );
    FORWARD_WM_COMMAND( hwnd, cm_MotorInit, 0, 0, PostMessage );
    break;

    case id_AngleWidth:
    hDlgItem = GetDlgItem( hwnd, id_AngleWidth );
    break;

    case id_SpeedValue:
    hDlgItem = GetDlgItem( hwnd, id_SpeedValue );
    break;

    case id_NewAngle:
    hDlgItem = GetDlgItem( hwnd, id_NewAngle );
    break;

    case IDOK:
    if (!hDlgItem)
    {
      TModalDlg::Dlg_OnCommand( hwnd, id, hwndCtl, codeNotify );
      break;
    }
    // Der Nutzer hat mit Return eine neue Position, eine neue Geschwindigkeit
    // oder eine neue Schrittweite eingegeben
    for (;;)
    {
      if (hDlgItem == GetDlgItem( hwnd, id_AngleWidth ))
      {
        GetDlgItemText( hwnd, id_AngleWidth, (LPSTR)buf, 10 );
        mSetValue( Width, atof( buf ) );
        sprintf( buf, mGetSF(), mGetValue( Width ) );
        SetDlgItemText( hwnd, id_AngleWidth, (LPSTR)buf );
        SetScrollRange( BarHandle, SB_CTL, GetBarEgde( LEFT ),
            GetBarEgde( RIGHT ), TRUE );
        SetScrollPos( BarHandle, SB_CTL, GetBarPos(), TRUE );
        break;
      }
      if (hDlgItem == GetDlgItem( hwnd, id_NewAngle ))
      {
        if (!bMoveActive)
        {
          GetDlgItemText( hwnd, id_NewAngle, (LPSTR)buf, 10 );
          bMoveActive = TRUE;
          bLongMove = TRUE;
          mMoveToDistance( atof( buf ) );
          FORWARD_WM_COMMAND( hwnd, cm_MoveButton, 0, 0, PostMessage );
        }
        break;
      }
      if (hDlgItem == GetDlgItem( hwnd, id_SpeedValue ))
      {
        GetDlgItemText( hwnd, id_SpeedValue, (LPSTR)buf, 10 );
        mSetValue( Speed, atof( buf ) );
        MoveSpeed[nMotor] = mGetValue( Speed );
        sprintf( buf, mGetSF(), (float)MoveSpeed[nMotor] );
        SetDlgItemText( hwnd, id_SpeedValue, (LPSTR)buf );
        break;
      }
    }
    hDlgItem = NULL;
    SetFocus( BarHandle );
    break;

    case cm_MoveButton:
    bMoveActive = TRUE;
    SetCursor( LoadCursor( NULL, IDC_WAIT ) );
    SetTimer( hwnd, TimerIdInformation, AskTime, NULL );
    break;

    default:
    TModalDlg::Dlg_OnCommand( hwnd, id, hwndCtl, codeNotify );
  }
};

void TAngleControl::Interrupt( void )
{
  mStopDrive( TRUE );
  DelayTime( 5 );
};

#pragma argsused
void TAngleControl::Dlg_OnHScrollBar( HWND hwnd, HWND hwndCtl, UINT code,
    int pos )
{
  if (bMeasureHwb)
    return;
  switch ( code )
  {
    case SB_LINEUP:
    if (bMoveActive)
      return;
    if (bStepMode)
      mMoveToDistance( mGetValue( Distance ) - mGetValue( Width ) );
    else
    {
      mMoveToDistance( mGetValue( MinDistance ) );
      bLongMove = TRUE;
    }
    FORWARD_WM_COMMAND( hwnd, cm_MoveButton, 0, 0, SendMessage );
    break;
 
    case SB_LINEDOWN:
    if (bMoveActive)
      return;
    if (bStepMode)
      mMoveToDistance( mGetValue( Distance ) + mGetValue( Width ) );
    else
    {
      mMoveToDistance( mGetValue( MaxDistance ) );
      bLongMove = TRUE;
    }
    FORWARD_WM_COMMAND( hwnd, cm_MoveButton, 0, 0, SendMessage );
    break;
 
    case SB_ENDSCROLL:
    // Bewegung stoppen,  wenn laenger gefahren wurde
    if (bLongMove)
      Interrupt();
    break;
 
    case SB_PAGEUP: case SB_PAGEDOWN:
    break;
  }
};

int TAngleControl::GetBarEgde( int side )
{
  long steps;
  int ret;

  if (side == LEFT)
  {
    steps = (long)(( mGetValue( MaxDistance ) - mGetValue( MinDistance ) ) /
        mGetValue( Width ));
    BarFactor = (int)( steps / 20000l ) + 1;
    ret = (int)(mGetValue( MinDistance ) / ( mGetValue( Width ) * BarFactor ));
  }
  else
  {
    ret = (int)(mGetValue( MaxDistance ) / ( mGetValue( Width ) * BarFactor ));
  }
  return ret;
};

int TAngleControl::GetBarPos()
{
  int ret;

  ret = (int)( mGetValue( Distance ) / ( mGetValue( Width ) * BarFactor ) );
  return ret;
};

// Basisklasse TModalDlg in Dlg_OnCommand wird bei den messages
// IDOK, IDCANCEL, IDABORT vor EndDialog aufgerufen
BOOL TAngleControl::LeaveDialog( void )
{
  int cnt;

  // stoppt zeitgeber
  cnt = KillTimer( GetHandle(), TimerIdInformation );
  // speichern der aktuellen settings im aktuellen device
  // (ausser wenn dies ein psd ist)
  if (Sensor->GetId() != dlGetIdByName( PsdDevice ))
  {
    Sensor->MeasureStop();
    Sensor->PopSettings();
    Sensor->MeasureStart();
  }
  // anhalten des aktuellen Motors
  mStopDrive( TRUE );
  // restauriert in allen Motoren die alten 'settings' (bis auf die Position)
  for (cnt = 0; cnt < mlGetAxisNumber(); cnt++)
  {
    mlSetAxis( cnt );
    mPopSettings( ThisPosition );
    // ???
    mSetCorrectionState( OFF );
  }
  // (re)aktiviert den Motor
  mlSetAxis( nMotor );
  return TRUE;
};
 

// __LastLine__