00001
00004
00005
00006 #include "stdafx.h"
00007 #include "UpdateHandler.h"
00008
00010
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
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,
00067 0,
00068 &update,
00069 this,
00070 0,
00071 NULL);
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;
00086
00087 DWORD exitCode;
00088 GetExitCodeThread(hUpdateThread, &exitCode);
00089
00090
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) ){
00111 if( !SetCurrentDirectory(update->captureDir) )
00112 update->capture = false;
00113 }
00114
00115 if( !update->captureName ){
00116 update->capture = false;
00117 }
00118
00119 int screenNum = -1;
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;
00145 }
00146
00147 update->screen->invalidate(update->hWnd);
00148
00149
00150 if(update->exit)
00151 continue;
00152
00153 screenNum++;
00154
00155
00156 if( !update->capture || !((screenNum % update->captureEvery) == 0) )
00157 continue;
00158
00159
00160 if( update->captureLimit != 0 && captureNum > update->captureLimit ){
00161 update->capture = false;
00162 continue;
00163 }
00164
00165 readBuffer = update->screen->getReadBuffer();
00166
00167
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, ¬Needed, NULL);
00177 if(freeBytes.QuadPart < 1024 * 1024){
00178 update->capture = false;
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) ){
00301 if ( SetCurrentDirectory(captureDir) ){
00302 capture = true;
00303 }
00304 } else {
00305 capture = true;
00306 }
00307 return capture;
00308 }