%% options copyright owner = Dirk Krause copyright year = 2013-xxxx license = bsd %% header class WinprintThread : public wxThread { protected: /** File to print. */ wxChar const *sFilename; /** Printer to use. */ dkChar const *sPrintername; /** Communicator object. */ DkWxCommunicator *pComm; /** Localized texts. */ wxChar const * const *sTexts; /** Application helper. */ DkWxAppHelper *pHelper; /** Print configuration. */ dk3_print_conf_t *pc; /** Encoding for dkChar strings. */ int dkenc; public: /** Constructor. @param communicator Communication object. @param localizedTexts Localized texts. @param applicationHelper Application helper object. @param printConfiguration Print configuration. @param fileName File to print. @param printerName Printer to use. */ WinprintThread( DkWxCommunicator *communicator, wxChar const * const *localizedTexts, DkWxAppHelper *applicationHelper, dk3_print_conf_t *printConfiguration, wxChar const *fileName, wxChar const *printerName ); /** Destructor. */ ~WinprintThread(); /** Check setup. @return true on success, false on error. */ bool checkSetup(); /** Thread function. @return Pointer which is ignored. */ virtual void * Entry(); /** Method executed at end of thread, doest nothing. */ virtual void OnExit(); }; %% module #include "winprint.h" $!trace-include WinprintThread::WinprintThread( DkWxCommunicator *communicator, wxChar const * const *localizedTexts, DkWxAppHelper *applicationHelper, dk3_print_conf_t *printConfiguration, wxChar const *fileName, wxChar const *printerName ) { $? "+ WinprintThread::WinprintThread" pComm = communicator; sTexts = localizedTexts; pHelper = applicationHelper; pc = printConfiguration; dkenc = applicationHelper->getDkEncoding(); sFilename = NULL; sPrintername = NULL; if(fileName) { sFilename = dk3wxs_dup(fileName); } if(printerName) { sPrintername = dk3wxs_dup(printerName); } $? "- WinprintThread::WinprintThread" } WinprintThread::~WinprintThread() { /* Release resources. */ $? "+ WinprintThread::~WinprintThread" dk3_release(sPrintername); dk3_release(sFilename); $? "- WinprintThread::~WinprintThread" } bool WinprintThread::checkSetup() { bool back = false; $? "+ WinprintThread::checkSetup" if((sFilename) && (sPrintername)) { back = true; } $? "- WinprintThread::checkSetup %d", ((back) ? 1 : 0) return back; } void * WinprintThread::Entry() { void *back = NULL; /* Switch between a test version (1) and the real version (0). */ #if 0 int i; $? "+ WinprintThread::Entry (test)" for(i = 0; i < 10; i++) { this->Sleep(200); pComm->setUpdates(sFilename, 100*i); } pComm->setUpdates(sFilename, 1000); pComm->addWxText(wxT("Test error message")); /* pComm->setLogLevel(DK3_LL_ERROR); */ pComm->setRunning(0); $? "- WinprintThread::Entry (test)" #else char buf[4096]; /* Buffer for copying data.*/ dkChar pName[DK3_MAX_PATH]; /* Buffer for printer name. */ dkChar fName[DK3_MAX_PATH]; /* Buffer for file name. */ #if DK3_CHAR_SIZE > 1 char ajbu[sizeof(ADDJOB_INFO_1W)+(sizeof(dkChar)*DK3_MAX_PATH)]; /* Buffer for job creation. */ ADDJOB_INFO_1W *aji1; /* Job creation structure. */ #else char ajbu[sizeof(ADDJOB_INFO_1A)+(sizeof(dkChar)*DK3_MAX_PATH)]; /* Buffer for job creation. */ ADDJOB_INFO_1A *aji1; /* Job creation structure. */ #endif dk3_stat_t stb; /* Information about named file. */ FILE *ifile; /* Input file. */ HANDLE hPr; /* Printer handle. */ HANDLE hFile; /* Handle for print job file. */ dk3_um_t summary; /* Number of bytes processed. */ DWORD dwAcc; /* Access permissions required. */ DWORD dwSh; /* Print job file share mode. */ DWORD dwDisp; /* Print job file disposition. */ DWORD dwAttr; /* Print job file attributes. */ DWORD dwSz; /* Buffer size for job creation. */ DWORD written; /* NUmber of bytes currently written. */ DWORD dwNeeded; /* Number of bytes needed. */ size_t szrd; /* Number of bytes read from file. */ int dke; /* dkChar encoding. */ int wxe; /* wxChar encoding. */ int havestat; /* Flag: File information found. */ int ok; /* Flag: Success. */ int level; /* Data structure level. */ BOOL bres; /* Operation result. */ $? "+ WinprintThread::Entry (real)" dke = pHelper->getDkEncoding(); wxe = pHelper->getWxEncoding(); if(dk3wxs_to_dkstr(pName,DK3_SIZEOF(pName,dkChar),dke,sPrintername,wxe)) { if(dk3wxs_to_dkstr(fName,DK3_SIZEOF(fName,dkChar),dke,sFilename,wxe)) { pComm->setUpdates(sFilename, WINPRINT_LEVEL_1); hPr = INVALID_HANDLE_VALUE; #if DK3_CHAR_SIZE > 1 bres = OpenPrinterW(pName, &hPr, NULL); #else bres = OpenPrinterA(pName, &hPr, NULL); #endif if(bres) { dwSz = sizeof(ajbu); dwNeeded = (DWORD)0UL; #if DK3_CHAR_SIZE > 1 bres = AddJobW(hPr, 1, (LPBYTE)ajbu, dwSz, &dwNeeded); #else bres = AddJobA(hPr, 1, (LPBYTE)ajbu, dwSz, &dwNeeded); #endif if(bres) { aji1 = (ADDJOB_INFO_1 *)ajbu; if(aji1->Path) { hFile = INVALID_HANDLE_VALUE; dwAcc = GENERIC_WRITE; dwSh = FILE_SHARE_READ; dwDisp = CREATE_ALWAYS; dwAttr = FILE_ATTRIBUTE_NORMAL; #if DK3_CHAR_SIZE > 1 hFile = CreateFileW(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL); #else hFile = CreateFileA(aji1->Path,dwAcc,dwSh,NULL,dwDisp,dwAttr,NULL); #endif if(INVALID_HANDLE_VALUE != hFile) { if(dk3sf_stat_app(&stb, fName, NULL)) { havestat = 1; } ifile = dk3sf_fopen_app(fName, dkT("rb"), pHelper->getApp()); if(ifile) { ok = 1; summary = (dk3_um_t)DK3_UM_0; do { szrd = dk3sf_fread_app( (void *)buf, 1, sizeof(buf), ifile, pHelper->getApp() ); if(szrd > 0) { bres = WriteFile( hFile, (LPCVOID)buf, (DWORD)szrd, &written, NULL ); if(bres) { if(written == (DWORD)szrd) { summary += (dk3_um_t)written; if(havestat) { level = WINPRINT_LEVEL_1 + ( (WINPRINT_LEVEL_2 - WINPRINT_LEVEL_1) * summary ) / stb.sz; if(level >= WINPRINT_LEVEL_2) { level = WINPRINT_LEVEL_2; } pComm->setUpdates(sFilename, level); } } else { ok = 0; /* ERROR: Too few bytes! */ pComm->addWxText(sTexts[38]); pComm->setLogLevel(DK3_LL_ERROR); } } else { ok = 0; /* ERROR: Write failed! */ pComm->addWxText(sTexts[38]); pComm->setLogLevel(DK3_LL_ERROR); } } } while((szrd > 0) && (ok)); fclose(ifile); } else { /* ERROR: Failed to open input file! */ pComm->addWxText(sTexts[39]); pComm->setLogLevel(DK3_LL_ERROR); } CloseHandle(hFile); pComm->setUpdates(sFilename, WINPRINT_LEVEL_2); if(ScheduleJob(hPr, aji1->JobId)) { /* ##### SUCCESS */ } else { /* ERROR: Failed to schedule job! */ pComm->addWxText(sTexts[40]); pComm->setLogLevel(DK3_LL_ERROR); } } else { /* ERROR: Failed to create file! */ pComm->addWxText(sTexts[41]); pComm->setLogLevel(DK3_LL_ERROR); } } else { /* ERROR: Path not set in add job info */ pComm->addWxText(sTexts[42]); pComm->setLogLevel(DK3_LL_ERROR); } } else { /* ERROR: Failed to add job! */ pComm->addWxText(sTexts[42]); pComm->setLogLevel(DK3_LL_ERROR); } ClosePrinter(hPr); } else { /* ERROR: Failed to open printer! */ pComm->addWxText(sTexts[43]); pComm->setLogLevel(DK3_LL_ERROR); } } else { /* ERROR: Failed to convert file name! */ pComm->addWxText(sTexts[44]); pComm->setLogLevel(DK3_LL_ERROR); } } else { /* ERROR: Failed to convert printer name! */ pComm->addWxText(sTexts[45]); pComm->setLogLevel(DK3_LL_ERROR); } pComm->setUpdates(sFilename, 1000); pComm->setRunning(0); $? "- WinprintThread::Entry (real)" #endif return back; } void WinprintThread::OnExit() { $? "+ WinprintThread::OnExit" $? "- WinprintThread::OnExit" }