ATMO_BOOL CAtmoLiveSettings::ExecuteCommand(HWND hControl,int wmId, int wmEvent) {

    switch(wmId) {
        case IDOK: {
           CAtmoConfig *pAtmoConfig = this->m_pDynData->getAtmoConfig();

           if(UpdateLiveViewValues(ATMO_FALSE) == ATMO_FALSE) return 0;

           EndDialog(this->m_hDialog, wmId);
           break;
        }

        case IDCANCEL: {
            // m_pBackupConfig --> wieder herstellen...
            CAtmoConfig *pAtmoConfig = this->m_pDynData->getAtmoConfig();
            pAtmoConfig->Assign(this->m_pBackupConfig);

            EndDialog(this->m_hDialog, wmId);
            break;
        }

        case IDC_WIDESCREEN: {
            CAtmoConfig *pAtmoConfig = this->m_pDynData->getAtmoConfig();
            if(Button_GetCheck(hControl) == BST_CHECKED)
               pAtmoConfig->setLiveView_WidescreenMode(1);
            else
               pAtmoConfig->setLiveView_WidescreenMode(0);
            break;
        }

        case IDC_FILTERMODE: {
             /// CBN_SELCHANGE
            if(wmEvent == CBN_SELCHANGE) {
               CAtmoConfig *pAtmoConfig = this->m_pDynData->getAtmoConfig();
               int i = ComboBox_GetCurSel(hControl);
               pAtmoConfig->setLiveViewFilterMode((AtmoFilterMode)i);
            }
            break;
        }

        case IDC_DISPLAYS: {
            if(wmEvent == CBN_SELCHANGE) {
               CAtmoConfig *pAtmoConfig = this->m_pDynData->getAtmoConfig();
               int i = ComboBox_GetCurSel(hControl);
               if(i != pAtmoConfig->getLiveView_DisplayNr()) {
                  UpdateLiveViewValues( pAtmoConfig->getEffectMode() == emLivePicture );
               }
            }
            break;
        }

        case IDC_GDI_CAPURE_RATE: {
            if(wmEvent == EN_CHANGE) {
                char buffer[20];
                if(Edit_GetText(hControl,buffer,sizeof(buffer))>0) {
                    int value = atoi(buffer);
                    if((value>=1) && (value<=50)) {
                        CAtmoConfig *pAtmoConfig = this->m_pDynData->getAtmoConfig();
                        pAtmoConfig->setLiveView_GDI_FrameRate(value);
                    } else {
                        MessageBeep(MB_ICONEXCLAMATION);
                    }
                }
            }
            break;
        }

       default:
           return ATMO_FALSE;

    }

    return ATMO_TRUE;
}
// Opens the input-device. Parameters (e.g. the device-name) can be given in 'param'.
// Returns true if the input-device was opened successfully.
ATMO_BOOL CAtmoGdiDisplayCaptureInput::Open() {

     CAtmoConfig *pAtmoConfig = m_pAtmoDynData->getAtmoConfig();
     CAtmoDisplays *pAtmoDisplays = m_pAtmoDynData->getAtmoDisplays();
     
	 m_rowsPerFrame = pAtmoConfig->getLiveView_RowsPerFrame();
     if(m_rowsPerFrame < 1) m_rowsPerFrame = 1;
     if(m_rowsPerFrame >= CAP_HEIGHT) m_rowsPerFrame = CAP_HEIGHT - 1;
     m_CurrentFrame = 0; // halbbild counter
     
     // clear temp hsv image 
     memset(&HSV_Img, 0, IMAGE_SIZE * sizeof(tHSVColor) );

#ifndef UseGdiDesktopGetPixel
     // setup handles and stuff for screen copy ...
     m_hdcScreen      = GetDC(NULL);

     // used as device context for temporary screenshot bitmap
     m_hTempBitmapDC  = CreateCompatibleDC(m_hdcScreen);
#endif

     int displayNr = pAtmoConfig->getLiveView_DisplayNr();
     if(displayNr >= pAtmoDisplays->getCount())
        displayNr = 0; // drop back to display 0 ;-)
     TAtmoDisplayInfo dislayInfo = pAtmoDisplays->getDisplayInfo(displayNr);


     // here TODO insert Screen! - in the config we have the display number to use
     // get resolution of this display and its position in the world of the current
     // windows desktop device context....!!! todo!
     m_ScreenSourceRect.left   = dislayInfo.horz_ScreenPos + pAtmoConfig->getLiveView_HOverscanBorder();
     m_ScreenSourceRect.top    = dislayInfo.vert_ScreenPos + pAtmoConfig->getLiveView_VOverscanBorder();
     m_ScreenSourceRect.right  = m_ScreenSourceRect.left + dislayInfo.horz_res - (2 * pAtmoConfig->getLiveView_HOverscanBorder());
     m_ScreenSourceRect.bottom = m_ScreenSourceRect.top  + dislayInfo.vert_res - (2 * pAtmoConfig->getLiveView_VOverscanBorder());

     // calculate lShift and tShift?
     /*
       for what?
       ok ... lets do some basics... our temp picutre has 64 columns?
       our source (my desktop) is 1600 columns wide?
       ... so i Have to grab every 64th Pixel?
       a simple calculation would result into
       destination column 0:   --> source column 0
       destincation column 63: --> source column 1575 ... so we will lose 25 pixel to the right?
       so m_lShift is the value we have to move the "Grab Raster to right" so that
       destination column 0:   --> source column 12
       destincation column 63: --> source column 1587 ... so we will lose 12 pixel to the right and 12 to the left.. a nice small ignored Border around...

       that same happens to the row position...
     */

     // precalculate Pixel Coordinates for Capture to save some cpu time?
     int capture_area_width  = m_ScreenSourceRect.right - m_ScreenSourceRect.left;
     int capture_area_height = m_ScreenSourceRect.bottom - m_ScreenSourceRect.top;
     for(int y=1;y<=CAP_HEIGHT;y++) {
         m_iSrcRows[y-1] = ((y * capture_area_height) / (CAP_HEIGHT+1) );
     }
     for(int x=1;x<=CAP_WIDTH;x++) {
         m_iSrcCols[x-1] = ((x * capture_area_width) / (CAP_WIDTH+1) );
     }
     // 25.09.2007 Igor: + m_ScreenSourceRect.left +m_ScreenSourceRect.top --> ist falsch
     // weil die Koordinaten in m_iSrcCols und m_iSrcRows - beziehen sich ja schon auf die mittels m_ScreenSourceRect erzeugte
     // Kopie des Desktops Device Contexts ... thanks to MacGyver for debugging.

#ifndef UseGdiGetPixel
     // should be enough memory for one row of pixels! in each Color Depth?
     m_PixelBuffer = (unsigned char *)malloc((capture_area_width+1) * 4);
#endif

     // run this thread
     this->Run();
     return true;
}