Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

UpdateHandler.cpp

Go to the documentation of this file.
00001 // UpdateHandler.cpp: implementation of the UpdateHandler class.
00004 
00005 
00006 #include "stdafx.h"
00007 #include "UpdateHandler.h"
00008 
00010 // Construction/Destruction
00012 
00021 UpdateHandler::UpdateHandler(ScreenPipe &s, BitmapScreen& b, HWND h)
00022 :hWnd(h)
00023 {
00024     pipe = &s;
00025     screen = &b;
00026     hUpdateThread = NULL;
00027 
00028     captureName = TEXT("ScreenCap_");
00029     captureEvery = 1;
00030     captureLimit = 50;
00031     capture = false;
00032 
00033     captureMutex = CreateMutex(NULL, false, NULL);
00034 }
00035 
00039 UpdateHandler::~UpdateHandler()
00040 {
00041     stop(true);
00042     CloseHandle(captureMutex);
00043     CloseHandle(hUpdateThread);
00044 }
00045 
00047 // Member Functions
00049 
00053 bool UpdateHandler::run()
00054 {
00055     DWORD exitCode;
00056     GetExitCodeThread(hUpdateThread, &exitCode);
00057 
00058     if( exitCode == STILL_ACTIVE )
00059         return true;
00060 
00061     exit = false;
00062 
00063     CloseHandle(hUpdateThread);
00064 
00065     hUpdateThread = chBEGINTHREADEX(
00066         NULL,           // Default Security, non inheritable
00067         0,              // use default stack size  
00068         &update,        // thread function
00069         this,           // thread argument
00070         0,              // use default creation flags 
00071         NULL);          // don't need thread identifier
00072     
00073     if(hUpdateThread == NULL){
00074         return false;
00075     }
00076 
00077     return true;
00078 }
00079 
00083 void UpdateHandler::stop(const bool force)
00084 {
00085     exit = true;    // Signal thread to stop
00086 
00087     DWORD exitCode;
00088     GetExitCodeThread(hUpdateThread, &exitCode);
00089 
00090     // If still active after a second terminate the thread
00091     if( force && exitCode == STILL_ACTIVE ){
00092         if( WaitForSingleObject(hUpdateThread, 1000) == WAIT_TIMEOUT )
00094             TerminateThread(hUpdateThread, 0);
00095     }
00096 
00097 }
00098 
00104 DWORD WINAPI UpdateHandler::update(LPVOID param)
00105 {
00106     UpdateHandler* update = (UpdateHandler*) param;
00107 
00108     WaitForSingleObject(update->captureMutex, INFINITE);
00109 
00110     if( !(!update->captureDir) ){ // not empty
00111         if( !SetCurrentDirectory(update->captureDir) )
00112             update->capture = false;
00113     }
00114 
00115     if( !update->captureName ){ // is empty
00116         update->capture = false;
00117     }
00118     
00119     int screenNum = -1;  // screenNo incremented before use
00120     int captureNum = 1;
00121     bool success;
00122     ULARGE_INTEGER freeBytes, notNeeded;
00123 
00124     DIBitmap *writeBuffer;
00125     const DIBitmap *readBuffer;
00126 
00127     DWORD readResult;
00128     while(!update->exit){
00129 
00130         writeBuffer = update->screen->getWriteBuffer();
00131         
00132         readResult = update->pipe->readToDIB(*writeBuffer);
00133 
00134         update->screen->DoneWriting();
00135 
00136         switch(readResult){
00137             case SP_SUCCESS:
00138                 break;
00139             case SP_UNKNOWN_ERROR:
00140             case SP_ERROR_CREATING_BITMAP:
00141             case SP_NOT_CONNECTED:
00142             case SP_INVALID_DATA:
00143             default:
00144                 return false;   // Abandons mutex
00145         }
00146 
00147         update->screen->invalidate(update->hWnd);
00148         
00149         // restart loop if signaled to exit
00150         if(update->exit)
00151             continue;
00152         
00153         screenNum++;
00154 
00155         // Check that we wish to capture this screen
00156         if( !update->capture || !((screenNum % update->captureEvery) == 0) )
00157             continue;
00158         
00159         // Check we haven't reached capture limit;
00160         if( update->captureLimit != 0 && captureNum > update->captureLimit ){
00161             update->capture = false;
00162             continue;
00163         }
00164 
00165         readBuffer = update->screen->getReadBuffer();
00166 
00167         // Write buffer to disk   
00168         success = readBuffer->saveFile(
00169             update->captureName + TString(screenNum) + TString(TEXT(".bmp")) ); 
00170         
00171         update->screen->DoneReading();
00172 
00173         captureNum++;
00174 
00175         if( !success ){
00176             GetDiskFreeSpaceEx(NULL, &freeBytes, &notNeeded, NULL);
00177             if(freeBytes.QuadPart < 1024 * 1024){ // less than a megabyte
00178                 update->capture = false; // Stop capturing
00179             }
00180         }
00181 
00182     }
00183 
00184     ReleaseMutex(update->captureMutex);
00185 
00186     return true;
00187 }
00188 
00190 bool UpdateHandler::setCapture(
00191             const TString &name, 
00192             const TString &directory, 
00193             const int limit, 
00194             const int frequency)
00195 {
00196     bool success = false;
00197 
00198     switch(WaitForSingleObject(captureMutex, 0) ) {
00199     case  WAIT_OBJECT_0:
00200         captureName = name;
00201         captureDir = directory;
00202         captureLimit = limit;
00203         captureEvery = frequency;
00204         success = true;
00205     case WAIT_ABANDONED:
00206         ReleaseMutex(captureMutex);
00207         break;
00208     default:
00209         break;
00210     }
00211 
00212     return success;
00213 }
00214 
00216 bool UpdateHandler::setCaptureName(const TString &name)
00217 {
00218     bool success = false;
00219 
00220     switch(WaitForSingleObject(captureMutex, 0) ) {
00221     case  WAIT_OBJECT_0:
00222         captureName = name;
00223         success = true;
00224     case WAIT_ABANDONED:
00225         ReleaseMutex(captureMutex);
00226         break;
00227     default:
00228         break;
00229     }
00230 
00231     return success;
00232 }
00233 
00235 bool UpdateHandler::setCaptureDir(const TString &directory)
00236 {
00237     bool success = false;
00238 
00239     switch(WaitForSingleObject(captureMutex, 0) ) {
00240     case  WAIT_OBJECT_0:
00241         captureDir = directory;
00242         success = true;
00243     case WAIT_ABANDONED:
00244         ReleaseMutex(captureMutex);
00245         break;
00246     default:
00247         break;
00248     }
00249 
00250     return success;
00251 }
00252 
00254 bool UpdateHandler::setCaptureLimit(const int limit)
00255 {
00256     bool success = false;
00257 
00258     switch(WaitForSingleObject(captureMutex, 0) ) {
00259     case  WAIT_OBJECT_0:
00260         captureLimit = limit;
00261         success = true;
00262     case WAIT_ABANDONED:
00263         ReleaseMutex(captureMutex);
00264         break;
00265     default:
00266         break;
00267     }
00268 
00269     return success;
00270 }
00271 
00273 bool UpdateHandler::setCaptureFrequency(const int frequency)
00274 {
00275     bool success = false;
00276 
00277     switch(WaitForSingleObject(captureMutex, 0) ) {
00278     case  WAIT_OBJECT_0:
00279         captureEvery = frequency;
00280         success = true;
00281     case WAIT_ABANDONED:
00282         ReleaseMutex(captureMutex);
00283         break;
00284     default:
00285         break;
00286     }
00287 
00288     return success;
00289 }
00290 
00292 void UpdateHandler::disableCapture()
00293 {
00294     capture = false;
00295 }
00296 
00298 bool UpdateHandler::enableCapture()
00299 {
00300     if( !(!captureDir) ){ // not empty
00301         if ( SetCurrentDirectory(captureDir) ){
00302             capture = true;
00303         }
00304     } else {
00305         capture = true;
00306     }
00307     return capture;
00308 }

Generated on Mon Mar 25 06:29:59 2002 for Window Dressing by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001