/*------------ Model.idl ------------*/ // Model.idl : IDL source for Model.dll // // This file will be processed by the MIDL tool to // produce the type library (Model.tlb) and marshalling code. import "oaidl.idl"; import "ocidl.idl"; // *********************************************************************** // // // [ object, uuid(7700BD00-1020-11D1-8304-0060979B3BF2), pointer_default(unique) ] interface IModelSecuritySink : IUnknown { [id(1)] HRESULT PasswordDialog(long pObject, BSTR* pPassword); }; // --------------------------------------------------------------------- // ModelLib [ uuid(2E638520-61B4-11d2-B7DB-0060979B3BF2), version(1.0), ] library ModelLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); interface IModelSecuritySink; }; /*------------ TBook.cpp ------------*/ #include "StdAfx.h" // MAIN INCLUDE #ifndef T_BOOK #include "TBook.h" #endif // OTHER INCLUDES #ifndef T_PAGE #include "TPage.h" #endif #ifndef T_SUMMARY #include "TSummary.h" #endif #ifndef T_INDEX #include "TIndex.h" #endif #ifndef T_DB_PTR_ARRAY #include "TDBPtrArray.h" #endif #ifndef T_PRIVATE_DB_ITERATOR #include "TPrivateDBIterator.h" #endif #ifndef T_PSEPRO_DB #include "TPseProDB.h" #endif #ifndef T_PTR_ARRAY #include "TPtrArray.h" #endif #ifndef T_PROPERTY_OBJECT #include "TPropertyObject.h" #endif #include "TPagePropertiesConstants.h" #include "TBookPropertiesConstants.h" #include "TPageIdentifiersConstants.h" #include "TAppBrandingInfo.h" #include "TUserInfo.h" #include "TAppVersionInfo.h" #include "TAnonymousGUID.h" /***********************/ /***** class TBook *****/ /***********************/ _7X_DB_OBJECT_IMPLEMENT_ID(TBook, TMedium) /****************************/ // SPECIFIC PSE PRO STUFF boolean TBook::bStuff = TBook::init_relocation_hooks(); boolean TBook::init_relocation_hooks() { // Uncomment this if you want to debug 'fetch' ops /* os_ts::set_fetch_hook( os_typespec::before_hook, TBook::fetch_before, (void*)NULL ); os_ts::set_fetch_hook( os_typespec::after_hook, TBook::fetch_after, (void*)NULL ); */ return true; } void TBook::fetch_before(void* object, os_int32, void* data, void*) { TBook* book = (TBook*)object; TRACE1("TBook::fetch_before - [0x%x]\n",(void*)book); } void TBook::fetch_after(void* object, os_int32, void* data, void*) { TBook* book = (TBook*)object; TRACE1("TBook::fetch_after - [0x%x]\n",(void*)book); } // CONSTRUCTORS TBook::TBook() : TMedium() { DB_ESTABLISH_FAULT_HANDLER DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TDBPtrArray,fPageList,this); DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TSummary,fSummary,this); fSummary->setBook(this); addPage(fSummary); // We want the root page to be in the flat list DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TIndex,fIndex,this); fIndex->setBook(this); // We need to do that because the Index is not under the Summary fPagesBeforeSummaryList = null; // We directly add the 'author' page to the pages before the summary TPage* authorPage = null; DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TPage,authorPage,this); authorPage->setBook(this); TPropertyObject* defaultProp = authorPage->getDefaultProperty(); defaultProp->putStringField(T_PAGE_PROPERTY_PAGELET_TYPE, TString("property")); // Besides, the author page is considered SYTEM page long systemFlag = F_PAGE_SYSTEM; defaultProp->putLongField(T_PAGE_DEFAULT_PROPERTY_BEHAVIOUR, systemFlag); // And the author page is attributed an identifier TString authorIdentifier = T_AUTHOR_PAGE_IDENTIFIER; defaultProp->putStringField(T_PAGE_DEFAULT_PROPERTY_IDENTIFIER, authorIdentifier); addPageBeforeSummary(authorPage); // Let's set the various properties default values /******************/ /* Default Values */ /******************/ TPropertyObject* lBookDefaultProperty = null; lBookDefaultProperty = getDefaultProperty(); ASSERT(lBookDefaultProperty); USES_CONVERSION; CLSID lBookID = CLSID_NULL; TAnonymousGUID::CoCreateGuid(&lBookID); CComBSTR lBookIDStr(lBookID); lBookDefaultProperty->putStringField(T_BOOK_DEFAULT_PROPERTY_BOOK_ID, W2CT(lBookIDStr)); /*********************/ /* Author Properties */ /*********************/ TPropertyObject* lAuthorProperty = null; DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TPropertyObject,lAuthorProperty,this); TAppBrandingInfo lBrandingInfo; TUserInfo lUserInfo; TAppVersionInfo lAppInfo; lAuthorProperty->putStringField(T_BOOK_AUTHOR_PROPERTY_AUTHOR_USER, lUserInfo.GetUserID()); lAuthorProperty->putStringField(T_BOOK_AUTHOR_PROPERTY_AUTHOR_SKU, lAppInfo.GetSKU()); lAuthorProperty->putStringField(T_BOOK_AUTHOR_PROPERTY_AUTHOR_PARTNER, lBrandingInfo.GetPartnerID()); setProperty(T_BOOK_AUTHOR_PROPERTY,lAuthorProperty); DB_END_FAULT_HANDLER } // DESTRUCTORS TBook::~TBook() { DB_ESTABLISH_FAULT_HANDLER // Here I destroy my pointer fields not directly // handled by a model DB_DESTROY_OBJECT(fPageList); DB_DESTROY_OBJECT(fPagesBeforeSummaryList); DB_END_FAULT_HANDLER } // METHODS TSummary* TBook::getSummary() { DB_ESTABLISH_FAULT_HANDLER return fSummary; DB_END_FAULT_HANDLER // If fail return null; } void TBook::setSummary(TSummary* pSummary) { DB_ESTABLISH_FAULT_HANDLER fSummary = pSummary; DB_END_FAULT_HANDLER } int TBook::getPageCount() { DB_ESTABLISH_FAULT_HANDLER return fPageList->size(); //return fSummary->GetTotalPageCount(); DB_END_FAULT_HANDLER // If fail return 0; } void TBook::setBookStyle(int pBookStyle) { DB_ESTABLISH_FAULT_HANDLER fBookStyle = pBookStyle; DB_END_FAULT_HANDLER } int TBook::getBookStyle() { DB_ESTABLISH_FAULT_HANDLER return fBookStyle; DB_END_FAULT_HANDLER // If fail return 0; } TIndex* TBook::getIndex() { DB_ESTABLISH_FAULT_HANDLER return fIndex; DB_END_FAULT_HANDLER // If fail return null; } void TBook::setIndex(TIndex* pIndex) { DB_ESTABLISH_FAULT_HANDLER fIndex = pIndex; DB_END_FAULT_HANDLER } int TBook::getPagesBeforeSummaryCount() { DB_ESTABLISH_FAULT_HANDLER if (fPagesBeforeSummaryList != null) { return fPagesBeforeSummaryList->size(); } DB_END_FAULT_HANDLER // If fail return 0; } void TBook::addPageBeforeSummary(TPage* pPage) { DB_ESTABLISH_FAULT_HANDLER if (pPage != null) { if (fPagesBeforeSummaryList == null) { DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TDBPtrArray,fPagesBeforeSummaryList,this); } fPagesBeforeSummaryList->addElement(pPage); } DB_END_FAULT_HANDLER } void TBook::removePageBeforeSummary(TPage* pPage) { DB_ESTABLISH_FAULT_HANDLER if (pPage != null) { if (fPagesBeforeSummaryList != null) { fPagesBeforeSummaryList->removeElement(pPage); } } DB_END_FAULT_HANDLER } TPage* TBook::getPageBeforeSummary(int pIndex) { DB_ESTABLISH_FAULT_HANDLER if ((pIndex > 0) && (pIndex <= fPagesBeforeSummaryList->size())) { return (TPage *)fPagesBeforeSummaryList->elementAt(pIndex - 1); } DB_END_FAULT_HANDLER // If fail return null; } boolean TBook::isPageBeforeSummary(TPage* pPage) { DB_ESTABLISH_FAULT_HANDLER if (pPage != null) { return fPagesBeforeSummaryList->contains(pPage); } DB_END_FAULT_HANDLER // If fail return false; } TPage* TBook::getPrimaryPage() { DB_ESTABLISH_FAULT_HANDLER return m_pPrimaryPage; DB_END_FAULT_HANDLER // If fail return null; } void TBook::setPrimaryPage(TPage* pPage) { DB_ESTABLISH_FAULT_HANDLER m_pPrimaryPage = pPage; DB_END_FAULT_HANDLER } TPage* TBook::getSecondaryPage() { DB_ESTABLISH_FAULT_HANDLER return m_pSecondaryPage; DB_END_FAULT_HANDLER // If fail return null; } void TBook::setSecondaryPage(TPage* pPage) { DB_ESTABLISH_FAULT_HANDLER m_pSecondaryPage = pPage; DB_END_FAULT_HANDLER } TPage* TBook::getSelectedPage() { DB_ESTABLISH_FAULT_HANDLER return m_pSelectedPage; DB_END_FAULT_HANDLER // If fail return null; } void TBook::setSelectedPage(TPage* pPage) { DB_ESTABLISH_FAULT_HANDLER m_pSelectedPage = pPage; DB_END_FAULT_HANDLER } ////////// // Methods dealing with the fPageList ////////// void TBook::addPage(TPage* pPage) { DB_ESTABLISH_FAULT_HANDLER if (pPage != null) { if (fPageList != null) { // We must handle here the fact that the pPage // may be a chapter and have sub-pages and no forget //to actually add ALL the pages fPageList->addElement(pPage); TPtrIterator* pageIter = pPage->getPages(); if (pageIter != null) { while (pageIter->hasMoreElements()) { TPage* curPage = (TPage *)pageIter->nextElement(); this->addPage(curPage); } delete pageIter; } } } DB_END_FAULT_HANDLER } void TBook::insertPage(TPage* pPage, int pPos) { DB_ESTABLISH_FAULT_HANDLER if (pPage != null) { if (fPageList != null) { // We must handle here the fact that the pPage // may be a chapter and have sub-pages and no forget //to actually insert ALL the pages TPtrIterator* pageIter = pPage->getPages(); if ((pageIter != null) && (pageIter->hasMoreElements())) { delete pageIter; // it was just to see if subPages or not TPtrArray tmpArray; insertPageHelper((TPtrArray *)&tmpArray,pPage); // Here I have a filled tmpArray int insertPos = pPos; TPtrIterator* tmpArrayIter = tmpArray.elements(); while (tmpArrayIter->hasMoreElements()) { TPage* curPage = (TPage *)tmpArrayIter->nextElement(); fPageList->insertElementAt(curPage,insertPos-1); insertPos++; } delete tmpArrayIter; } else { fPageList->insertElementAt(pPage,pPos-1); } } } DB_END_FAULT_HANDLER } void TBook::insertPageHelper(TPtrArray* pArray, TPage* pPage) { DB_ESTABLISH_FAULT_HANDLER pArray->addElement(pPage); TPtrIterator* pageIter = pPage->getPages(); if (pageIter != null) { while (pageIter->hasMoreElements()) { TPage* curPage = (TPage *)pageIter->nextElement(); insertPageHelper(pArray,curPage); } delete pageIter; } DB_END_FAULT_HANDLER } boolean TBook::removePage(TPage* pPage) { boolean lRemoved = false; DB_ESTABLISH_FAULT_HANDLER if ((pPage != null) && (fPageList != null)) { // We must handle here the fact that the pPage // may be a chapter and have sub-pages and no forget //to actually remove ALL the pages lRemoved = fPageList->removeElement(pPage); /* TPtrIterator* pageIter = pPage->getPages(); if (pageIter != null) { while (pageIter->hasMoreElements()) { TPage* curPage = (TPage *)pageIter->nextElement(); this->removePage(curPage); } delete pageIter; } */ } DB_END_FAULT_HANDLER return lRemoved; } TPage* TBook::getPage(int pIndex) { DB_ESTABLISH_FAULT_HANDLER if ((pIndex > 0) && (pIndex <= fPageList->size())) { TPage* thePage; thePage = (TPage *)fPageList->elementAt(pIndex - 1); ATLASSERT(thePage); if (thePage == NULL) { fPageList->removeElementAt(pIndex - 1); } return thePage; } DB_END_FAULT_HANDLER return null; } int TBook::getPageIndex(TPage* pPage) { DB_ESTABLISH_FAULT_HANDLER if ((pPage != null) && (fPageList != null)) { return fPageList->indexOf(pPage) + 1; } DB_END_FAULT_HANDLER return 0; }/*------------ TBook.h ------------*/ #ifndef T_BOOK #define T_BOOK #ifndef T_MEDIUM #include "TMedium.h" #endif // INCLUDES #ifndef T_STRING #include "TString.h" #endif #include // CLASS IMPORTS class TString; class TDBString; class TMedium; class TPage; class TSummary; class TIndex; class TDBPtrArray; class TPtrArray; //#include "TPtrArray.h" /***********************/ /***** class TBook *****/ /***********************/ class TBook : public TMedium { // SPECIFIC PSE PRO STUFF public: static void fetch_before(void*, os_int32, void*, void*); static void fetch_after(void*, os_int32, void*, void*); static boolean init_relocation_hooks(); static boolean bStuff; // CONSTRUCTORS public: TBook(); //default protected: private: // DESTRUCTORS public: ~TBook(); protected: private: // FIELDS public: protected: private: int fLastPrimaryPage; //the last opened page, in order to open the book at this page the next time TDBPtrArray* fPagesBeforeSummaryList; //list of the special pages located before the summary TSummary* fSummary; //the summary is the tree-root of the chapter/page hierarchy TIndex* fIndex; //the index is the last page of the book (the last item in the fPageList in fact) int fBookStyle; // Index of book style for interface TDBPtrArray* fPageList; //useful to speed-up page number display on the bookbinding TPage* m_pPrimaryPage; TPage* m_pSecondaryPage; TPage* m_pSelectedPage; // METHODS public: TSummary* getSummary(); void setSummary(TSummary* pSummary); int getPageCount(); //total nb. of pages in the book TIndex* getIndex(); void setIndex(TIndex* pIndex); int getBookStyle(); void setBookStyle(int pBookStyle); TPage* getPrimaryPage(); void setPrimaryPage(TPage* pPage); TPage* getSecondaryPage(); void setSecondaryPage(TPage* pPage); TPage* getSelectedPage(); void setSelectedPage(TPage* pPage); int getPagesBeforeSummaryCount(); void addPageBeforeSummary(TPage* pPage); void removePageBeforeSummary(TPage* pPage); TPage* getPageBeforeSummary(int pIndex); // 1-based boolean isPageBeforeSummary(TPage* pPage); // Methods dealing with the fPageList void addPage(TPage* pPage); void insertPage(TPage* pPage, int pPos); // 1-based boolean removePage(TPage* pPage); TPage* getPage(int pIndex); // 1-based int getPageIndex(TPage* pPage); // 1-based public: _7X_DB_OBJECT_DECLARE_ID() protected: private: void insertPageHelper(TPtrArray* pArray, TPage* pPage); }; // class TBook #endif // T_BOOK /*------------ THighlighter.cpp ------------*/ #include "StdAfx.h" // MAIN INCLUDE #ifndef T_HIGHLIGHTER #include "THighlighter.h" #endif // OTHER INCLUDES #ifndef T_PSEPRO_DB #include "TPseProDB.h" #endif /**************************/ /***** class THighlighter *****/ /**************************/ _7X_DB_OBJECT_IMPLEMENT_ID(THighlighter, TAnnotation) /****************************/ // CONSTRUCTORS THighlighter::THighlighter() : TAnnotation() { DB_ESTABLISH_FAULT_HANDLER DB_END_FAULT_HANDLER } // DESTRUCTORS THighlighter::~THighlighter() { DB_ESTABLISH_FAULT_HANDLER // Here I destroy my pointer fields not directly // handled by a model DB_END_FAULT_HANDLER } // METHODS void THighlighter::setIndexBegin(long pIndexBegin) { DB_ESTABLISH_FAULT_HANDLER fIndexBegin = pIndexBegin; DB_END_FAULT_HANDLER } long THighlighter::getIndexBegin() { DB_ESTABLISH_FAULT_HANDLER return fIndexBegin; DB_END_FAULT_HANDLER } void THighlighter::setIndexEnd(long pIndexEnd) { DB_ESTABLISH_FAULT_HANDLER fIndexEnd = pIndexEnd; DB_END_FAULT_HANDLER } long THighlighter::getIndexEnd() { DB_ESTABLISH_FAULT_HANDLER return fIndexEnd; DB_END_FAULT_HANDLER } /*------------ THighlighter.h ------------*/ #ifndef T_HIGHLIGHTER #define T_HIGHLIGHTER // INCLUDES #ifndef T_ANNOTATION #include "TAnnotation.h" #endif // CLASS IMPORTS /**************************/ /***** class THighlighter *****/ /**************************/ class THighlighter : public TAnnotation { // CONSTRUCTORS public: THighlighter(); //default protected: private: // DESTRUCTORS public: ~THighlighter(); protected: private: // FIELDS public: protected: private: long fIndexBegin; long fIndexEnd; // METHODS public: void setIndexBegin(long pIndexBegin); long getIndexBegin(); void setIndexEnd(long pIndexEnd); long getIndexEnd(); public: _7X_DB_OBJECT_DECLARE_ID() protected: private: }; // class THighlighter #endif // T_HIGHLIGHTER /*------------ TMetaManager.cpp ------------*/ #include "StdAfx.h" // MAIN INCLUDE #ifndef T_META_MANAGER #include "TMetaManager.h" #endif // OTHER INCLUDES #ifndef T_STRING_TO_PTR_HASHTABLE #include "TStringToPtrHashTable.h" #endif #ifndef T_PTR_TO_PTR_HASHTABLE #include "TPtrToPtrHashTable.h" #endif #ifndef T_GLOBALS_DB #include "TGlobalsDB.h" #endif #ifndef T_DB_NAME_TRANSLATOR #include "TDbNameTranslator.h" #endif #ifndef T_PTR_ITERATOR #include "TPtrIterator.h" #endif #ifndef T_STRING_ITERATOR #include "TStringIterator.h" #endif #include "TAllModel.h" #include "TAllDBObject.h" #include "TManager.h" #include "TManagerTemplate.h" #include "TModelNames.h" #include "TLocker.h" // Root Managers #ifndef T_MEDIA_LIBRARY_MANAGER #include "TMediaLibraryManager.h" #endif #ifndef T_CONTENTS_BAG_MANAGER #include "TContentsBagManager.h" #endif #ifndef T_CONTEXT_OBJECT_MANAGER #include "TContextObjectManager.h" #endif #ifndef T_ANNOTATIONS_BAG_MANAGER #include "TAnnotationsBagManager.h" #endif #ifndef T_MEDIUM_SHELL_LINKS_STORE_MANAGER #include "TMediumShellLinksStoreManager.h" #endif /******************************/ /***** class TMetaManager *****/ /******************************/ //#define USE_GUID_HASHTABLE //#define USE_GUID_MAP template<> UINT AFXAPI HashKey (GUID& key) { UINT lHash = key.Data1 + key.Data2 + key.Data3; // lHash += (DWORD)key.Data4 + (DWORD)&key.Data4[4]; return lHash; } #ifndef USE_GUID_MODEL_IDS CMap gTable; #else // USE_GUID_MODEL_IDS #ifdef USE_GUID_HASHTABLE #include "TGenericHashTable.h" #include "TPtrIterator.h" class TGUIDIterator : public TIterator {}; TGenericHashTable gTable; #else // USE_GUID_HASHTABLE #ifdef USE_GUID_MAP CMap gTable; #else // USE_GUID_MAP CMap gTable; #endif // USE_GUID_MAP #endif // USE_GUID_HASHTABLE #endif // USE_GUID_MODEL_IDS TLocker gManagerLock; // METHODS TManager* TMetaManager::getMgrFromDbName(TString pDbName) { // for thread safeness TLockPtr lLock(&gManagerLock); TModelID modelName = TDbNameTranslator::getModelNameFromDbName(pDbName); TManager* lManager = null; #if defined(USE_GUID_MODEL_IDS) && !defined(USE_GUID_HASHTABLE) #ifdef USE_GUID_MAP gTable.Lookup(modelName, lManager); #else // USE_GUID_MAP gTable.Lookup(&modelName, lManager); #endif // USE_GUID_MAP #else gTable.Lookup(modelName, lManager); #endif if (lManager == null) { lManager = initTableEntry(modelName); } return lManager; } TManager* TMetaManager::getMgrFromModelName(TModelID pModelName) { // for thread safeness TLockPtr lLock(&gManagerLock); TManager* lManager = null; #if defined(USE_GUID_MODEL_IDS) && !defined(USE_GUID_HASHTABLE) #ifdef USE_GUID_MAP gTable.Lookup(pModelName, lManager); #else // USE_GUID_MAP gTable.Lookup(&pModelName, lManager); #endif // USE_GUID_MAP #else gTable.Lookup(pModelName, lManager); #endif if (lManager == null) { lManager = initTableEntry(pModelName); } return lManager; } TObjectModel* TMetaManager::createModelInstance(TModelID pModelName, boolean pForceNotRoot) { // for thread safeness TLockPtr lLock(&gManagerLock); TManager* lManager = getMgrFromModelName(pModelName); if (lManager != null) return lManager->createInstance(pForceNotRoot); return null; } boolean TMetaManager::createModelInstance(TModelID pModelName, void** pObject, boolean pForceNotRoot) { // for thread safeness TLockPtr lLock(&gManagerLock); *pObject = createModelInstance(pModelName, pForceNotRoot); return *pObject ? true : false; } void TMetaManager::cleanAll() { // for thread safeness TLockPtr lLock(&gManagerLock); // We need to maintain a list of the removed managers // because removing (mgr2) may cause the re-creation of an already // removed one (mgr1)... // I know this isn't very clean, but as we have already handled the // models managed by mgr1, we'll let it die alone in memory after // mgr2 has re-created it... #ifndef USE_GUID_MODEL_IDS CArray lAlreadyProcessedMgrsArray; #else // USE_GUID_MODEL_IDS CArray lAlreadyProcessedMgrsArray; #endif // USE_GUID_MODEL_IDS POSITION lPos = gTable.GetStartPosition(); while (lPos != NULL) { TManager* curMgr; #ifdef USE_GUID_MODEL_IDS #if defined(USE_GUID_MAP) TModelID curKey; gTable.GetNextAssoc(lPos, curKey, curMgr); #else // USE_GUID_MAP void* curKey; gTable.GetNextAssoc(lPos, curKey, curMgr); #endif // USE_GUID_MAP #else // USE_GUID_MODEL_IDS CString curKey; gTable.GetNextAssoc(lPos, curKey, curMgr); #endif // USE_GUID_MODEL_IDS boolean bContains = false; for (int ii = 0; ii < lAlreadyProcessedMgrsArray.GetSize(); ii++) { if ( lAlreadyProcessedMgrsArray[ii] == curKey) { bContains = true; break; } } if (!bContains) { lAlreadyProcessedMgrsArray.Add(curKey); gTable.RemoveKey(curKey); delete curMgr; lPos = gTable.GetStartPosition(); } } lAlreadyProcessedMgrsArray.RemoveAll(); gTable.RemoveAll(); } TManager* TMetaManager::initTableEntry(TModelID pModelName) { TManager* lManager = null; if (pModelName == T_MEDIA_CASE_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_MEDIA_LIBRARY_MODEL_NAME) { lManager = new TMediaLibraryManager(); } else if (pModelName == T_MEDIA_SHELF_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_BOOK_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_BOOK_ALIAS_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_CHAPTER_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_DIVIDER_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_INDEX_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_PAGE_MODEL_NAME) { lManager = new TManagerTemplate(); } // else if (pModelName == T_SUBSCRIPTION_MODEL_NAME) // lManager = new TManagerTemplate(); else if (pModelName == T_SUMMARY_MODEL_NAME) { lManager = new TManagerTemplate(); } // else if (pModelName == T_BOOKMARK_MODEL_NAME) // lManager = new TManagerTemplate(); // else if (pModelName == T_KEYWORD_MODEL_NAME) // lManager = new TManagerTemplate(); // else if (pModelName == T_KEYWORDS_STICKER_MODEL_NAME) // lManager = new TManagerTemplate(); else if (pModelName == T_HIGHLIGHTER_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_STICKER_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_ANNOTATIONS_BAG_MODEL_NAME) { lManager = new TAnnotationsBagManager(); } else if (pModelName == T_CONTENT_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_CONTENTS_BAG_MODEL_NAME) { lManager = new TContentsBagManager(); } else if (pModelName == T_PROPERTY_OBJECT_MODEL_NAME) { lManager = new TManagerTemplate(); } else if (pModelName == T_CONTEXT_MODEL_NAME) { lManager = new TContextObjectManager(); } else if (pModelName == T_MEDIUM_SHELL_LINKS_STORE_MODEL_NAME) { lManager = new TMediumShellLinksStoreManager(); } else if (pModelName == T_MEDIUM_SHELL_LINK_MODEL_NAME) { lManager = new TManagerTemplate(); } if (lManager != null) #if defined(USE_GUID_MODEL_IDS) && !defined(USE_GUID_HASHTABLE) #ifdef USE_GUID_MAP gTable.SetAt(pModelName, lManager); #else // USE_GUID_MAP gTable.SetAt(&pModelName, lManager); #endif // USE_GUID_MAP #else gTable.SetAt(pModelName, lManager); #endif return lManager; } boolean TMetaManager::checkModelPointerValidity(void* pPtr) { // for thread safeness TLockPtr lLock(&gManagerLock); boolean res = FALSE; POSITION lPos = gTable.GetStartPosition(); while (lPos != NULL) { TManager* curManager; #ifdef USE_GUID_MODEL_IDS #if defined(USE_GUID_MAP) TModelID curKey; gTable.GetNextAssoc(lPos, curKey, curManager); #else // USE_GUID_MAP void* curKey; gTable.GetNextAssoc(lPos, curKey, curManager); #endif // USE_GUID_MAP #else // USE_GUID_MODEL_IDS CString curKey; gTable.GetNextAssoc(lPos, curKey, curManager); #endif // USE_GUID_MODEL_IDS res = curManager->checkModelPointerValidity(pPtr); if (res == TRUE) break; } return res; } HRESULT TMetaManager::setModelCachedDataModified(TObjectModel* pObjectModel) { // for thread safeness TLockPtr lLock(&gManagerLock); TManager* lManager = getMgrFromModelName(pObjectModel->getID()); if (lManager != null) { return lManager->setModelCachedDataModified(pObjectModel); } return S_FALSE; } HRESULT TMetaManager::flushCachedData() { HRESULT hRes = S_OK; // for thread safeness TLockPtr lLock(&gManagerLock); POSITION lPos = gTable.GetStartPosition(); while (lPos != NULL) { TManager* curManager; #ifdef USE_GUID_MODEL_IDS #if defined(USE_GUID_MAP) TModelID curKey; gTable.GetNextAssoc(lPos, curKey, curManager); #else // USE_GUID_MAP void* curKey; gTable.GetNextAssoc(lPos, curKey, curManager); #endif // USE_GUID_MAP #else // USE_GUID_MODEL_IDS CString curKey; gTable.GetNextAssoc(lPos, curKey, curManager); #endif // USE_GUID_MODEL_IDS HRESULT res = curManager->flushCachedData(); if (res != S_OK) hRes = res; } return hRes; } HRESULT TMetaManager::flushCachedData(TObjectModel* pObjectModel) { // for thread safeness TLockPtr lLock(&gManagerLock); TManager* lManager = getMgrFromModelName(pObjectModel->getID()); if (lManager != null) { return lManager->flushCachedData(pObjectModel); } return S_FALSE; }/*------------ TModelHelpers.h ------------*/ #ifndef T_MODEL_HELPERS #define T_MODEL_HELPERS #include "TMetaManager.h" #include "TPropertyObjectModel.h" #include "TMediaLibraryModel.h" #include "TBookModel.h" #include "TPageModel.h" #include "TIndexModel.h" #include "TSummaryModel.h" #include "TMediumPropertiesConstants.h" #include "TBookPropertiesConstants.h" #include "TPagePropertiesConstants.h" #include "TModelNames.h" template HRESULT GetModelProperty(model* pModel, LPCTSTR pName, TPropertyObjectModel** pProp) { HRESULT lResult; lResult = pModel->getProperty(pName, pProp); ATLASSERT(FAILED(lResult) || (*pProp != NULL)); return lResult; } template HRESULT GetModelProperty(model* pModel, LPCTSTR pName, TPropertyObjectModel** pProp, BOOL pCreate) { HRESULT lResult; lResult = pModel->getProperty(pName, pProp); ATLASSERT(FAILED(lResult) || (*pProp != NULL)); if (FAILED(lResult)) { if ( (!pCreate) || (*pProp != NULL) ) return lResult; lResult = TMetaManager::createModelInstance(T_PROPERTY_OBJECT_MODEL_NAME, (void**)pProp) ? S_OK : E_FAIL; ATLASSERT(SUCCEEDED(lResult)); if (SUCCEEDED(lResult) && (*pProp != NULL)) { pModel->setProperty(pName, *pProp); } } return lResult; } template HRESULT GetSecurityProperty(model* pMedium, TPropertyObjectModel** pSecurity) { ATLASSERT(pMedium); return GetModelProperty(pMedium, T_MEDIUM_SECURITY_PROPERTY, pSecurity); } template HRESULT GetAuthorProperty(model* pBook, TPropertyObjectModel** pAuthor) { ATLASSERT(pBook); return GetModelProperty(pBook, T_BOOK_AUTHOR_PROPERTY, pAuthor); } template BOOL IsReadProtected(model* pMedium) { ATLASSERT(pMedium); TModelPtr lProp; if (GetSecurityProperty(pMedium, &lProp) == S_OK) { boolean lBool; if (lProp->getBooleanField(T_MEDIUM_SECURITY_PROPERTY_READ_PROTECTED, &lBool) && lBool) return TRUE; } return FALSE; } template BOOL IsModifyProtected(model* pMedium) { ATLASSERT(pMedium); TModelPtr lProp; if (GetSecurityProperty(pMedium, &lProp) == S_OK) { boolean lBool; if (lProp->getBooleanField(T_MEDIUM_SECURITY_PROPERTY_MODIFY_PROTECTED, &lBool) && lBool) return TRUE; } return FALSE; } template BOOL IsTrashable(model* pBook) { ATLASSERT(pBook); if (IsSystem(pBook) || IsModifyProtected(pBook)) return FALSE; return TRUE; } template long GetBehaviour(model* pPage) { TModelPtr lPageProperty; pPage->getDefaultProperty(&lPageProperty); ATLASSERT(lPageProperty); if (lPageProperty == NULL) return F_PAGE_DEFAULT_BEHAVIOUR; long lPageBehaviour = F_PAGE_DEFAULT_BEHAVIOUR; lPageProperty->getLongField(T_PAGE_DEFAULT_PROPERTY_BEHAVIOUR, &lPageBehaviour); return lPageBehaviour; } template HRESULT AddBehaviour(model* pPage, long pNewBehavior) { TModelPtr lPageProperty; pPage->getDefaultProperty(&lPageProperty); ATLASSERT(lPageProperty); if (lPageProperty == NULL) return E_FAIL; long lPageBehaviour = F_PAGE_DEFAULT_BEHAVIOUR; lPageProperty->getLongField(T_PAGE_DEFAULT_PROPERTY_BEHAVIOUR, &lPageBehaviour); lPageProperty->putLongField(T_PAGE_DEFAULT_PROPERTY_BEHAVIOUR, lPageBehaviour | pNewBehavior); return S_OK; } template BOOL IsRemovable(model* pPage) { ATLASSERT(pPage); TModelPtr lBook; pPage->getBook(&lBook); ATLASSERT(lBook); if (IsModifyProtected(lBook.p)) return FALSE; if (GetBehaviour(pPage) & F_PAGE_NOT_REMOVABLE) return FALSE; return TRUE; } template BOOL IsCopiable(model* pPage) { ATLASSERT(pPage); if (GetBehaviour(pPage) & F_PAGE_NOT_COPIABLE) return FALSE; return TRUE; } template BOOL IsMovable(model* pPage) { ATLASSERT(pPage); if (GetBehaviour(pPage) & F_PAGE_NOT_MOVABLE) return FALSE; return TRUE; } template BOOL IsStretchable(model* pPage) { ATLASSERT(pPage); if (GetBehaviour(pPage) & F_PAGE_NOT_STRETCHABLE) return FALSE; return TRUE; } template BOOL HaveUserDefinedTitle(model* pPage) { ATLASSERT(pPage); if (GetBehaviour(pPage) & F_PAGE_DEFINED_TITLE) return TRUE; return FALSE; } template BOOL IsSystem(model* ); inline BOOL IsSystem(TBookModel* pBook) { TModelPtr lProp; if (pBook && pBook->getDefaultProperty(&lProp) == S_OK) { boolean lBool; if (lProp->getBooleanField(T_BOOK_DEFAULT_PROPERTY_SYSTEM_BOOK, &lBool) && lBool) return TRUE; } return FALSE; } inline BOOL IsSystem(TPageModel* pPage) { ATLASSERT(pPage); if ((GetBehaviour(pPage) & F_PAGE_SYSTEM) == F_PAGE_SYSTEM) return TRUE; return FALSE; } inline BOOL IsChapter(TPageModel* pPage) { ATLASSERT(pPage); return pPage->isInstanceOf(T_CHAPTER_MODEL_NAME); } template void GetAnnotationsPossibilities(model*,bool* pIsHighlightable,bool* pIsNotable ); inline void GetAnnotationsPossibilities( TPageModel *pPage,bool* pIsHighlightable,bool* pIsNotable ) { if( pPage ) { ATLASSERT( pPage ); CString lPageType = pPage->getID(); // We can put post-it only on web page *pIsNotable = IsSystem( pPage ) ? false : lPageType == T_PAGE_MODEL_NAME; // We can put highlight only on non system web page *pIsHighlightable = *pIsNotable; // To do : manage the readonly state of the book } else { *pIsHighlightable = *pIsNotable = false; } } inline HRESULT GetNextPage(TPageModel* pPage, TPageModel** pNext) { ATLASSERT(pNext); if (pNext == NULL) return E_INVALIDARG; ATLASSERT(pPage); TModelPtr lBook; pPage->getBook(&lBook); ATLASSERT(lBook); if (lBook == NULL) return E_FAIL; int lIndex; lBook->getPageIndex(pPage, &lIndex); if (lIndex) { if (lBook->getPage(lIndex + 1, pNext) == S_OK) return S_OK; return lBook->getIndex((TIndexModel**)pNext); } TModelPtr lIndexPage; lBook->getIndex(&lIndexPage); if (lIndexPage == pPage) return S_FALSE; int lCount = lBook->getPagesBeforeSummaryCount(); // If more then 1 page, change this !!!! ATLASSERT(lCount == 1); TModelPtr lAuthorPage; lBook->getPageBeforeSummary(1, &lAuthorPage); // this was first page if (lAuthorPage == pPage) return lBook->getSummary((TSummaryModel**)pNext); *pNext = NULL; return E_FAIL; } inline HRESULT GetPrevPage(TPageModel* pPage, TPageModel** pPrev) { ATLASSERT(pPage); TModelPtr lBook; pPage->getBook(&lBook); ATLASSERT(lBook); if (lBook == NULL) return E_FAIL; int lIndex; lBook->getPageIndex(pPage, &lIndex); if (lIndex > 1) return lBook->getPage(lIndex - 1, pPrev); TModelPtr lIndexPage; int lCount = 0; lBook->getIndex(&lIndexPage); if (lIndexPage == pPage) { lBook->getPageCount(&lCount); return lBook->getPage(lCount, pPrev); } lCount = lBook->getPagesBeforeSummaryCount(); // If more then 1 page, change this !!!! ATLASSERT(lCount == 1); if (!lIndex) // this was already the first page of the book return S_FALSE; return lBook->getPageBeforeSummary(1, pPrev); } inline HRESULT GetSystemBook(long pId, TBookModel** pBook) { ATLASSERT(pBook); if (pBook == NULL) return E_INVALIDARG; *pBook = NULL; TModelPtr lLib; TModelPtr lBook; TMetaManager::createModelInstance(T_MEDIA_LIBRARY_MODEL_NAME, (void**)&lLib); ATLASSERT(lLib); if (lLib == NULL) return E_FAIL; lLib->getSpecialMediumInLibrary((TMediaLibraryModel::ESpecialMediumId)pId, (TMediumModel**)&lBook); ATLASSERT(lBook); if (lBook == NULL) return E_FAIL; *pBook = lBook; (*pBook)->AddRef(); return S_OK; } inline HRESULT GetLastPageBeforeIndex(TBookModel* pBook, TPageModel** pPage) { ATLASSERT(pBook); return pBook->getPage(pBook->getPageCount(), pPage); } template BOOL GetStringDefaultProperty(model* pModel, LPCTSTR pField, CString& pValue) { TModelPtr lModelProperty; pModel->getDefaultProperty(&lModelProperty); ATLASSERT(lModelProperty); if (lModelProperty == NULL) return FALSE; return lModelProperty->getStringField(pField, &pValue); } template BOOL SetStringDefaultProperty(model* pModel, LPCTSTR pField, LPCTSTR pValue) { TModelPtr lModelProperty; pModel->getDefaultProperty(&lModelProperty); ATLASSERT(lModelProperty); if (lModelProperty == NULL) return FALSE; lModelProperty->putStringField(pField, pValue); return TRUE; } template BOOL GetBooleanDefaultProperty(model* pModel, LPCTSTR pField, VARIANT_BOOL* pValue) { TModelPtr lModelProperty; pModel->getDefaultProperty(&lModelProperty); ATLASSERT(lModelProperty); if (lModelProperty == NULL) return FALSE; boolean lBool; if (lModelProperty->getBooleanField(pField, &lBool)) { *pValue = ( lBool ? VARIANT_TRUE : VARIANT_FALSE ); return TRUE; } else return FALSE; } template BOOL SetBooleanDefaultProperty(model* pModel, LPCTSTR pField, VARIANT_BOOL pValue) { TModelPtr lModelProperty; pModel->getDefaultProperty(&lModelProperty); ATLASSERT(lModelProperty); if (lModelProperty == NULL) return FALSE; lModelProperty->putBooleanField(pField, ( (pValue == VARIANT_TRUE) ? true : false )); return TRUE; } #endif // T_MODEL_HELPERS /*------------ TPage.cpp ------------*/ #include "StdAfx.h" // MAIN INCLUDE #ifndef T_PAGE #include "TPage.h" #endif // OTHER INCLUDES #ifndef T_CHAPTER #include "TChapter.h" #endif #ifndef T_ANNOTATION #include "TAnnotation.h" #endif #ifndef T_CONTENT #include "TContent.h" #endif #ifndef T_DB_PTR_ARRAY #include "TDBPtrArray.h" #endif #ifndef T_PRIVATE_DB_ITERATOR #include "TPrivateDBIterator.h" #endif #ifndef T_PSEPRO_DB #include "TPseProDB.h" #endif #ifndef T_EXCEPTION #include "TException.h" #endif #ifndef T_PROPERTY_OBJECT #include "TPropertyObject.h" #endif #ifndef T_PAGE_PROPERTIES_CONSTANTS #include "TPagePropertiesConstants.h" #endif /********************************/ /***** abstract class TPage *****/ /********************************/ _7X_DB_OBJECT_IMPLEMENT_ID(TPage, TDBObject) /****************************/ // SPECIFIC PSE PRO STUFF boolean TPage::bStuff = TPage::init_relocation_hooks(); boolean TPage::init_relocation_hooks() { // Uncomment this if you want to debug 'fetch' ops /* os_ts::set_fetch_hook( os_typespec::before_hook, TPage::fetch_before, (void*)NULL ); os_ts::set_fetch_hook( os_typespec::after_hook, TPage::fetch_after, (void*)NULL ); */ return true; } void TPage::fetch_before(void* object, os_int32, void* data, void*) { TPage* page = (TPage*)object; TRACE1("TPage::fetch_before - [0x%x]\n",(void*)page); } void TPage::fetch_after(void* object, os_int32, void* data, void*) { TPage* page = (TPage*)object; TRACE1("TPage::fetch_after - [0x%x]\n",(void*)page); } // CONSTRUCTORS TPage::TPage() : TDBObject() { DB_ESTABLISH_FAULT_HANDLER fChapter = null; fAnnotationVector = null; fContent = null; fSubscription = null; // Let's set the various properties default values TPropertyObject* defaultProp = this->getDefaultProperty(); defaultProp->putBooleanField(T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY, true); defaultProp->putLongField(T_PAGE_DEFAULT_PROPERTY_SUB_ANNOTATIONS_COUNT, 0); DB_END_FAULT_HANDLER } // DESTRUCTORS TPage::~TPage() { DB_ESTABLISH_FAULT_HANDLER // Here I destroy my pointer fields not directly // handled by a model DB_DESTROY_OBJECT(fAnnotationVector); fTitle.Empty(); DB_END_FAULT_HANDLER } // METHODS int TPage::searchWordFrom(TString pWord, int pFrom) { //DB_ESTABLISH_FAULT_HANDLER return 0; //DB_END_FAULT_HANDLER } TBook* TPage::getBook() { TBook* lResBook = NULL; DB_ESTABLISH_FAULT_HANDLER lResBook = fBook; DB_END_FAULT_HANDLER return lResBook; } void TPage::setBook(TBook* pBook) { DB_ESTABLISH_FAULT_HANDLER fBook = pBook; DB_END_FAULT_HANDLER } TPtrIterator* TPage::getPages() { //DB_ESTABLISH_FAULT_HANDLER return NULL; //DB_END_FAULT_HANDLER } TChapter* TPage::getChapter() { TChapter* lResChapter = NULL; DB_ESTABLISH_FAULT_HANDLER lResChapter = fChapter; DB_END_FAULT_HANDLER return lResChapter; } void TPage::setChapter(TChapter* pParent) { DB_ESTABLISH_FAULT_HANDLER fChapter = pParent; DB_END_FAULT_HANDLER } TPageNumbering TPage::getPageNumber() { LONG lPageNumber = -1; DB_ESTABLISH_FAULT_HANDLER lPageNumber = fPageNumber; DB_END_FAULT_HANDLER return TPageNumbering(lPageNumber, T_PAGE_NUMBERING_TYPE_PAGE); } void TPage::setPageNumber(int pPageNumber) { DB_ESTABLISH_FAULT_HANDLER fPageNumber = pPageNumber; DB_END_FAULT_HANDLER } int TPage::getPagePosition() { DB_ESTABLISH_FAULT_HANDLER TChapter* parentChapter; parentChapter = getChapter(); if (parentChapter == null) return 0; int pos = 1; TPtrIterator* iter; iter = parentChapter->getPages(); while (iter->hasMoreElements()) { TPage* curPage; curPage = (TPage *)iter->nextElement(); if (curPage == this) { delete iter; return pos; } pos++; } delete iter; DB_END_FAULT_HANDLER return 0; } TString TPage::getTitle() { DB_ESTABLISH_FAULT_HANDLER return LPCTSTR(fTitle); DB_END_FAULT_HANDLER } void TPage::setTitle(TString pTitle) { DB_ESTABLISH_FAULT_HANDLER fTitle = pTitle; DB_END_FAULT_HANDLER } boolean TPage::containsAnnotation(TAnnotation* pAnnotation) { DB_ESTABLISH_FAULT_HANDLER if (fAnnotationVector && pAnnotation) { TPtrIterator *iter = fAnnotationVector->elements(); while (iter->hasMoreElements()) { TAnnotation* curAnnotation = (TAnnotation *)iter->nextElement(); if (curAnnotation == pAnnotation) { delete iter; return true; } } delete iter; } DB_END_FAULT_HANDLER return false; } void TPage::addAnnotation(TAnnotation* pAnnotation) { if (pAnnotation == null) return ; DB_ESTABLISH_FAULT_HANDLER if (!fAnnotationVector) { DB_CREATE_NEW_OBJECT_IN_SAME_DB_AS(TDBPtrArray,fAnnotationVector,this); //fAnnotationVector = TPseProObjectCreator::createPtrArray(this); fAnnotationVector->addElement(pAnnotation); } else if (!containsAnnotation(pAnnotation)) { fAnnotationVector->addElement(pAnnotation); } DB_END_FAULT_HANDLER } void TPage::removeAnnotation(TAnnotation* pAnnotation) { DB_ESTABLISH_FAULT_HANDLER if (fAnnotationVector && pAnnotation) { for (int ii = 0; ii < fAnnotationVector->size(); ii++) { if (fAnnotationVector->elementAt(ii) == pAnnotation) { fAnnotationVector->removeElementAt(ii); return; } } } DB_END_FAULT_HANDLER } TPtrIterator* TPage::getAnnotations() { TPtrIterator* lResult = null; DB_ESTABLISH_FAULT_HANDLER if (fAnnotationVector) lResult = new TDBPtrArrayIterator(fAnnotationVector); DB_END_FAULT_HANDLER return lResult; } long TPage::getAnnotationsCount() { long lResult = 0; DB_ESTABLISH_FAULT_HANDLER if (fAnnotationVector) lResult = fAnnotationVector->size(); DB_END_FAULT_HANDLER return lResult; } TContent* TPage::getContent() { TContent* lResContent = NULL; DB_ESTABLISH_FAULT_HANDLER lResContent = fContent; DB_END_FAULT_HANDLER return lResContent; } void TPage::setContent(TContent* pContent) { DB_ESTABLISH_FAULT_HANDLER if (fContent == pContent) return ; if (fContent != null) fContent->removePage(this); fContent = pContent; if (fContent != null) fContent->addPage(this); DB_END_FAULT_HANDLER }/*------------ TPage.h ------------*/ #ifndef T_PAGE #define T_PAGE // INCLUDES #ifndef T_DB_OBJECT #include "TDBObject.h" #endif #ifndef T_DB_STRING #include "TDBString.h" #endif #ifndef T_PAGE_NUMBERING #include "TPageNumbering.h" #endif // CLASS IMPORTS class TChapter; class TAnnotation; class TBook; class TDBObject; class TString; class TDBString; class TDBPtrArray; class TSubscription; class TContent; class TPtrIterator; /***********************/ /***** class TPage *****/ /***********************/ class TPage : public TDBObject { // SPECIFIC PSE PRO STUFF public: static void fetch_before(void*, os_int32, void*, void*); static void fetch_after(void*, os_int32, void*, void*); static boolean init_relocation_hooks(); static boolean bStuff; // CONSTRUCTORS public: TPage(); //default protected: private: // DESTRUCTORS public: ~TPage(); protected: private: // FIELDS public: protected: int fPageNumber; //fPageNumber : page's position in its parent chapter : //Example : parentChapter --- page 1 (=> (1,typePage) == "1") // | // |- subChapter 1 (=> (1,typeChapter) == "I") // | // |- page 2 (=> (2,typePage) == "2") private: TBook* fBook; TDBString fTitle; TChapter* fChapter; //the chapter this page is in TDBPtrArray* fAnnotationVector; TContent* fContent; TSubscription* fSubscription; // METHODS public: virtual int searchWordFrom(TString pWord, int pFrom); //text search in page virtual TBook* getBook(); virtual void setBook(TBook* pBook); virtual TPtrIterator* getPages(); // return the sub-pages of this page (actually used by TChapter....) TChapter* getChapter(); void setChapter(TChapter* pParent); virtual TPageNumbering getPageNumber(); void setPageNumber(int pPageNumber); int getPagePosition(); // 1-based // sequential pos in parent, not taking into // account any kind of page's type TString getTitle(); void setTitle(TString pTitle); void addAnnotation(TAnnotation* pAnnotation); void removeAnnotation(TAnnotation* pAnnotation); boolean containsAnnotation(TAnnotation* pAnnotation); TPtrIterator* getAnnotations(); long getAnnotationsCount(); TContent* getContent(); void setContent(TContent* pContent); public: _7X_DB_OBJECT_DECLARE_ID() protected: private: }; // class TPage #endif // T_PAGE /*------------ TSticker.cpp ------------*/ #include "StdAfx.h" // MAIN INCLUDE #ifndef T_STICKER #include "TSticker.h" #endif // OTHER INCLUDES #ifndef T_PSEPRO_DB #include "TPseProDB.h" #endif /**************************/ /***** class TSticker *****/ /**************************/ _7X_DB_OBJECT_IMPLEMENT_ID(TSticker, TAnnotation) /****************************/ // CONSTRUCTORS TSticker::TSticker() : TAnnotation() { DB_ESTABLISH_FAULT_HANDLER DB_END_FAULT_HANDLER } // DESTRUCTORS TSticker::~TSticker() { DB_ESTABLISH_FAULT_HANDLER // Here I destroy my pointer fields not directly // handled by a model DB_END_FAULT_HANDLER } // METHODS void TSticker::setPosition(int pX, int pY) { DB_ESTABLISH_FAULT_HANDLER fPosX = pX; fPosY = pY; DB_END_FAULT_HANDLER } void TSticker::setSize(int pWidth, int pHeight) { DB_ESTABLISH_FAULT_HANDLER fWidth = pWidth; fHeight = pHeight; DB_END_FAULT_HANDLER } TPoint TSticker::getPosition() { DB_ESTABLISH_FAULT_HANDLER return TPoint(fPosX,fPosY); DB_END_FAULT_HANDLER } TPoint TSticker::getSize() { DB_ESTABLISH_FAULT_HANDLER return TPoint(fWidth,fHeight); DB_END_FAULT_HANDLER } /*------------ TSticker.h ------------*/ #ifndef T_STICKER #define T_STICKER // INCLUDES #ifndef T_ANNOTATION #include "TAnnotation.h" #endif #ifndef T_POINT #include "TPoint.h" #endif // CLASS IMPORTS /**************************/ /***** class TSticker *****/ /**************************/ class TSticker : public TAnnotation { // CONSTRUCTORS public: TSticker(); //default protected: private: // DESTRUCTORS public: ~TSticker(); protected: private: // FIELDS public: protected: private: int fPosX; int fPosY; int fWidth; int fHeight; // METHODS public: void setPosition(int pX = 0, int pY = 0); TPoint getPosition(); void setSize(int pWidth = 100, int pHeight = 100); TPoint getSize(); public: _7X_DB_OBJECT_DECLARE_ID() protected: private: }; // class TSticker #endif // T_STICKER /*------------ TOfficeConverter.cpp ------------*/ // MAIN INCLUDE #include "stdafx.h" #include "TOfficeConverter.h" // OTHER INCLUDES #include #include "TErr.h" #include "TSystemMimeHelper.h" #include "TInternetExplorerMimeHelper.h" #include "TPtrArray.h" #include "TGlobalResource.h" // DEFINES const GUID IID_IWorksheet = { 0x000208D8, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } }; const GUID IID_IChart = { 0x000208D6, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } }; // Microsoft Word Error Codes #define E_MICROSOFT_WORD_WRONG_PASSWORD 0x800a1520 // Microsoft Excel Error Codes #define E_MICROSOFT_EXCEL_WRONG_PASSWORD 0x03ec /********************************/ /***** class TWordConverter *****/ /********************************/ TWordConverter::TWordConverter() : TOfficeConverter() { } TWordConverter::~TWordConverter() { } HRESULT TWordConverter::Convert() { HRESULT lResult; CComBSTR lProgID; lResult = GetApplicationProgID(&lProgID); if (SUCCEEDED(lResult)) lResult = ConvertDocument(lProgID, L"Documents"); return lResult; } HRESULT TWordConverter::GetSaveAsConvertFormat(DWORD* pFormatResult) { if (!pFormatResult) return E_INVALIDARG; if ( m_lSaveAsConvertFormat.vt == VT_I4 ) { // already computed *pFormatResult = m_lSaveAsConvertFormat.iVal; return S_OK; } if (GetCurrentVersion() > 8) { // We must get the HTML Format Number from Word TypeLib HRESULT lResult; long lHTMLFileFormat; lResult = GetEnumConstantFromTypeLib(L"WdSaveFormat",L"wdFormatHTML",&lHTMLFileFormat); if (SUCCEEDED(lResult)) { m_lSaveAsConvertFormat = CComVariant(lHTMLFileFormat,VT_I4); *pFormatResult = lHTMLFileFormat; return S_OK; } } else { // We must get the HTML Format Number from Word // (generic method found at http://msdn.microsoft.com/library/techart/w2h.htm) HRESULT lResult; if (!m_OfficeAppDriver) { // Create Office App Object lResult = InitializeOfficeAppDriver(); ATLASSERT(SUCCEEDED(lResult) && m_OfficeAppDriver); if (!(SUCCEEDED(lResult) && m_OfficeAppDriver)) return E_FAIL; } // Do not show window CComVariant lVisible(false); lResult = m_OfficeAppDriver.PutPropertyByName(L"Visible", &lVisible); CComVariant lFileConvertersResult; lResult = m_OfficeAppDriver.GetPropertyByName(L"FileConverters", &lFileConvertersResult); if (SUCCEEDED(lResult) && lFileConvertersResult.vt == VT_DISPATCH) { CComDispatchDriver lFileConvertersDriver(lFileConvertersResult.pdispVal); CComVariant lFileConvertersCountResult; lResult = lFileConvertersDriver.GetPropertyByName(L"Count", &lFileConvertersCountResult); ATLASSERT(SUCCEEDED(lResult) && lFileConvertersCountResult.vt == VT_I4); if (SUCCEEDED(lResult) && lFileConvertersCountResult.vt == VT_I4) { for (int ii = 1; ii <= lFileConvertersCountResult.iVal; ii++) { CComVariant lCurFileConverterIdx(ii); CComVariant lCurFileConverterResult; lResult = lFileConvertersDriver.Invoke1(L"Item", &lCurFileConverterIdx, &lCurFileConverterResult); if (SUCCEEDED(lResult) && lCurFileConverterResult.vt == VT_DISPATCH) { // Here we have an IFileConverter dispatch CComDispatchDriver lCurFileConverterDriver(lCurFileConverterResult.pdispVal); CComVariant lCurFileConverterClassNameResult; lResult = lCurFileConverterDriver.GetPropertyByName(L"ClassName", &lCurFileConverterClassNameResult); ATLASSERT(SUCCEEDED(lResult) && lCurFileConverterClassNameResult.vt == VT_BSTR); if (SUCCEEDED(lResult) && lCurFileConverterClassNameResult.vt == VT_BSTR) { if (lCurFileConverterClassNameResult.bstrVal && (!wcsicmp(L"HTML", lCurFileConverterClassNameResult.bstrVal))) { CComVariant lCurFileConverterSaveFormatResult; lResult = lCurFileConverterDriver.GetPropertyByName(L"SaveFormat", &lCurFileConverterSaveFormatResult); ATLASSERT(SUCCEEDED(lResult) && lCurFileConverterSaveFormatResult.vt == VT_I4); if (SUCCEEDED(lResult) && lCurFileConverterSaveFormatResult.vt == VT_I4) { m_lSaveAsConvertFormat = lCurFileConverterSaveFormatResult; *pFormatResult = lCurFileConverterSaveFormatResult.iVal; // Release Office App Object // -> NO - It will be done when the converter is destroyed return S_OK; } } } } } } } // Release Office App Object // -> NO - It will be done when the converter is destroyed } return E_FAIL; } HRESULT TWordConverter::GetConvertedDocumentMime(BSTR* pResMime) { *pResMime = CComBSTR(L"text/html").Copy(); return S_OK; } HRESULT TWordConverter::OnOpen(LPDISPATCH pDisp, VARIANT* pResult) { CComDispatchDriver lDocumentsDriver(pDisp); CComVariant lOpenResult; HRESULT lResult; // The following call is supported by Word 97, 2000 and plus... { CComVariant varArgs[9]; varArgs[8] = m_From; // FileName varArgs[7] = false; // ConfirmConversions varArgs[6] = true; // ReadOnly varArgs[5] = false; // AddToRecentFiles varArgs[4] = L""; // PasswordDocument varArgs[3] = L""; // PasswordTemplate varArgs[2] = false; // Revert varArgs[1] = L""; // WritePasswordDocument varArgs[0] = L""; // WritePasswordTemplate long lDispId_Documents_Open; lResult = lDocumentsDriver.GetIDOfName(L"Open", &lDispId_Documents_Open); if (SUCCEEDED(lResult)) { EXCEPINFO pExcepInfo; unsigned int puArgErr = 0; DISPPARAMS dispparams = { &varArgs[0], NULL, 9, 0 }; lResult = ((IDispatch *)lDocumentsDriver)->Invoke( lDispId_Documents_Open, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &lOpenResult, &pExcepInfo, &puArgErr); if (SUCCEEDED(lResult) && (lOpenResult.vt == VT_DISPATCH)) { lOpenResult.Detach(pResult); } else { if (pExcepInfo.scode == E_MICROSOFT_WORD_WRONG_PASSWORD) { lResult = OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED; } } } } return lResult; } HRESULT TWordConverter::OnSave(LPDISPATCH pDisp) { CComDispatchDriver lDocumentDriver(pDisp); HRESULT lResult; // Before doing any publication to HTML, let's set the HTML format // options for the current document CComVariant lWebOptionsResult; // DISPID lWebOptionsID; // lResult = GetPropertyIDFromTypeLib(L"Document", L"WebOptions", &lWebOptionsID); lResult = lDocumentDriver.GetPropertyByName(L"WebOptions", &lWebOptionsResult); if (FAILED(lResult) || lWebOptionsResult.vt != VT_DISPATCH) lResult = lDocumentDriver.GetProperty(0x14a, &lWebOptionsResult); if (SUCCEEDED(lResult) && lWebOptionsResult.vt == VT_DISPATCH) { CComDispatchDriver lWebOptionsDriver(lWebOptionsResult.pdispVal); long lWdBrowserLevel_wdBrowserLevelV4; lResult = GetEnumConstantFromTypeLib(L"WdBrowserLevel",L"wdBrowserLevelV4",&lWdBrowserLevel_wdBrowserLevelV4); if (SUCCEEDED(lResult)) { CComVariant lWebOptions_BrowserLevel(lWdBrowserLevel_wdBrowserLevelV4); lResult = lWebOptionsDriver.PutPropertyByName(L"BrowserLevel", &lWebOptions_BrowserLevel); } CComVariant lWebOptions_OptimizeForBrowser(true); lResult = lWebOptionsDriver.PutPropertyByName(L"OptimizeForBrowser", &lWebOptions_OptimizeForBrowser); CComVariant lWebOptions_AllowPNG(false); lResult = lWebOptionsDriver.PutPropertyByName(L"AllowPNG", &lWebOptions_AllowPNG); CComVariant lWebOptions_RelyOnVML(false); lResult = lWebOptionsDriver.PutPropertyByName(L"RelyOnVML", &lWebOptions_RelyOnVML); } DWORD lConvertFormat = 0; lResult = GetSaveAsConvertFormat(&lConvertFormat); if (SUCCEEDED(lResult)) { CComVariant lTo(m_To); CComVariant lFormat(lConvertFormat, VT_I4); lResult = lDocumentDriver.Invoke2(L"SaveAs", &lTo, &lFormat); if (FAILED(lResult)) lResult = lDocumentDriver.Invoke2(0x178, &lTo, &lFormat); ATLASSERT(SUCCEEDED(lResult)); } return lResult; } HRESULT TWordConverter::OnClose(LPDISPATCH pDisp) { CComDispatchDriver lDocumentDriver(pDisp); HRESULT lCloseResult; long lWdSaveOptions_wdDoNotSaveChanges = 0; lCloseResult = GetEnumConstantFromTypeLib(L"WdSaveOptions", L"wdDoNotSaveChanges", &lWdSaveOptions_wdDoNotSaveChanges); ATLASSERT(SUCCEEDED(lCloseResult)); long lWdOriginalFormat_wdOriginalDocumentFormat = 0; lCloseResult = GetEnumConstantFromTypeLib(L"WdOriginalFormat", L"wdOriginalDocumentFormat", &lWdOriginalFormat_wdOriginalDocumentFormat); ATLASSERT(SUCCEEDED(lCloseResult)); CComVariant lSaveChanges(lWdSaveOptions_wdDoNotSaveChanges); CComVariant lOriginalFormat(lWdOriginalFormat_wdOriginalDocumentFormat); lCloseResult = lDocumentDriver.Invoke2(L"Close", &lSaveChanges, &lOriginalFormat); if (FAILED(lCloseResult)) lCloseResult = lDocumentDriver.Invoke2(0x451, &lSaveChanges, &lOriginalFormat); ATLASSERT(SUCCEEDED(lCloseResult) && "Close fail: trying to Quit app"); if (FAILED(lCloseResult)) { lCloseResult = UninitializeOfficeAppDriver(); ATLASSERT(SUCCEEDED(lCloseResult) && "Uninitialize fail: Doc not closed => convertion will fail"); } return lCloseResult; } HRESULT TWordConverter::OnPostProcessDocument(LPDISPATCH pDisp) { if (GetCurrentVersion() <= 8) return E_NOTIMPL; // On some IE 5.0 versions, the HTML source generated by Word 2000 contains some // attributes that make images not to display properly. // Therefore, we will rewrite those HTML source parts CComDispatchDriver lDocumentDriver(pDisp); HRESULT lResult; CString lFromFileContent; CStdioFile lFromFile; if (lFromFile.Open(CString(m_To), CFile::modeRead)) { { const int bufferSize = 4096; BYTE buffer[bufferSize]; memset(&buffer,0,bufferSize); for (;;) { int bytesRead = lFromFile.Read(buffer,bufferSize); if (bytesRead <= 0) { break; } buffer[bytesRead] = 0; lFromFileContent += buffer; } } lFromFile.Close(); } if (!lFromFileContent.IsEmpty()) { // Let's do our post-processing here { // On some IE 5.0 versions, we have issues with images not displaying correctly. // It seems that it is due to the 'class=shape' attribute that Word put on IMG tags... // Therefore, let's rename the '.shape' style lFromFileContent.Replace( _T(".shape"), _T(".shap0") ); lFromFileContent.Replace( _T(".SHAPE"), _T(".SHAP0") ); CString lResultBuffer; lResult = OnPostProcessDocument_RemoveConditionalComments(pDisp, lFromFileContent, lResultBuffer); if (SUCCEEDED(lResult)) { lFromFileContent = lResultBuffer; } lResultBuffer.Empty(); lResult = OnPostProcessDocument_RemoveXmlNamespaces(pDisp, lFromFileContent, lResultBuffer); if (SUCCEEDED(lResult)) { lFromFileContent = lResultBuffer; } } // And then, let's save our post-processed document back CStdioFile lToFile; if (lToFile.Open(CString(m_To), CFile::modeWrite | CFile::modeCreate)) { lToFile.Write( lFromFileContent.GetBuffer(1), lFromFileContent.GetLength()); lToFile.Flush(); lToFile.Close(); } } return S_OK; } HRESULT TWordConverter::DisableAlerts() { HRESULT lResult; LONG lDisableAlertValue; lResult = GetEnumConstantFromTypeLib(L"WdAlertLevel", L"wdAlertsNone", &lDisableAlertValue); ATLASSERT(SUCCEEDED(lResult)); if (SUCCEEDED(lResult)) { CComVariant lDisplayAlerts(lDisableAlertValue); lResult = m_OfficeAppDriver.PutPropertyByName(L"DisplayAlerts", &lDisplayAlerts); ATLASSERT(SUCCEEDED(lResult)); } return lResult; } /*************************************/ /***** class TWordImageConverter *****/ /*************************************/ TWordImageConverter::TWordImageConverter() : TWordConverter() { } HRESULT TWordImageConverter::OnOpen(LPDISPATCH pDisp, VARIANT* pResult) { CComDispatchDriver lDocumentsDriver(pDisp); CComVariant lAddResult; HRESULT lResult; lResult = lDocumentsDriver.Invoke0(L"Add", pResult); ATLASSERT(SUCCEEDED(lResult) && pResult->vt == VT_DISPATCH); if (SUCCEEDED(lResult) && pResult->vt == VT_DISPATCH) { CComDispatchDriver lDocumentDriver(pResult->pdispVal); CComVariant lShapes; lResult = lDocumentDriver.GetPropertyByName(L"Shapes", &lShapes); ATLASSERT(SUCCEEDED(lResult) && lShapes.vt == VT_DISPATCH); if (SUCCEEDED(lResult) && lShapes.vt == VT_DISPATCH) { CComVariant lFrom(m_From); CComDispatchDriver lShapesDriver(lShapes.pdispVal); lResult = lShapesDriver.Invoke1(L"AddPicture", &lFrom); ATLASSERT(SUCCEEDED(lResult)); return lResult; } } return E_FAIL; } HRESULT TWordImageConverter::OnEnumerateGeneratedFiles(LPDISPATCH pDisp) { // This is the place to do everything you want with generated files since everything // is closed by now, and we have to fill our m_ExportedFilesList array in... CComDispatchDriver lDocumentDriver(pDisp); // HRESULT lResult; CString lFolderTo(m_To); TPath lPath(lFolderTo); lPath.RemoveFileSpec(); TStringArray lExportedFilesList; /* BOOL bResFileList = */ TPath::GetFileListInDirectory(lFolderTo,TRUE,FALSE,lExportedFilesList); TSystemMimeHelper* lSystemMimeHelper = new TSystemMimeHelper(); TInternetExplorerMimeHelper* lIEMimeHelper = new TInternetExplorerMimeHelper(); TString lFirstImageFoundPath; TString lFirstImageFoundMimeType; for (int ii = 0; ii < lExportedFilesList.size(); ii++) { TString curFilePath = lExportedFilesList.elementAt(ii); if (curFilePath) { TString curFileExt; TString curFileMime; TPath::FindExtension(curFilePath,curFileExt); lSystemMimeHelper->getFirstMimeTypeFromFileExtension(curFileExt,curFileMime); curFileMime.MakeLower(); if ((curFileMime.Find(_T("image/")) != -1) && lIEMimeHelper->isMimeTypeSupported(curFileMime)) { /* Test Aborted Defect 544 CFileStatus status; CFile cfile; // Test the picture size if it is valid // Case Filter Error No544 if( CFile::GetStatus( curFilePath, status ) ) // static function { if ((status.m_size == 0) || ((curFileMime.Find(_T("gif")) != -1) && (status.m_size <= 73))) { break; } } else break; */ lFirstImageFoundPath = curFilePath; lFirstImageFoundMimeType = curFileMime; // Since we have issues with IE which says that it supports PNG whereas it does not completely, // (actually, PNG is supported if embedded in an HTML page, but not when navigating directly on it) // we prefer not to output PNG files... // This test should be temporary since we may not be always sure that Office Converters generate // other image formats (GIF,JPG...) than PNG!!! if (curFileMime.Find(_T("png")) == -1) break; } } } delete lIEMimeHelper; delete lSystemMimeHelper; if (!lFirstImageFoundPath.IsEmpty()) { BOOL lFileOp; CString lTarget(m_To); lFileOp = ::DeleteFile(lTarget); if (!lFileOp) { // On Office 97 it something need times to close the file !!!! ::Sleep(300); lFileOp = ::DeleteFile(lTarget); } ATLASSERT(lFileOp); if (lFileOp) { lFileOp = ::MoveFile(lFirstImageFoundPath, lTarget); ATLASSERT(lFileOp); if (lFileOp) m_ExportedFilesList.addElement(lTarget); } m_ConvertedImageMime = lFirstImageFoundMimeType; return S_OK; } else { return E_FAIL; } } HRESULT TWordImageConverter::GetConvertedDocumentMime(BSTR* pResMime) { if (m_ConvertedImageMime.Length() > 0) { *pResMime = CComBSTR(m_ConvertedImageMime).Copy(); return S_OK; } else { if (!m_ExportedFilesList.isEmpty()) { TSystemMimeHelper* lSystemMimeHelper = new TSystemMimeHelper(); TInternetExplorerMimeHelper* lIEMimeHelper = new TInternetExplorerMimeHelper(); BOOL bMimeFound = FALSE; for (int ii = 0; ii < m_ExportedFilesList.size(); ii++) { TString curFilePath = m_ExportedFilesList.elementAt(ii); if (curFilePath) { TString curFileExt; TString curFileMime; TPath::FindExtension(curFilePath,curFileExt); lSystemMimeHelper->getFirstMimeTypeFromFileExtension(curFileExt,curFileMime); curFileMime.MakeLower(); if ((curFileMime.Find(_T("image/")) != -1) && lIEMimeHelper->isMimeTypeSupported(curFileMime)) { *pResMime = CComBSTR(curFileMime).Copy(); bMimeFound = TRUE; break; } } } delete lIEMimeHelper; delete lSystemMimeHelper; if (bMimeFound) return S_OK; } // Either we do not have converted anything // or we do not have filled the m_ExportedFilesList list up... *pResMime = NULL; return E_FAIL; } } /*********************************/ /***** class TExcelConverter *****/ /*********************************/ TExcelConverter::TExcelConverter() : TOfficeConverter() { } HRESULT TExcelConverter::Convert() { HRESULT lResult; CComBSTR lProgID; lResult = GetApplicationProgID(&lProgID); if (SUCCEEDED(lResult)) lResult = ConvertDocument(lProgID, L"WorkBooks"); return lResult; } HRESULT TExcelConverter::GetConvertedDocumentMime(BSTR* pResMime) { *pResMime = CComBSTR(L"text/html").Copy(); return S_OK; } HRESULT TExcelConverter::GetSaveAsConvertFormat(DWORD* pFormatResult) { if (!pFormatResult) return E_INVALIDARG; if (GetCurrentVersion() > 8) { if ( m_lSaveAsConvertFormat.vt == VT_I4 ) { // already computed *pFormatResult = m_lSaveAsConvertFormat.iVal; return S_OK; } // We must get the HTML Format Number from Excel TypeLib HRESULT lResult; long lHTMLFileFormat; lResult = GetEnumConstantFromTypeLib(L"XlFileFormat",L"xlHtml",&lHTMLFileFormat); if (SUCCEEDED(lResult)) { m_lSaveAsConvertFormat = CComVariant(lHTMLFileFormat,VT_I4); *pFormatResult = lHTMLFileFormat; return S_OK; } else { return E_FAIL; } } else { // Previous version of Excel did not support 'Save As... HTML' return E_NOTIMPL; } } HRESULT TExcelConverter::OnOpen(LPDISPATCH pDisp, VARIANT* pResult) { CComDispatchDriver lDocumentsDriver(pDisp); HRESULT lResult; if (GetCurrentVersion() <= 8) { // Excel 97 CComVariant lApplicationResult; lResult = lDocumentsDriver.GetPropertyByName(L"Application", &lApplicationResult); ATLASSERT(SUCCEEDED(lResult) && lApplicationResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lApplicationResult.vt == VT_DISPATCH)) return E_FAIL; CComDispatchDriver lApplicationDriver(lApplicationResult.pdispVal); CComVariant lAppAddInsResult; lResult = lApplicationDriver.GetPropertyByName(L"AddIns", &lAppAddInsResult); ATLASSERT(SUCCEEDED(lResult) && lAppAddInsResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lAppAddInsResult.vt == VT_DISPATCH)) return E_FAIL; CComDispatchDriver lAppAddInsDriver(lAppAddInsResult.pdispVal); long lDispId_AddIns_Item; lResult = lAppAddInsDriver.GetIDOfName(L"Item", &lDispId_AddIns_Item); if (!SUCCEEDED(lResult)) return E_FAIL; CComVariant lInternetAssistantWizardAddInFullName; BOOL bInternetAssistantWizardAddInInstalled = FALSE; CComVariant lAddInsCountResult; lResult = lAppAddInsDriver.GetPropertyByName(L"Count", &lAddInsCountResult); ATLASSERT(SUCCEEDED(lResult) && lAddInsCountResult.vt == VT_I4); if (SUCCEEDED(lResult) && lAddInsCountResult.vt == VT_I4) { for (int ii = 1; ii <= lAddInsCountResult.iVal; ii++) { CComVariant lCurAddInResult; { CComVariant varArgs_param1(ii); CComVariant varArgs[1] = { varArgs_param1 }; DISPPARAMS dispparams = { &varArgs[0], NULL, 1, 0}; lResult = ((IDispatch *)lAppAddInsDriver)->Invoke( lDispId_AddIns_Item, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &lCurAddInResult, NULL, NULL); } ATLASSERT(SUCCEEDED(lResult) && lCurAddInResult.vt == VT_DISPATCH); if (SUCCEEDED(lResult) && lCurAddInResult.vt == VT_DISPATCH) { // Here we have an IAddIn dispatch CComDispatchDriver lAppAddInDriver(lCurAddInResult.pdispVal); CComVariant lAddInFileNameResult; lResult = lAppAddInDriver.GetPropertyByName(L"Name", &lAddInFileNameResult); ATLASSERT(SUCCEEDED(lResult) && lAddInFileNameResult.vt == VT_BSTR); if (SUCCEEDED(lResult) && lAddInFileNameResult.vt == VT_BSTR) { if (lAddInFileNameResult.bstrVal && (!wcsicmp(L"HTML.XLA", lAddInFileNameResult.bstrVal))) { CComVariant lAddInInstalled(true); lResult = lAppAddInDriver.PutPropertyByName(L"Installed",&lAddInInstalled); if (SUCCEEDED(lResult)) { lResult = lAppAddInDriver.GetPropertyByName(L"FullName", &lInternetAssistantWizardAddInFullName); if (SUCCEEDED(lResult)) { bInternetAssistantWizardAddInInstalled = TRUE; } break; } } } } } } if (!bInternetAssistantWizardAddInInstalled) return E_FAIL; // At least, now we know the HTML.XLA library is installed, let's load it in // our document's context so that its macros get accessible CComVariant lHtmlLibraryOpenResult; lResult = lDocumentsDriver.Invoke1(L"Open", &lInternetAssistantWizardAddInFullName, &lHtmlLibraryOpenResult); ATLASSERT(SUCCEEDED(lResult) && lHtmlLibraryOpenResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lHtmlLibraryOpenResult.vt == VT_DISPATCH)) return E_FAIL; // Now, the 'htmlconvert' macro is loaded // (see http://www.microsoft.com/ExcelDev/Articles/ConvHTML.htm for API details) } CComVariant lOpenResult; // The following call is supported by Excel 97, 2000 and plus... { CComVariant varArgs[11]; varArgs[10] = m_From; // FileName varArgs[9] = 0; // UpdateLinks varArgs[8] = true; // ReadOnly varArgs[7].vt = VT_ERROR; varArgs[7].scode = DISP_E_PARAMNOTFOUND; varArgs[6] = L""; // Password varArgs[5] = L""; // WriteResPassword varArgs[4] = true; // IgnoreReadOnlyRecommended varArgs[3].vt = VT_ERROR; varArgs[3].scode = DISP_E_PARAMNOTFOUND; varArgs[2].vt = VT_ERROR; varArgs[2].scode = DISP_E_PARAMNOTFOUND; varArgs[1].vt = VT_ERROR; varArgs[1].scode = DISP_E_PARAMNOTFOUND; varArgs[0] = false; // Notify long lDispId_Documents_Open; lResult = lDocumentsDriver.GetIDOfName(L"Open", &lDispId_Documents_Open); if (SUCCEEDED(lResult)) { EXCEPINFO pExcepInfo; unsigned int puArgErr = 0; DISPPARAMS dispparams = { &varArgs[0], NULL, 11, 0 }; lResult = ((IDispatch *)lDocumentsDriver)->Invoke( lDispId_Documents_Open, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &lOpenResult, &pExcepInfo, &puArgErr); if (SUCCEEDED(lResult) && (lOpenResult.vt == VT_DISPATCH)) { lOpenResult.Detach(pResult); } else { if (pExcepInfo.wCode == E_MICROSOFT_EXCEL_WRONG_PASSWORD) { lResult = OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED; } } } } return lResult; } HRESULT TExcelConverter::OnSave_Excel2000(LPDISPATCH pDisp) { if (GetCurrentVersion() <= 8) return E_NOTIMPL; CComDispatchDriver lDocumentDriver(pDisp); HRESULT lResult; CString lFolderTo(m_To); TPath lPath(lFolderTo); lPath.RemoveFileSpec(); // Before doing any publication to HTML, let's set the HTML format // options for the current document CComVariant lWebOptionsResult; lResult = lDocumentDriver.GetPropertyByName(L"WebOptions", &lWebOptionsResult); if (SUCCEEDED(lResult) && lWebOptionsResult.vt == VT_DISPATCH) { CComDispatchDriver lWebOptionsDriver(lWebOptionsResult.pdispVal); CComVariant lWebOptions_AllowPNG(false); lResult = lWebOptionsDriver.PutPropertyByName(L"AllowPNG", &lWebOptions_AllowPNG); CComVariant lWebOptions_DownloadComponents(false); lResult = lWebOptionsDriver.PutPropertyByName(L"DownloadComponents", &lWebOptions_DownloadComponents); CComVariant lWebOptions_RelyOnVML(false); lResult = lWebOptionsDriver.PutPropertyByName(L"RelyOnVML", &lWebOptions_RelyOnVML); } // Then, let's iterate on each workbook's sheet and publish it to HTML CComVariant lSheetsResult; lResult = lDocumentDriver.GetPropertyByName(L"Sheets", &lSheetsResult); ATLASSERT(SUCCEEDED(lResult) && lSheetsResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lSheetsResult.vt == VT_DISPATCH)) return E_FAIL; CComDispatchDriver lSheetsDriver(lSheetsResult.pdispVal); // We will store here the file path of each published workbook's sheet, // as well as its sheet name, // so that we will reassemble them into one big file when the work is done... struct TPublishedSheetData { TString m_stgMainHTMLFilePath; TString m_stgSheetName; }; TPtrArray lPublishedSheetsDataArray; CComVariant lSheetsCountResult; lResult = lSheetsDriver.GetPropertyByName(L"Count", &lSheetsCountResult); ATLASSERT(SUCCEEDED(lResult) && lSheetsCountResult.vt == VT_I4); if (SUCCEEDED(lResult) && lSheetsCountResult.vt == VT_I4 && lSheetsCountResult.iVal > 0) { // Let's get the constant values needed when invoking the IPublishObjects methods long lXlSourceType_xlSourceSheet; lResult = GetEnumConstantFromTypeLib(L"XlSourceType",L"xlSourceSheet",&lXlSourceType_xlSourceSheet); long lXlSourceType_xlSourceChart; lResult = GetEnumConstantFromTypeLib(L"XlSourceType",L"xlSourceChart",&lXlSourceType_xlSourceChart); long lXlHtmlType_xlHtmlStatic; lResult = GetEnumConstantFromTypeLib(L"XlHtmlType",L"xlHtmlStatic",&lXlHtmlType_xlHtmlStatic); CComVariant lPublishObjectsResult; lResult = lDocumentDriver.GetPropertyByName(L"PublishObjects", &lPublishObjectsResult); ATLASSERT(SUCCEEDED(lResult) && lPublishObjectsResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lPublishObjectsResult.vt == VT_DISPATCH)) return E_FAIL; CComDispatchDriver lPublishObjectsDriver(lPublishObjectsResult.pdispVal); long lDispId_Sheets_Item; lResult = lSheetsDriver.GetIDOfName(L"Item", &lDispId_Sheets_Item); if (!SUCCEEDED(lResult)) return E_FAIL; long lDispId_PublishObjects_Item; lResult = lPublishObjectsDriver.GetIDOfName(L"Item", &lDispId_PublishObjects_Item); if (!SUCCEEDED(lResult)) return E_FAIL; for (int iSheetIdx = 1; iSheetIdx <= lSheetsCountResult.iVal; iSheetIdx++) { CComVariant lCurSheetIdx(iSheetIdx); CComVariant lCurSheetResult; { CComVariant varArgs_param1(lCurSheetIdx); CComVariant varArgs[1] = { varArgs_param1 }; DISPPARAMS dispparams = { &varArgs[0], NULL, 1, 0}; lResult = ((IDispatch *)lSheetsDriver)->Invoke( lDispId_Sheets_Item, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &lCurSheetResult, NULL, NULL); } ATLASSERT(SUCCEEDED(lResult) && lCurSheetResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lCurSheetResult.vt == VT_DISPATCH)) continue; // Here we have an IWorksheet or an IChart dispatch CComDispatchDriver lCurSheetDriver(lCurSheetResult.pdispVal); CComVariant lPublishObjectResult; // Let's generate a temporary file name for the published file CString lTemporaryPublishedFilePath; TPath::CreateRandomFilePath(lFolderTo,_T(".htm"),lTemporaryPublishedFilePath); CString lCurSheetName(_T("")); CComPtr lCheckIWorksheetInterface; lResult = lCurSheetDriver.p->QueryInterface(IID_IWorksheet,(void**)&lCheckIWorksheetInterface); if (lCheckIWorksheetInterface) { // We know that we have an IWorksheet dispatch CComDispatchDriver lCurWorksheetDriver(lCurSheetDriver.p); CComVariant lCurWorksheetNameResult; lResult = lCurWorksheetDriver.GetPropertyByName(L"Name", &lCurWorksheetNameResult); lCurSheetName = CString(lCurWorksheetNameResult.bstrVal); { CComVariant varArgs_param1(lXlSourceType_xlSourceSheet); // SourceType CComVariant varArgs_param2(lTemporaryPublishedFilePath); // FileName CComVariant varArgs_param3(lCurWorksheetNameResult); // Sheet CComVariant varArgs_param4(L""); // Source CComVariant varArgs_param5(lXlHtmlType_xlHtmlStatic); // HtmlType CComVariant varArgs[5] = { varArgs_param5, varArgs_param4, varArgs_param3, varArgs_param2, varArgs_param1 }; long lDispId_PublishObjects_Add; lResult = lPublishObjectsDriver.GetIDOfName(L"Add", &lDispId_PublishObjects_Add); if (SUCCEEDED(lResult)) { EXCEPINFO pExcepInfo; unsigned int puArgErr = 0; DISPPARAMS dispparams = { &varArgs[0], NULL, 5, 0 }; lResult = ((IDispatch *)lPublishObjectsDriver)->Invoke( lDispId_PublishObjects_Add, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &lPublishObjectResult, &pExcepInfo, &puArgErr); } } } else { CComPtr lCheckIChartInterface; lResult = lCurSheetDriver.p->QueryInterface(IID_IChart,(void**)&lCheckIChartInterface); if (lCheckIChartInterface) { // We know that we have an IChart dispatch CComDispatchDriver lCurChartDriver(lCurSheetDriver.p); CComVariant lCurChartNameResult; lResult = lCurChartDriver.GetPropertyByName(L"Name", &lCurChartNameResult); lCurSheetName = CString(lCurChartNameResult.bstrVal); { CComVariant varArgs_param1(lXlSourceType_xlSourceChart); // SourceType CComVariant varArgs_param2(lTemporaryPublishedFilePath); // FileName CComVariant varArgs_param3(lCurChartNameResult); // Sheet CComVariant varArgs_param4(L""); // Source CComVariant varArgs_param5(lXlHtmlType_xlHtmlStatic); // HtmlType CComVariant varArgs[5] = { varArgs_param5, varArgs_param4, varArgs_param3, varArgs_param2, varArgs_param1 }; long lDispId_PublishObjects_Add; lResult = lPublishObjectsDriver.GetIDOfName(L"Add", &lDispId_PublishObjects_Add); if (SUCCEEDED(lResult)) { EXCEPINFO pExcepInfo; unsigned int puArgErr = 0; DISPPARAMS dispparams = { &varArgs[0], NULL, 5, 0 }; lResult = ((IDispatch *)lPublishObjectsDriver)->Invoke( lDispId_PublishObjects_Add, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &lPublishObjectResult, &pExcepInfo, &puArgErr); } } } } ATLASSERT(SUCCEEDED(lResult) && lPublishObjectResult.vt == VT_DISPATCH); if (SUCCEEDED(lResult) && lPublishObjectResult.vt == VT_DISPATCH) { // Here we have an PublishObject dispatch CComDispatchDriver lPublishObjectDriver(lPublishObjectResult.pdispVal); CComVariant lCreate(true); lResult = lPublishObjectDriver.Invoke1(L"Publish", &lCreate); ATLASSERT(SUCCEEDED(lResult)); if (SUCCEEDED(lResult)) { TPublishedSheetData* lNewData = new TPublishedSheetData(); lNewData->m_stgMainHTMLFilePath = lTemporaryPublishedFilePath; lNewData->m_stgSheetName = lCurSheetName; lPublishedSheetsDataArray.addElement(lNewData); } } } // Let's now reassemble every generated file into one big HTML file if (lPublishedSheetsDataArray.size() > 0) { CStdioFile lToFile; if (lToFile.Open(CString(m_To), CFile::modeWrite | CFile::modeCreate)) { for (int ii = 0; ii < lPublishedSheetsDataArray.size(); ii++) { TPublishedSheetData* curSheetData = (TPublishedSheetData*)lPublishedSheetsDataArray.elementAt(ii); CString curGeneratedFilePath = curSheetData->m_stgMainHTMLFilePath; CString curSheetName = curSheetData->m_stgSheetName; CStdioFile lFromFile; if (lFromFile.Open(curGeneratedFilePath, CFile::modeRead)) { CString lFromFileContent; { const int bufferSize = 4096; BYTE buffer[bufferSize]; memset(&buffer,0,bufferSize); for (;;) { int bytesRead = lFromFile.Read(buffer,bufferSize); if (bytesRead <= 0) { break; } buffer[bytesRead] = 0; lFromFileContent += buffer; } } lFromFile.Close(); // Here we can write some extra HTML CString lSheetHeaderHtmlTemplate; KBLoadString(IDS_MIMEFILTER_OFFICE_EXCEL2000_SHEET_HEADER_TEMPLATE,lSheetHeaderHtmlTemplate); if (!lSheetHeaderHtmlTemplate.IsEmpty()) { CString lSheetNameTemplate; KBLoadString(IDS_MIMEFILTER_OFFICE_EXCEL2000_SHEET_NAME_TEMPLATE,lSheetNameTemplate); CString lSheetNameCompleted; lSheetNameCompleted.FormatMessage( lSheetNameTemplate, curSheetName ); CString lSheetNumberCompleted; if (lPublishedSheetsDataArray.size() > 1) { CString lSheetNumberTemplate; KBLoadString(IDS_MIMEFILTER_OFFICE_EXCEL2000_SHEET_NUMBER_TEMPLATE,lSheetNumberTemplate); lSheetNumberCompleted.FormatMessage( lSheetNumberTemplate, ii+1, lPublishedSheetsDataArray.size() ); } CString lSheetHeaderHtmlCompleted; lSheetHeaderHtmlCompleted.FormatMessage( lSheetHeaderHtmlTemplate, lSheetNameCompleted, lSheetNumberCompleted ); lToFile.WriteString(lSheetHeaderHtmlCompleted); } lToFile.Write( lFromFileContent.GetBuffer(1), lFromFileContent.GetLength()); TRY { CFile::Remove(curGeneratedFilePath); } CATCH(CFileException, e) { } END_CATCH // Here we can write some extra HTML if (ii < lPublishedSheetsDataArray.size() - 1) { lToFile.WriteString("\r\n"); lToFile.WriteString("


\r\n"); } } } lToFile.Flush(); lToFile.Close(); lResult = S_OK; } else { lResult = E_FAIL; } } else { lResult = E_FAIL; } } // Clean-up for (int ii = 0; ii < lPublishedSheetsDataArray.size(); ii++) { TPublishedSheetData* curSheetData = (TPublishedSheetData*)lPublishedSheetsDataArray.elementAt(ii); delete curSheetData; } lPublishedSheetsDataArray.removeAllElements(); return lResult; } HRESULT TExcelConverter::OnSave_Excel97(LPDISPATCH pDisp) { if (GetCurrentVersion() > 8) return E_NOTIMPL; CComDispatchDriver lDocumentDriver(pDisp); HRESULT lResult; CComVariant lApplicationResult; lResult = lDocumentDriver.GetPropertyByName(L"Application", &lApplicationResult); ATLASSERT(SUCCEEDED(lResult) && lApplicationResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lApplicationResult.vt == VT_DISPATCH)) return E_FAIL; CComDispatchDriver lApplicationDriver(lApplicationResult.pdispVal); // The 'htmlconvert' macro has been loaded in the 'OnOpen' method // (see http://www.microsoft.com/ExcelDev/Articles/ConvHTML.htm for API details) // Let's now pick up everything we want to export in our excel workspace... CComVariant lSheetsResult; lResult = lDocumentDriver.GetPropertyByName(L"Sheets", &lSheetsResult); ATLASSERT(SUCCEEDED(lResult) && lSheetsResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lSheetsResult.vt == VT_DISPATCH)) return E_FAIL; CComDispatchDriver lSheetsDriver(lSheetsResult.pdispVal); // I guess we should try and do something very clever like iterating on all the // sheets, exporting all of them one by one, and then generating a root HTML // document from scratch that would reference all of them in a very nice looking // way... (TO DO) // Anyway, for now, let's just iterate on all the sheets on save them foot-to-head // in one single file... CComVariant lSheetsCountResult; lResult = lSheetsDriver.GetPropertyByName(L"Count", &lSheetsCountResult); ATLASSERT(SUCCEEDED(lResult) && lSheetsCountResult.vt == VT_I4); if (SUCCEEDED(lResult) && lSheetsCountResult.vt == VT_I4 && lSheetsCountResult.iVal > 0) { // Let's create the "array of variants" variant which will hold all // the objects we want to be exported by the 'HTMLConvert' macro // As we do not know yet the number of items we will export, we create at first an empty array CComVariant lRangeAndChartToConvertSafeArray; lResult = CreateRedimOneDimArray(lRangeAndChartToConvertSafeArray,0); if (!(SUCCEEDED(lResult))) return E_FAIL; long lDispId_Sheets_Item; lResult = lSheetsDriver.GetIDOfName(L"Item", &lDispId_Sheets_Item); if (!SUCCEEDED(lResult)) return E_FAIL; for (int iSheetIdx = 1; iSheetIdx <= lSheetsCountResult.iVal; iSheetIdx++) { CComVariant lCurSheetIdx(iSheetIdx); CComVariant lCurSheetResult; { CComVariant varArgs_param1(lCurSheetIdx); CComVariant varArgs[1] = { varArgs_param1 }; DISPPARAMS dispparams = { &varArgs[0], NULL, 1, 0}; lResult = ((IDispatch *)lSheetsDriver)->Invoke( lDispId_Sheets_Item, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &lCurSheetResult, NULL, NULL); } ATLASSERT(SUCCEEDED(lResult) && lCurSheetResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lCurSheetResult.vt == VT_DISPATCH)) return E_FAIL; // Here we have an IWorksheet or an IChart dispatch CComDispatchDriver lCurSheetDriver(lCurSheetResult.pdispVal); CComPtr lCheckIWorksheetInterface; lResult = lCurSheetDriver.p->QueryInterface(IID_IWorksheet,(void**)&lCheckIWorksheetInterface); if (lCheckIWorksheetInterface) { // We know that we have an IWorksheet dispatch CComDispatchDriver lCurWorksheetDriver(lCurSheetDriver.p); //****** //*** Here we get the RANGE we want to export //****** CComVariant lCurWorksheetRangeResult; lResult = lCurWorksheetDriver.GetPropertyByName(L"UsedRange", &lCurWorksheetRangeResult); if (!(SUCCEEDED(lResult) && lCurWorksheetRangeResult.vt == VT_DISPATCH)) { ATLASSERT(FALSE); TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, _T("Error (0x%1!x!) - Worksheet.UsedRange FAILED"), lResult); } else { // Let's add our RANGE object to the objects to export CComVariant lCurVariantToInsert(lCurWorksheetRangeResult.pdispVal); long lNewSize; GetOneDimArrayElemCount(lRangeAndChartToConvertSafeArray,&lNewSize); lNewSize++; long idx[1]; idx[0] = lNewSize - 1; lResult = CreateRedimOneDimArray(lRangeAndChartToConvertSafeArray,lNewSize); if (SUCCEEDED(lResult)) { SafeArrayPutElement(lRangeAndChartToConvertSafeArray.parray, idx, &lCurVariantToInsert); } } //****** //*** Here we get the CHART OBJECTS we want to export //****** CComVariant lCurWorksheetChartObjectsResult; lResult = lCurWorksheetDriver.Invoke0(L"ChartObjects", &lCurWorksheetChartObjectsResult); if (SUCCEEDED(lResult) && lCurWorksheetChartObjectsResult.vt == VT_DISPATCH) { CComDispatchDriver lChartObjectsDriver(lCurWorksheetChartObjectsResult.pdispVal); CComVariant lChartObjectsCountResult; lResult = lChartObjectsDriver.GetPropertyByName(L"Count", &lChartObjectsCountResult); ATLASSERT(SUCCEEDED(lResult) && lChartObjectsCountResult.vt == VT_I4); if (SUCCEEDED(lResult) && lChartObjectsCountResult.vt == VT_I4) { for (int ii = 1; ii <= lChartObjectsCountResult.iVal; ii++) { CComVariant lCurChartObjectIdx(ii); CComVariant lCurChartObjectResult; lResult = lChartObjectsDriver.Invoke1(L"Item", &lCurChartObjectIdx, &lCurChartObjectResult); if (SUCCEEDED(lResult) && lCurChartObjectResult.vt == VT_DISPATCH) { // Here we have an IChartObject dispatch CComDispatchDriver lCurChartObjectDriver(lCurChartObjectResult.pdispVal); CComVariant lCurChartResult; lResult = lCurChartObjectDriver.GetPropertyByName(L"Chart", &lCurChartResult); ATLASSERT(SUCCEEDED(lResult) && lCurChartResult.vt == VT_DISPATCH); if (SUCCEEDED(lResult) && lCurChartResult.vt == VT_DISPATCH) { // Here we have an IChart dispatch CComDispatchDriver lCurChartDriver(lCurChartResult.pdispVal); // Let's add our CHART object to the objects to export CComVariant lCurVariantToInsert(lCurChartResult.pdispVal); long lNewSize; GetOneDimArrayElemCount(lRangeAndChartToConvertSafeArray,&lNewSize); lNewSize++; long idx[1]; idx[0] = lNewSize - 1; lResult = CreateRedimOneDimArray(lRangeAndChartToConvertSafeArray,lNewSize); if (SUCCEEDED(lResult)) { SafeArrayPutElement(lRangeAndChartToConvertSafeArray.parray, idx, &lCurVariantToInsert); } } } } } } } else { CComPtr lCheckIChartInterface; lResult = lCurSheetDriver.p->QueryInterface(IID_IChart,(void**)&lCheckIChartInterface); if (lCheckIChartInterface) { // We know that we have an IChart dispatch CComDispatchDriver lCurChartDriver(lCurSheetDriver.p); // Let's add our CHART object to the objects to export CComVariant lCurVariantToInsert(lCurSheetResult.pdispVal); long lNewSize; GetOneDimArrayElemCount(lRangeAndChartToConvertSafeArray,&lNewSize); lNewSize++; long idx[1]; idx[0] = lNewSize - 1; lResult = CreateRedimOneDimArray(lRangeAndChartToConvertSafeArray,lNewSize); if (SUCCEEDED(lResult)) { SafeArrayPutElement(lRangeAndChartToConvertSafeArray.parray, idx, &lCurVariantToInsert); } } } } //****** //*** Here we get the worksheet's name we will display as HTML header //****** CComVariant lDocumentTitleResult; { lResult = lDocumentDriver.GetPropertyByName(L"Title", &lDocumentTitleResult); ATLASSERT(SUCCEEDED(lResult) && lDocumentTitleResult.vt == VT_BSTR); if (!(SUCCEEDED(lResult) && lDocumentTitleResult.vt == VT_BSTR)) { lDocumentTitleResult = L""; } } CComVariant lDocumentDescription(L""); CComVariant lLineBeforeTable(false); if ( (CComBSTR(lDocumentTitleResult.bstrVal).Length() != 0) || (CComBSTR(lDocumentDescription.bstrVal).Length() != 0) ) { lLineBeforeTable = VARIANT_TRUE; } { // Macro Name CComVariant varArgs_param1(L"HTMLConvert"); // Macro Param 1: RangeAndChartToConvert CComVariant varArgs_param2(lRangeAndChartToConvertSafeArray); // Macro Param 2: UseExistingFile CComVariant varArgs_param3(false); // Macro Param 3: UseFrontPageForExistingFile CComVariant varArgs_param4(false); // Macro Param 4: AddToFrontPageWeb CComVariant varArgs_param5(false); // Macro Param 5: CodePage CComVariant varArgs_param6((long)1252); // Macro Param 6: HTMLFilePath CComVariant varArgs_param7(m_To); // Macro Param 7: ExistingFilePath CComVariant varArgs_param8(L""); // Macro Param 8: TitleFullPage CComVariant varArgs_param9(lDocumentTitleResult); // Macro Param 9: HeaderFullPage CComVariant varArgs_param10(lDocumentTitleResult); // Macro Param 10: DescriptionFullPage CComVariant varArgs_param11(lDocumentDescription); // Macro Param 11: LineBeforeTableFullPage CComVariant varArgs_param12(lLineBeforeTable); // Macro Param 12: LineAfterTableFullPage CComVariant varArgs_param13(false); // Macro Param 13: LastUpdate CComVariant varArgs_param14; // Macro Param 14: NameFullPage CComVariant varArgs_param15; // Macro Param 15: EmailFullPage CComVariant varArgs_param16; CComVariant varArgs[16] = { varArgs_param16, varArgs_param15, varArgs_param14, varArgs_param13, varArgs_param12, varArgs_param11, varArgs_param10, varArgs_param9, varArgs_param8, varArgs_param7, varArgs_param6, varArgs_param5, varArgs_param4, varArgs_param3, varArgs_param2, varArgs_param1 }; CComVariant lRunHtmlConvertResult; { // We'd rather use the fastidious 'Invoke' code instead of the shorter 'InvokeN' call // because it allows us to catch exceptions and if the MACRO is not found, we do not // get an error code but rather an exception... //lResult = lApplicationDriver.InvokeN( L"Run", &varArgs[0], 7, &lRunHtmlConvertResult ); long lDispId_Application_Run; lResult = lApplicationDriver.GetIDOfName(L"Run", &lDispId_Application_Run); if (SUCCEEDED(lResult)) { EXCEPINFO pExcepInfo; unsigned int puArgErr = 0; DISPPARAMS dispparams = { &varArgs[0], NULL, 16, 0 }; lResult = ((IDispatch *)lApplicationDriver)->Invoke( lDispId_Application_Run, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &lRunHtmlConvertResult, &pExcepInfo, &puArgErr); if (lResult == DISP_E_EXCEPTION) { ATLTRACE("EXCEPTION - Source: %s - Description: %s\n",CString(pExcepInfo.bstrSource),CString(pExcepInfo.bstrDescription)); } else if ( (lResult == DISP_E_TYPEMISMATCH) || (lResult == DISP_E_PARAMNOTFOUND) ) { ATLTRACE("PARAMETER ERROR - ArgPos: %d\n",puArgErr); } } } if (SUCCEEDED(lResult)) ATLTRACE("htmlconvert SUCCESS\n"); else ATLTRACE("htmlconvert FAILURE\n"); } DestroyOneDimArray(lRangeAndChartToConvertSafeArray); } return lResult; } HRESULT TExcelConverter::OnSave(LPDISPATCH pDisp) { if (GetCurrentVersion() > 8) return OnSave_Excel2000(pDisp); return OnSave_Excel97(pDisp); } HRESULT TExcelConverter::OnClose(LPDISPATCH pDisp) { // For now, let's just have the default behavior, that is close the xls doxument // To make things cleaner, we might want to close the html.xla library as well, but // as it is closed anyway when Excel is closed, let's get rid of this... CComDispatchDriver lDocumentDriver(pDisp); HRESULT lCloseResult; CComVariant lSaveChanges(false); lCloseResult = lDocumentDriver.Invoke1(L"Close", &lSaveChanges); return lCloseResult; } HRESULT TExcelConverter::OnPostProcessDocument(LPDISPATCH pDisp) { if (GetCurrentVersion() <= 8) return E_NOTIMPL; // On some IE 5.0 versions, the HTML source generated by Word 2000 contains some // attributes that make images not to display properly. // Therefore, we will rewrite those HTML source parts CComDispatchDriver lDocumentDriver(pDisp); HRESULT lResult; CString lFromFileContent; CStdioFile lFromFile; if (lFromFile.Open(CString(m_To), CFile::modeRead)) { { const int bufferSize = 4096; BYTE buffer[bufferSize]; memset(&buffer,0,bufferSize); for (;;) { int bytesRead = lFromFile.Read(buffer,bufferSize); if (bytesRead <= 0) { break; } buffer[bytesRead] = 0; lFromFileContent += buffer; } } lFromFile.Close(); } if (!lFromFileContent.IsEmpty()) { // Let's do our post-processing here { // On some IE 5.0 versions, we have issues with images not displaying correctly. // It seems that it is due to the 'class=shape' attribute that Word put on IMG tags... // Therefore, let's rename the '.shape' style lFromFileContent.Replace( _T(".shape"), _T(".shap0") ); lFromFileContent.Replace( _T(".SHAPE"), _T(".SHAP0") ); CString lResultBuffer; lResult = OnPostProcessDocument_RemoveConditionalComments(pDisp, lFromFileContent, lResultBuffer); if (SUCCEEDED(lResult)) { lFromFileContent = lResultBuffer; } lResultBuffer.Empty(); lResult = OnPostProcessDocument_RemoveXmlNamespaces(pDisp, lFromFileContent, lResultBuffer); if (SUCCEEDED(lResult)) { lFromFileContent = lResultBuffer; } } // And then, let's save our post-processed document back CStdioFile lToFile; if (lToFile.Open(CString(m_To), CFile::modeWrite | CFile::modeCreate)) { lToFile.Write( lFromFileContent.GetBuffer(1), lFromFileContent.GetLength()); lToFile.Flush(); lToFile.Close(); } } return S_OK; } HRESULT TExcelConverter::DisableAlerts() { HRESULT lResult; CComVariant lDisplayAlertsValue(false); lResult = m_OfficeAppDriver.PutPropertyByName(L"DisplayAlerts", &lDisplayAlertsValue); ATLASSERT(SUCCEEDED(lResult)); return lResult; } HRESULT TExcelConverter::CreateRedimOneDimArray(VARIANT& varSrc, DWORD dwSize) { HRESULT lResult; UINT nDim; // Clear VARIANT and re-create SafeArray if necessary if ( (varSrc.vt != (VT_VARIANT | VT_ARRAY)) || ((nDim = ::SafeArrayGetDim(varSrc.parray)) != 1) ) { lResult = ::VariantClear(&varSrc); ASSERT( SUCCEEDED(lResult) ); varSrc.vt = VT_VARIANT | VT_ARRAY; SAFEARRAYBOUND bound; bound.cElements = dwSize; bound.lLbound = 0; varSrc.parray = ::SafeArrayCreate(VT_VARIANT, 1, &bound); if (varSrc.parray == NULL) return E_FAIL; } else { // Must redimension array if necessary long lLower, lUpper; lResult = ::SafeArrayGetLBound(varSrc.parray, 1, &lLower); ASSERT( SUCCEEDED(lResult) ); lResult = ::SafeArrayGetUBound(varSrc.parray, 1, &lUpper); ASSERT( SUCCEEDED(lResult) ); // Upper bound should always be greater than lower bound long lSize = lUpper - lLower; if (lSize < 0) { lSize = 0; } if ((DWORD)lSize != dwSize) { SAFEARRAYBOUND bound; bound.cElements = dwSize; bound.lLbound = lLower; lResult = ::SafeArrayRedim(varSrc.parray, &bound); ASSERT( SUCCEEDED(lResult) ); } } return S_OK; } HRESULT TExcelConverter::GetOneDimArrayElemCount(VARIANT& varSrc, long* dwSize) { if (!dwSize) return S_FALSE; HRESULT lResult; UINT nDim; if ( (varSrc.vt != (VT_VARIANT | VT_ARRAY)) || ((nDim = ::SafeArrayGetDim(varSrc.parray)) != 1) ) { return E_FAIL; } else { long lLower, lUpper; lResult = ::SafeArrayGetLBound(varSrc.parray, 1, &lLower); ASSERT( SUCCEEDED(lResult) ); lResult = ::SafeArrayGetUBound(varSrc.parray, 1, &lUpper); ASSERT( SUCCEEDED(lResult) ); long lElemCount = lUpper - lLower; if (lElemCount < 0) lElemCount = 0; else lElemCount++; *dwSize = lElemCount; } return S_OK; } HRESULT TExcelConverter::DestroyOneDimArray(VARIANT& varSrc) { HRESULT lResult; if ( (varSrc.vt != (VT_VARIANT | VT_ARRAY)) ) { return E_FAIL; } else { lResult = ::SafeArrayDestroy(varSrc.parray); ASSERT( SUCCEEDED(lResult) ); } return S_OK; } /**************************************/ /***** class TPowerPointConverter *****/ /**************************************/ TPowerPointConverter::TPowerPointConverter() : TOfficeConverter() { } HRESULT TPowerPointConverter::Convert() { HRESULT lResult; CComBSTR lProgID; lResult = GetApplicationProgID(&lProgID); if (SUCCEEDED(lResult)) lResult = ConvertDocument(lProgID, L"Presentations"); return lResult; } HRESULT TPowerPointConverter::GetSaveAsConvertFormat(DWORD* pFormatResult) { if (!pFormatResult) return E_INVALIDARG; if (GetCurrentVersion() > 8) { if ( m_lSaveAsConvertFormat.vt == VT_I4 ) { // already computed *pFormatResult = m_lSaveAsConvertFormat.iVal; return S_OK; } // We must get the HTML Format Number from PowerPoint TypeLib HRESULT lResult; long lGIFFileFormat; lResult = GetEnumConstantFromTypeLib(L"PpSaveAsFileType",L"ppSaveAsGIF",&lGIFFileFormat); if (SUCCEEDED(lResult)) { m_lSaveAsConvertFormat = CComVariant(lGIFFileFormat,VT_I4); *pFormatResult = lGIFFileFormat; return S_OK; } else { return E_FAIL; } } else { // Previous version of PowerPoint did not support 'Save As... HTML' return E_NOTIMPL; } } HRESULT TPowerPointConverter::GetConvertedDocumentMime(BSTR* pResMime) { *pResMime = CComBSTR(L"text/html").Copy(); return S_OK; } HRESULT TPowerPointConverter::OnOpen(LPDISPATCH pDisp, VARIANT* pResult) { CComDispatchDriver lDocumentsDriver(pDisp); CComVariant lOpenResult; HRESULT lResult; // The following call is supported by PowerPoint 97, 2000 and plus... { CComVariant varArgs_param1(m_From); // FileName CComVariant varArgs_param2(true); // ReadOnly CComVariant varArgs_param3(false); // Untitled CComVariant varArgs_param4(false); // WithWindow CComVariant varArgs[4] = { varArgs_param4, varArgs_param3, varArgs_param2, varArgs_param1 }; long lDispId_Documents_Open; lResult = lDocumentsDriver.GetIDOfName(L"Open", &lDispId_Documents_Open); if (SUCCEEDED(lResult)) { EXCEPINFO pExcepInfo; unsigned int puArgErr = 0; DISPPARAMS dispparams = { &varArgs[0], NULL, 4, 0 }; lResult = ((IDispatch *)lDocumentsDriver)->Invoke( lDispId_Documents_Open, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &lOpenResult, &pExcepInfo, &puArgErr); if (SUCCEEDED(lResult) && (lOpenResult.vt == VT_DISPATCH)) { lOpenResult.Detach(pResult); } } } return lResult; } HRESULT TPowerPointConverter::OnSave(LPDISPATCH pDisp) { CComDispatchDriver lDocumentDriver(pDisp); HRESULT lResult; CComVariant lTo(m_To); CComVariant lFilterName; if (this->IsExportGraphicFilterInstalled(_T("image/gif"))) { lFilterName = CComVariant(L"gif"); } else if (this->IsExportGraphicFilterInstalled(_T("image/jpeg"))) { lFilterName = CComVariant(L"jpg"); } if (lFilterName.vt != VT_EMPTY) { lResult = lDocumentDriver.Invoke2(L"Export", &lTo, &lFilterName); ATLASSERT(SUCCEEDED(lResult)); } else { if (GetCurrentVersion() > 8) { // In the PowerPoint 2000 & + case, we still have the possibility to // use the 'Save As... HTML' feature DWORD lConvertFormat = 0; lResult = GetSaveAsConvertFormat(&lConvertFormat); if (SUCCEEDED(lResult)) { CComVariant lFormat(lConvertFormat, VT_I4); lResult = lDocumentDriver.Invoke2(L"SaveAs", &lTo, &lFormat); ATLASSERT(SUCCEEDED(lResult)); } } else { // Else, we cannot export therefore we fail return E_FAIL; } } if (!SUCCEEDED(lResult)) return lResult; // At last, now that we have generated the 'graphic' files, let's generate the // HTML file putting together all of them TStringArray lGeneratedFilesArray; CString lToDirectory(m_To); TPath lPath(lToDirectory); lPath.RemoveFileSpec(); /* BOOL bResFileList = */ TPath::GetFileListInDirectory(lToDirectory,TRUE,FALSE,lGeneratedFilesArray); if (!lGeneratedFilesArray.isEmpty()) { // First, let's sort the array by creation date TStringArray lDuplicateGeneratedFilesArray; TStringIterator* lIter = lGeneratedFilesArray.elements(); while (lIter && lIter->hasMoreElements()) { lDuplicateGeneratedFilesArray.addElement(lIter->nextElement()); } delete lIter; TStringArray lSortedGeneratedFilesArray; int lDuplicateGeneratedFilesArraySize = lDuplicateGeneratedFilesArray.size(); for (int ii = 0; ii < lDuplicateGeneratedFilesArraySize; ii++) { int lFoundIndex = 0; CTime lFoundCreationTime; for (int jj = 0; jj < lDuplicateGeneratedFilesArray.size(); jj++) { TString lCurFile = lDuplicateGeneratedFilesArray.elementAt(jj); CFileStatus lFileStatus; CFile::GetStatus(lCurFile,lFileStatus); CTime lCurFileCreationTime = lFileStatus.m_ctime; if ( (jj == 0) || (lCurFileCreationTime < lFoundCreationTime) ) { lFoundCreationTime = lCurFileCreationTime; lFoundIndex = jj; } } lSortedGeneratedFilesArray.addElement(lDuplicateGeneratedFilesArray.elementAt(lFoundIndex)); lDuplicateGeneratedFilesArray.removeElementAt(lFoundIndex); } // Generate HTML file beside the graphic files CString lToFileName; CString lToPath(m_To); TPath::FindFileName(lToPath, lToFileName); CString lToGraphicFilesDirectory(lSortedGeneratedFilesArray.elementAt(0)); TPath::RemoveFileSpec(lToGraphicFilesDirectory); CString lHtmlFilePath(lToGraphicFilesDirectory); TPath lPath(lHtmlFilePath); lPath.AddPath(lToFileName); CStdioFile lFile; if (lFile.Open(lHtmlFilePath, CFile::modeWrite | CFile::modeCreate)) { lFile.WriteString(""); for (int ii = 0; ii < lSortedGeneratedFilesArray.size(); ii++) { CString lCurImageSrc = lSortedGeneratedFilesArray.elementAt(ii); CString lCurImageSrcFileName; TPath::FindFileName(lCurImageSrc,lCurImageSrcFileName); lFile.WriteString(""); if (ii != lSortedGeneratedFilesArray.size() - 1) { lFile.WriteString("\r\n"); lFile.WriteString("


\r\n"); } } lFile.WriteString(""); lFile.Close(); } } return lResult; } HRESULT TPowerPointConverter::OnClose(LPDISPATCH) { return E_NOTIMPL; } HRESULT TPowerPointConverter::OnPostProcessDocument(LPDISPATCH pDisp) { if (GetCurrentVersion() <= 8) return E_NOTIMPL; // On some IE 5.0 versions, the HTML source generated by Word 2000 contains some // attributes that make images not to display properly. // Therefore, we will rewrite those HTML source parts CComDispatchDriver lDocumentDriver(pDisp); HRESULT lResult; CString lFromFileContent; CStdioFile lFromFile; if (lFromFile.Open(CString(m_To), CFile::modeRead)) { { const int bufferSize = 4096; BYTE buffer[bufferSize]; memset(&buffer,0,bufferSize); for (;;) { int bytesRead = lFromFile.Read(buffer,bufferSize); if (bytesRead <= 0) { break; } buffer[bytesRead] = 0; lFromFileContent += buffer; } } lFromFile.Close(); } if (!lFromFileContent.IsEmpty()) { // Let's do our post-processing here { // On some IE 5.0 versions, we have issues with images not displaying correctly. // It seems that it is due to the 'class=shape' attribute that Word put on IMG tags... // Therefore, let's rename the '.shape' style lFromFileContent.Replace( _T(".shape"), _T(".shap0") ); lFromFileContent.Replace( _T(".SHAPE"), _T(".SHAP0") ); CString lResultBuffer; lResult = OnPostProcessDocument_RemoveConditionalComments(pDisp, lFromFileContent, lResultBuffer); if (SUCCEEDED(lResult)) { lFromFileContent = lResultBuffer; } lResultBuffer.Empty(); lResult = OnPostProcessDocument_RemoveXmlNamespaces(pDisp, lFromFileContent, lResultBuffer); if (SUCCEEDED(lResult)) { lFromFileContent = lResultBuffer; } } // And then, let's save our post-processed document back CStdioFile lToFile; if (lToFile.Open(CString(m_To), CFile::modeWrite | CFile::modeCreate)) { lToFile.Write( lFromFileContent.GetBuffer(1), lFromFileContent.GetLength()); lToFile.Flush(); lToFile.Close(); } } return S_OK; }/*------------ TOfficeConverter.h ------------*/ #ifndef _T_Office_Converter_h_ #define _T_Office_Converter_h_ // MAIN INCLUDE #include "TOfficeHelper.h" // OTHER INCLUDES #include #include "TStringArray.h" #include "TPath.h" #include "TErr.h" #include "TIEConditionalCommentsParser.h" // DEFINES #ifdef _DEBUG #define _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib 0 #endif // _DEBUG /****************************************/ /***** TOfficeConverter Error Codes *****/ /****************************************/ #define OFFICECONVERTER_E_APPLICATION_CREATION_FAILED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 200) #define OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 201) #define OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 202) #define OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 203) #define OFFICECONVERTER_E_APPLICATION_ENUMERATE_GENERATED_FILES_FAILED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 204) /*******************************************/ /***** template class TOfficeConverter *****/ /*******************************************/ template class TOfficeConverter : public theOfficeHelper { public: TOfficeConverter() : theOfficeHelper() { m_lSaveAsConvertFormat.Clear(); } virtual ~TOfficeConverter() { // Release Office App Object HRESULT lResult; lResult = UninitializeOfficeAppDriver(); ATLASSERT(SUCCEEDED(lResult)); } virtual HRESULT Convert() = 0; virtual HRESULT GetSaveAsConvertFormat(DWORD* pFormatResult) = 0; virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime) = 0; void SetSource(LPCTSTR pFrom) { m_From = pFrom; } void SetTarget(LPCTSTR pTo) { m_To = pTo; } void GetExportedFilesList(TStringArray& pResultArray) { if (!pResultArray.isEmpty()) pResultArray.removeAllElements(); for (int ii = 0; ii < m_ExportedFilesList.size(); ii++) { pResultArray.addElement(m_ExportedFilesList.elementAt(ii)); } } protected: virtual HRESULT OnVersion(BSTR) { return E_NOTIMPL; } virtual HRESULT OnOpen(LPDISPATCH, VARIANT*) { return E_NOTIMPL; } virtual HRESULT OnSave(LPDISPATCH) { return E_NOTIMPL; } virtual HRESULT OnClose(LPDISPATCH) { return E_NOTIMPL; } virtual HRESULT OnPostProcessDocument(LPDISPATCH) { return E_NOTIMPL; } virtual HRESULT OnEnumerateGeneratedFiles(LPDISPATCH) { return E_NOTIMPL; } virtual HRESULT DisableAlerts() { return E_NOTIMPL; } virtual bool GetVisible() { return false; } HRESULT GetInitialVisibleStateForQuitHandling(VARIANT* pInitialVisibleStateResult) { // This method should be virtual but it is called from the TOfficeConverter destructor and we // do not have the virtual table of our specialized object anymore!!! // Therfore, let's be really dirty... if (m_AppName.CompareNoCase(CString("powerpoint")) == 0) { *pInitialVisibleStateResult = m_InitialVisibleState; return S_OK; } return E_NOTIMPL; } HRESULT ConvertDocument(LPCWSTR pAppProgID, LPCWSTR pDocumentsName) { HRESULT lResult; // Initialize generated files list m_ExportedFilesList.removeAllElements(); // Make sure the Office App Object is created if (!m_OfficeAppDriver) { lResult = InitializeOfficeAppDriver(); ATLASSERT(SUCCEEDED(lResult) && m_OfficeAppDriver); if (!(SUCCEEDED(lResult) && m_OfficeAppDriver)) { return lResult; } } DisableAlerts(); CComVariant lValue; lResult = m_OfficeAppDriver.GetPropertyByName(L"Version", &lValue); ATLASSERT(SUCCEEDED(lResult)); // Do some special processing on version if (SUCCEEDED(lResult) && lValue.vt == VT_BSTR) { lResult = OnVersion(lValue.bstrVal); if (FAILED(lResult) && lResult != E_NOTIMPL) { // Release Office App Object // -> NO - It will be done when the converter is destroyed return lResult; } } // Open source document CComVariant lDocumentsValue; CComPtr lDocument; lResult = m_OfficeAppDriver.GetPropertyByName(pDocumentsName, &lDocumentsValue); ATLASSERT(SUCCEEDED(lResult) && lDocumentsValue.vt == VT_DISPATCH); if (SUCCEEDED(lResult) && lDocumentsValue.vt == VT_DISPATCH) { CComVariant lOpenResult; lResult = OnOpen(lDocumentsValue.pdispVal, &lOpenResult); if (lResult == E_NOTIMPL) { CComDispatchDriver lDocumentsDriver(lDocumentsValue.pdispVal); CComVariant lFrom(m_From); lResult = lDocumentsDriver.Invoke1(L"Open", &lFrom, &lOpenResult); } ATLASSERT(SUCCEEDED(lResult) && lOpenResult.vt == VT_DISPATCH); if (SUCCEEDED(lResult) && lOpenResult.vt == VT_DISPATCH) { lDocument = lOpenResult.pdispVal; CComDispatchDriver lDocumentDriver(lDocument); lResult = OnSave(lDocument); if (lResult == E_NOTIMPL) { DWORD lConvertFormat = 0; lResult = GetSaveAsConvertFormat(&lConvertFormat); if (SUCCEEDED(lResult)) { CComVariant lTo(m_To); CComVariant lFormat(lConvertFormat, VT_I4); lResult = lDocumentDriver.Invoke2(L"SaveAs", &lTo, &lFormat); ATLASSERT(SUCCEEDED(lResult)); } } if (!SUCCEEDED(lResult)) { lResult = OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED; } HRESULT lCloseResult; lCloseResult = OnClose(lDocument); if (lCloseResult == E_NOTIMPL) { lCloseResult = lDocumentDriver.Invoke0(L"Close"); } ATLASSERT(SUCCEEDED(lCloseResult)); if (!SUCCEEDED(lCloseResult)) { CComBSTR lAppName; GetCurrentVersionFullAppName(&lAppName); TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, _T("Error (0x%1!x!) when closing the [%2] document"), lCloseResult, (CString(lAppName).IsEmpty()?_T("??"):CString(lAppName))); } HRESULT lPostProcessDocumentResult; lPostProcessDocumentResult = OnPostProcessDocument(lDocument); if ( (lPostProcessDocumentResult != E_NOTIMPL) && (!SUCCEEDED(lPostProcessDocumentResult)) ) { CComBSTR lAppName; GetCurrentVersionFullAppName(&lAppName); TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, _T("Error (0x%1!x!) when post-processing the [%2] document"), lPostProcessDocumentResult, (CString(lAppName).IsEmpty()?_T("??"):CString(lAppName))); } HRESULT lEnumerateGeneratedFilesResult; lEnumerateGeneratedFilesResult = OnEnumerateGeneratedFiles(lDocument); if (lEnumerateGeneratedFilesResult == E_NOTIMPL) { CString lTo(m_To); TPath lPath(lTo); lPath.RemoveFileSpec(); BOOL bResFileList = TPath::GetFileListInDirectory(lTo,TRUE,FALSE,m_ExportedFilesList); lEnumerateGeneratedFilesResult = (bResFileList?S_OK:E_FAIL); } ATLASSERT(SUCCEEDED(lEnumerateGeneratedFilesResult)); if (!SUCCEEDED(lEnumerateGeneratedFilesResult)) { lResult = OFFICECONVERTER_E_APPLICATION_ENUMERATE_GENERATED_FILES_FAILED; } } else { if (lResult != OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED) { lResult = OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED; } } } // Release Office App Object // -> NO - It will be done when the converter is destroyed return lResult; } HRESULT GetEnumNameFromTypeLib(BSTR pEnumName, ITypeInfo** pTypeInfo) { HRESULT lResult; if ((!pEnumName) || (!pTypeInfo)) return E_INVALIDARG; if (!m_OfficeAppDriver) { // Create Office App Object lResult = InitializeOfficeAppDriver(); ATLASSERT(SUCCEEDED(lResult) && m_OfficeAppDriver); if (!(SUCCEEDED(lResult) && m_OfficeAppDriver)) return E_FAIL; } CComPtr lOfficeAppTypeLib; CComPtr lTypeInfo_OfficeApp; lResult = ((IDispatch*)m_OfficeAppDriver)->GetTypeInfo(0, LOCALE_USER_DEFAULT, &lTypeInfo_OfficeApp); if (!(SUCCEEDED(lResult) && lTypeInfo_OfficeApp)) return E_FAIL; unsigned int lNotUsed = 0; lResult = lTypeInfo_OfficeApp->GetContainingTypeLib(&lOfficeAppTypeLib,&lNotUsed); if (!SUCCEEDED(lResult)) return E_FAIL; CComPtr lOfficeAppTypeLib_Comp; lResult = lOfficeAppTypeLib->GetTypeComp(&lOfficeAppTypeLib_Comp); HRESULT lHashVal_EnumName; lHashVal_EnumName = LHashValOfNameSys(SYS_WIN32,LOCALE_USER_DEFAULT,pEnumName); CComPtr lTypeComp_EnumName; return lOfficeAppTypeLib_Comp->BindType(pEnumName, lHashVal_EnumName, pTypeInfo, &lTypeComp_EnumName); } HRESULT GetEnumConstantFromTypeLib(BSTR pEnumName, BSTR pConstantInEnumName, long* pConstantValue) { if ((!pEnumName) || (!pConstantInEnumName) || (!pConstantValue)) return E_INVALIDARG; HRESULT lResult; CComPtr lTypeInfo_EnumName; lResult = GetEnumNameFromTypeLib(pEnumName, &lTypeInfo_EnumName); if (FAILED(lResult) || (lTypeInfo_EnumName == NULL)) return E_FAIL; TYPEATTR* lTypeAttr_EnumName = NULL; lResult = lTypeInfo_EnumName->GetTypeAttr(&lTypeAttr_EnumName); if (FAILED(lResult) || (lTypeAttr_EnumName == NULL)) return E_FAIL; if (lTypeAttr_EnumName->typekind == TKIND_ENUM) { for (int ii = 0; ii < lTypeAttr_EnumName->cVars; ii++) { VARDESC* lCurVarDesc = NULL; lResult = lTypeInfo_EnumName->GetVarDesc(ii,&lCurVarDesc); if (FAILED(lResult) || (lCurVarDesc == NULL)) continue; long idMember = lCurVarDesc->memid; CComBSTR lCurVar_Name; lResult = lTypeInfo_EnumName->GetDocumentation(idMember, &lCurVar_Name, NULL, NULL, NULL); if (SUCCEEDED(lResult) && lCurVar_Name) { if (!wcsicmp(pConstantInEnumName, lCurVar_Name)) { if (lCurVarDesc->varkind == VAR_CONST) { ASSERT(lCurVarDesc->lpvarValue->vt == VT_I4); long lCurVarDesc_Value = lCurVarDesc->lpvarValue->iVal; ATLTRACE("Name: %s - Value: %d\n",CString(lCurVar_Name),lCurVarDesc_Value); #if _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib CString lTmp; lTmp.Format( "Name: %s - Value: %d", CString(lCurVar_Name), lCurVarDesc_Value); ::MessageBox(NULL,lTmp,CString("GetEnumConstantFromTypeLib"),MB_OK); #endif // _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib // Yeepee!! We have our result! // 1- Let's release everything we got lTypeInfo_EnumName->ReleaseVarDesc(lCurVarDesc); lTypeInfo_EnumName->ReleaseTypeAttr(lTypeAttr_EnumName); // 2- Let's return our result *pConstantValue = lCurVarDesc_Value; return S_OK; } } } lTypeInfo_EnumName->ReleaseVarDesc(lCurVarDesc); } } lTypeInfo_EnumName->ReleaseTypeAttr(lTypeAttr_EnumName); // Release Office App Object // -> NO - It will be done when the converter is destroyed return E_FAIL; } HRESULT GetPropertyIDFromTypeLib(BSTR pObjectName, BSTR pPropertyName, DISPID* pId) { if ((!pObjectName) || (!pPropertyName) || (!pId)) return E_INVALIDARG; HRESULT lResult; CComPtr lTypeInfo_ObjectName; lResult = GetEnumNameFromTypeLib(pObjectName, &lTypeInfo_ObjectName); if (FAILED(lResult) || (lTypeInfo_ObjectName == NULL)) return E_FAIL; TYPEATTR* lTypeAttr_ObjectName = NULL; lResult = lTypeInfo_ObjectName->GetTypeAttr(&lTypeAttr_ObjectName); if (FAILED(lResult) || (lTypeAttr_ObjectName == NULL)) return E_FAIL; if (lTypeAttr_ObjectName->typekind == TKIND_DISPATCH) { for (int ii = 0; ii < lTypeAttr_ObjectName->cFuncs; ii++) { VARDESC* lCurVarDesc = NULL; lResult = lTypeInfo_ObjectName->GetVarDesc(ii,&lCurVarDesc); if (FAILED(lResult) || (lCurVarDesc == NULL)) continue; long idMember = lCurVarDesc->memid; CComBSTR lCurVar_Name; lResult = lTypeInfo_ObjectName->GetDocumentation(idMember, &lCurVar_Name, NULL, NULL, NULL); if (SUCCEEDED(lResult) && lCurVar_Name) { if (!wcsicmp(pPropertyName, lCurVar_Name)) { if (lCurVarDesc->varkind == VAR_DISPATCH) { ATLTRACE("Name: %s - Value: %d\n",CString(lCurVar_Name), idMember); #if _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib CString lTmp; lTmp.Format("Name: %s - Value: %d", CString(lCurVar_Name), idMember); ::MessageBox(NULL,lTmp,CString("GetPropertyIDFromTypeLib"),MB_OK); #endif // _OFFICE_CONVERTER_DEBUG_GetEnumConstantFromTypeLib // Yeepee!! We have our result! // 1- Let's release everything we got lTypeInfo_ObjectName->ReleaseVarDesc(lCurVarDesc); lTypeInfo_ObjectName->ReleaseTypeAttr(lTypeAttr_ObjectName); // 2- Let's return our result *pId = idMember; return S_OK; } } } lTypeInfo_ObjectName->ReleaseVarDesc(lCurVarDesc); } } lTypeInfo_ObjectName->ReleaseTypeAttr(lTypeAttr_ObjectName); // Release Office App Object // -> NO - It will be done when the converter is destroyed return E_FAIL; } HRESULT InitializeOfficeAppDriver() { HRESULT lResult; CComPtr lOfficeAppResult; // Create Office App Object CComBSTR lProgID; lResult = GetApplicationProgID(&lProgID); if (FAILED(lResult)) return E_FAIL; lResult = CreateApplication(lProgID, &lOfficeAppResult); ATLASSERT(SUCCEEDED(lResult) && lOfficeAppResult); if (FAILED(lResult) || (lOfficeAppResult == NULL)) return OFFICECONVERTER_E_APPLICATION_CREATION_FAILED; m_OfficeAppDriver = lOfficeAppResult; CComVariant lInitialVisibleState; lResult = m_OfficeAppDriver.GetPropertyByName(L"Visible", &lInitialVisibleState); ATLASSERT(SUCCEEDED(lResult)); if (SUCCEEDED(lResult)) { m_InitialVisibleState = lInitialVisibleState; } // Set the show State CComVariant lVisible(GetVisible()); lResult = m_OfficeAppDriver.PutPropertyByName(L"Visible", &lVisible); ATLASSERT(SUCCEEDED(lResult)); return S_OK; } HRESULT UninitializeOfficeAppDriver() { // Let's be sure we quit properly the office app if (m_OfficeAppDriver == NULL) return S_OK; HRESULT lResult = S_OK; CComVariant lInitialVisibleState; if ( (GetInitialVisibleStateForQuitHandling(&lInitialVisibleState) == E_NOTIMPL) || (lInitialVisibleState.bVal == CComVariant(VARIANT_FALSE).bVal) ) { lResult = m_OfficeAppDriver.Invoke0(L"Quit"); ATLASSERT(SUCCEEDED(lResult)); if (!SUCCEEDED(lResult)) { CComBSTR lAppName; GetCurrentVersionFullAppName(&lAppName); TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, _T("Error (0x%1!x!) when quitting the [%2] application"), lResult, (CString(lAppName).IsEmpty()?_T("??"):CString(lAppName))); } } m_OfficeAppDriver.Release(); return lResult; } HRESULT OnPostProcessDocument_RemoveConditionalComments(LPDISPATCH pDisp, CString pBufferIn, CString& pBufferOut) { if (GetCurrentVersion() <= 8) return E_NOTIMPL; CComDispatchDriver lDocumentDriver(pDisp); HRESULT lResult; CString lBufferIn = pBufferIn; CString lBufferOut; int lBufferInCopyFromPos = 0; TIEConditionalCommentsCollection* lCollection = NULL; TIEConditionalCommentsParser lParser; lResult = lParser.setStringToParse(lBufferIn); if ( lResult == S_OK ) { lResult = lParser.getConditionalComments(&lCollection); if ( (lResult == S_OK) && (lCollection != NULL) ) { TIEConditionalCommentsCollectionIterator* lIterator = lCollection->elements(); while (lIterator && lIterator->hasMoreElements()) { TIEConditionalCommentInfo* lCurCCInfo = (TIEConditionalCommentInfo *)lIterator->nextElement(); if ( lCurCCInfo->fBeginningPattern_stgFeature.CompareNoCase(_T("vml")) == 0 ) { if ( lCurCCInfo->fBeginningPattern_bFeatureVersionComparisonCase ) { // Let's remove the whole Conditional Comment block int lCCBlock_BeginPos = lCurCCInfo->fHeader_nBeginPos; int lCCBlock_EndPos = lCurCCInfo->fEndingPattern_nEndPos; lBufferOut += lBufferIn.Mid(lBufferInCopyFromPos,lCCBlock_BeginPos-lBufferInCopyFromPos); lBufferInCopyFromPos = lCCBlock_EndPos; } else if ( lCurCCInfo->fBeginningPattern_bFeaturePresenceCase && lCurCCInfo->fBeginningPattern_bFeaturePresenceCase_Negation ) { // Let's just remove the Conditional Comment tags int lCCBeginTag_BeginPos = lCurCCInfo->fHeader_nBeginPos; int lCCBeginTag_EndPos = lCurCCInfo->fBeginningPattern_nEndPos; int lCCEndTag_BeginPos = lCurCCInfo->fEndingPattern_nBeginPos; int lCCEndTag_EndPos = lCurCCInfo->fEndingPattern_nEndPos; lBufferOut += lBufferIn.Mid(lBufferInCopyFromPos,lCCBeginTag_BeginPos-lBufferInCopyFromPos); lBufferOut += lBufferIn.Mid(lCCBeginTag_EndPos,lCCEndTag_BeginPos-lCCBeginTag_EndPos); lBufferInCopyFromPos = lCCEndTag_EndPos; } } } delete lIterator; } } delete lCollection; lBufferOut += lBufferIn.Mid(lBufferInCopyFromPos); pBufferOut = lBufferOut; return S_OK; } HRESULT OnPostProcessDocument_RemoveXmlNamespaces(LPDISPATCH pDisp, CString pBufferIn, CString& pBufferOut) { if (GetCurrentVersion() <= 8) return E_NOTIMPL; CComDispatchDriver lDocumentDriver(pDisp); CString lBufferIn = pBufferIn; // We do not want any XML namespace specification global to the document to be kept // because it causes problems when displayed on Netscape... // For instance, we want to remove the string below: // xmlns:v="urn:schemas-microsoft-com:vml" CString lBufferIn_lowerCase = lBufferIn; lBufferIn_lowerCase.MakeLower(); CString lPattern_FirstMatchingPattern( _T("xmlns:") ); // *** Detection of the Global XML Namespace Definition beginning pattern *** // State Diagram: s=="xmlns:" --> E1 // E1 --> E2 (s=="[A-Za-z0-9]") // E2 --> E2 (s=="[A-Za-z0-9]*") // E2 --> E3 (s==" ") // E2 --> E4 (s=="=") // E3 --> E3 (s==" ") // E3 --> E4 (s=="=") // E4 --> E4 (s==" ") // E4 --> E_OK (s=="\"") // Error State: E_FAIL enum eStatesDiagram { E_STATE_E1, E_STATE_E2, E_STATE_E3, E_STATE_E4, E_STATE_E_OK, E_STATE_E_FAIL, }; int lSearchPos = 0; BOOL bSearchOver = FALSE; while (!bSearchOver) { int lPattern_BeginPos = -1; int lPattern_EndPos = -1; int lFoundPos = lBufferIn_lowerCase.Find( lPattern_FirstMatchingPattern , lSearchPos ); if (lFoundPos != -1) { lPattern_BeginPos = lFoundPos; int lCurPos = lFoundPos; lCurPos += lPattern_FirstMatchingPattern.GetLength(); eStatesDiagram lCurrentEngineState = E_STATE_E1; while ( (lCurrentEngineState != E_STATE_E_OK) && (lCurrentEngineState != E_STATE_E_FAIL) ) { TCHAR lCurChar = lBufferIn_lowerCase.GetAt(lCurPos); switch (lCurrentEngineState) { case E_STATE_E1: { if ( _istalnum( lCurChar ) != 0 ) { lCurrentEngineState = E_STATE_E2; lCurPos++; } else lCurrentEngineState = E_STATE_E_FAIL; // Error break; } case E_STATE_E2: { if ( _istalnum( lCurChar ) != 0 ) { lCurrentEngineState = E_STATE_E2; lCurPos++; } else if ( lCurChar == _T(' ') ) { lCurrentEngineState = E_STATE_E3; lCurPos++; } else if ( lCurChar == _T('=') ) { lCurrentEngineState = E_STATE_E4; lCurPos++; } else lCurrentEngineState = E_STATE_E_FAIL; // Error break; } case E_STATE_E3: { if ( lCurChar == _T(' ') ) { lCurrentEngineState = E_STATE_E3; lCurPos++; } else if ( lCurChar == _T('=') ) { lCurrentEngineState = E_STATE_E4; lCurPos++; } else lCurrentEngineState = E_STATE_E_FAIL; // Error break; } case E_STATE_E4: { if ( lCurChar == _T(' ') ) { lCurrentEngineState = E_STATE_E4; lCurPos++; } else if ( lCurChar == _T('\"') ) { lCurrentEngineState = E_STATE_E_OK; lCurPos++; lPattern_EndPos = lCurPos; } else lCurrentEngineState = E_STATE_E_FAIL; // Error break; } default: { // Error lCurrentEngineState = E_STATE_E_FAIL; } } } if (lCurrentEngineState == E_STATE_E_OK) { // Success // Here I've got something like xmlns:v=" // Therefore I must find the ending double-quote and do deletions int lEndDoubleQuotePos = lBufferIn_lowerCase.Find( _T("\"") , lPattern_EndPos ); if ( lEndDoubleQuotePos != -1 ) { lBufferIn_lowerCase.Delete( lPattern_BeginPos , (lEndDoubleQuotePos + 1) - lPattern_BeginPos ); lBufferIn.Delete( lPattern_BeginPos , (lEndDoubleQuotePos + 1) - lPattern_BeginPos ); } lSearchPos = 0; } else { lSearchPos += lPattern_FirstMatchingPattern.GetLength(); } } else { bSearchOver = TRUE; } } pBufferOut = lBufferIn; return S_OK; } protected: CComBSTR m_From; CComBSTR m_To; TStringArray m_ExportedFilesList; CComVariant m_lSaveAsConvertFormat; CComVariant m_InitialVisibleState; // m_OfficeAppDriver is initialized by calling InitializeOfficeAppDriver() // You should always check m_OfficeAppDriver (in fact m_OfficeAppDriver.p) to see if it has been initialized // before using it CComDispatchDriver m_OfficeAppDriver; }; /********************************/ /***** class TWordConverter *****/ /********************************/ class TWordConverter : public TOfficeConverter { public: TWordConverter(); ~TWordConverter(); virtual HRESULT Convert(); virtual HRESULT GetSaveAsConvertFormat(DWORD* pFormatResult); virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime); virtual HRESULT OnOpen(LPDISPATCH pDisp, VARIANT* pResult); virtual HRESULT OnSave(LPDISPATCH pDisp); virtual HRESULT OnClose(LPDISPATCH pDisp); virtual HRESULT OnPostProcessDocument(LPDISPATCH pDisp); virtual HRESULT DisableAlerts(); }; /*************************************/ /***** class TWordImageConverter *****/ /*************************************/ class TWordImageConverter : public TWordConverter { public: TWordImageConverter(); virtual HRESULT OnOpen(LPDISPATCH pDisp, VARIANT* pResult); virtual HRESULT OnEnumerateGeneratedFiles(LPDISPATCH pDisp); virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime); protected: CComBSTR m_ConvertedImageMime; }; /*********************************/ /***** class TExcelConverter *****/ /*********************************/ class TExcelConverter : public TOfficeConverter { public: TExcelConverter(); virtual HRESULT Convert(); virtual HRESULT GetSaveAsConvertFormat(DWORD* pFormatResult); virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime); virtual HRESULT OnOpen(LPDISPATCH pDisp, VARIANT* pResult); virtual HRESULT OnSave(LPDISPATCH pDisp); virtual HRESULT OnClose(LPDISPATCH pDisp); virtual HRESULT OnPostProcessDocument(LPDISPATCH pDisp); virtual HRESULT DisableAlerts(); protected: HRESULT CreateRedimOneDimArray(VARIANT& varSrc, DWORD dwSize); HRESULT GetOneDimArrayElemCount(VARIANT& varSrc, long* dwSize); HRESULT DestroyOneDimArray(VARIANT& varSrc); HRESULT OnSave_Excel2000(LPDISPATCH pDisp); HRESULT OnSave_Excel97(LPDISPATCH pDisp); }; /**************************************/ /***** class TPowerPointConverter *****/ /**************************************/ class TPowerPointConverter : public TOfficeConverter { public: TPowerPointConverter(); virtual HRESULT Convert(); virtual HRESULT GetSaveAsConvertFormat(DWORD* pFormatResult); virtual HRESULT GetConvertedDocumentMime(BSTR* pResMime); virtual HRESULT OnOpen(LPDISPATCH pDisp, VARIANT* pResult); virtual HRESULT OnSave(LPDISPATCH pDisp); virtual HRESULT OnClose(LPDISPATCH); virtual HRESULT OnPostProcessDocument(LPDISPATCH pDisp); virtual bool GetVisible() { if (GetCurrentVersion() < 10) return true; return false; } }; #endif // _T_Office_Converter_h_ /*------------ TOfficeHelper.cpp ------------*/ #include "stdafx.h" // MAIN INCLUDE #include "TOfficeHelper.h" // OTHER INCLUDES #include "TPath.h" #include "TStringArray.h" #include "TRegKey.h" #include "TSystemMimeHelper.h" #include "TOfficeImportMimeHelper.h" #include "TErr.h" /*******************************/ /***** class TOfficeHelper *****/ /*******************************/ TOfficeHelper::TOfficeHelper(LPCTSTR pAppName) : m_AppName(pAppName), m_dwVersion(0) { // Init IsInstalled(); } BOOL TOfficeHelper::IsInstalled(BSTR* pVersion) { return GetCurrentVersion(m_AppName + _T(".Application"), pVersion); } HRESULT TOfficeHelper::CanExportToHTML(BSTR pMime) { // Use specialized office helpers instead ASSERT(FALSE); return E_FAIL; } HRESULT TOfficeHelper::GetApplicationProgID(BSTR* pProgIDResult) { // Use specialized office helpers instead ASSERT(FALSE); return E_NOTIMPL; } BOOL TOfficeHelper::GetInstallPath(BSTR* pPath) { if (m_InstallPath.IsEmpty()) { HRESULT lResult; HKEY lAppKey; CRegKey lKey; CString lKeyName; lAppKey = GetAppKey(); if (lAppKey == NULL) return FALSE; lResult = lKey.Open(lAppKey, _T("InstallRoot"), KEY_READ); ::RegCloseKey(lAppKey); if (lResult != ERROR_SUCCESS) return FALSE; DWORD lSize = MAX_PATH; lResult = lKey.QueryValue(m_InstallPath.GetBufferSetLength(lSize), _T("Path"), &lSize); m_InstallPath.ReleaseBuffer(); if (lResult != ERROR_SUCCESS) return FALSE; } if (pPath) *pPath = CComBSTR(m_InstallPath).Detach(); return TRUE; } BOOL TOfficeHelper::MinimumVersion(DWORD pVersion) { return GetCurrentVersion() >= pVersion; } DWORD TOfficeHelper::GetCurrentVersion() { if (m_dwVersion == 0 && m_AppName.GetLength()) GetCurrentVersion(m_AppName + _T(".Application"), NULL); return m_dwVersion; } BOOL TOfficeHelper::GetCurrentVersion(LPCTSTR pApp, BSTR* pVersion) { if (m_dwVersion == 0) { CRegKey lKey; if (lKey.Open(HKEY_CLASSES_ROOT, pApp, KEY_READ) != ERROR_SUCCESS) return FALSE; if (lKey.Open(lKey.m_hKey, _T("CurVer"), KEY_READ) != ERROR_SUCCESS) return FALSE; DWORD lSize = 128; if (lKey.QueryValue(m_AppFullName.GetBufferSetLength(lSize), NULL, &lSize) != ERROR_SUCCESS) return FALSE; m_AppFullName.ReleaseBuffer(); m_AppVersion = m_AppFullName.Mid(_tcslen(pApp) + 1); m_dwVersion = atoi(m_AppVersion); } else { if (m_AppVersion.IsEmpty()) { m_AppVersion.Format(_T("%d"), m_dwVersion); } } if (pVersion) *pVersion = CComBSTR(m_AppVersion).Detach(); return TRUE; } BOOL TOfficeHelper::GetCurrentVersionFullAppName(BSTR* pFullAppName) { if (m_AppFullName.IsEmpty()) { if (!GetCurrentVersion(m_AppName + _T(".Application"), NULL)) return FALSE; ASSERT(!m_AppVersion.IsEmpty()); } if (pFullAppName) *pFullAppName = CComBSTR(m_AppFullName).Detach(); return TRUE; } BOOL TOfficeHelper::IsExportGraphicFilterInstalled(LPCTSTR pMime) { BOOL bResult = FALSE; if (CString(pMime).IsEmpty()) return FALSE; CString lKeyPath; lKeyPath = "Software\\Microsoft\\Shared Tools"; CRegKey lKey; HRESULT lResult; lResult = lKey.Open(HKEY_LOCAL_MACHINE, lKeyPath, KEY_READ); if (lResult == ERROR_SUCCESS) { CRegKey lGraphicKey; lResult = lGraphicKey.Open(lKey.m_hKey, _T("Graphics Filters\\Export"), KEY_READ); if (lResult == ERROR_SUCCESS) { TStringArray lResArray; GetExportMimes(lGraphicKey.m_hKey, &lResArray); CString lMime(pMime); lMime.MakeLower(); if ( lResArray.contains(lMime) ) { return TRUE; } } } return bResult; } BOOL TOfficeHelper::IsExportTextConverterInstalled(LPCTSTR pMime) { BOOL bResult = FALSE; if (CString(pMime).IsEmpty()) return FALSE; CString lKeyPath; lKeyPath = "Software\\Microsoft\\Shared Tools"; CRegKey lKey; HRESULT lResult; lResult = lKey.Open(HKEY_LOCAL_MACHINE, lKeyPath, KEY_READ); if (lResult == ERROR_SUCCESS) { CRegKey lTextKey; lResult = lTextKey.Open(lKey.m_hKey, _T("Text Converters\\Export"), KEY_READ); if (lResult == ERROR_SUCCESS) { TStringArray lResArray; GetExportMimes(lTextKey.m_hKey, &lResArray); CString lMime(pMime); lMime.MakeLower(); if ( lResArray.contains(lMime) ) { return TRUE; } } } return bResult; } HKEY TOfficeHelper::GetAppKey() { CRegKey lKey; CString lKeyName; if (m_AppVersion.IsEmpty()) { if (!GetCurrentVersion(m_AppName + _T(".Application"), NULL)) return NULL; ASSERT(!m_AppVersion.IsEmpty()); } lKeyName = _T("Software\\Microsoft\\Office\\") + m_AppVersion + _T(".0\\") + m_AppName; lKey.Open(HKEY_LOCAL_MACHINE, lKeyName, KEY_READ); return lKey.Detach(); } void TOfficeHelper::GetExportMimes(HKEY hKey, TStringArray* pInResArray) { HRESULT lResult = ERROR_SUCCESS; CRegKey lSubKey; DWORD lIndex; CString lKeyName; CString lDefaultValue; TSystemMimeHelper lHelper; for (lIndex = 0; lResult != ERROR_NO_MORE_ITEMS; lIndex++) { DWORD lSize = 128; lResult = ::RegEnumKey(hKey, lIndex, lKeyName.GetBufferSetLength(lSize), lSize); if (lResult == ERROR_SUCCESS) { lResult = lSubKey.Open(hKey, lKeyName, KEY_READ); if (lResult == ERROR_SUCCESS) { CString lExtensions; lResult = lSubKey.QueryValue(lExtensions.GetBufferSetLength(lSize), _T("Extensions"), &lSize); if (lResult == ERROR_SUCCESS) { DWORD lNextExtPos; CString lExt; BOOL lEnd = FALSE; while (!lEnd) { lNextExtPos = lExtensions.Find(' '); if (lNextExtPos != -1) { lExt = lExtensions.Mid(0, lNextExtPos); lExtensions = lExtensions.Mid(lNextExtPos + 1); } else { lExt = lExtensions; lEnd = TRUE; } lHelper.getMimeTypesFromFileExtension(lExt, &pInResArray); } } } } } } TOfficeHelper::E_OFFICE_HELPER TOfficeHelper::GetPreferredExportToHTMLHelper(BSTR pMime) { HRESULT lResult_PowerPoint; HRESULT lResult_Excel; HRESULT lResult_Word; if (!pMime) return E_HELPER_UNKNOWN; TPowerPointHelper lPowerpointHelper; lResult_PowerPoint = lPowerpointHelper.CanExportToHTML(pMime); if (lResult_PowerPoint == S_OK) { return E_HELPER_POWERPOINT; } TExcelHelper lExcelHelper; lResult_Excel = lExcelHelper.CanExportToHTML(pMime); if (lResult_Excel == S_OK) { return E_HELPER_EXCEL; } TWordHelper lWordHelper; lResult_Word = lWordHelper.CanExportToHTML(pMime); if (lResult_Word == S_OK) { return E_HELPER_WORD; } // Error case if (lResult_Excel == OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED) { return E_HELPER_UNKNOWN_EXCEL97_HTMLCONVERTER_MISSING_CASE; } else { return E_HELPER_UNKNOWN; } } HRESULT TOfficeHelper::CreateApplication(LPCWSTR pName, LPDISPATCH* pDisp) { HRESULT lResult; CLSID clsid; lResult = CLSIDFromProgID(pName, &clsid); // Very important: let's other threads and processes do stuffs before we go on // (it allows for instance a closing PowerPoint instance to shutdown properly...) ::Sleep(100); // First method to do it lResult = ::CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void **)pDisp); if (SUCCEEDED(lResult)) return lResult; // Second method to do it !!! BIND_OPTS bo = { sizeof(BIND_OPTS) }; lResult = ::CoGetObject(pName, &bo, IID_IDispatch, (void**)pDisp); if (SUCCEEDED(lResult)) return lResult; // Third method to do it !!! CComPtr lMoniker; CComPtr lApp; lResult = ::CreateClassMoniker(clsid, &lMoniker); if (SUCCEEDED(lResult)) { CComPtr lBindCtx; lResult = ::CreateBindCtx(0, &lBindCtx); if (SUCCEEDED(lResult) && lBindCtx) { // Let's set a deadline for binding operations // *** The code below crashes on SetBindOptions !!! *** /* BIND_OPTS lBindOptions; lBindOptions.cbStruct = sizeof(BIND_OPTS); lResult = lBindCtx->GetBindOptions(&lBindOptions); if ( SUCCEEDED(lResult) ) { lBindOptions.dwTickCountDeadline = 100; lResult = lBindCtx->SetBindOptions(&lBindOptions); } */ // Now, let's try some times to create our application instance for (int ii = 0; ii <= 5; ii++) { lResult = lMoniker->BindToObject(lBindCtx, NULL, IID_IUnknown, (void**)&lApp); if ( SUCCEEDED(lResult) ) { CComQIPtr lFactory(lApp); if (lFactory) { lResult = lFactory->CreateInstance(NULL, IID_IDispatch, (void**)pDisp); if ( SUCCEEDED(lResult) ) { break; } } else { lResult = E_FAIL; } lApp.Release(); } ::Sleep(1000); } } } return lResult; } /*****************************/ /***** class TWordHelper *****/ /*****************************/ CComVariant TWordHelper::m_bWord97HTMLConverterInstalled; TWordHelper::TWordHelper() : TOfficeHelper(_T("Word")) { } HRESULT TWordHelper::CanExportToHTML(BSTR pMime) { ////////// // First, let's see if OFFICE can import such MIME ////////// if (pMime) { TOfficeImportMimeHelper* lMimeHelper = new TOfficeImportMimeHelper(); BOOL bResult = lMimeHelper->isMimeTypeSupported(CString(pMime)); delete lMimeHelper; if (!bResult) return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_SUPPORTED; } ////////// // Then, let's define here which MIMEs we want our WORD app to export to HTML ////////// // In order to simplify things up, let's say that WORD app will be used to export // every MIME that won't get exported by other office apps, namely EXCEL and POWERPOINT if (pMime) { TExcelHelper lExcelHelper; if (lExcelHelper.CanExportToHTML(pMime) == S_OK) return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_HANDLED; TPowerPointHelper lPowerpointHelper; if (lExcelHelper.CanExportToHTML(pMime) == S_OK) return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_HANDLED; } ////////// // Then, let's see if our WORD app is able to export to HTML ////////// // Word 2000 or + if (MinimumVersion(9)) { return S_OK; } // Word 97 if (GetCurrentVersion() == 8) { // Need to check if the HTML File Converter is installed BOOL bHTMLConverterInstalled = FALSE; if ( (m_bWord97HTMLConverterInstalled.vt != VT_EMPTY) ) { bHTMLConverterInstalled = ((m_bWord97HTMLConverterInstalled.boolVal == VARIANT_TRUE)?TRUE:FALSE); } else { HRESULT lResult; CComPtr lWordAppResult; // Create WORD App Object CComBSTR lProgID; lResult = GetApplicationProgID(&lProgID); if (FAILED(lResult)) { m_bWord97HTMLConverterInstalled = VARIANT_FALSE; return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED; } lResult = CreateApplication(lProgID, &lWordAppResult); ATLASSERT(SUCCEEDED(lResult) && lWordAppResult); if (FAILED(lResult) || (lWordAppResult == NULL)) { m_bWord97HTMLConverterInstalled = VARIANT_FALSE; return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED; } CComDispatchDriver lWordAppDriver(lWordAppResult); // Do not show window CComVariant lVisible(VARIANT_FALSE); lResult = lWordAppDriver.PutPropertyByName(L"Visible", &lVisible); CComVariant lFileConvertersResult; lResult = lWordAppDriver.GetPropertyByName(L"FileConverters", &lFileConvertersResult); if (SUCCEEDED(lResult) && lFileConvertersResult.vt == VT_DISPATCH) { CComDispatchDriver lFileConvertersDriver(lFileConvertersResult.pdispVal); CComVariant lFileConvertersCountResult; lResult = lFileConvertersDriver.GetPropertyByName(L"Count", &lFileConvertersCountResult); ATLASSERT(SUCCEEDED(lResult) && lFileConvertersCountResult.vt == VT_I4); if (SUCCEEDED(lResult) && lFileConvertersCountResult.vt == VT_I4) { for (int ii = 1; ii <= lFileConvertersCountResult.iVal; ii++) { CComVariant lCurFileConverterIdx(ii); CComVariant lCurFileConverterResult; lResult = lFileConvertersDriver.Invoke1(L"Item", &lCurFileConverterIdx, &lCurFileConverterResult); if (SUCCEEDED(lResult) && lCurFileConverterResult.vt == VT_DISPATCH) { // Here we have an IFileConverter dispatch CComDispatchDriver lCurFileConverterDriver(lCurFileConverterResult.pdispVal); CComVariant lCurFileConverterClassNameResult; lResult = lCurFileConverterDriver.GetPropertyByName(L"ClassName", &lCurFileConverterClassNameResult); ATLASSERT(SUCCEEDED(lResult) && lCurFileConverterClassNameResult.vt == VT_BSTR); if (SUCCEEDED(lResult) && lCurFileConverterClassNameResult.vt == VT_BSTR) { if (lCurFileConverterClassNameResult.bstrVal && (!wcsicmp(L"HTML", lCurFileConverterClassNameResult.bstrVal))) { bHTMLConverterInstalled = TRUE; break; } } } } } } // Release WORD App Object lResult = lWordAppDriver.Invoke0(L"Quit"); ATLASSERT(SUCCEEDED(lResult)); m_bWord97HTMLConverterInstalled = (bHTMLConverterInstalled?VARIANT_TRUE:VARIANT_FALSE); } if (bHTMLConverterInstalled) return S_OK; else return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED; } // Before Word 97 if (GetCurrentVersion() < 8) return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_APPVERSION_LT_8; return E_FAIL; } HRESULT TWordHelper::GetApplicationProgID(BSTR* pProgIDResult) { if (!pProgIDResult) return E_INVALIDARG; *pProgIDResult = CComBSTR(L"Word.Application").Copy(); return S_OK; } /******************************/ /***** class TExcelHelper *****/ /******************************/ CComVariant TExcelHelper::m_bExcel97HTMLConverterInstalled; TExcelHelper::TExcelHelper() : TOfficeHelper(_T("Excel")) { } HRESULT TExcelHelper::CanExportToHTML(BSTR pMime) { ////////// // First, let's see if OFFICE can import such MIME ////////// if (pMime) { TOfficeImportMimeHelper* lMimeHelper = new TOfficeImportMimeHelper(); BOOL bResult = lMimeHelper->isMimeTypeSupported(CString(pMime)); delete lMimeHelper; if (!bResult) return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_SUPPORTED; } ////////// // Then, let's define here which MIMEs we want our EXCEL app to export to HTML ////////// // Let's only export EXCEL documents through EXCEL if (pMime) { if ( (wcsstr(pMime, L"excel") == NULL) && (wcsstr(pMime, L"xls") == NULL) ) { return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_HANDLED; } } ////////// // Then, let's see if our EXCEL app is able to export to HTML ////////// // Excel 2000 or + if (MinimumVersion(9)) { return S_OK; } // Excel 97 if (GetCurrentVersion() == 8) { // Need to check if the HTML File Converter is installed BOOL bHTMLConverterInstalled = FALSE; if ( (m_bExcel97HTMLConverterInstalled.vt != VT_EMPTY) ) { bHTMLConverterInstalled = ((m_bExcel97HTMLConverterInstalled.boolVal == VARIANT_TRUE)?TRUE:FALSE); } else { BOOL bHeavyCheck = TRUE; // a light check might be enough??? if (bHeavyCheck) { ////////// // HEAVY CHECK: We will create an EXCEL app and ask it if the "html.xla" addin is installed ////////// HRESULT lResult; CComPtr lExcelAppResult; // Create EXCEL App Object CComBSTR lProgID; lResult = GetApplicationProgID(&lProgID); if (FAILED(lResult)) { m_bExcel97HTMLConverterInstalled = VARIANT_FALSE; return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED; } lResult = CreateApplication(lProgID, &lExcelAppResult); ATLASSERT(SUCCEEDED(lResult) && lExcelAppResult); if (FAILED(lResult) || (lExcelAppResult == NULL)) { m_bExcel97HTMLConverterInstalled = VARIANT_FALSE; return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED; } CComDispatchDriver lExcelAppDriver(lExcelAppResult); // Do not show window CComVariant lVisible(VARIANT_FALSE); lResult = lExcelAppDriver.PutPropertyByName(L"Visible", &lVisible); CComVariant lAppAddInsResult; lResult = lExcelAppDriver.GetPropertyByName(L"AddIns", &lAppAddInsResult); ATLASSERT(SUCCEEDED(lResult) && lAppAddInsResult.vt == VT_DISPATCH); if (!(SUCCEEDED(lResult) && lAppAddInsResult.vt == VT_DISPATCH)) { // Release EXCEL App Object lResult = lExcelAppDriver.Invoke0(L"Quit"); ATLASSERT(SUCCEEDED(lResult)); m_bExcel97HTMLConverterInstalled = VARIANT_FALSE; return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED; } CComDispatchDriver lAppAddInsDriver(lAppAddInsResult.pdispVal); long lDispId_AddIns_Item; lResult = lAppAddInsDriver.GetIDOfName(L"Item", &lDispId_AddIns_Item); if (!SUCCEEDED(lResult)) { // Release EXCEL App Object lResult = lExcelAppDriver.Invoke0(L"Quit"); ATLASSERT(SUCCEEDED(lResult)); m_bExcel97HTMLConverterInstalled = VARIANT_FALSE; return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED; } CComVariant lAddInsCountResult; lResult = lAppAddInsDriver.GetPropertyByName(L"Count", &lAddInsCountResult); ATLASSERT(SUCCEEDED(lResult) && lAddInsCountResult.vt == VT_I4); if (SUCCEEDED(lResult) && lAddInsCountResult.vt == VT_I4) { for (int ii = 1; ii <= lAddInsCountResult.iVal; ii++) { CComVariant lCurAddInResult; { CComVariant varArgs_param1(ii); CComVariant varArgs[1] = { varArgs_param1 }; DISPPARAMS dispparams = { &varArgs[0], NULL, 1, 0}; lResult = ((IDispatch *)lAppAddInsDriver)->Invoke( lDispId_AddIns_Item, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &lCurAddInResult, NULL, NULL); } ATLASSERT(SUCCEEDED(lResult) && lCurAddInResult.vt == VT_DISPATCH); if (SUCCEEDED(lResult) && lCurAddInResult.vt == VT_DISPATCH) { // Here we have an IAddIn dispatch CComDispatchDriver lAppAddInDriver(lCurAddInResult.pdispVal); CComVariant lAddInFileNameResult; lResult = lAppAddInDriver.GetPropertyByName(L"Name", &lAddInFileNameResult); ATLASSERT(SUCCEEDED(lResult) && lAddInFileNameResult.vt == VT_BSTR); if (SUCCEEDED(lResult) && lAddInFileNameResult.vt == VT_BSTR) { if (lAddInFileNameResult.bstrVal && (!wcsicmp(L"HTML.XLA", lAddInFileNameResult.bstrVal))) { bHTMLConverterInstalled = TRUE; break; } } } } } // Release EXCEL App Object lResult = lExcelAppDriver.Invoke0(L"Quit"); ATLASSERT(SUCCEEDED(lResult)); } else // !bHeavyCheck { ////////// // LIGHT CHECK: We will simply search on our hard-drive if the "html.xla" file is present ////////// if ( GetInstallPath() ) { // This way, we do not rely upon some folder name not even published in the registry... CString lHtmlXlaFilePath; BOOL bFound = TPath::SearchFilePath(m_InstallPath,_T("html.xla"),lHtmlXlaFilePath); if (bFound) { bHTMLConverterInstalled = TRUE; } } } m_bExcel97HTMLConverterInstalled = (bHTMLConverterInstalled?VARIANT_TRUE:VARIANT_FALSE); } if (bHTMLConverterInstalled) return S_OK; else return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED; } // Before Excel 97 if (GetCurrentVersion() < 8) return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_APPVERSION_LT_8; return E_FAIL; } HRESULT TExcelHelper::GetApplicationProgID(BSTR* pProgIDResult) { if (!pProgIDResult) return E_INVALIDARG; *pProgIDResult = CComBSTR(L"Excel.Application").Copy(); return S_OK; } /***********************************/ /***** class TPowerPointHelper *****/ /***********************************/ CComVariant TPowerPointHelper::m_bPowerpoint97WebGraphicConverterInstalled; TPowerPointHelper::TPowerPointHelper() : TOfficeHelper(_T("PowerPoint")) { } HRESULT TPowerPointHelper::GetApplicationProgID(BSTR* pProgIDResult) { if (!pProgIDResult) return E_INVALIDARG; *pProgIDResult = CComBSTR(L"PowerPoint.Application").Copy(); return S_OK; } HRESULT TPowerPointHelper::CanExportToHTML(BSTR pMime) { ////////// // First, let's see if OFFICE can import such MIME ////////// if (pMime) { TOfficeImportMimeHelper* lMimeHelper = new TOfficeImportMimeHelper(); BOOL bResult = lMimeHelper->isMimeTypeSupported(CString(pMime)); delete lMimeHelper; if (!bResult) return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_SUPPORTED; } ////////// // Then, let's define here which MIMEs we want our POWERPOINT app to export to HTML ////////// // Let's only export POWERPOINT documents through POWERPOINT if (pMime) { if ( wcsstr(pMime, L"powerpoint") == NULL ) { return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_MIME_NOT_HANDLED; } } ////////// // Then, let's see if our POWERPOINT app is able to export to HTML ////////// // Powerpoint 2000 or + if (MinimumVersion(9)) { return S_OK; } // Powerpoint 97 if (GetCurrentVersion() == 8) { // Need to check if a web graphic format converter is installed BOOL bWebGraphicConverterInstalled = FALSE; if ( (m_bPowerpoint97WebGraphicConverterInstalled.vt != VT_EMPTY) ) { bWebGraphicConverterInstalled = ((m_bPowerpoint97WebGraphicConverterInstalled.boolVal == VARIANT_TRUE)?TRUE:FALSE); } else { bWebGraphicConverterInstalled = IsExportGraphicFilterInstalled(_T("image/gif")); if (!bWebGraphicConverterInstalled) bWebGraphicConverterInstalled = IsExportGraphicFilterInstalled(_T("image/jpeg")); m_bPowerpoint97WebGraphicConverterInstalled = (bWebGraphicConverterInstalled?VARIANT_TRUE:VARIANT_FALSE); } if (bWebGraphicConverterInstalled) return S_OK; else return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_HTML_CONVERTER_NOT_INSTALLED; } // Before Powerpoint 97 if (GetCurrentVersion() < 8) return OFFICEHELPER_E_CANEXPORTTOHTML_FAILED_APPVERSION_LT_8; return E_FAIL; } /*------------ TOfficeToHTMLExportEngine.cpp ------------*/ #include "StdAfx.h" #include "Cache.h" #include "TNetHelpers.h" #include "TUrl.h" #include "TOfficeToHTMLExportEngine.h" #include "TOfficeConverter.h" #include "TOfficeHelper.h" #include "TPath.h" #include "TSystemInfo.h" #include "TOfficeImportMimeHelper.h" TOfficeToHTMLExportEngine::TOfficeToHTMLExportEngine(LPCWSTR pMime) { m_InMime = pMime; } TOfficeToHTMLExportEngine::~TOfficeToHTMLExportEngine() { } HRESULT TOfficeToHTMLExportEngine::Initialize() { return E_NOTIMPL; } HRESULT TOfficeToHTMLExportEngine::Uninitialize() { return E_NOTIMPL; } HRESULT TOfficeToHTMLExportEngine::export(LPCTSTR inFileName, LPCTSTR outFileName, LPCTSTR inFileURL) { HRESULT lResult = E_FAIL; TOfficeHelper::E_OFFICE_HELPER lPreferredOfficeApp = TOfficeHelper::GetPreferredExportToHTMLHelper(m_InMime); if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_UNKNOWN_EXCEL97_HTMLCONVERTER_MISSING_CASE) { return EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME_EXCEL97_HTMLCONVERTER_MISSING_CASE; } else if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_UNKNOWN) { return EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME; } TOfficeImportMimeHelper* lHelper; LPCTSTR lExtension; lExtension = ::PathFindExtension(outFileName); if (*lExtension == 0) lExtension = ::PathFindExtension(inFileName); if (*lExtension == 0) lExtension = ::PathFindExtension(inFileURL); lHelper = new TOfficeImportMimeHelper(); if (!lHelper->isExtensionSupported(lExtension)) { delete lHelper; return EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_EXTENSION; } delete lHelper; // We will generate our converted files to a temporary folder at first // Therefore, let's create a temporary folder... CString lTmpOutFilePath; { CString lTempPath; TPath::CreateNewDirectoryPath(TSystemInfo::GetTempPath(),lTempPath); TPath::CreateDirectory(lTempPath); CString lTmpOutFileName; lTmpOutFileName = ::PathFindFileName(outFileName); lTmpOutFilePath = lTempPath; TPath lPath(lTmpOutFilePath); lPath.AddPath(lTmpOutFileName); } // Then, let's instantiate the right converter and do conversion TStringArray lGeneratedFilesList; CComBSTR bstrOfficeConverterFullName; BOOL lIsImage = FALSE; if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_WORD) { lIsImage = !wcsnicmp(m_InMime, L"image/", 6); // Special case for encapsuleted postscript if (!wcsicmp(m_InMime, L"application/postscript")) { if (!_tcscmp(lExtension, ".eps")) lIsImage = TRUE; } if (lIsImage) { TWordImageConverter lConverter; lConverter.GetCurrentVersionFullAppName(&bstrOfficeConverterFullName); lConverter.SetSource(inFileName); lConverter.SetTarget(lTmpOutFilePath); lResult = lConverter.Convert(); if (SUCCEEDED(lResult)) { lConverter.GetExportedFilesList(lGeneratedFilesList); lConverter.GetConvertedDocumentMime(&m_OutMime); } } else { TWordConverter lConverter; lConverter.GetCurrentVersionFullAppName(&bstrOfficeConverterFullName); lConverter.SetSource(inFileName); lConverter.SetTarget(lTmpOutFilePath); lResult = lConverter.Convert(); if (SUCCEEDED(lResult)) { lConverter.GetExportedFilesList(lGeneratedFilesList); lConverter.GetConvertedDocumentMime(&m_OutMime); } } } else if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_EXCEL) { TExcelConverter lConverter; lConverter.GetCurrentVersionFullAppName(&bstrOfficeConverterFullName); lConverter.SetSource(inFileName); lConverter.SetTarget(lTmpOutFilePath); lResult = lConverter.Convert(); if (SUCCEEDED(lResult)) { lConverter.GetExportedFilesList(lGeneratedFilesList); lConverter.GetConvertedDocumentMime(&m_OutMime); } } else if (lPreferredOfficeApp == TOfficeHelper::E_HELPER_POWERPOINT) { TPowerPointConverter lConverter; lConverter.GetCurrentVersionFullAppName(&bstrOfficeConverterFullName); lConverter.SetSource(inFileName); lConverter.SetTarget(lTmpOutFilePath); lResult = lConverter.Convert(); if (SUCCEEDED(lResult)) { lConverter.GetExportedFilesList(lGeneratedFilesList); ATLASSERT(lGeneratedFilesList.size() > 0); lConverter.GetConvertedDocumentMime(&m_OutMime); } } else { return EXPORTENGINE_E_MICROSOFT_OFFICE_CONVERTER_NOT_IMPLEMENTED; } m_OfficeConverterFullName = CString(bstrOfficeConverterFullName); if (SUCCEEDED(lResult) && lGeneratedFilesList.size() == 0) { lResult = EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME; } if (SUCCEEDED(lResult)) { // I'm gonna move every file to its final destination // and I'll add every sub-file of the main outfile to our cache CString lOutFileFolderPath(outFileName); TPath::RemoveFileSpec(lOutFileFolderPath); CString lTmpOutFileName; TPath::FindFileName(lTmpOutFilePath,lTmpOutFileName); CString lTmpOutFileFolderPath; // The folder where the lTmpOutFilePath has actually been generated { for (int ii = 0; ii < lGeneratedFilesList.size(); ii++) { CString lCurGeneratedFile = lGeneratedFilesList.elementAt(ii); CString lCurFileName; TPath::FindFileName(lCurGeneratedFile,lCurFileName); if (lTmpOutFileName.CompareNoCase(lCurFileName) == 0) { lTmpOutFileFolderPath = lCurGeneratedFile; TPath::RemoveFileSpec(lTmpOutFileFolderPath); break; } } } ASSERT(!lTmpOutFileFolderPath.IsEmpty()); for (int ii = 0; ii < lGeneratedFilesList.size(); ii++) { CString lCurGeneratedFile = lGeneratedFilesList.elementAt(ii); CString lCurFileName; TPath::FindFileName(lCurGeneratedFile,lCurFileName); CString lCurRelativeFilePath; BOOL bResRelative = TPath::GetRelativeFilePath(lTmpOutFileFolderPath, lCurGeneratedFile, lCurRelativeFilePath); if (bResRelative) { if (lTmpOutFileName.CompareNoCase(lCurFileName) == 0) { CString lCurNewFilePath(lOutFileFolderPath); TPath lPath(lCurNewFilePath); lPath.AddPath(lCurFileName); // Just to be sure the folder exists CString lDestFolder(lCurNewFilePath); TPath::RemoveFileSpec(lDestFolder); TPath::CreateDirectory(lDestFolder); TRY { CFile::Rename(lCurGeneratedFile,lCurNewFilePath); } CATCH (CFileException, cfe) { } END_CATCH } else { CComPtr lFilterCache; // Try to create the filter cache if (lFilterCache == NULL && FAILED(GetCache(T_FILTER_CACHE_NAME, &lFilterCache))) continue; CComPtr lCacheEntry; // Create new URL TUrl lUrl(inFileURL); lUrl.CombineUrl(lCurRelativeFilePath); // Create Cache entry CComBSTR bstr_nonExportedFileURL = lUrl.extendedUrlString(); lResult = lFilterCache->createEntry(bstr_nonExportedFileURL, &lCacheEntry); // Get Cache file name CComBSTR bstr_lFileName; lCacheEntry->getFileName(&bstr_lFileName); // Move file to cache file // and add to list TRY { CFile::Rename(lCurGeneratedFile,CString(bstr_lFileName)); } CATCH (CFileException, cfe) { } END_CATCH // validate cache entry, so that it can be saved and used lCacheEntry->commit(); } } } } else { switch (lResult) { case OFFICECONVERTER_E_APPLICATION_CREATION_FAILED: { lResult = EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_CREATION_FAILED; break; } case OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED: { lResult = EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED; break; } case OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED: { lResult = EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED; break; } case OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED: { lResult = EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED; break; } case OFFICECONVERTER_E_APPLICATION_ENUMERATE_GENERATED_FILES_FAILED: { lResult = EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME; break; } default: { lResult = EXPORTENGINE_E_OFFICECONVERTER_GENERIC_ERROR; } } } if (!lTmpOutFilePath.IsEmpty()) { CString lTmpOutDirPath(lTmpOutFilePath); TPath::RemoveFileSpec(lTmpOutDirPath); TPath::RemoveDirectory(lTmpOutDirPath); } if ( SUCCEEDED(lResult) && lIsImage ) { // We return a special success value to avoid caller to check mime type // (and maybe in case lIsImage is not equivalent to 'image/...' mime type???) return EXPORTENGINE_S_PICTURE_RESULT; } return lResult; } TString TOfficeToHTMLExportEngine::getExportedMime() { if (m_OutMime.Length() > 0) { return CString(m_OutMime); } else { // default return value return _T("text/html"); } } TString TOfficeToHTMLExportEngine::getOfficeConverterFullName() { return CString(m_OfficeConverterFullName); } /*------------ TOfficeToHTMLExportEngine.h ------------*/ #ifndef T_OFFICE_TO_HTML_EXPORT_ENGINE #define T_OFFICE_TO_HTML_EXPORT_ENGINE // INCLUDES #include "TExportEngine.h" #include "TString.h" #include "TLocker.h" #include "TPtrArray.h" // CLASS IMPORTS /*************************************/ /** class TOfficeToHTMLExportEngine **/ /*************************************/ class TOfficeToHTMLExportEngine : public TExportEngine { // CONSTRUCTORS public: TOfficeToHTMLExportEngine(LPCWSTR pMime = NULL); //default virtual ~TOfficeToHTMLExportEngine(); // METHODS public: virtual HRESULT Initialize(); virtual HRESULT Uninitialize(); virtual HRESULT export(LPCTSTR inFileName, LPCTSTR outFileName, LPCTSTR inFileURL); virtual TString getExportedMime(); TString getOfficeConverterFullName(); protected: CComBSTR m_InMime; CComBSTR m_OutMime; CComBSTR m_OfficeConverterFullName; }; // class TOfficeToHTMLExportEngine #endif // T_HTML_EXPORT_ENGINE /*------------ TSOfficeMimeFilter.cpp ------------*/ // MAIN INCLUDE #include "stdafx.h" #include "TSOfficeMimeFilter.h" // OTHER INCLUDES #include "TFilterGlobals.h" #include "TOfficeToHTMLExportEngine.h" // Cache Stuff #include "TNetHelpers.h" #include "TUrl.h" #include "atlconv.h" #include "FilterResource.h" #include "SharedResource.h" #include "TLanguage.h" #include "TSystemMimeHelper.h" #include "THtmlString.h" #include "TSystemInfo.h" #include "TPath.h" #include "TSevenixUrlInfo.h" #include "Shlwapi.h" // DEBUG DEFINES //#define DEBUG_MIME_FILTER #ifndef RT_HTML #define RT_HTML MAKEINTRESOURCE(23) #endif ///////////////////// extern HINSTANCE g_hDllMain; ///////////////////////////////////////////////////////////////////////////// // TSevenixOfficeMimeFilter HRESULT TSevenixOfficeMimeFilter::FinalConstruct() { TRACE(_T("TSevenixOfficeMimeFilter::FinalConstruct\n")); // Initialize personnal data fReportDataSFalseOccurred = false; fExporterActive = true; fExportedFile = null; fNonExportedFile = null; fNonExportedFileCached = false; fExportSucceeded = false; fReadSFalseOccurred = false; m_ReportDataReadState = 0; m_ReadState = 0; m_DocSize = 0; m_CurrentRead = 0; m_IsLocked = FALSE; m_IsTerminate = FALSE; m_HandleError = FALSE; m_Redirecting = FALSE; m_HaveAbort = FALSE; m_RootDocument = FALSE; m_CanReload = TRUE; m_IsSearch = FALSE; return S_OK; } void TSevenixOfficeMimeFilter::FinalRelease() { TRACE(_T("TSevenixOfficeMimeFilter::FinalRelease\n")); if (m_SupBindInfo) m_SupBindInfo.Release(); if (m_SupSink) m_SupSink.Release(); if (fProtocolProxy) fProtocolProxy.Release(); fCacheEntry = NULL; } // ******************************************************************************** // IInternetProtocolRoot HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Start( /* [in] */ LPCWSTR szMime, /* [in] */ IInternetProtocolSink __RPC_FAR *pOIProtSink, /* [in] */ IInternetBindInfo __RPC_FAR *pOIBindInfo, /* [in] */ DWORD grfPI, /* [in] */ DWORD dwReserved) { TRACE(_T("TSevenixOfficeMimeFilter::Start\n")); USES_CONVERSION; HRESULT lResult = S_OK; // Initialization PROTOCOLFILTERDATA* pfd = (PROTOCOLFILTERDATA *)dwReserved; BINDINFO lBi; lBi.cbSize = sizeof(BINDINFO); DWORD pBindf; HRESULT bindRes = pOIBindInfo->GetBindInfo(&pBindf,&lBi); ATLASSERT(SUCCEEDED(bindRes)); fProtocolProxy = pfd->pProtocol; m_SupSink = pOIProtSink; m_SupBindInfo = pOIBindInfo; ASSERT(fProtocolProxy); ASSERT(m_SupSink); ASSERT(m_SupBindInfo); fExportedFile = null; fNonExportedFile = null; fNonExportedFileCached = false; fExportSucceeded = false; fReadSFalseOccurred = false; fExporterActive = true; m_SourceMime = szMime; return lResult; } HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Continue( /* [in] */ PROTOCOLDATA __RPC_FAR *pMimeFilterData) { TRACE(_T("TSevenixOfficeMimeFilter::Continue\n")); HRESULT lResult = S_OK; if (fProtocolProxy != NULL) lResult = fProtocolProxy->Continue(pMimeFilterData); return lResult; } HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Abort( /* [in] */ HRESULT hrReason, /* [in] */ DWORD dwOptions) { TRACE(_T("TSevenixOfficeMimeFilter::Abort\n")); HRESULT lResult = S_OK; // Proxy the call if (fProtocolProxy != NULL) { lResult = fProtocolProxy->Abort(hrReason, dwOptions); } m_HaveAbort = TRUE; return lResult; } HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Terminate( /* [in] */ DWORD dwOptions) { TRACE(_T("TSevenixOfficeMimeFilter::Terminate\n")); HRESULT lResult = S_OK; // proxy call if (fProtocolProxy != NULL) { lResult = fProtocolProxy->Terminate(dwOptions); } if (!m_IsLocked) { CloseAll(); ReleaseAll(); } m_IsTerminate = TRUE; return lResult; } HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Suspend( void) { TRACE(_T("TSevenixOfficeMimeFilter::Suspend\n")); HRESULT lResult = S_OK; if (fProtocolProxy != NULL) lResult = fProtocolProxy->Suspend(); return lResult; } HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Resume( void) { TRACE(_T("TSevenixOfficeMimeFilter::Resume\n")); HRESULT lResult = S_OK; if (fExporterActive != NULL) lResult = fProtocolProxy->Resume(); return lResult; } // ******************************************************************************** // IInternetProtocol : public IInternetProtocolRoot HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Read( /* [length_is][size_is][out][in] */ void __RPC_FAR *pv, /* [in] */ ULONG cb, /* [out] */ ULONG __RPC_FAR *pcbRead) { if (m_HandleError || m_Redirecting) { // If the data came from the error handler return ReadFromErrorString(pv, cb, pcbRead); } if (!fExporterActive) return fProtocolProxy->Read(pv,cb,pcbRead); if (!fExportSucceeded) return INET_E_DOWNLOAD_FAILURE; // Here data will be read from exported file if (fReadSFalseOccurred) { // In the case we are called after having returned S_FALSE *pcbRead = 0; return S_FALSE; } if (!fExportedFile) { fExportedFile = new CFile(fExportedFileName, CFile::modeRead | CFile::shareDenyNone); m_DocSize = fExportedFile->GetLength(); } unsigned long dataRead = 0; dataRead = fExportedFile->Read(pv,cb); *pcbRead = (ULONG)dataRead; m_ReadState += dataRead; TRACE(_T("TSevenixOfficeMimeFilter::Read (%d / %d) File (%d / %d)\n"), dataRead, cb, m_ReadState, m_DocSize); if (m_ReadState == m_DocSize) { // The EOF has been reached fReadSFalseOccurred = true; fExportedFile->Close(); return S_FALSE; } return S_OK; } HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::Seek( /* [in] */ LARGE_INTEGER dlibMove, /* [in] */ DWORD dwOrigin, /* [out] */ ULARGE_INTEGER __RPC_FAR *plibNewPosition) { TRACE(_T("TSevenixOfficeMimeFilter::Seek\n")); HRESULT lResult = E_FAIL; if (fExporterActive) { // Could be implementable since we use a plain file to do the export // so we could just Seek in it... Later... lResult = E_FAIL; } else { if (fProtocolProxy) lResult = fProtocolProxy->Seek(dlibMove,dwOrigin,plibNewPosition); } return lResult; } HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::LockRequest( /* [in] */ DWORD dwOptions) { TRACE(_T("TSevenixOfficeMimeFilter::LockRequest\n")); m_IsLocked = TRUE; if (fProtocolProxy != NULL) return fProtocolProxy->LockRequest(dwOptions); return S_OK; } HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::UnlockRequest( void) { TRACE(_T("TSevenixOfficeMimeFilter::UnlockRequest\n")); HRESULT lResult; if (fProtocolProxy != NULL) { lResult = fProtocolProxy->UnlockRequest(); } m_IsLocked = FALSE; if (m_IsTerminate) { CloseAll(); ReleaseAll(); } return lResult = S_OK; } // ******************************************************************************** // IInternetBindInfo HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::GetBindInfo( DWORD __RPC_FAR *grfBINDF, BINDINFO __RPC_FAR *pbindinfo) { // Do we pass here ? TRACE(_T("TSevenixOfficeMimeFilter::GetBindInfo")); // set required flags. *grfBINDF = BINDF_NO_UI | BINDF_SILENTOPERATION; return S_OK; } HRESULT STDMETHODCALLTYPE TSevenixOfficeMimeFilter::GetBindString( ULONG ulStringType, LPOLESTR __RPC_FAR *ppwzStr, ULONG cEl, ULONG __RPC_FAR *pcElFetched) { // Do we pass here ? TRACE(_T("TSevenixOfficeMimeFilter::GetBindString")); // I'm not sure what to do here ??? return S_OK; } // ******************************************************************************** // // // HRESULT TSevenixOfficeMimeFilter::ReadFromErrorString(void *pv, ULONG cb, ULONG *pcbRead) { ASSERT(m_HandleError || m_Redirecting); // Read from error string DWORD lStillToRead = m_ErrorHtmlString.GetLength() - m_CurrentRead; if (lStillToRead == 0) return S_FALSE; // ASSERT(cb <= lStillToRead); LONG lGoingToRead = min(cb, lStillToRead); CString lSubString = m_ErrorHtmlString.Mid(m_CurrentRead, lGoingToRead); memcpy(pv, lSubString.GetBuffer(0), lGoingToRead); lSubString.ReleaseBuffer(); *pcbRead = lGoingToRead; m_CurrentRead += lGoingToRead; return S_OK; } void TSevenixOfficeMimeFilter::CreateNewFile() { if (fNonExportedFile) return ; // I didn't receive the ReportProgress specifying the name // of the cached file. // Either something went wrong with this message, or the url // isn't cached because it is a local file // Let's check if the file is local boolean bLocalFile = false; TString lLocalFilePath(""); ULONG ulCount; LPOLESTR rgwzStr = NULL; // Wide Char HRESULT gbsRes = m_SupBindInfo->GetBindString( BINDSTRING_URL, &rgwzStr, 1, &ulCount); if( gbsRes == S_OK && ulCount == 1) { TUrl lUrl(rgwzStr); if (lUrl.getProtocol().CompareNoCase(_T("file")) == 0) { bLocalFile = true; lLocalFilePath = lUrl.getFile(); } TSevenixUrlInfo* lInfo; lInfo = (TSevenixUrlInfo*)lUrl.getExtendedInfo(); if (lInfo) { if (lInfo->haveProperty(T_NO_RELOAD_PROPERTY)) m_CanReload = FALSE; if (lInfo->haveProperty(T_ROOT_PROPERTY)) m_RootDocument = TRUE; if (lInfo->haveProperty(T_SEARCH_PROPERTY)) m_IsSearch = TRUE; } } /* if (bLocalFile) { // The File is LOCAL, so I don't have to cache it myself // and I can consider it is cached in some way fNonExportedFileName = lLocalFilePath; fNonExportedFileCached = true; } else */ { // The File is NOT LOCAL, and as I haven't receive any 'cached file path' // notification, I have to cache it myself somewhere // We put the copy in the Temp Folder TString filePath; #if defined(_DEBUG) && defined(DEBUG_MIME_FILTER) filePath = TString("d:\\temp\\export\\"); #else filePath = TSystemInfo::GetTempPath(); ASSERT(!filePath.IsEmpty()); #endif CString lExtension; lExtension = ::PathFindExtension(fNonExportedFileName); TPath::CreateRandomFilePath(filePath, NULL, fNonExportedFileName); if (lExtension.IsEmpty()) { USES_CONVERSION; TSystemMimeHelper* lSystemHelper; lSystemHelper = new TSystemMimeHelper(); lSystemHelper->getFirstFileExtensionsFromMimeType(W2CT(m_SourceMime), lExtension); delete lSystemHelper; } if (lExtension.CompareNoCase(_T(".ps")) == 0) { lExtension = _T(".eps"); } fNonExportedFileName += lExtension; fNonExportedFile = new CFile(fNonExportedFileName, CFile::modeCreate | CFile::modeWrite); } } HRESULT TSevenixOfficeMimeFilter::ConvertFile() { LPWSTR lMime = NULL; // do IMPORTANT stuff here HRESULT exportRes = launchExportProcessing(); if (exportRes == S_OK) { CFileStatus lStatus; if (CFile::GetStatus(fExportedFileName, lStatus)) m_DocSize = lStatus.m_size; lMime = m_TargetMime; } // Handle Error if (!m_ErrorHtmlString.IsEmpty()) { m_DocSize = m_ErrorHtmlString.GetLength(); // We simulate that the export succeeded to be able // to display our custom error page fExportSucceeded = true; // Let's set the Mime to HTML lMime = L"text/html"; } if (m_DocSize) { HRESULT lResult; if (lMime) { // Since the output data won't have the same MIME, let's tell the // client which one it'll be lResult = m_SupSink->ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, lMime); // necessary ?? ATLASSERT(SUCCEEDED(lResult)); lResult = m_SupSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, lMime); ATLASSERT(SUCCEEDED(lResult)); // This is used by a pluggable MIME filter to report a change in the MIME type after it // has processed the resource. // This value was added for Internet Explorer 5 lResult = m_SupSink->ReportProgress(BINDSTATUS_FILTERREPORTMIMETYPE, lMime); ATLASSERT(SUCCEEDED(lResult)); } // Let's then report all the data we have lResult = m_SupSink->ReportData(BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE, m_DocSize, m_DocSize); ATLASSERT(SUCCEEDED(lResult)); // At last, we report that everything went right... lResult = m_SupSink->ReportResult(lResult, 0, NULL); return lResult; } // If everything went wrong, we assume a failure at last fExportSucceeded = false; HRESULT repResultRes = m_SupSink->ReportResult(E_FAIL, 0, NULL); return E_FAIL; } // ******************************************************************************** // IInternetProtocolSink HRESULT TSevenixOfficeMimeFilter::ReportData(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) { USES_CONVERSION; TRACE(_T("TSevenixOfficeMimeFilter::ReportData: %d/%d\n"), ulProgress, ulProgressMax); HRESULT lResult; if (fExporterActive) { if (fReportDataSFalseOccurred == TRUE) { // We already did receive a S_FALSE from the underlying protocol's Read() return S_OK; } // FIRST TIME STUFF CreateNewFile(); const unsigned long bufferSize = 4096; TCHAR buffer[bufferSize]; ULONG dataRead = 0; for (;;) { lResult = fProtocolProxy->Read(&buffer,bufferSize,&dataRead); m_ReportDataReadState += dataRead; if (lResult == S_OK) { TRACE(_T("TSevenixOfficeMimeFilter::ReportData -- Read returned S_OK - m_ReportDataReadState: %d\n"), m_ReportDataReadState); if ((dataRead != 0)) { fNonExportedFile->Write(&buffer, dataRead); } } else if (lResult == E_PENDING) { TRACE(_T("TSevenixOfficeMimeFilter::ReportData -- Read returned E_PENDING - m_ReportDataReadState: %d\n"), m_ReportDataReadState); if ((dataRead != 0)) { fNonExportedFile->Write(&buffer, dataRead); } return S_OK; } else if (lResult == S_FALSE) { TRACE(_T("TSevenixOfficeMimeFilter::ReportData -- Read returned S_FALSE - m_ReportDataReadState: %d\n"), m_ReportDataReadState); if ((dataRead != 0)) { fNonExportedFile->Write(&buffer, dataRead); } fNonExportedFile->Flush(); fNonExportedFile->Close(); delete fNonExportedFile; fNonExportedFile = NULL; fReportDataSFalseOccurred = true; lResult = ConvertFile(); ATLASSERT(SUCCEEDED(lResult) || m_IsSearch); return S_OK; } else { // FAILURE TRACE(_T("TSevenixOfficeMimeFilter::ReportData -- Read FAILED\n")); return E_FAIL; } } // If I am here, that means that I have read all the data reported, and // not encountered S_FALSE yet... return S_OK; } else { return m_SupSink->ReportData(grfBSCF,ulProgress,ulProgressMax); } } LONG gExportErrorTranslationTable[] = { EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME, 0, IDR_HTML_MIMEFILTER_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME, EXPORTENGINE_E_MICROSOFT_OFFICE_CONVERTER_NOT_IMPLEMENTED, 0, IDR_HTML_MIMEFILTER_CONVERTER_GENERIC_ERROR/*IDR_HTML_MIMEFILTER_OFFICE_CONVERTER_NOT_IMPLEMENTED*/, EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_CREATION_FAILED, 0, IDR_HTML_MIMEFILTER_CONVERTER_APPLICATION_CREATION_FAILED, EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED, 0, IDR_HTML_MIMEFILTER_CONVERTER_OPEN_DOCUMENT_FAILED, EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED, 0, IDR_HTML_MIMEFILTER_CONVERTER_OPEN_DOCUMENT_FAILED_PASSWORD_PROTECTED, EXPORTENGINE_E_OFFICECONVERTER_E_APPLICATION_SAVE_DOCUMENT_FAILED, 0, IDR_HTML_MIMEFILTER_CONVERTER_SAVE_DOCUMENT_FAILED, EXPORTENGINE_E_OFFICECONVERTER_GENERIC_ERROR, 0, IDR_HTML_MIMEFILTER_CONVERTER_GENERIC_ERROR, EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_EXTENSION, 0, IDR_HTML_MIMEFILTER_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME, EXPORTENGINE_E_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME_EXCEL97_HTMLCONVERTER_MISSING_CASE, 0, IDR_HTML_MIMEFILTER_MICROSOFT_OFFICE_CANNOT_EXPORT_MIME_EXCEL97_HTMLCONVERTER_MISSING_CASE, }; LONG TSevenixOfficeMimeFilter::TranslateError(HRESULT hrResult, DWORD dwError) { for (long lIndex = 0; lIndex < sizeof(gExportErrorTranslationTable) / sizeof(LONG); lIndex += 3) { if (gExportErrorTranslationTable[lIndex] == hrResult) { if ((gExportErrorTranslationTable[lIndex + 1] == 0) || (gExportErrorTranslationTable[lIndex + 1] == dwError)) return gExportErrorTranslationTable[lIndex + 2]; } } return 0; } HRESULT TSevenixOfficeMimeFilter::HandleError(HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { LONG lErrorID; // HRESULT lResult; lErrorID = TranslateError(hrResult, dwError); THTMLString lErrorString; USES_CONVERSION; if (szResult) lErrorString.StdFormat(lErrorID, hrResult, (LPCTSTR)CString(szResult), W2CT(m_SourceMime), m_OfficeConvertingAppFullName); else lErrorString.StdFormat(lErrorID, hrResult, W2CT(m_SourceMime), m_OfficeConvertingAppFullName); m_ErrorHtmlString = lErrorString; m_HandleError = TRUE; return S_OK; } HRESULT TSevenixOfficeMimeFilter::launchExportProcessing() { HRESULT hr = E_FAIL; // Here I need the URL I process in order to create an entry // in the filtered documents cache. CString nonExportedFileURL; ULONG ulCount; LPOLESTR rgwzStr = NULL; // Wide Char HRESULT gbsRes; gbsRes = m_SupBindInfo->GetBindString( BINDSTRING_URL, &rgwzStr, 1, &ulCount); if (gbsRes == S_OK && ulCount == 1) { nonExportedFileURL = rgwzStr; if (!nonExportedFileURL.IsEmpty()) { CComPtr lFilterCache; if ( SUCCEEDED(hr = GetCache(T_FILTER_CACHE_NAME, &lFilterCache)) ) { CComBSTR bstr_nonExportedFileURL = nonExportedFileURL; hr = lFilterCache->createEntry(bstr_nonExportedFileURL, &fCacheEntry); } } } else { // FAILURE // After all, I went down here without problem, so let's just not cache the // file and just export and output it... nonExportedFileURL.Empty(); } if (FAILED(hr) || fCacheEntry == NULL) { TString filePath; filePath = TSystemInfo::GetTempPath(); ASSERT(!filePath.IsEmpty()); TPath::CreateRandomFilePath(filePath, NULL, fExportedFileName); } else { CComBSTR bstr_lFileName; fCacheEntry->getFileName(&bstr_lFileName); fExportedFileName = TString(bstr_lFileName); } HRESULT exportRes; TExportEngine* lEngine; lEngine = new TOfficeToHTMLExportEngine(m_SourceMime); exportRes = lEngine->export(fNonExportedFileName, fExportedFileName, nonExportedFileURL); m_TargetMime = lEngine->getExportedMime(); m_OfficeConvertingAppFullName = ((TOfficeToHTMLExportEngine *)lEngine)->getOfficeConverterFullName(); delete lEngine; if (FAILED(exportRes)) { // FAILURE fExportSucceeded = false; // clean up the cache so that an invalid entry // is not insert if (fCacheEntry) { fCacheEntry->remove(); fCacheEntry = NULL; } if (!m_IsSearch) { HRESULT handleErrorRes = HandleError(exportRes,0,NULL); ATLASSERT(SUCCEEDED(handleErrorRes)); } return E_FAIL; } else { fExportSucceeded = true; // Since the output data won't have the same MIME, let's tell the // client which one it'll be if (fCacheEntry) { fCacheEntry->addHeader(T_HEADER_CONTENT_TYPE, m_TargetMime); // validate cache entry, so that it can be saved and used fCacheEntry->commit(); fCacheEntry = NULL; } // If we should DELETE the entry in the Native Cache, // here should it be done... if ((exportRes == EXPORTENGINE_S_PICTURE_RESULT) && m_RootDocument && m_CanReload) return RedirectingTo(L"internal://neutral/picture.htm"); return S_OK; } } HRESULT TSevenixOfficeMimeFilter::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatusText) { TRACE(_T("TSevenixOfficeMimeFilter::ReportProgress\n")); HRESULT lResult; if (fExporterActive) { if (ulStatusCode == BINDSTATUS_CACHEFILENAMEAVAILABLE) { fNonExportedFileName = szStatusText; fNonExportedFileCached = true; lResult = S_OK; } else if (ulStatusCode == BINDSTATUS_MIMETYPEAVAILABLE) { // We will set the MIME elsewhere lResult = S_OK; } else if (ulStatusCode == BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) { // We will set the Verified MIME elsewhere lResult = S_OK; } else { lResult = S_OK; } } else { lResult = m_SupSink->ReportProgress(ulStatusCode,szStatusText); } return lResult; } HRESULT TSevenixOfficeMimeFilter::ReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { HRESULT lResult; TRACE(_T("TSevenixOfficeMimeFilter::ReportResult\n")); if (fExporterActive) { if (hrResult == S_OK) { //hrResult = m_SupSink->ReportData(BSCF_DATAFULLYAVAILABLE | BSCF_LASTDATANOTIFICATION, 0, 0); hrResult = S_OK; dwError = 0; szResult = NULL; } } return S_OK; } HRESULT TSevenixOfficeMimeFilter::Switch(PROTOCOLDATA *pPROTOCOLDATA) { TRACE(_T("TSevenixOfficeMimeFilter::Switch\n")); HRESULT lResult; if (fExporterActive) { lResult = fProtocolProxy->Continue(pPROTOCOLDATA); //lResult = m_SupSink->Switch(pPROTOCOLDATA); if (lResult != S_OK) return E_FAIL; else return S_OK; } else { lResult = m_SupSink->Switch(pPROTOCOLDATA); return lResult; } } void TSevenixOfficeMimeFilter::CloseAll() { TRACE(_T("TSevenixOfficeMimeFilter::CloseAll\n")); if (fExporterActive) { if (fExportedFile != null) { delete fExportedFile; fExportedFile = null; } if (!fNonExportedFileName.IsEmpty()) { TRY { CFile::Remove(fNonExportedFileName); } CATCH(CFileException, e) { TRACE1("File %s cannot be removed\n",fNonExportedFileName); } END_CATCH } if (fNonExportedFile != null) { delete fNonExportedFile; fNonExportedFile = null; } } } void TSevenixOfficeMimeFilter::ReleaseAll() { TRACE(_T("TSevenixOfficeMimeFilter::ReleaseAll\n")); m_SupBindInfo.Release(); if (!m_IsLocked) { m_SupSink.Release(); fProtocolProxy.Release(); } #ifdef _DEBUG else { TRACE(_T(" - MimeFilter is Locked, so do not Release Interfaces\n")); } #endif // _DEBUG } HRESULT TSevenixOfficeMimeFilter::RedirectingTo(LPCWSTR szStatusText) { USES_CONVERSION; LPCTSTR theString = ""; m_ErrorHtmlString.FormatMessage(theString, W2CT(szStatusText)); m_Redirecting = TRUE; m_HandleError = TRUE; return S_OK; }/*------------ TSOfficeMimeFilter.h ------------*/ #ifndef T_OFFICE_MIME_FILTER #define T_OFFICE_MIME_FILTER // DEFINES // INCLUDES #include "KBFilter.h" #include "Cache.h" #include "FilterResource.h" // IMPORTS class TString; interface ISevenixCacheEntry; ///////////////////////////////////////////////////////////////////////////// // TSevenixMimeFilter class ATL_NO_VTABLE TSevenixOfficeMimeFilter : public CComObjectRootEx, public CComCoClass, public IInternet, public IInternetProtocol, public IInternetProtocolSink, public IInternetBindInfo { public: HRESULT FinalConstruct(); void FinalRelease(); DECLARE_REGISTRY(CLSID_TSevenixOfficeMimeFilter, KEEBOO_COMPANY".Net.MimeFilter.1", KEEBOO_COMPANY".Net.MimeFilter", 0, THREADFLAGS_BOTH ) BEGIN_COM_MAP(TSevenixOfficeMimeFilter) COM_INTERFACE_ENTRY(IInternet) COM_INTERFACE_ENTRY2(IUnknown, IInternet) COM_INTERFACE_ENTRY(IInternetProtocolRoot) COM_INTERFACE_ENTRY(IInternetProtocol) COM_INTERFACE_ENTRY(IInternetProtocolSink) COM_INTERFACE_ENTRY(IInternetBindInfo) END_COM_MAP() // IInternetProtocolRoot STDMETHOD(Start)(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, DWORD dwReserved); STDMETHOD(Continue)(PROTOCOLDATA *pProtocolData); STDMETHOD(Abort)(HRESULT hrReason, DWORD dwOptions); STDMETHOD(Terminate)(DWORD dwOptions); STDMETHOD(Suspend)(); STDMETHOD(Resume)(); // IInternetProtocol : public IInternetProtocolRoot STDMETHOD(Read)(void *pv, ULONG cb, ULONG *pcbRead); STDMETHOD(Seek)(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition); STDMETHOD(LockRequest)(DWORD dwOptions); STDMETHOD(UnlockRequest)(); // IInternetBindInfo STDMETHOD(GetBindInfo)(DWORD *grfBINDF, BINDINFO *pbindinfo); STDMETHOD(GetBindString)(ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched); // IInternetProtocolSink STDMETHOD(ReportData)(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax); STDMETHOD(ReportProgress)(ULONG ulStatusCode, LPCWSTR szStatusText); STDMETHOD(ReportResult)(HRESULT hrResult, DWORD dwError, LPCWSTR szResult); STDMETHOD(Switch)(PROTOCOLDATA *pPROTOCOLDATA); private: CComPtr m_SupSink; CComPtr fProtocolProxy; CComPtr m_SupBindInfo; // Personnal variables boolean fReportDataSFalseOccurred; CComPtr fCacheEntry; // This field assure an exporter is behind all this and // that the filter will be used boolean fExporterActive; CFile* fExportedFile; CFile* fNonExportedFile; boolean fNonExportedFileCached; TString fExportedFileName; TString fNonExportedFileName; boolean fExportSucceeded; boolean fReadSFalseOccurred; CComBSTR m_TargetMime; CComBSTR m_SourceMime; CString m_ErrorHtmlString; CString m_OfficeConvertingAppFullName; LONG m_ReportDataReadState; LONG m_ReadState; LONG m_DocSize; LONG m_CurrentRead; BOOL m_IsLocked:2; BOOL m_IsTerminate:2; BOOL m_HaveAbort:2; BOOL m_HandleError:2; BOOL m_Redirecting:2; BOOL m_RootDocument:2; BOOL m_CanReload:2; BOOL m_IsSearch:2; private: void CloseAll(); void ReleaseAll(); HRESULT launchExportProcessing(); HRESULT ConvertFile(); void CreateNewFile(); HRESULT RedirectingTo(LPCWSTR szStatusText); LONG TranslateError(HRESULT hrResult, DWORD dwError); HRESULT HandleError(HRESULT hrResult, DWORD dwError, LPCWSTR szResult); HRESULT ReadFromErrorString(void *pv, ULONG cb, ULONG *pcbRead); }; #endif // T_OFFICE_MIME_FILTER /*------------ BookBrowser.cpp ------------*/ #include "StdAfx.h" // *** MAIN INCLUDE #include "BookBrowser.h" // *** OTHER INCLUDE #include "TBookModel.h" #include "TSummaryModel.h" #include "TIndexModel.h" #include "TMediaShelfModel.h" #include "TContextModel.h" #include "TModelIterator.h" #include "TModelNames.h" #include "TModelHelpers.h" #include "BackGround.h" #include "TabsViewer.h" #include "ArrowBand.h" #include "BinderView.h" #include "BookUtils.h" #include "PagemarksViewer.h" #include "PropertyChangeEvent.h" #include "TBoolean.h" #include "TErr.h" #include "TPageEditor.h" #include "TPageModel.h" #include "TPtrArray.h" #include "TString.h" #include "TInteger.h" #include "TPageletViewManager.h" #include "SharedlookAndFeelRes.h" #include "TGlobalsDB.h" #include "PrintingEngine.h" #include "ResBookBrowser.h" #include "eViewMode.h" #include "Pagelet.h" #include "Controler.h" #include "TUserMessage.h" // ************************************************************************************************ class TBrowserBookListener : public TPropertyChangeListener { TBookBrowser* m_pBookBrowser; public: TBrowserBookListener(TBookBrowser* pBookBrowser); ~TBrowserBookListener(); virtual void propertyChange(TPropertyChangeEvent *evt); }; class TBrowserShelfListener : public TPropertyChangeListener { TBookBrowser* m_pBookBrowser; public: TBrowserShelfListener(TBookBrowser* pBookBrowser); ~TBrowserShelfListener(); virtual void propertyChange(TPropertyChangeEvent *evt); }; // *** Message map BEGIN_MESSAGE_MAP(TBookBrowser, TWnd) //{{AFX_MSG_MAP(TWnd) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_SHOWWINDOW() // ON_WM_LBUTTONDOWN() // ON_WM_LBUTTONUP() //}}AFX_MSG_MAP ON_MESSAGE(WM_USER_SET_NAME, OnSetName) ON_MESSAGE(WM_USER_ADD_PAGE, OnAddPage) ON_MESSAGE(WM_USER_INSERT_PAGE, OnInsertPage) ON_MESSAGE(WM_USER_REMOVE_PAGE, OnRemovePage) ON_MESSAGE(WM_USER_SET_WRITABLE, OnSetWritable) ON_MESSAGE(WM_USER_ADD_PAGE_BEFORE_SUMMARY, OnAddPageBeforeSummary) ON_MESSAGE(WM_USER_REMOVE_PAGE_BEFORE_SUMMARY, OnRemovePageBeforeSummary) ON_MESSAGE(WM_USER_WANT_TO_BE_DESTROYED, OnWantToBeDestroyed) ON_MESSAGE(WM_USER_SET_PROPERTY, OnSetProperty) ON_MESSAGE(WM_USER_REMOVE_PROPERTY, OnRemoveProperty) ON_MESSAGE(WM_USER_SET_LOCATION, OnSetLocation) ON_MESSAGE(WM_USER_SET_IS_ALIASED, OnSetIsAliased) ON_MESSAGE(WM_USER_SET_BOOK_STYLE, OnSetBookStyle) ON_MESSAGE(WM_USER_CHANGE_PRIMARY_PAGE, OnChangePrimaryPage) ON_MESSAGE(WM_USER_CHANGE_SECONDARY_PAGE, OnChangeSecondaryPage) ON_MESSAGE(WM_USER_CHANGE_SELECTED_PAGE, OnChangeSelectedPage) ON_MESSAGE(WM_USER_CHANGE_BOOK, OnChangeBook) ON_MESSAGE(ID_UM_CHANGE_ACTIVE_VIEW, OnModeChange) ON_MESSAGE(WM_USER_UPDATE_PAGES, OnUpdatePages) ON_MESSAGE(WM_USER_SHOW_BOOK_VIEWS, OnShowBookViews) END_MESSAGE_MAP() IMPLEMENT_DYNAMIC(TBookBrowser, TWnd); // ************************************************************************************************ // *** BookBrowser Constructor TBookBrowser::TBookBrowser() : TWnd(), m_DisplayAnnotations(FALSE), m_SupportFlying(FALSE), m_IsVisible(FALSE), m_BookLogicalRect(0,0,0,0), m_SelectedSide(T_NONE), m_TotalTabsNb(0), m_pBinderView(NULL), m_PageletManager(NULL), m_ModeView(T_UNDEFINED_MODE), m_Resources("BOOK_BROWSER"), m_pPrintingEngine(NULL) { memset(&m_Primary, 0, sizeof(m_Primary)); memset(&m_Secondary, 0, sizeof(m_Secondary)); initResources(); } // ************************************************************************************************ // *** BookBrowser Destructor TBookBrowser::~TBookBrowser() { // *** Remove book listener and release book removeBook(); exitResources(); } // ************************************************************************************************ // *** Initialisation of resources used by the book browser void TBookBrowser::initResources() { AFX_MANAGE_STATE(AfxGetAppModuleState()); m_Resources.LoadInfo(); CSize lLogicalSize(m_Resources.m_pInfo->m_Width, m_Resources.m_pInfo->m_Height); setBookLogicalRect(CRect(CPoint(0,0), lLogicalSize)); } void TBookBrowser::exitResources() { } // ************************************************************************************************ BOOL TBookBrowser::PreCreateWindow(CREATESTRUCT& cs) { if (cs.style & WS_VISIBLE) { m_IsVisible = TRUE; } cs.lpszName = _T("TBookBrowser"); return TWnd::PreCreateWindow(cs); } int TBookBrowser::OnCreate(LPCREATESTRUCT lpCreateStruct) { int result; // long lCode; if ((result = TWnd::OnCreate(lpCreateStruct)) != 0) return result; if (m_pBookControler == NULL) m_pBookControler.CoCreateInstance(CLSID_TBookControler); ASSERT(m_pBookControler); if (m_pBookControler == NULL) { DestroyWindow(); return -1; } // *** Create all the views used to display the book createBookViews(T_PRIMARY); createBookViews(T_SECONDARY); m_pPrintingEngine = new CPrintingEngine(); VERIFY(m_pPrintingEngine->Create( this, 1)); return result; } void TBookBrowser::OnDestroy() { m_pBookControler.Release(); /* if (m_Primary.m_Page) m_Primary.m_Page->removePageletView(); if (m_Secondary.m_Page) m_Secondary.m_Page->removePageletView(); */ if (m_PageletManager) { m_PageletManager->cleanAllViews(); m_PageletManager->OnDestroyBook(); // *** Delete pagelet manager m_PageletManager->Release(); m_PageletManager = NULL; } m_Primary.m_Page = NULL; m_Primary.m_TabsViewer = NULL; m_Secondary.m_Page = NULL; m_Secondary.m_TabsViewer = NULL; m_pBinderView = NULL; m_pPrintingEngine = NULL; TWnd::OnDestroy(); } void TBookBrowser::OnShowWindow( BOOL pShow, UINT ) { m_IsVisible = pShow; } // ************************************************************************************************ void TBookBrowser::createBookViews(ePageSide pSide) { HRESULT lResult; if (m_pBinderView == NULL) { lResult = createBinder(); ASSERT(SUCCEEDED(lResult)); } lResult = createPageEditor(pSide); ASSERT(SUCCEEDED(lResult)); lResult = createTabsViewer(pSide); ASSERT(SUCCEEDED(lResult)); #ifdef SUPPORT_PAGEMARK lResult = createPagemarksViewer(pSide); ASSERT(SUCCEEDED(lResult)); #endif // SUPPORT_PAGEMARK #ifdef SUPPORT_FLYING_PAGE if (m_SupportFlying) { lResult = createFlyingPage(pSide); ASSERT(SUCCEEDED(lResult)); m_Primary.m_FlyingPage->setFlying(TRUE); } #endif // SUPPORT_FLYING_PAGE } // ************************************************************************************************ // *** // *** Create the page editor correspondig to the position 'pPageSide' (Primary or secondary) // *** Also creates the associated tabs viewer // *** HRESULT TBookBrowser::createPageEditor(ePageSide pSide) { t_Side_Data* lSideData; CRect lLogicalRect; TPageEditor* lPageEditor; lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary; // *** Verify that the tabs viewer to create doesn't exist yet ASSERT(lSideData->m_Page == NULL); GetPageLogicalRect(lLogicalRect, pSide); lPageEditor = new TPageEditor(); VERIFY(lPageEditor); lPageEditor->setLogicalPoint(lLogicalRect.TopLeft()); lPageEditor->setLogicalSize(lLogicalRect.Size()); lPageEditor->setLogicalSpace(lLogicalRect.Size()); // *** Create the page editor LPtoDP(&lLogicalRect); if (!lPageEditor->Create(NULL, NULL, WS_CHILD, lLogicalRect, this, 0)) return E_FAIL; addChild(lPageEditor); // *** Set view to be refreshed lPageEditor->setViewToRefresh(lPageEditor); // *** Set book browser and position lPageEditor->setBookBrowser(this); lPageEditor->setPageSide(pSide); CDC* lDC = GetDC(); ASSERT_VALID(lDC); setDCMappingMode(lDC); lPageEditor->logicalResizeAndPos(lDC); ReleaseDC(lDC); lPageEditor->LoadBackground(m_Resources.m_pInfo); // *** Set the good page editor lSideData->m_Page = lPageEditor; return S_OK; } // ************************************************************************************************ HRESULT TBookBrowser::createTabsViewer(ePageSide pPageSide) { t_Side_Data* lSideData; TPageEditor* lPageEditor; TTabsViewer* lTabsViewer; CRect lLogicalRect; lSideData = (pPageSide == T_PRIMARY) ? &m_Primary : &m_Secondary; // *** Verify that the tabs viewer to create doesn't exist yet ASSERT(lSideData->m_TabsViewer == NULL); ASSERT(lSideData->m_Page != NULL); lPageEditor = lSideData->m_Page; GetTabsLogicalRect(lLogicalRect, pPageSide); lTabsViewer = new TTabsViewer(); VERIFY( lTabsViewer); CPoint lPosition(lLogicalRect.TopLeft()); CSize lSize(lLogicalRect.Size()); lTabsViewer->setLogicalPoint(lPosition); lTabsViewer->setLogicalSize(lSize); lTabsViewer->setLogicalSpace(lSize); // --- CtrlId will be overridded by his WM_HELPHITTEST LPtoDP(&lLogicalRect); lTabsViewer->Create(NULL, NULL, WS_CHILD, lLogicalRect, this, 0); // lTabsViewer->setViewToRefresh(this); lTabsViewer->setBookControler(m_pBookControler); addChild(lTabsViewer); CDC* lDC = GetDC(); ASSERT_VALID(lDC); setDCMappingMode(lDC); lTabsViewer->logicalResizeAndPos(lDC); ReleaseDC(lDC); lTabsViewer->setPageSide(pPageSide); lTabsViewer->LoadBackground(m_Resources.m_pInfo->m_TabZoneBitmap); lSideData->m_TabsViewer = lTabsViewer; return S_OK; } // ************************************************************************************************ HRESULT TBookBrowser::createBinder() { CRect lLogicalRect; GetBinderLogicalRect(lLogicalRect); m_pBinderView = new TBinderView(this); VERIFY(m_pBinderView); CPoint lPosition(lLogicalRect.TopLeft()); CSize lSize(lLogicalRect.Size()); m_pBinderView->setLogicalPoint(lPosition); m_pBinderView->setLogicalSize(lSize); m_pBinderView->setLogicalSpace(lSize); LPtoDP(&lLogicalRect); m_pBinderView->Create(NULL, NULL, WS_CHILD, lLogicalRect, this, 0); addChild(m_pBinderView); CDC* lDC = GetDC(); ASSERT_VALID(lDC); setDCMappingMode(lDC); m_pBinderView->logicalResizeAndPos(lDC); ReleaseDC(lDC); m_pBinderView->LoadBackground(m_Resources.m_pInfo->m_RWBinderBitmap, m_Resources.m_pInfo->m_RBinderBitmap, m_Resources.m_pInfo->m_DBinderBitmap); CRect lArrowRect(CPoint(m_Resources.m_pInfo->m_ArrowX, m_Resources.m_pInfo->m_ArrowY), CSize(m_Resources.m_pInfo->m_ArrowWidth, m_Resources.m_pInfo->m_ArrowHeight)); m_pBinderView->LoadToolbar(lArrowRect, m_Resources.m_pInfo->m_ArrowUpID, m_Resources.m_pInfo->m_ArrowDownID); return S_OK; } // ************************************************************************************************ #ifdef SUPPORT_PAGEMARK HRESULT TBookBrowser::createPagemarksViewer(ePageSide pPageSide) { t_Side_Data* lSideData; TPageEditor* lPageEditor; lSideData = (pPageSide == T_PRIMARY) ? &m_Primary : &m_Secondary; // *** Verify that the pagemarks viewer to create doesn't exist yet ASSERT(lSideData->m_PagemarksViewer == NULL); ASSERT(lSideData->m_Page != NULL); lPageEditor = lSideData->m_Page; CSize lLogicalSize = lPageEditor->getLogicalSize(); CRect lRect(CPoint(0, 0), lLogicalSize); lRect.bottom = lRect.top + 50; // *** TO DO : put in resources long lShift = lSideData->m_TabsLogicalRect.Width(); if (pPageSide == T_PRIMARY) lRect.left += lShift; else lRect.right -= lShift; TPagemarksViewer* lPagemarksViewer; lPagemarksViewer = new TPagemarksViewer(); VERIFY( lPagemarksViewer); lPagemarksViewer->setViewToRefresh(lPageEditor); lPagemarksViewer->setBookBrowser(this); // lPagemarksViewer->setLogicalSpace(m_pBookBkgnd->getWidth() - m_Primary.m_TabsLogicalRect.Width(), 50); // *** TO DO : put in resources lPagemarksViewer->setLogicalPoint(CPoint(lRect.left, lRect.top)); lPagemarksViewer->setLogicalSize(CSize(lRect.Width(), lRect.Height())); lPagemarksViewer->Create(NULL, NULL, WS_CHILD, lRect, this, 0); addChild(lPagemarksViewer); CDC* lDC = GetDC(); ASSERT_VALID(lDC); lPagemarksViewer->logicalResizeAndPos(lDC); ReleaseDC(lDC); lPagemarksViewer->setPageSide(pPageSide); lSideData->m_PagemarksViewer = lPagemarksViewer; return S_OK; } #endif // SUPPORT_PAGEMARK // ************************************************************************************************ void TBookBrowser::showBookViews(long pShow) { // *** Validity of parameters ASSERT(pShow == SW_HIDE || pShow == SW_SHOW); // *** Validity of views ASSERT(m_Primary.m_Page && m_Primary.m_TabsViewer); ASSERT(m_Secondary.m_Page && m_Secondary.m_TabsViewer); if (!m_Primary.m_Page || !m_Primary.m_TabsViewer) return ; if (!m_Secondary.m_Page || !m_Secondary.m_TabsViewer) return ; m_Primary.m_TabsViewer->ShowWindow(pShow); // In Page mode, the Show / Hide is only apply to the selected page if ((m_ModeView != T_PAGE_MODE) || m_Primary.m_Page->isSelected() || ((m_Book == NULL) && (pShow == SW_HIDE))) { m_Primary.m_Page->ShowWindow(pShow); } m_pBinderView->ShowWindow(pShow); // In Page mode, the Show / Hide is only apply to the selected page if ((m_ModeView != T_PAGE_MODE) || m_Secondary.m_Page->isSelected() || ((m_Book == NULL) && (pShow == SW_HIDE))) { m_Secondary.m_Page->ShowWindow(pShow); } m_Secondary.m_TabsViewer->ShowWindow(pShow); // *** Refresh background if hidden, in order to restore it. if (pShow == SW_HIDE) { ASSERT(!m_Primary.m_TabsViewer->IsWindowVisible()); ASSERT(!m_Primary.m_Page->IsWindowVisible()); ASSERT(!m_pBinderView->IsWindowVisible()); ASSERT(!m_Secondary.m_Page->IsWindowVisible()); ASSERT(!m_Secondary.m_TabsViewer->IsWindowVisible()); if (!m_WasEmpty) { CRect lDeviceRect(getDevicePoint(), getDeviceSize()); GetParent()->InvalidateRect(lDeviceRect); GetParent()->UpdateWindow(); } } } // ************************************************************************************************ // // Compute the size of all the views. // HRESULT TBookBrowser::GetPageLogicalRect(CRect& pRect, ePageSide pSide) { long lTotalSpace; long lPageSpace; lTotalSpace = m_BookLogicalRect.Width() - (m_Resources.m_pInfo->m_TabWidth * 2) - m_Resources.m_pInfo->m_BinderWidth; if (m_ModeView == T_PAGE_MODE) lPageSpace = lTotalSpace; else lPageSpace = lTotalSpace / 2; pRect.top = 0; pRect.bottom = m_BookLogicalRect.Height(); if (pSide == T_PRIMARY) { pRect.left = m_Resources.m_pInfo->m_TabWidth; pRect.right = pRect.left + lPageSpace; } else if (pSide == T_SECONDARY) { pRect.right = m_BookLogicalRect.Width() - m_Resources.m_pInfo->m_TabWidth; pRect.left = pRect.right - lPageSpace; } return S_OK; } HRESULT TBookBrowser::GetTabsLogicalRect(CRect& pRect, ePageSide pSide) { pRect.top = 0; pRect.bottom = m_BookLogicalRect.Height(); if (pSide == T_PRIMARY) { pRect.left = 0; pRect.right = m_Resources.m_pInfo->m_TabWidth; } else if (pSide == T_SECONDARY) { pRect.right = m_BookLogicalRect.Width(); pRect.left = pRect.right - m_Resources.m_pInfo->m_TabWidth; } return S_OK; } HRESULT TBookBrowser::GetBinderLogicalRect(CRect& pRect, ePageSide pSide) { pRect.top = 0; pRect.bottom = m_BookLogicalRect.Height(); if (m_ModeView == T_PAGE_MODE) { if (pSide == T_SECONDARY) pRect.left = m_Resources.m_pInfo->m_TabWidth; else pRect.left = m_BookLogicalRect.Width() - m_Resources.m_pInfo->m_TabWidth - m_Resources.m_pInfo->m_BinderWidth; } else pRect.left = m_BookLogicalRect.Width() / 2 - m_Resources.m_pInfo->m_BinderWidth / 2; pRect.right = pRect.left + m_Resources.m_pInfo->m_BinderWidth; return S_OK; } // ***************************************************************************** // // // void TBookBrowser::OnSize(UINT nType, int cx, int cy) { TWnd::OnSize(nType, cx, cy); constraintLogicalResize(); } // ***************************************************************************** // // // void TBookBrowser::constraintLogicalResize() { CRect lPrevDeviceRect; CRect lDeviceRect; CRect lPrevLogicalRect; CRect lLogicalRect; m_Primary.m_TabsViewer->GetWindowRect(&lPrevDeviceRect); ScreenToClient(&lPrevDeviceRect); lPrevLogicalRect = CRect(m_Primary.m_TabsViewer->getLogicalPoint(), m_Primary.m_TabsViewer->getLogicalSize()); m_Primary.m_Page->GetWindowRect(&lDeviceRect); ScreenToClient(&lDeviceRect); lLogicalRect = CRect(m_Primary.m_Page->getLogicalPoint(), m_Primary.m_Page->getLogicalSize()); if (lPrevDeviceRect.right < lDeviceRect.left) { long lDelta = lDeviceRect.left - lPrevDeviceRect.right; m_Primary.m_Page->SetWindowPos(0, lDeviceRect.left - lDelta, lDeviceRect.top, lDeviceRect.Width() + lDelta, lDeviceRect.Height(), SWP_NOOWNERZORDER); m_Primary.m_Page->GetWindowRect(&lDeviceRect); ScreenToClient(&lDeviceRect); ASSERT(lPrevDeviceRect.right >= lDeviceRect.left); } lPrevLogicalRect = lLogicalRect; lPrevDeviceRect = lDeviceRect; m_pBinderView->GetWindowRect(&lDeviceRect); ScreenToClient(&lDeviceRect); lLogicalRect = CRect(m_pBinderView->getLogicalPoint(), m_pBinderView->getLogicalSize()); if (lPrevDeviceRect.right < lDeviceRect.left) { long lDelta = lDeviceRect.left - lPrevDeviceRect.right; m_Primary.m_Page->SetWindowPos(0, lPrevDeviceRect.left, lPrevDeviceRect.top, lPrevDeviceRect.Width() + lDelta, lPrevDeviceRect.Height(), SWP_NOOWNERZORDER); m_Primary.m_Page->GetWindowRect(&lPrevDeviceRect); ScreenToClient(&lPrevDeviceRect); ASSERT(lPrevDeviceRect.right >= lDeviceRect.left); } lPrevLogicalRect = lLogicalRect; lPrevDeviceRect = lDeviceRect; m_Secondary.m_Page->GetWindowRect(&lDeviceRect); ScreenToClient(&lDeviceRect); lLogicalRect = CRect(m_Secondary.m_Page->getLogicalPoint(), m_Secondary.m_Page->getLogicalSize()); if (lPrevDeviceRect.right < lDeviceRect.left) { long lDelta = lDeviceRect.left - lPrevDeviceRect.right; m_Secondary.m_Page->SetWindowPos(0, lDeviceRect.left - lDelta, lDeviceRect.top, lDeviceRect.Width() + lDelta, lDeviceRect.Height(), SWP_NOOWNERZORDER); m_Secondary.m_Page->GetWindowRect(&lDeviceRect); ScreenToClient(&lDeviceRect); ASSERT(lPrevDeviceRect.right >= lDeviceRect.left); } lPrevLogicalRect = lLogicalRect; lPrevDeviceRect = lDeviceRect; m_Secondary.m_TabsViewer->GetWindowRect(&lDeviceRect); ScreenToClient(&lDeviceRect); lLogicalRect = CRect(m_Secondary.m_TabsViewer->getLogicalPoint(), m_Secondary.m_TabsViewer->getLogicalSize()); if (lPrevDeviceRect.right < lDeviceRect.left) { long lDelta = lDeviceRect.left - lPrevDeviceRect.right; m_Secondary.m_Page->SetWindowPos(0, lPrevDeviceRect.left, lPrevDeviceRect.top, lPrevDeviceRect.Width() + lDelta, lPrevDeviceRect.Height(), SWP_NOOWNERZORDER); m_Secondary.m_Page->GetWindowRect(&lPrevDeviceRect); ScreenToClient(&lPrevDeviceRect); ASSERT(lPrevDeviceRect.right >= lDeviceRect.left); } } #ifdef SUPPORT_PAGEMARK HRESULT TBookBrowser::GetPagemarkLogicalRect(CRect& pRect, ePageSide pSide) { return S_OK; } #endif // SUPPORT_PAGEMARK // ------------------------------------------------------------------- // // void TBookBrowser::setPrimaryPage(TPageModel* pPage) { // ASSERT(pPageModel); if (pPage == NULL) return ; // Invalid Arguments ASSERT_VALID(this); // ASSERT(fBook); m_Primary.m_Page->setPage(pPage); } // ------------------------------------------------------------------- // // void TBookBrowser::setSecondaryPage(TPageModel* pPage) { // ASSERT(pPageModel); if (pPage == NULL) return ; // Invalid Arguments ASSERT_VALID(this); // ASSERT(fBook); m_Secondary.m_Page->setPage(pPage); } // ******************************************************************** void TBookBrowser::computeTabsViewerNbTabs() // TPageModel* pPage) { ASSERT_VALID(this); ATLASSERT(m_Book); if (m_Book == NULL) return ; ATLASSERT(m_Summary); if (m_Summary == NULL) return ; ATLASSERT(m_Index); if (m_Index == NULL) return ; TPageModelArray lPrimaryPages; TPageModelArray lSecondaryPages; TModelPtr lPrimaryPage; TModelPtr lPrimaryChapter; TModelPtr lSecondaryPage; TModelIterator* lPages = NULL; BOOL lPrimaryCount = TRUE; m_Primary.m_TabsViewer->cleanTab(); m_Secondary.m_TabsViewer->cleanTab(); lPrimaryPage = m_Primary.m_Page->getPage(); lSecondaryPage = m_Secondary.m_Page->getPage(); TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_READONLY); m_Summary->getPages(&lPages); if (lSecondaryPage == m_Summary) { lSecondaryPages.push_back(m_Summary.p); lPrimaryCount = FALSE; } else { lPrimaryPages.push_back(m_Summary.p); if (lPrimaryPage == m_Summary) lPrimaryCount = FALSE; else if (lPrimaryPage) { lPrimaryPage->getChapter(&lPrimaryChapter); while (lPrimaryChapter && (lPrimaryChapter != m_Summary)) { lPrimaryPage = lPrimaryChapter; lPrimaryChapter.Release(); lPrimaryPage->getChapter(&lPrimaryChapter); } // now PrimaryPage is a first level chapter !!! // or is NULL } } if (lPages != NULL) { while (lPages->hasMoreElements()) { TModelPtr lPage; lPages->nextElement((TObjectModel**)&lPage); if (lPage->getID() == T_CHAPTER_MODEL_NAME) { if (lPrimaryCount) lPrimaryPages.push_back(lPage); else lSecondaryPages.push_back(lPage); } if (lPage == lPrimaryPage) lPrimaryCount = FALSE; } } delete lPages; lSecondaryPages.push_back(m_Index.p); TGlobalsDB::getLibraryDBManager()->commitTransaction(); long lIndex; long lPrimarySize = lPrimaryPages.size(); long lSecondarySize = lSecondaryPages.size(); for (lIndex = 0; lIndex < lPrimarySize; lIndex++) m_Primary.m_TabsViewer->addTab(lIndex, lPrimaryPages[lIndex]); for (lIndex = 0; lIndex < lSecondarySize; lIndex++) m_Secondary.m_TabsViewer->addTab(lIndex, lSecondaryPages[lIndex]); m_TotalTabsNb = lPrimarySize + lSecondarySize; m_Primary.m_TabsViewer->setTotalTabs(m_TotalTabsNb); m_Secondary.m_TabsViewer->setTotalTabs(m_TotalTabsNb); m_Primary.m_TabsViewer->calcTabsData(); m_Secondary.m_TabsViewer->calcTabsData(); if (IsWindowVisible()) { m_Primary.m_TabsViewer->refresh(); m_Secondary.m_TabsViewer->refresh(); } lPrimaryPages.erase(lPrimaryPages.begin(), lPrimaryPages.end()); lSecondaryPages.erase(lSecondaryPages.begin(), lSecondaryPages.end()); } long TBookBrowser::getFirstLevelChapterCount() { long lCount = 0; TModelIterator* lPages = NULL; m_Summary->getPages(&lPages); while (lPages->hasMoreElements()) { TModelPtr lPage; lPages->nextElement((TObjectModel**)&lPage); ASSERT(lPages); // *** Count the number of first level chapters if (lPage->getID() == T_CHAPTER_MODEL_NAME) lCount++; } delete lPages; return lCount; } // ************************************************************************************************ BOOL TBookBrowser::setBook(TBookModel* pBook) { m_WasEmpty = FALSE; // *** Doesn't change book --> nothing to do if (pBook == m_Book) return FALSE; if (m_Book == NULL) m_WasEmpty = TRUE; showBookViews(SW_HIDE); // *** Remove previous book removeBook(); m_pBookControler->put_book((long)pBook); if(pBook == NULL) { ShowWindow(SW_HIDE); return TRUE; } else ShowWindow(SW_SHOW); if (!addBook(pBook)) return FALSE; #ifdef _DEBUG CString stgName = pBook->getName(); TRACE("TBookBrowser::setBook - Open Book: %s\n", stgName); #endif UpdatePages(); computeTabsViewerNbTabs(); // *** Show the views PostMessage(WM_USER_SHOW_BOOK_VIEWS); return TRUE; } // ******************************************************************************* BOOL TBookBrowser::addBook(TBookModel* pBook) { ASSERT(m_PageletManager == NULL); if (m_PageletManager == NULL) { // *** Create pagelet view manager m_PageletManager = new TPageletViewManager(); ASSERT(m_PageletManager); if (m_PageletManager) m_PageletManager->AddRef(); } // *** Set new book m_Book = pBook; m_Book->getSummary(&m_Summary); m_Book->getIndex(&m_Index); m_BookIsWritable = !IsModifyProtected(pBook); // *** Add new listener m_BookListener = new TBrowserBookListener(this); VERIFY(m_BookListener != NULL); m_Book->addPropertyChangeListener(m_BookListener); // *** Reset the book browser m_TotalTabsNb = 0; ASSERT(m_Primary.m_TabsViewer && m_Secondary.m_TabsViewer); if ((m_Primary.m_TabsViewer == NULL) || (m_Secondary.m_TabsViewer == NULL)) return FALSE; m_Secondary.m_TabsViewer->setTotalTabs(0); m_Primary.m_TabsViewer->setTotalTabs(0); return TRUE; } // ********************************************************************************* BOOL TBookBrowser::removeBook() { if (m_Book == NULL) return FALSE; // *** Remove listener if (m_BookListener) { m_Book->removePropertyChangeListener(m_BookListener); m_BookListener->setInvalid(); m_BookListener = NULL; } TMetaManager::flushCachedData(m_Book); m_Book.Release(); m_Summary.Release(); m_Index.Release(); // *** Show the views if (GetSafeHwnd()) { showBookViews(SW_HIDE); refresh(); } if (m_Primary.m_Page) m_Primary.m_Page->setPage(NULL); if (m_Secondary.m_Page) m_Secondary.m_Page->setPage(NULL); if (m_Primary.m_TabsViewer) m_Primary.m_TabsViewer->cleanTab(); if (m_Secondary.m_TabsViewer) m_Secondary.m_TabsViewer->cleanTab(); if (m_PageletManager) { m_PageletManager->cleanAllViews(); m_PageletManager->OnDestroyBook(); m_PageletManager->Release(); m_PageletManager = NULL; } return TRUE; } LRESULT TBookBrowser::OnShowBookViews(WPARAM, LPARAM) { showBookViews(SW_SHOW); return S_OK; } void TBookBrowser::UpdatePages(BOOL pLoop) { // *** Get the primary and secondary pages TModelPtr lPrimaryPage; TModelPtr lSecondaryPage; TModelPtr lSelectedPage; TModelPtr lNextPage; m_Book->getPrimaryPage(&lPrimaryPage); m_Book->getSecondaryPage(&lSecondaryPage); m_Book->getSelectedPage(&lSelectedPage); TModelPtr lPageBook; if (lPrimaryPage != NULL) { lPrimaryPage->getBook(&lPageBook); if (lPageBook == m_Book) { GetNextPage(lPrimaryPage, &lNextPage); } } if ((lPrimaryPage == NULL) || (lPageBook != m_Book) || (lNextPage == NULL)) { // *** We open the book on the property page m_pBookControler->ChangePageTo(T_CPT_SUMMARY, T_SIDE_SECONDARY, CComVariant(1)); if (!pLoop) PostMessage(WM_USER_UPDATE_PAGES); } else { ASSERT(lPrimaryPage); ASSERT(lNextPage); if (lNextPage != lSecondaryPage) { // *** We open the book on the property page m_pBookControler->ChangePageTo(T_CPT_PAGE, T_SIDE_PRIMARY, CComVariant((long)lPrimaryPage.p)); if (!pLoop) PostMessage(WM_USER_UPDATE_PAGES); } else { ASSERT(lSecondaryPage); ASSERT((lSelectedPage == lPrimaryPage) || (lSelectedPage == lSecondaryPage)); m_Primary.m_Page->setPage(lPrimaryPage); m_Secondary.m_Page->setPage(lSecondaryPage); m_Primary.m_Page->Select(lSelectedPage == lPrimaryPage); m_Secondary.m_Page->Select(lSelectedPage != lPrimaryPage); ePageSide lSelectedSide; lSelectedSide = (lSelectedPage == lPrimaryPage) ? T_PRIMARY : T_SECONDARY; if (m_WasEmpty || (lSelectedSide != m_SelectedSide)) { m_SelectedSide = lSelectedSide; if (m_ModeView == T_PAGE_MODE) ResizeView(m_SelectedSide, FALSE); } } } } LRESULT TBookBrowser::OnUpdatePages(WPARAM, LPARAM) { UpdatePages(TRUE); return S_OK; } // ************************************************************************************************ void TBookBrowser::setModeView(long pModeView) { m_ModeView = pModeView; } // ************************************************************************************************ TBookModel* TBookBrowser::getBook() { return m_Book; } // ************************************************************************************************ void TBookBrowser::setFlyingPage(TPageModel* /*pPage*/) { } long TBookBrowser::GetPageBehaviour(ePageSide pSide) { t_Side_Data* lSideData; lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary; ASSERT(lSideData->m_Page); if (lSideData->m_Page) return lSideData->m_Page->GetPageBehaviour(); return 0; } // ************************************************************************************************ void TBookBrowser::setSelectedPage(TPageModel* pPage) { TModelPtr lPrimaryPage = m_Primary.m_Page->getPage(); TModelPtr lSecondaryPage = m_Secondary.m_Page->getPage(); // Selected page must be primary or secondary page ASSERT((lPrimaryPage == pPage) || (lSecondaryPage == pPage)); if (lPrimaryPage == pPage) { m_Primary.m_Page->Select(TRUE); m_Secondary.m_Page->Select(FALSE); } else if (lSecondaryPage == pPage) { m_Primary.m_Page->Select(FALSE); m_Secondary.m_Page->Select(TRUE); } } TPageEditor* TBookBrowser::getPageEditor(ePageSide pPageSide) { return ((pPageSide == T_PRIMARY) ? m_Primary.m_Page : m_Secondary.m_Page); } TTabsViewer* TBookBrowser::getTabsViewer(ePageSide pPageSide) { return ((pPageSide == T_PRIMARY) ? m_Primary.m_TabsViewer : m_Secondary.m_TabsViewer); } // ************************************************************************************************ void TBookBrowser::getTabScreenRect(TPageEditor* pPageEditor, long pIndex, CRect* pRect) { TTabsViewer* lTabsViewer; if (pPageEditor == m_Primary.m_Page) lTabsViewer = m_Primary.m_TabsViewer; else lTabsViewer = m_Secondary.m_TabsViewer; lTabsViewer->getTabScreenRect(pIndex, pRect); } // ************************************************************************************************ void TBookBrowser::changeSelectedPage(TPageModel* pPage) { if (pPage == NULL) { m_Primary.m_Page->Select(FALSE); m_Secondary.m_Page->Select(FALSE); m_SelectedSide = T_NONE; return ; } ASSERT_VALID(this); ASSERT(m_Book); ASSERT(m_pBookControler); TModelPtr lPrimaryPage = m_Primary.m_Page->getPage(); TModelPtr lSecondaryPage = m_Secondary.m_Page->getPage(); #ifdef Pierre ASSERT(lPrimaryPage == pPage || lSecondaryPage == pPage); #endif if (pPage == lPrimaryPage) { SwitchSelectedPage(T_PRIMARY); m_SelectedSide = T_PRIMARY; } else if (pPage == lSecondaryPage) { SwitchSelectedPage(T_SECONDARY); m_SelectedSide = T_SECONDARY; } computeTabsViewerNbTabs(); } // *** changeSelectedPage // ************************************************************************************************ // *** EVENTS HANDLER ON BOOK CHANGE PROPERTIES // ************************************************************************************************ void TBookBrowser::addPageEvt(TPageModel* pPage) { ASSERT(pPage); if (pPage == NULL) return ; ASSERT_VALID(this); ASSERT(m_Book); if (TBookUtils::isFirstLevelChapter(pPage)) computeTabsViewerNbTabs(); } // ************************************************************************************************ void TBookBrowser::insertPageEvt(TPageModel* pPage) { addPageEvt(pPage); } // ************************************************************************************************ void TBookBrowser::removePageEvt(TPageModel* pPage) { ASSERT(pPage); if (pPage == NULL) return ; if (pPage->isInstanceOf(T_CHAPTER_MODEL_NAME)) computeTabsViewerNbTabs(); } // ************************************************************************************************ void TBookBrowser::changeWritableEvt() { ASSERT_VALID(this); ASSERT(m_Book); BOOL lWritable = m_Book->isWritable(); m_Primary.m_Page->changeWritable(lWritable); m_Secondary.m_Page->changeWritable(lWritable); } // ************************************************************************************************ void TBookBrowser::addPageBeforeSummaryEvt(TPageModel* /*pPage*/) { TRACE("(TBookBrowser) : handle add page before summary event\n"); } // ************************************************************************************************ void TBookBrowser::removePageBeforeSummaryEvt(TPageModel* /*pPage*/) { TRACE("(TBookBrowser) : handle remove page before summary event\n"); } // ************************************************************************************************ void TBookBrowser::destroyBookModelEvt() { // *** Remove the book removeBook(); } // ************************************************************************************************ #ifdef SUPPORT_FLYING_PAGE void TBookBrowser::attachDivider(ePageSide pPageSide) { ASSERT(m_SupportFlying); TPageEditor* lPageEditor; TPageEditor* lFlyingPageEditor; TModelPtr lPage; lPageEditor = (pPageSide == T_PRIMARY ? m_Primary.m_Page : m_Secondary.m_Page); ASSERT(lPageEditor); lFlyingPageEditor = (pPageSide == T_PRIMARY ? m_Primary.m_FlyingPage : m_Secondary.m_FlyingPage); ASSERT(lFlyingPageEditor); lPage = lFlyingPageEditor->getPage(); lFlyingPageEditor->setPage(NULL); lFlyingPageEditor->ShowWindow(SW_HIDE); lPageEditor->showContent(TRUE); if (lPageEditor->getPage() == lPage) { // ????? lPageEditor->setPageViewParent(lPage); lPageEditor->setPage(lPage, TRUE); } } // ************************************************************************************************ void TBookBrowser::detachDivider(ePageSide pPageSide) { ASSERT(m_SupportFlying); TPageEditor* lPageEditor; TPageEditor* lFlyingPageEditor; TModelPtr lPage; lPageEditor = (pPageSide == T_PRIMARY ? m_Primary.m_Page : m_Secondary.m_Page); ASSERT(lPageEditor); lFlyingPageEditor = (pPageSide == T_PRIMARY ? fPrimaryFlyingPageEditor : fSecondaryFlyingPageEditor); ASSERT(lFlyingPageEditor); lPage = lPageEditor->getPage(); ASSERT(lPage); lPageEditor->showContent(FALSE); lFlyingPageEditor->ShowWindow(SW_SHOW); lFlyingPageEditor->setPageViewParent(lPage); lFlyingPageEditor->setPage(lPage); } #endif // SUPPORT_FLYING_PAGE // ************************************************************************************************ BOOL TBookBrowser::isFlying(TPageModel* pPage) { #ifdef SUPPORT_FLYING_PAGE // This function might be call even if Flying is not supported ? ASSERT(m_SupportFlying); if (pPage == NULL) return FALSE; if (m_Primary.m_FlyingPage) if (m_Primary.m_FlyingPage->getPage() == pPage) return TRUE; if (m_Secondary.m_FlyingPage) if (m_Secondary.m_FlyingPager->getPage() == pPage) return TRUE; #endif // SUPPORT_FLYING_PAGE return FALSE; } // ------------------------------------------------------------------------------ // // TPageEditor* TBookBrowser::getSelectedPageEditor() { if (m_Primary.m_Page->isSelected()) return m_Primary.m_Page; return m_Secondary.m_Page; } // ------------------------------------------------------------------------------ // // void TBookBrowser::setBookLogicalRect(CRect pLogicalRect) { m_BookLogicalRect = pLogicalRect; setLogicalSpace(pLogicalRect.Size()); recalcTabsRect(); } // ------------------------------------------------------------------------------ // // void TBookBrowser::recalcTabsRect() { // *** Set the rectangle of the tabs viewer TBackGround lBmp(TTabsViewer::gIDBTabTopLeftMask); // *** Used to set width of tabs viewer long lWidth = lBmp.getWidth(); // *** Primary side CPoint lTopLeft(0, 0); CSize lSize(lWidth, m_BookLogicalRect.Height()); m_Primary.m_TabsLogicalRect = CRect(lTopLeft, lSize); // *** Secondary side lTopLeft = CPoint(m_BookLogicalRect.Width() - lWidth, 0); m_Secondary.m_TabsLogicalRect = CRect(CPoint(m_BookLogicalRect.Width() / 2 - lSize.cx, lTopLeft.y), lSize); } // ------------------------------------------------------------------------------ // // LRESULT TBookBrowser::OnModeChange(WPARAM pMode, LPARAM) { if (!m_IsVisible && getBook()) ShowWindow(SW_SHOW); if (pMode == m_ModeView) return S_FALSE; long lOldMode = m_ModeView; if ((pMode == T_PAGE_MODE) || (pMode == T_BOOK_MODE)) { ShowToolbar(T_PRIMARY); ShowToolbar(T_SECONDARY); } else { HideToolbar(T_PRIMARY); HideToolbar(T_SECONDARY); } m_ModeView = pMode; if (pMode == T_PAGE_MODE) SwitchToPage(); if (lOldMode == T_PAGE_MODE) SwitchFromPage(); if (m_Primary.m_Page) m_Primary.m_Page->OnModeChange(pMode); if (m_Secondary.m_Page) m_Secondary.m_Page->OnModeChange(pMode); return S_OK; } void TBookBrowser::SwitchFromPage() { ASSERT(m_Primary.m_Page); ASSERT(m_Secondary.m_Page); if ((m_Primary.m_Page == NULL) || (m_Secondary.m_Page == NULL)) return ; /* if (m_Primary.m_Page->isSelected()) { m_Secondary.m_Page->ShowWindow(SW_SHOW); } else { m_Primary.m_Page->ShowWindow(SW_SHOW); } */ ResizeView(); } void TBookBrowser::SwitchToPage() { ASSERT(m_Primary.m_Page); ASSERT(m_Secondary.m_Page); if ((m_Primary.m_Page == NULL) || (m_Secondary.m_Page == NULL)) return ; if (m_Primary.m_Page->isSelected()) { ResizeView(T_PRIMARY); } else { ResizeView(T_SECONDARY); } } void TBookBrowser::SwitchSelectedPage(ePageSide pSide) { m_Primary.m_Page->Select(pSide == T_PRIMARY); m_Secondary.m_Page->Select(pSide == T_SECONDARY); if (m_ModeView != T_PAGE_MODE) return ; ResizeView(pSide); } void TBookBrowser::ResizeView(ePageSide pSide, BOOL pShow) { CRect lLogicalRect; GetBinderLogicalRect(lLogicalRect, pSide); m_pBinderView->setLogicalPoint(lLogicalRect.TopLeft()); m_pBinderView->setLogicalSize(lLogicalRect.Size()); m_pBinderView->setLogicalSpace(lLogicalRect.Size()); if (pSide != T_SECONDARY) { GetPageLogicalRect(lLogicalRect, T_PRIMARY); m_Primary.m_Page->setLogicalPoint(lLogicalRect.TopLeft()); m_Primary.m_Page->setLogicalSize(lLogicalRect.Size()); if (pSide != T_NONE) { if (pShow) m_Secondary.m_Page->ShowWindow(SW_HIDE); m_Primary.m_Page->setLogicalSpace(lLogicalRect.Width() / 2, lLogicalRect.Height()); } else m_Primary.m_Page->setLogicalSpace(lLogicalRect.Size()); if (pShow) m_Primary.m_Page->ShowWindow(SW_SHOW); } if (pSide != T_PRIMARY) { GetPageLogicalRect(lLogicalRect, T_SECONDARY); m_Secondary.m_Page->setLogicalPoint(lLogicalRect.TopLeft()); m_Secondary.m_Page->setLogicalSize(lLogicalRect.Size()); if (pSide != T_NONE) { if (pShow) m_Primary.m_Page->ShowWindow(SW_HIDE); m_Secondary.m_Page->setLogicalSpace(lLogicalRect.Width() / 2, lLogicalRect.Height()); } else m_Secondary.m_Page->setLogicalSpace(lLogicalRect.Size()); if (pShow) m_Secondary.m_Page->ShowWindow(SW_SHOW); } CDC* lDC = GetDC(); ASSERT_VALID(lDC); setDCMappingMode(lDC); m_pBinderView->logicalResizeAndPos(lDC); m_Primary.m_Page->logicalResizeAndPos(lDC); m_Secondary.m_Page->logicalResizeAndPos(lDC); ReleaseDC(lDC); constraintLogicalResize(); } void TBookBrowser::ShowToolbar(ePageSide pSide) { t_Side_Data* lSideData; lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary; if (lSideData->m_Page && lSideData->m_Page->haveToolbar()) { if (lSideData->m_Page->showToolbar()) m_pBinderView->ShowToolbar(pSide); } } void TBookBrowser::HideToolbar(ePageSide pSide) { t_Side_Data* lSideData; lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary; if (lSideData->m_Page->haveToolbar()) { if (lSideData->m_Page->hideToolbar()) m_pBinderView->HideToolbar(pSide); } } void TBookBrowser::OnBeforeLoad(ePageSide pSide) { t_Side_Data* lSideData; lSideData = (pSide == T_PRIMARY) ? &m_Primary : &m_Secondary; BOOL lHaveToolbar; lHaveToolbar = lSideData->m_Page->haveToolbar(); m_pBinderView->SetHaveToolbar(pSide, lHaveToolbar, lSideData->m_Page->isToolbarUp()); if (lHaveToolbar) { if ((m_ModeView == T_PAGE_MODE) || (m_ModeView == T_BOOK_MODE)) { ShowToolbar(pSide); } else { HideToolbar(pSide); } } } // -------------------------------------------------------------------- // Book Controls // -------------------------------------------------------------------- void TBookBrowser::getBookControler(IBookControler** pBookControler) { ASSERT(pBookControler); if (pBookControler == NULL) return ; *pBookControler = m_pBookControler; (*pBookControler)->AddRef(); } void TBookBrowser::setBookControler(IBookControler* pBookControler) { m_pBookControler = pBookControler; if (m_Primary.m_TabsViewer) m_Primary.m_TabsViewer->setBookControler(pBookControler); if (m_Secondary.m_TabsViewer) m_Secondary.m_TabsViewer->setBookControler(pBookControler); } // ------------------------------------------------------------------- // // void TBookBrowser::goToPage(TPageModel* pPage, ePageSide pSide, BOOL pSelect) { ASSERT_VALID(this); ASSERT(m_pBookControler); ePageSide2 lSide = T_SIDE_SECONDARY; if (pSide == T_PRIMARY) lSide = T_SIDE_PRIMARY; m_pBookControler->ChangePageTo(T_CPT_PAGE, lSide, CComVariant((long)pPage)); } #ifdef _DEBUG void TBookBrowser::AssertValid( ) const { // ASSERT(fBook); ASSERT(m_Primary.m_Page); if (m_ModeView != T_PAGE_MODE) { ASSERT(m_Secondary.m_Page); if (m_Primary.m_Page->getPage()) ASSERT(!m_Primary.m_Page->isIndex()); } // if (m_Primary.m_Page->getPage() && m_Secondary.m_Page->getPage()) // ASSERT(m_Primary.m_Page->getPage() != m_Secondary.m_Page->getPage()); ASSERT(m_Primary.m_TabsViewer); ASSERT(m_Secondary.m_TabsViewer); } #endif // -------------------------------------------------------------------- // Event Handlers // -------------------------------------------------------------------- LRESULT TBookBrowser::OnSetName(WPARAM, LPARAM) { // changeBookManeEvt(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnAddPage(WPARAM wParam, LPARAM ) { TPageModel* lPage = (TPageModel*)wParam; ASSERT(lPage); ASSERT_VALID(this); addPageEvt(lPage); ASSERT_VALID(this); if (lPage) lPage->Release(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnInsertPage(WPARAM wParam, LPARAM ) { TPageModel* lPage = (TPageModel*)wParam; ASSERT(lPage); ASSERT_VALID(this); insertPageEvt(lPage); ASSERT_VALID(this); if (lPage) lPage->Release(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnRemovePage(WPARAM wParam, LPARAM ) { TPageModel* lPage = (TPageModel*)wParam; ATLASSERT(lPage); if (m_Book) { ASSERT_VALID(this); removePageEvt(lPage); ASSERT_VALID(this); } if (lPage) lPage->Release(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnSetWritable(WPARAM , LPARAM ) { changeWritableEvt(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnAddPageBeforeSummary(WPARAM wParam, LPARAM lParam) { TPageModel* lPage = (TPageModel*)wParam; ASSERT(lPage); ASSERT_VALID(this); addPageBeforeSummaryEvt(lPage); ASSERT_VALID(this); if (lPage) lPage->Release(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnRemovePageBeforeSummary(WPARAM wParam, LPARAM lParam) { TPageModel* lPage = (TPageModel*)wParam; ASSERT(lPage); ASSERT_VALID(this); removePageBeforeSummaryEvt(lPage); ASSERT_VALID(this); if (lPage) lPage->Release(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnWantToBeDestroyed(WPARAM , LPARAM ) { destroyBookModelEvt(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnSetProperty(WPARAM, LPARAM) { return E_NOTIMPL; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnRemoveProperty(WPARAM, LPARAM) { return E_NOTIMPL; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnSetLocation(WPARAM, LPARAM) { return E_NOTIMPL; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnSetIsAliased(WPARAM, LPARAM) { return E_NOTIMPL; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnSetBookStyle(WPARAM, LPARAM) { return E_NOTIMPL; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnChangePrimaryPage(WPARAM wParam, LPARAM ) { TPageModel* lPage = (TPageModel*)wParam; // ASSERT(lPage); ASSERT_VALID(this); setPrimaryPage(lPage); ASSERT_VALID(this); if (lPage) lPage->Release(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnChangeSecondaryPage(WPARAM wParam, LPARAM ) { TPageModel* lPage = (TPageModel*)wParam; // ASSERT(lPage); ASSERT_VALID(this); setSecondaryPage(lPage); ASSERT_VALID(this); if (lPage) lPage->Release(); return S_OK; } // -------------------------------------------------------------------- // // LRESULT TBookBrowser::OnChangeSelectedPage(WPARAM wParam, LPARAM ) { TPageModel* lPage = (TPageModel*)wParam; ASSERT_VALID(this); changeSelectedPage(lPage); ASSERT_VALID(this); if (lPage) lPage->Release(); return S_OK; } LONG TBookBrowser::OnChangeBook(UINT wParam, LONG ) { TBookModel *lBook = (TBookModel *)wParam; setBook(lBook); if (lBook) lBook->Release(); return S_OK; } // ************************************************************************************************ // *** Listen to associated book changes TBrowserBookListener::TBrowserBookListener(TBookBrowser* pBookBrowser) { m_pBookBrowser = pBookBrowser; } TBrowserBookListener::~TBrowserBookListener() { m_pBookBrowser = NULL; } void TBrowserBookListener::propertyChange(TPropertyChangeEvent *evt) { ASSERT(evt); // *** Event should not be null CString lPropertyName(evt->getPropertyName()); if (lPropertyName == TBookModel::T_ADD_PAGE_PROPERTY) { TPageModel* lPage = (TPageModel*)evt->getNewValue(); ASSERT(lPage); if (lPage) lPage->AddRef(); m_pBookBrowser->PostMessage(WM_USER_ADD_PAGE, (WPARAM)lPage); } else if (lPropertyName == TBookModel::T_CHANGE_PRIMARY_PAGE) { TPageModel* lPage = (TPageModel*)evt->getNewValue(); // ASSERT(lPage); if (lPage) lPage->AddRef(); m_pBookBrowser->PostMessage(WM_USER_CHANGE_PRIMARY_PAGE, (WPARAM)lPage); } else if (lPropertyName == TBookModel::T_CHANGE_SECONDARY_PAGE) { TPageModel* lPage = (TPageModel*)evt->getNewValue(); // ASSERT(lPage); if (lPage) lPage->AddRef(); m_pBookBrowser->PostMessage(WM_USER_CHANGE_SECONDARY_PAGE, (WPARAM)lPage); } else if (lPropertyName == TBookModel::T_CHANGE_SELECTED_PAGE) { TPageModel* lPage = (TPageModel*)evt->getNewValue(); if (lPage) lPage->AddRef(); m_pBookBrowser->PostMessage(WM_USER_CHANGE_SELECTED_PAGE, (WPARAM)lPage); } else if (lPropertyName == TBookModel::T_INSERT_PAGE_PROPERTY) { TPageModel* lPage = (TPageModel*)evt->getNewValue(); ASSERT(lPage); if (lPage) lPage->AddRef(); m_pBookBrowser->PostMessage(WM_USER_INSERT_PAGE, (WPARAM)lPage); } else if (lPropertyName == TBookModel::T_REMOVE_PAGE_PROPERTY) { TPageModel* lPage = (TPageModel*)evt->getOldValue(); ASSERT(lPage); if (lPage) lPage->AddRef(); m_pBookBrowser->PostMessage(WM_USER_REMOVE_PAGE, (WPARAM)lPage); } else if (lPropertyName == TBookModel::T_ADD_PAGE_BEFORE_SUMMARY_PROPERTY) { TPageModel* lPage = (TPageModel*)evt->getNewValue(); ASSERT(lPage); if (lPage) lPage->AddRef(); m_pBookBrowser->PostMessage(WM_USER_ADD_PAGE_BEFORE_SUMMARY, (WPARAM)lPage); } else if (lPropertyName == TBookModel::T_REMOVE_PAGE_BEFORE_SUMMARY_PROPERTY) { TPageModel* lPage = (TPageModel*)evt->getOldValue(); ASSERT(lPage); if (lPage) lPage->AddRef(); m_pBookBrowser->PostMessage(WM_USER_REMOVE_PAGE_BEFORE_SUMMARY, (WPARAM)lPage); } else { if (lPropertyName == TMediumModel::T_SET_NAME_PROPERTY) m_pBookBrowser->PostMessage(WM_USER_SET_NAME); else if (lPropertyName == TBookModel::T_SET_WRITABLE_PROPERTY) m_pBookBrowser->PostMessage(WM_USER_SET_WRITABLE); else if (lPropertyName == TObjectModel::T_WANT_TO_BE_DESTROYED) m_pBookBrowser->PostMessage(WM_USER_WANT_TO_BE_DESTROYED); else if (lPropertyName == TObjectModel::T_SET_PROPERTY) m_pBookBrowser->PostMessage(WM_USER_SET_PROPERTY); else if (lPropertyName == TObjectModel::T_REMOVE_PROPERTY) m_pBookBrowser->PostMessage(WM_USER_REMOVE_PROPERTY); else if (lPropertyName == TMediumModel::T_SET_LOCATION_PROPERTY) m_pBookBrowser->PostMessage(WM_USER_SET_LOCATION); else if (lPropertyName == TMediumModel::T_SET_IS_ALIASED_PROPERTY) m_pBookBrowser->PostMessage(WM_USER_SET_IS_ALIASED); else if (lPropertyName == TBookModel::T_SET_BOOK_STYLE_PROPERTY) m_pBookBrowser->PostMessage(WM_USER_SET_BOOK_STYLE); } } TBrowserShelfListener::TBrowserShelfListener(TBookBrowser* pBookBrowser) { m_pBookBrowser = pBookBrowser; } TBrowserShelfListener::~TBrowserShelfListener() { m_pBookBrowser = NULL; } void TBrowserShelfListener::propertyChange(TPropertyChangeEvent *evt) { ASSERT(evt); CString lPropertyName(evt->getPropertyName()); /* if (lPropertyName == TMediaContainerModel::T_REMOVE_MEDIUM_PROPERTY) { if (fBook == (TBookModel*)(evt->getOldValue())) removeBook(); if (TContextModel::gContext->getCurrentModeNumber() == T_BOOK_MODE || TContextModel::gContext->getCurrentModeNumber() == T_PAGE_MODE) TContextModel::gContext->setCurrentModeNumber(T_BOOK_STAND_MODE); } */ } /*------------ IEHelperObject.h ------------*/ // IEHelperObject.h : Declaration of the CIEHelperObject #ifndef __IEHelperObject_H_ #define __IEHelperObject_H_ #include "ExDisp.h" #include "ExDispID.h" #include "dispex.h" #include "mshtml.h" //#include "IEVersion.h" /* #define DISPID_BEFORENAVIGATE 100 // this is sent before navigation to give a chance to abort #define DISPID_NAVIGATECOMPLETE 101 // in async, this is sent when we have enough to show #define DISPID_STATUSTEXTCHANGE 102 #define DISPID_QUIT 103 #define DISPID_DOWNLOADCOMPLETE 104 #define DISPID_COMMANDSTATECHANGE 105 #define DISPID_DOWNLOADBEGIN 106 #define DISPID_NEWWINDOW 107 // sent when a new window should be created #define DISPID_PROGRESSCHANGE 108 // sent when download progress is updated #define DISPID_WINDOWMOVE 109 // sent when main window has been moved #define DISPID_WINDOWRESIZE 110 // sent when main window has been sized #define DISPID_WINDOWACTIVATE 111 // sent when main window has been activated #define DISPID_PROPERTYCHANGE 112 // sent when the PutProperty method is called #define DISPID_TITLECHANGE 113 // sent when the document title changes #define DISPID_TITLEICONCHANGE 114 // sent when the top level window icon may have changed. #define DISPID_FRAMEBEFORENAVIGATE 200 #define DISPID_FRAMENAVIGATECOMPLETE 201 #define DISPID_FRAMENEWWINDOW 204 #define DISPID_BEFORENAVIGATE2 250 // hyperlink clicked on #define DISPID_NEWWINDOW2 251 #define DISPID_NAVIGATECOMPLETE2 252 // UIActivate new document #define DISPID_ONQUIT 253 #define DISPID_ONVISIBLE 254 // sent when the window goes visible/hidden #define DISPID_ONTOOLBAR 255 // sent when the toolbar should be shown/hidden #define DISPID_ONMENUBAR 256 // sent when the menubar should be shown/hidden #define DISPID_ONSTATUSBAR 257 // sent when the statusbar should be shown/hidden #define DISPID_ONFULLSCREEN 258 // sent when kiosk mode should be on/off #define DISPID_DOCUMENTCOMPLETE 259 // new document goes ReadyState_Complete #define DISPID_ONTHEATERMODE 260 // sent when theater mode should be on/off #define DISPID_ONADDRESSBAR 261 // sent when the address bar should be shown/hidden */ ///////////////////////////////////////////////////////////////////////////// // CIEHelperObject class ATL_NO_VTABLE CIEHelperObject : public CComObjectRootEx, public IObjectWithSiteImpl, public IDispatchImpl { public: DECLARE_NOT_AGGREGATABLE(CIEHelperObject) BEGIN_COM_MAP(CIEHelperObject) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IObjectWithSite) END_COM_MAP() // IIEHelperObject public: // CIEHelperObject Methods CIEHelperObject() : m_dwCookie(0) {} ~CIEHelperObject() {}; STDMETHOD(Invoke)(DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pdp, VARIANT * pvarResult, EXCEPINFO * pexcepinfo, UINT * puArgErr) { USES_CONVERSION; HRESULT lResult = S_OK; if (!pdp) return E_INVALIDARG; switch (id) { // // The parameters for this DISPID are as follows: // [0]: Cancel flag - VT_BYREF|VT_BOOL // [1]: HTTP headers - VT_BYREF|VT_VARIANT // [2]: Address of HTTP POST data - VT_BYREF|VT_VARIANT // [3]: Target frame name - VT_BYREF|VT_VARIANT // [4]: Option flags - VT_BYREF|VT_VARIANT // [5]: URL to navigate to - VT_BYREF|VT_VARIANT // [6]: An object that evaluates to the top-level or frame // WebBrowser object corresponding to the event. // case DISPID_BEFORENAVIGATE2: ATLASSERT(pdp->cArgs == 7); OnBeforeNavigate2(pdp->rgvarg[6].pdispVal, pdp->rgvarg[5].pvarVal, pdp->rgvarg[4].pvarVal, pdp->rgvarg[3].pvarVal, pdp->rgvarg[2].pvarVal, pdp->rgvarg[1].pvarVal, pdp->rgvarg[0].pboolVal); break; // // The parameters for this DISPID: // [0]: URL navigated to - VT_BYREF|VT_VARIANT // [1]: An object that evaluates to the top-level or frame // WebBrowser object corresponding to the event. // case DISPID_NAVIGATECOMPLETE2: ATLASSERT(pdp->cArgs == 2); OnNavigateComplete2(pdp->rgvarg[1].pdispVal, pdp->rgvarg[0].pvarVal); break; // // The parameters for this DISPID: // [0]: New status bar text - VT_BSTR // case DISPID_STATUSTEXTCHANGE: ATLASSERT(pdp->cArgs == 1); OnStatusTextChange(W2CT(pdp->rgvarg[0].bstrVal)); break; // // The parameters for this DISPID: // [0]: Maximum progress - VT_I4 // [1]: Amount of total progress - VT_I4 // case DISPID_PROGRESSCHANGE: ATLASSERT(pdp->cArgs == 2); OnProgressChange(pdp->rgvarg[1].lVal, pdp->rgvarg[0].lVal); break; // // The parameters for this DISPID: // [0]: URL navigated to - VT_BYREF|VT_VARIANT // [1]: An object that evaluates to the top-level or frame // WebBrowser object corresponding to the event. // case DISPID_DOCUMENTCOMPLETE: ATLASSERT(pdp->cArgs == 2); OnDocumentComplete(pdp->rgvarg[1].pdispVal, pdp->rgvarg[0].pvarVal); if (pdp->rgvarg[1].pdispVal == m_spWebBrowser2) OnLoad(); break; case DISPID_DOWNLOADBEGIN: ATLASSERT(pdp->cArgs == 0); OnDownloadBegin(); break; case DISPID_DOWNLOADCOMPLETE: ATLASSERT(pdp->cArgs == 0); OnDownloadComplete(); break; // // The parameters for this DISPID: // [0]: Enabled state - VT_BOOL // [1]: Command identifier - VT_I4 // case DISPID_COMMANDSTATECHANGE: ATLASSERT(pdp->cArgs == 2); OnCommandStateChange(pdp->rgvarg[1].lVal, pdp->rgvarg[0].boolVal); break; // // The parameters for this DISPID: // [0]: Cancel flag - VT_BYREF|VT_BOOL // [1]: An object that evaluates to the top-level or frame // WebBrowser object corresponding to the event. // case DISPID_NEWWINDOW2: ATLASSERT(pdp->cArgs == 2); OnNewWindow2(pdp->rgvarg[1].ppdispVal, pdp->rgvarg[0].pboolVal); break; // // The parameters for this DISPID: // [0]: Document title - VT_BSTR // case DISPID_TITLECHANGE: ATLASSERT(pdp->cArgs == 1); OnTitleChange(W2CT(pdp->rgvarg[0].bstrVal)); break; // // The parameters for this DISPID: // [0]: Name of property that changed - VT_BSTR // case DISPID_PROPERTYCHANGE: ATLASSERT(pdp->cArgs == 1); OnPropertyChange(W2CT(pdp->rgvarg[0].bstrVal)); break; // // The parameters for this DISPID: // [0]: Address of cancel flag - VT_BYREF|VT_BOOL // case DISPID_QUIT: case DISPID_ONQUIT: ATLASSERT(pdp->cArgs == 0); OnQuit(); // SetSite(NULL); break; default: ATLTRACE("--> CIEHelperObject::Invoke() --> Unknown Event %d\n", id); break; } long lSubCount; long lIndex = 0; lSubCount = m_SubHelper.GetSize(); if (lSubCount) { CIEHelperObject* lHelper; lHelper = m_SubHelper[lIndex]; lResult = lHelper->Invoke(id, riid, lcid, wFlags, pdp, pvarResult, pexcepinfo, puArgErr); lIndex++; } return lResult; } // IOleObjectWithSite Methods STDMETHOD(SetSite)(IUnknown *pUnkSite) { HRESULT lResult = S_OK; if (pUnkSite == NULL) { if (m_spWebBrowser2 && FindHelper(m_spUnkSite)) { ATLASSERT(FindHelper(m_spUnkSite) == this); ATLASSERT(m_dwCookie); RemoveHelper(m_spUnkSite); lResult = ManageConnection(Unadvise); } } else { CIEHelperObject* lHelper; lHelper = FindHelper(pUnkSite); // Do not register many time if (lHelper == NULL) { // Query pUnkSite for the IWebBrowser2 interface. m_spWebBrowser2 = pUnkSite; AddHelper(pUnkSite, this); if (m_spWebBrowser2 == NULL) return E_INVALIDARG; // Connect to the browser in order to handle events. lResult = ManageConnection(Advise); } /* else if (lHelper != this) { lHelper->AddSubHelper(this); } */ IObjectWithSiteImpl::SetSite(pUnkSite); } ATLASSERT(SUCCEEDED(lResult)); return lResult; } // DWebBrowserEvents2 methods virtual void OnProgressChange(long Progress, long ProgressMax) { // ATLTRACE("OnProgressChange\n"); } virtual void OnDownloadBegin() { // ATLTRACE("OnDownloadBegin\n"); } virtual void OnDownloadComplete() { // ATLTRACE("OnDownloadComplete\n"); } virtual void OnBeforeNavigate2(LPDISPATCH pDisp, VARIANT* URL, VARIANT* Flags, VARIANT* TargetFrameName, VARIANT* PostData, VARIANT* Headers, VARIANT_BOOL* Cancel) { // ATLTRACE("OnBeforeNavigate2\n"); } virtual void OnNavigateComplete2(LPDISPATCH pDisp, VARIANT* URL) { // ATLTRACE("OnNavigateComplete2\n"); } virtual void OnDocumentComplete(LPDISPATCH pDisp, VARIANT* URL) { // ATLTRACE("OnDocumentComplete\n"); } virtual void OnStatusTextChange(LPCTSTR Text) { // ATLTRACE("OnStatusTextChange\n"); } virtual void OnCommandStateChange(long Command, BOOL Enable) { // ATLTRACE("OnCommandStateChange\n"); } virtual void OnTitleChange(LPCTSTR Text) { // ATLTRACE("OnTitleChange\n"); } virtual void OnPropertyChange(LPCTSTR szProperty) { // ATLTRACE("OnPropertyChange\n"); } virtual void OnNewWindow2(LPDISPATCH* ppDisp, VARIANT_BOOL* Cancel) { // ATLTRACE("OnNewWindow2\n"); // return E_NOTIMPL; } virtual void OnQuit() { // ATLTRACE("OnQuit\n"); } virtual void OnLoad() { // ATLTRACE("OnLoad\n"); } HRESULT AddProperty(LPOLESTR nameDisp, LPDISPATCH pDisp) { HRESULT hResult = S_OK; if (!m_spWebBrowser2) return E_INVALIDARG; CComPtr spDispatch; hResult = m_spWebBrowser2->get_Document(&spDispatch); CComQIPtr spDocument(spDispatch); ATLASSERT(SUCCEEDED(hResult) && spDocument); if (SUCCEEDED(hResult) && spDocument) { CComPtr pWindow; hResult = spDocument->get_parentWindow(&pWindow); ATLASSERT(SUCCEEDED(hResult) && pWindow); if (FAILED(hResult) || !pWindow) return E_FAIL; DISPID lDispID; { CComVariant lVariant; CComBSTR bstrCode(nameDisp); bstrCode.Append("=0;"); hResult = pWindow->execScript(bstrCode, L"JScript", &lVariant); ATLASSERT(SUCCEEDED(hResult)); hResult = pWindow->GetIDsOfNames(IID_NULL, &nameDisp, 1, LOCALE_SYSTEM_DEFAULT, &lDispID); ATLASSERT(SUCCEEDED(hResult)); } if (SUCCEEDED(hResult) && (lDispID != DISPID_UNKNOWN)) { CComVariant lVariant(pDisp); hResult = CComDispatchDriver::PutProperty(pWindow, lDispID, &lVariant); ATLASSERT(SUCCEEDED(hResult)); } } return hResult; } protected: DWORD m_dwCookie; // Connection Token - used for Advise and Unadvise CComQIPtr m_spWebBrowser2; CSimpleArray m_SubHelper; static CSimpleMap* g_Map; enum ConnectType { Advise, Unadvise }; // What to do when managing the connection HRESULT ManageConnection(enum ConnectType eConnectType) { ATLASSERT(m_spWebBrowser2); if (m_spWebBrowser2 == NULL) return E_INVALIDARG; HRESULT lResult; // If eConnectType is Advise then we are advising IE that we want to handle events. // If eConnectType is Unadvise, we are telling IE that we no longer want to handle events. if (eConnectType == Advise) lResult = AtlAdvise(m_spWebBrowser2, (IDispatch*)this, DIID_DWebBrowserEvents2, &m_dwCookie); else { lResult = AtlUnadvise(m_spWebBrowser2, DIID_DWebBrowserEvents2, m_dwCookie); m_dwCookie = 0; } return lResult; } void AddSubHelper(CIEHelperObject* pHelper) { m_SubHelper.Add(pHelper); } static BOOL AddHelper(IUnknown* pUnk, CIEHelperObject* pHelper) { if (pUnk && pHelper) { if (g_Map == NULL) g_Map = new CSimpleMap(); ATLTRACE(" + AddHelper(0x%x, 0x%x)\n", pUnk, pHelper); return g_Map->Add(pUnk, pHelper); } return FALSE; } static void RemoveHelper(IUnknown* pUnk) { if (g_Map) { ATLTRACE(" - RemoveHelper(0x%x)\n", pUnk); g_Map->Remove(pUnk); if (g_Map->GetSize() == 0) { delete g_Map; g_Map = NULL; } } } public: static CIEHelperObject* FindHelper(IUnknown* pUnk) { if (g_Map) return g_Map->Lookup(pUnk); return NULL; } }; __declspec(selectany) CSimpleMap* CIEHelperObject::g_Map = NULL; #endif //__IEHelperObject_H_ /*------------ KbChapterToc.cpp ------------*/ // KbChapterToc.cpp : implementation file // #include "stdafx.h" #include #include "KbChapterToc.h" #include "KbModelItem.h" #include "Controler.h" #include "ResRgbInfo.h" #include "ResTocTextColorInfo.h" #include "InterfaceUtils.h" #include "WmUserMsgListener.h" #include "DragAndDropPageData.h" #include "ProgressDlg.h" #include "KbStickerTocWnd.h" #include "PageletToolbar.h" #include "TMain.h" #include "TModelIterator.h" #include "TModelPtr.h" #include "TChapterModel.h" #include "TSummaryModel.h" #include "TPageModel.h" #include "TPropertyObjectModel.h" #include "TModelPtr.h" #include "TBookModel.h" #include "TMediaLibraryModel.h" #include "TMetaManager.h" #include "TModelNames.h" #include "TSoundManager.h" #include "TContextModel.h" #include "TModelHelpers.h" #include "TTocBookListener.h" #include "TOleDataObject.h" #include "TGlobalsDB.h" #include "TBrowseDir.h" #include "TBooxFrame.h" #include "TKeeBooKeyController.h" #include "TPagePropertiesConstants.h" #include "TBoolean.h" #include "TPath.h" #include "TPageIdentifiersConstants.h" #include "TUserMessage.h" #include "SharedLookAndFeelRes.h" #include "SharedSoundAndFeelRes.h" #include "SharedResource.h" #include "TGlobalResource.h" // Interfaces #include "Pagelet.h" // D&D #include "TOleDataObject.h" #include "DragAndDropAnnotationData.h" // Utils #include "TSoundManager.h" #include "TUrl.h" #include "ProgressDlg.h" #include "TGlobalResource.h" #include "TBrowseDir.h" #include "TNetHelpers.h" #include "TSevenixUrl.h" #include "TPath.h" #include "TErr.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define IDC_POSTIT 2 ///////////////////////////////////////////////////////////////////////////// // CKbChapterToc CKbChapterToc::CKbChapterToc( TChapterModel *pChapterModel) { m_pChapterModel = pChapterModel; m_pChapterModel->getBook( &m_pBookModel); m_pTocChapterListener = NULL; m_pTocBookListener = NULL; m_pPostItWnd = NULL; m_dropEffectPage = DROPEFFECT_NONE; } CKbChapterToc::~CKbChapterToc() { } BEGIN_MESSAGE_MAP(CKbChapterToc, CKbTreeTocWnd) //{{AFX_MSG_MAP(CKbChapterToc) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_INITMENUPOPUP() //}}AFX_MSG_MAP ON_COMMAND( IDA_SUPPR, OnEditDel) ON_COMMAND( IDA_TOC_DELETE, OnEditDel) ON_COMMAND( IDM_TOC_RENAME, OnTocRename) ON_COMMAND( IDM_TOC_NEWCHAPTER, OnTocNewChapter) ON_COMMAND( IDM_TOC_NEWOSFILES, OnTocNewOsFiles) ON_COMMAND( IDM_TOC_NEWURL, OnTocNewUrl) ON_COMMAND( IDM_EDIT_COPY, OnEditCopy) ON_COMMAND( IDM_EDIT_CUT, OnEditCut) ON_COMMAND( IDM_EDIT_PASTE, OnEditPaste) ON_COMMAND( IDM_EDIT_DEL, OnEditDel) ON_MESSAGE( WM_USER_CHAPTER_REMOVE_PAGE, OnChapterRemovePage) ON_MESSAGE( WM_USER_CHAPTER_ADD_PAGE, OnChapterAddPage) ON_MESSAGE( WM_USER_NEW_CHAPTER, OnNewChapter) ON_NOTIFY( WM_DESTROY, IDC_POSTIT, OnNotifyDestroy) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CKbChapterToc creation destruction message handlers int CKbChapterToc::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CKbTreeTocWnd::OnCreate(lpCreateStruct) == -1) return -1; // --- initialize image list { AFX_MANAGE_STATE( AfxGetAppModuleState()); CResRgbInfo resBkColor( _T("TOC_BK_COLOR")); resBkColor.LoadInfo(); SetBkNormalColor( resBkColor.m_color); m_tocIl.SetBkColor( resBkColor.m_color); CResRgbInfo resBkSelColor( _T("TOC_BK_SELECT_COLOR")); if (resBkSelColor.LoadInfo()) { SetBkSelectedColor( resBkSelColor.m_color); } CResTocTextColorInfo resTextColor( _T("TOC_TEXT_COLOR")); if (resTextColor.LoadInfo()) { SetItemTextNormalColor( resTextColor.m_pInfo->m_normalColor); SetItemTextDropHilitedColor( resTextColor.m_pInfo->m_dropHilitedColor); SetItemTextSelectedColor( resTextColor.m_pInfo->m_selectedColor); SetItemTextCutColor( resTextColor.m_pInfo->m_cutColor); } m_treeCtrl.SetImageList( &(m_tocIl.m_ilSmall), TVSIL_NORMAL); } // --- initialize columns m_headerCtrl.InsertColumn( 0, _T(""), // --- Title HDF_STRING | HDF_LEFT, 100, KBF_EX_TABLEADER); // --- 100 % m_headerCtrl.InsertColumn( 1, _T(""), // --- Page number HDF_STRING | HDF_RIGHT, 32, KBF_EX_ABSOLUTEWIDTH | KBF_EX_INTEGER); m_headerCtrl.InsertColumn( 2, _T(""), // --- annotation HDF_BITMAP | HDF_CENTER, 32, KBF_EX_ABSOLUTEWIDTH | KBF_EX_INTEGER, &(m_tocIl.m_ilSmall)); // --- fill the list with 1 level children page FillList( m_pChapterModel); // --- add a listener for this chapter m_pTocChapterListener = new TTocChapterListener( GetSafeHwnd(), m_pChapterModel); ASSERT( m_pTocChapterListener); m_pChapterModel->addPropertyChangeListener( m_pTocChapterListener); m_pTocBookListener = new TTocBookListener( GetSafeHwnd()); ASSERT( m_pTocBookListener); m_pBookModel->addPropertyChangeListener( m_pTocBookListener); // --- check if i need to show empty sticker if( m_treeCtrl.GetCount() == 0) CreateSticker(); return 0; } void CKbChapterToc::OnDestroy() { // --- remove the listener ASSERT( m_pTocChapterListener); // Just in case // Don't want to crash in Release mode if (m_pTocChapterListener) { m_pChapterModel->removePropertyChangeListener( m_pTocChapterListener); m_pTocChapterListener->setInvalid(); //delete m_pTocChapterListener; // --- listener can't be delete m_pTocChapterListener = NULL; } ASSERT( m_pTocBookListener); // Just in case // Don't want to crash in Release mode if (m_pTocBookListener) { m_pBookModel->removePropertyChangeListener( m_pTocBookListener); m_pTocBookListener->setInvalid(); //delete m_pTocBookListener; // --- listener can't be delete m_pTocBookListener = NULL; } CKbTreeTocWnd::OnDestroy(); } ///////////////////////////////////////////////////////////////////////////// // CKbChapterToc Fill List void CKbChapterToc::FillList( TChapterModel* pChapterParent, HTREEITEM hTiParent) { ASSERT( pChapterParent); // --- first be sure that the list is empty. // --- use a safe loop, get always the first item for( HTREEITEM hTi = m_treeCtrl.GetChildItem( hTiParent); hTi; hTi = m_treeCtrl.GetChildItem( hTiParent)) { m_treeCtrl.DeleteBranch( hTi); } // --- iteration on pages in this chapter TGlobalsDB::getLibraryDBManager()->beginTransaction( t_transaction_types::TRANSACTION_READONLY); TModelIterator* iter = NULL; pChapterParent->getPages( &iter); while( iter && iter->hasMoreElements()) { // --- get the page model TModelPtr page; iter->nextElement( (TObjectModel**) &page); // --- insert item in the list HTREEITEM hTiInserted = InsertItem( page, hTiParent); if (hTiInserted == NULL) continue; if (page->isInstanceOf( T_CHAPTER_MODEL_NAME)) { // --- read the expand state TModelPtr pPropModel; pPropModel = page->getDefaultProperty(); ASSERT( pPropModel); boolean bSet; if (pPropModel->getBooleanField( T_PAGE_DEFAULT_PROPERTY_TOC_EXPANDED, &bSet)) { if (bSet) m_treeCtrl.Expand( hTiInserted, TVE_EXPAND); } } } delete iter; TGlobalsDB::getLibraryDBManager()->commitTransaction(); } ///////////////////////////////////////////////////////////////////////////// // CKbChapterToc tree list notification BOOL CKbChapterToc::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { NMTREEVIEW* pNMTreeView = (NMTREEVIEW*) lParam; int nCode = pNMTreeView->hdr.code; int nId = pNMTreeView->hdr.idFrom; // --- handle the tree item expansion if( nCode == TVN_ITEMEXPANDING && nId == IDC_TREE) { TRACE( _T("*** CKbChapterToc::OnNotify TVN_ITEMEXPANDING\n")); HTREEITEM hTiNew = pNMTreeView->itemNew.hItem; CKbModelItem* pItem = (CKbModelItem*) pNMTreeView->itemNew.lParam; ASSERT( pItem); if( !m_treeCtrl.IsItemExpandedOnce( hTiNew)) { // --- it's the first time expansion TChapterModel* pChapterModel = (TChapterModel*) pItem->GetPageModel(); FillList( pChapterModel, hTiNew); } // --- update expand state in the db TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE); if( pItem->IsItemContainer()) { CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiNew); ASSERT( pItem); TPageModel* pPageModel = pItem->GetPageModel(); TModelPtr pPropModel; pPageModel->getDefaultProperty( &pPropModel); ASSERT( pPropModel); boolean bSet = !m_treeCtrl.IsItemExpanded( hTiNew); pPropModel->putBooleanField( T_PAGE_DEFAULT_PROPERTY_TOC_EXPANDED, bSet); } TGlobalsDB::getLibraryDBManager()->commitTransaction(); *pResult = FALSE; // --- continue } // --- handle this end of the inplace edition else if( nCode == TVN_ENDLABELEDIT && nId == IDC_TREE) { TRACE( _T("*** CKbChapterToc::OnNotify TVN_ENDLABELEDIT\n")); TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*) lParam; // --- get the result of the edition LPCTSTR szText = pTVDispInfo->item.pszText; if( szText) { // --- and update the title in the database CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( pTVDispInfo->item.hItem); TPageModel* pPageModel = pItem->GetPageModel(); pPageModel->setTitle( szText); AddBehaviour( pPageModel, F_PAGE_DEFINED_TITLE); } *pResult = FALSE; // --- don't update the tree item } return CKbTreeTocWnd::OnNotify(wParam, lParam, pResult); } ///////////////////////////////////////////////////////////////////////////// // CKbChapterToc message handlers BOOL CKbChapterToc::PreTranslateMessage(MSG* pMsg) { return CKbTreeTocWnd::PreTranslateMessage(pMsg); } void CKbChapterToc::OnNotifyDestroy( NMHDR *pNotifyStruct, LRESULT *result) { m_pPostItWnd = NULL; } ///////////////////////////////////////////////////////////////////////////// // CKbTreeWndDrag and drop handlers DROPEFFECT CKbChapterToc::OnDragEnter( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { m_dropEffect = CKbTreeTocWnd::OnDragEnter( pDataObject, dwKeyState, point); /* CPoint pt( point); ClientToScreen( &pt); CImageList::DragEnter( this, pt); */ return CheckDragOver(pDataObject, dwKeyState, point); } void CKbChapterToc::OnDragLeave() { /* CImageList::DragLeave( this); */ CKbTreeTocWnd::OnDragLeave(); } DROPEFFECT CKbChapterToc::OnDragOver( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { /* CPoint pt( point); ClientToScreen( &pt); CImageList::DragMove( pt); */ CKbTreeTocWnd::OnDragOver( pDataObject, dwKeyState, point); return CheckDragOver(pDataObject, dwKeyState, point); } DROPEFFECT CKbChapterToc::CheckDragOver( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point) { if (m_dropEffect && m_keyState == dwKeyState) return m_dropEffect; m_keyState = dwKeyState; // --- if the book is protected, no modification is allowed if ( IsModifyProtected()) return DROPEFFECT_NONE; TOleDataObject lDataObject; lDataObject.Attach(pDataObject->m_lpDataObject, FALSE); #ifdef DEBUG_DRAG_FORMAT DumpDragFormat(lDataObject); #endif if (lDataObject.HaveData(E_DATA_TYPE_KEEBOO_NEW_CHAPTER)) { m_dropEffect = DROPEFFECT_COPY; } else if (lDataObject.HaveData(E_DATA_TYPE_BROWSER_URL)) { // *** Drop files from ie or Netscape in the WebBrowser CString lUrl = lDataObject.GetUrlData(); // Do not allow script or mailto url if ((lUrl.Find("script:") != -1) || (lUrl.Find("mailto:") != -1)) m_dropEffect = DROPEFFECT_NONE; else m_dropEffect = DROPEFFECT_COPY; } else if (lDataObject.HaveData(E_DATA_TYPE_KEEBOO_PAGE)) { if( (dwKeyState & MK_CONTROL) == MK_CONTROL) m_dropEffect = DROPEFFECT_COPY; else m_dropEffect = DROPEFFECT_MOVE; // --- don't allow to drop inside the drag selection and inside the selection for( HTREEITEM hTiInc = m_treeCtrl.m_hTiDragOver; hTiInc; hTiInc = m_treeCtrl.GetParentItem( hTiInc)) { int nMax = m_treeCtrl.m_arrayHtiDragged.GetSize(); for( int n=0; nIsDataAvailable(CF_HDROP)) { m_dropEffect = DROPEFFECT_LINK; } else { m_dropEffect = DROPEFFECT_NONE; } return m_dropEffect; } DROPEFFECT CKbChapterToc::OnDragScroll( DWORD dwKeyState, CPoint point ) { return CKbTreeTocWnd::OnDragScroll( dwKeyState, point ); } BOOL CKbChapterToc::OnDrop( COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point) { (void) CKbTreeTocWnd::OnDrop( pDataObject, dropEffect, point); BOOL bResult = TRUE; // --- Disable any drop at the top of an unmovable page !! // --- This is used for instance in the Surf Book not to be able to insert anything BEFORE the Web Search page... // !!! THIS IS WRONG BUT IT WORKS... CHANGE IT QUICKLY TO THE RIGHT TEST !!! HTREEITEM hTiDrop = m_treeCtrl.m_hTiOnDrop; if( hTiDrop == TVI_FIRST) { hTiDrop = m_treeCtrl.m_hTiOnDropParent; if (hTiDrop == TVI_ROOT) { hTiDrop = m_treeCtrl.GetRootItem(); } CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDrop); TModelPtr pPageModel; pPageModel = pItem->GetPageModel(); if( !IsMovable( pPageModel)) { TSoundManager::PlayFromResource( IDSOUND_ALERT); return FALSE; } } TOleDataObject lDataObject; lDataObject.Attach(pDataObject->m_lpDataObject, FALSE); if (lDataObject.HaveData(E_DATA_TYPE_KEEBOO_NEW_CHAPTER)) { bResult = OnTocDropChapter( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent); } else if (lDataObject.HaveData(E_DATA_TYPE_BROWSER_URL)) { bResult = OnTocDropUrl( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject); } else if (lDataObject.HaveData(E_DATA_TYPE_KEEBOO_PAGE)) { // --- store dropEffect to avoid use moving page m_dropEffectPage = dropEffect; bResult = OnTocDropPages( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject, dropEffect ); } #ifdef CAN_DRAG_MAIL else if (lDataObject.HaveData(E_DATA_TYPE_EMAIL)) { bResult = OnTocDropMail( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject); } #endif // CAN_DRAG_MAIL #ifdef CAN_DRAG_TEXT else if (lDataObject.HaveData(E_DATA_TYPE_TEXT)) { bResult = OnTocDropText( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject); } #endif // CAN_DRAG_TEXT else if (pDataObject->IsDataAvailable(CF_HDROP)) { bResult = OnTocDropOsFiles( m_treeCtrl.m_hTiOnDrop, m_treeCtrl.m_hTiOnDropParent, pDataObject); } else { bResult = FALSE; TSoundManager::PlayFromResource( IDSOUND_ALERT); } return bResult; } ///////////////////////////////////////////////////////////////////////////// // CKbTreeWnd message drop handlers BOOL CKbChapterToc::OnTocDropChapter( HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent) { TRACE( _T("CKbChapterToc::OnTocDropChapter\n")); // --- get the chapter controler CComPtr pChapterControler; HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler); if( FAILED( hResult)) return FALSE; long lPos; TModelPtr pPageSelected; TModelPtr pChapterParent; if( hTiDropped == TVI_FIRST) { // --- put in the begin of the chapter if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT) { CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent); ASSERT( pItem); TChapterModel *pChapterModel = (TChapterModel*) pItem->GetPageModel(); ASSERT( pChapterModel); pChapterControler->put_chapter( (long) pChapterModel); } else { pChapterControler->put_chapter( (long) GetChapterModel()); } lPos = 0; } else if( hTiDropped == TVI_LAST) { // --- put in the end of the chapter pChapterControler->put_chapter( (long) GetChapterModel()); lPos = T_POS_LAST; } else if( hTiDropped) { // --- get item data CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped); ASSERT( pItem); pPageSelected = pItem->GetPageModel(); HRESULT hResult = pPageSelected->getPagePosition( &lPos); ASSERT( SUCCEEDED( hResult)); pPageSelected->getChapter( &pChapterParent); pChapterControler->put_chapter( (long) pChapterParent.p); } else { // --- the tree ctrl is empty, or no item is selected pChapterControler->put_chapter( (long) GetChapterModel()); lPos = 0; } // --- create a new chapter AFX_MANAGE_STATE( AfxGetAppModuleState()); TModelPtr pNewChapter; TMetaManager::createModelInstance( T_CHAPTER_MODEL_NAME, (void**) &pNewChapter); CString stgChapterTitle; KBLoadString( IDS_TOC_NEW_CHAPTER, stgChapterTitle); pNewChapter->setTitle( stgChapterTitle); // --- add it in the database CComVariant varChapter( (long) pNewChapter.p); long lNotUsed; if( SUCCEEDED( pChapterControler->Add( varChapter, lPos, (long *) &lNotUsed))) { // Play sound when inserting a chapter in the toc TSoundManager::PlayFromResource( IDSOUND_DROP_PAGE); TSoundManager::PlayFromResource( IDSOUND_NEW_ITEM); // --- keep chapter to edit it later, release when page arrive in the listener m_pPageToEdit = pNewChapter; m_pPageToEdit.p->AddRef(); return TRUE; } return FALSE; } BOOL CKbChapterToc::OnTocDropOsFiles( HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject) { // --- get the page model from the htreeItem int nPosition = T_POS_LAST; TModelPtr pPageModel; if ( hTiDropped == TVI_FIRST) { if ( hTiDroppedParent && hTiDroppedParent != TVI_ROOT) { // --- get item data CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent); ASSERT( pItem); pPageModel = pItem->GetPageModel(); } else { pPageModel = (TPageModel *) GetChapterModel(); } nPosition = 0; } else if ( hTiDropped == TVI_LAST) { // --- it's the last item, so insert it to the end of this chapter pPageModel = (TPageModel *) GetChapterModel(); } else if ( hTiDropped != NULL) { CKbModelItem* pItem; if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT) { // --- get item data pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent); ASSERT( pItem); pPageModel = pItem->GetPageModel(); } else { pPageModel = (TPageModel *) GetChapterModel(); } // --- get item data pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped); ASSERT( pItem); TPageModel* pPageModelTmp = pItem->GetPageModel(); ASSERT( pPageModelTmp); HRESULT hResult = pPageModelTmp->getPagePosition( (long*) &nPosition); ASSERT( SUCCEEDED( hResult)); } else { // --- the tree ctrl is empty, or no item is selected pPageModel = (TPageModel *) GetChapterModel(); } // --- get the number of file dropped STGMEDIUM* pStgMedium = new STGMEDIUM; memset( pStgMedium, 0, sizeof( STGMEDIUM)); pDataObject->GetData( CF_HDROP, pStgMedium); HDROP pFileData = (HDROP) ::GlobalLock( pStgMedium->hGlobal); ASSERT( pFileData); int nFileNameCount = DragQueryFile( pFileData, 0xFFFFFFFF, NULL, 0); // --- prepare the progress dialog // TBooxFrame::GetMainWnd()->EnableWindow( FALSE); CProgressDlg* pDlg; CString stgFormatStep; long lPosition; { AFX_MANAGE_STATE( AfxGetAppModuleState()); pDlg = new CProgressDlg; VERIFY( pDlg->Create( _T("CProgressDlg"), WS_CHILD/* | WS_VISIBLE*/, CRect( 0, 0, 10, 10), AfxGetMainWnd(), 1 )); CString stgTmp; VERIFY( KBLoadString( IDS_PROGDLG_COPY_FILE_TITLE, stgTmp)); pDlg->SetTitle( stgTmp); VERIFY( KBLoadString( IDS_CANCEL, stgTmp)); pDlg->SetCancel( stgTmp); KBLoadString( IDS_PROGDLG_STEP, stgFormatStep); pDlg->ChangeAnimation( 1 /*FILECOPY*/); pDlg->SetUpper( (short) nFileNameCount); lPosition = 1; } // --- insert all the pages CWaitCursor waitCursor; TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE); for(int n = 0; n < nFileNameCount; n++) { // --- get the filename CString stgFileName; LPTSTR szBuffer = stgFileName.GetBuffer( _MAX_PATH); DragQueryFile( pFileData, n, szBuffer, _MAX_PATH); stgFileName.ReleaseBuffer(); // --- update the progress dialog { // AFX_MANAGE_STATE( AfxGetAppModuleState()); if( pDlg->IsProcessCanceled()) break; // --- get the kind of the file UINT uStringId = IDS_PROGDLG_COPY_FILE_NAME; CFileStatus fileStatus; if( CFile::GetStatus( stgFileName, fileStatus)) { if( fileStatus.m_attribute & CFile::directory) { uStringId = IDS_PROGDLG_COPY_DIR_NAME; } } CString stgTmp; KBLoadString( uStringId, stgTmp); stgTmp.FormatMessage( stgTmp, (LPCTSTR) stgFileName); pDlg->SetComment( (LPCTSTR) stgTmp); stgTmp.FormatMessage( stgFormatStep, lPosition, nFileNameCount); pDlg->SetStep( stgTmp); pDlg->SetPosition( (short) lPosition++); } CString stgExt; TPath::FindExtension( stgFileName, stgExt); if( stgExt.CompareNoCase( _T(".7xB"))) { // --- insert all file under this filename TBrowseDir browseDir; browseDir.SetCallback(NULL); browseDir.Reset(); browseDir.Run( stgFileName, pPageModel, TRUE, nPosition); } } TGlobalsDB::getLibraryDBManager()->commitTransaction(); ::GlobalUnlock( pStgMedium->hGlobal); delete pStgMedium; pStgMedium = NULL; // --- close the progress bar { AFX_MANAGE_STATE( AfxGetAppModuleState()); pDlg->DestroyWindow(); pDlg = NULL; } // TBooxFrame::GetMainWnd()->EnableWindow( TRUE); return TRUE; } BOOL CKbChapterToc::OnTocDropUrl( HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject) { CString stgTitle, stgUrl; TOleDataObject lDataObject; lDataObject.Attach(pDataObject->m_lpDataObject, FALSE); // --- get the url string stgUrl = lDataObject.GetUrlData(); // --- get the link name if any if (lDataObject.HaveData(E_DATA_TYPE_SHELL_LINK_NAME)) { // --- Get url name stgTitle = lDataObject.GetLinkName(); } else { stgTitle = stgUrl; } // --- get the chapter controler CComPtr pChapterControler; HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler); if( FAILED( hResult)) return FALSE; // --- get the page model from the htreeItem long lPos = 0; TModelPtr pPageSelected; TModelPtr pChapterParent; if( hTiDropped == TVI_FIRST) { if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT) { // --- get item data CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent); ASSERT( pItem); TChapterModel* pChapterModel = (TChapterModel *) pItem->GetPageModel(); ASSERT( pChapterModel); pChapterControler->put_chapter( (long) pChapterModel); } else { pChapterControler->put_chapter( (long) GetChapterModel()); } lPos = 0; } else if( hTiDropped == TVI_LAST) { pChapterControler->put_chapter( (long) GetChapterModel()); lPos = T_POS_LAST; } else if( hTiDropped != NULL) { // --- get item data CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped); ASSERT( pItem); pPageSelected = pItem->GetPageModel(); HRESULT hResult = pPageSelected->getPagePosition( &lPos); ASSERT( SUCCEEDED( hResult)); pPageSelected->getChapter( &pChapterParent); pChapterControler->put_chapter( (long) pChapterParent.p); } else { // --- the tree ctrl is empty, or no item is selected pChapterControler->put_chapter( (long) GetChapterModel()); } // --- add it in the database CComBSTR bstr( stgUrl); CComVariant varPage( (BSTR) bstr); TPageModel* pPageModelAdded; CWaitCursor waitCursor; BOOL bResult = FALSE; TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE); if( SUCCEEDED( pChapterControler->Add( varPage, lPos, (long *) &pPageModelAdded))) { // Play sound when inserting a chapter in the toc TSoundManager::PlayFromResource( IDSOUND_DROP_PAGE); TSoundManager::PlayFromResource( IDSOUND_NEW_ITEM); ASSERT( pPageModelAdded); pPageModelAdded->setTitle( stgTitle); bResult = TRUE; } TGlobalsDB::getLibraryDBManager()->commitTransaction(); return bResult; } BOOL CKbChapterToc::OnTocDropPages(HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject, DROPEFFECT dropEffect) { TRACE( _T("CKbChapterToc::OnTocDropPages\n")); // --- get the chapter controler CComPtr pChapterControler; HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler); if( FAILED( hResult)) { TSoundManager::PlayFromResource( IDSOUND_ALERT); return FALSE; } long lPos = 0; TModelPtr pPageSelected; TModelPtr pChapterParent; if( hTiDropped == TVI_FIRST) { if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT) { // --- get item data CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent); ASSERT( pItem); TChapterModel* pChapterModel = (TChapterModel *) pItem->GetPageModel(); ASSERT( pChapterModel); pChapterControler->put_chapter( (long) pChapterModel); } else { // --- put in the begin of the chapter pChapterControler->put_chapter( (long) GetChapterModel()); } lPos = 0; } else if( hTiDropped == TVI_LAST) { // --- put in the end of the chapter TModelPtr pChapter; pChapter = GetChapterModel(); pChapterControler->put_chapter( (long) pChapter.p); TModelPtr pPage; int nPageCount = pChapter->getPageCount(); if( nPageCount == 0) { lPos = 0; } else { pChapter->getPage( nPageCount, &pPage); if (pPage) { pPage->getPagePosition( &lPos); } else { // Error value lPos = 0; } } } else if( hTiDropped != NULL) { // --- get item data CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped); ASSERT( pItem); pPageSelected = pItem->GetPageModel(); HRESULT hResult = pPageSelected->getPagePosition( &lPos); ASSERT( SUCCEEDED( hResult)); pPageSelected->getChapter( &pChapterParent); pChapterControler->put_chapter( (long) pChapterParent.p); } else { // --- the tree ctrl is empty, or no item is selected pChapterControler->put_chapter( (long) GetChapterModel()); } TOleDataObject lDataObject; lDataObject.Attach(pDataObject->m_lpDataObject, FALSE); // --- get drag and drop data TDragAndDropPageData* pPageData; pPageData = lDataObject.GetPageData(); ASSERT( pPageData); // --- browse all page CWaitCursor waitCursor; TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE); TPtrArray* pArray = pPageData->getPagesList(); ASSERT( pArray); TPtrIterator *pIter = pArray->elements(); while( pIter->hasMoreElements()) { TPageModel *pPageModel = (TPageModel*) pIter->nextElement(); // --- add it in the database CComVariant varChapter( (long) pPageModel); long lNotUsed; if( dropEffect == DROPEFFECT_COPY) { hResult = pChapterControler->Copy( varChapter, lPos, (long *) &lNotUsed); } else if( dropEffect == DROPEFFECT_MOVE) { hResult = pChapterControler->Move( varChapter, lPos); } else { ASSERT( false); // --- can't be another value } } delete pIter; TGlobalsDB::getLibraryDBManager()->commitTransaction(); // Play sound when inserting a chapter in the toc if (SUCCEEDED( hResult)) { TSoundManager::PlayFromResource( IDSOUND_DROP_PAGE); TSoundManager::PlayFromResource( IDSOUND_NEW_ITEM); } return SUCCEEDED( hResult); } HRESULT CKbChapterToc::OnTocDropMail(HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject) { HRESULT lResult; HGLOBAL lHGlobal; TOleDataObject lDataObject; lDataObject.Attach(pDataObject->m_lpDataObject, FALSE); lHGlobal = lDataObject.GetGlobalData(TOleDataObject::GetClipFormat(E_DATA_TYPE_EMAIL)); lResult = CreateFakeFile( hTiDropped, hTiDroppedParent, pDataObject, (LPBYTE)::GlobalLock(lHGlobal), ::GlobalSize(lHGlobal)); ::GlobalUnlock(lHGlobal); return lResult; } HRESULT CKbChapterToc::OnTocDropText(HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject) { HRESULT lResult = S_OK; HGLOBAL lHGlobal = NULL; LPCTSTR lMime = NULL; LPBYTE lData = NULL; DWORD dwSize = 0; TOleDataObject lDataObject; lDataObject.Attach(pDataObject->m_lpDataObject, FALSE); TString lTitle = _T(""); CHtmlClipFormat lHtmlFormat; if (lDataObject.HaveData(E_DATA_TYPE_TEXT_HTML)) { // Do HTML handling lMime = _T("text/html"); lHtmlFormat = lDataObject.GetHTMLFormat(); lData = lHtmlFormat.AllocHtml(dwSize); lTitle = lHtmlFormat.GetSourceUrl(); } else if (lDataObject.HaveData(E_DATA_TYPE_TEXT_RTF)) { lMime = _T("text/rtf"); lHGlobal = lDataObject.GetGlobalData(TOleDataObject::GetClipFormat(E_DATA_TYPE_TEXT_RTF)); } else if (lDataObject.HaveData(E_DATA_TYPE_TEXT)) { lMime = _T("text/plain"); lHGlobal = lDataObject.GetGlobalData(TOleDataObject::GetClipFormat(E_DATA_TYPE_TEXT)); } if (lHGlobal || lData) { if (lData == NULL) { lData = (LPBYTE)::GlobalLock(lHGlobal); dwSize = ::GlobalSize(lHGlobal); } lResult = CreateFakeFile(hTiDropped, hTiDroppedParent, pDataObject, lData, dwSize, lMime, lTitle ); if (lHGlobal) ::GlobalUnlock(lHGlobal); } return lResult; } HRESULT CKbChapterToc::CreateFakeFile(HTREEITEM hTiDropped, HTREEITEM hTiDroppedParent, COleDataObject* pDataObject, LPBYTE pData, DWORD dwSize, LPCTSTR pMime, TString lTitle ) { USES_CONVERSION; CComPtr lCache; HRESULT lResult; TOleDataObject lDataObject; lDataObject.Attach(pDataObject->m_lpDataObject, FALSE); // Create Fake URL CString lStrUrl; lStrUrl.Format("internal://cache/filecontent/%d", time(0)); TSevenixUrl lUrl(lStrUrl); // Create Cache Entry if (pData && SUCCEEDED(GetCache(T_NETWORK_CACHE_NAME, &lCache))) { CComPtr lEntry; if (SUCCEEDED(lCache->createEntry(CComBSTR(lUrl.extendedUrlString()), &lEntry))) { CComBSTR lFileName; // Fill Cache File if (SUCCEEDED(lEntry->getFileName(&lFileName))) { CFile lFile; if (lFile.Open(W2CT(lFileName), CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite)) { TRY { lFile.Write(pData, dwSize); } CATCH_ALL(e) { } END_CATCH_ALL lFile.Flush(); lFile.Close(); /* CComPtr lBookControler; lBookControler.CoCreateInstance(CLSID_TBookControler); ATLASSERT(lBookControler); if (lBookControler) { TModelPtr lNewPage; TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE); lResult = lBookControler->Add(COleVariant(lUrl.extendedUrlString(), VT_BSTR), T_POS_REPLACE_SELECTED, (long*)&lNewPage); ATLASSERT(SUCCEEDED(lResult) && lNewPage); if (SUCCEEDED(lResult) && lNewPage) { lNewPage->setTitle(lUrl.simpleUrlString()); // Cast because model are not COM interface !!! lBookControler->ChangePageTo(T_CPT_PAGE, T_SIDE_SELECTED, CComVariant((long)lNewPage.p)); } TGlobalsDB::getLibraryDBManager()->commitTransaction(); if (pMime) lEntry->addHeader(L"Content-Type", T2CW(pMime)); lEntry->commit(); return S_OK; } */ // --- get the chapter controler CComPtr pChapterControler; HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler); if( FAILED( hResult)) return FALSE; // --- get the page model from the htreeItem long lPos = 0; TModelPtr pPageSelected; TModelPtr pChapterParent; if( hTiDropped == TVI_FIRST) { if( hTiDroppedParent && hTiDroppedParent != TVI_ROOT) { // --- get item data CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDroppedParent); ASSERT( pItem); TChapterModel* pChapterModel = (TChapterModel *) pItem->GetPageModel(); ASSERT( pChapterModel); pChapterControler->put_chapter( (long) pChapterModel); } else { pChapterControler->put_chapter( (long) GetChapterModel()); } lPos = 0; } else if( hTiDropped == TVI_LAST) { pChapterControler->put_chapter( (long) GetChapterModel()); lPos = T_POS_LAST; } else if( hTiDropped != NULL) { // --- get item data CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiDropped); ASSERT( pItem); pPageSelected = pItem->GetPageModel(); HRESULT hResult = pPageSelected->getPagePosition( &lPos); ASSERT( SUCCEEDED( hResult)); pPageSelected->getChapter( &pChapterParent); pChapterControler->put_chapter( (long) pChapterParent.p); } else { // --- the tree ctrl is empty, or no item is selected pChapterControler->put_chapter( (long) GetChapterModel()); } // --- add it in the database CComBSTR bstr( lUrl.extendedUrlString() ); CComVariant varPage( (BSTR) bstr); TPageModel* pPageModelAdded; CWaitCursor waitCursor; BOOL bResult = FALSE; TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE); if( SUCCEEDED( pChapterControler->Add( varPage, lPos, (long *) &pPageModelAdded))) { // Play sound when inserting a chapter in the toc TSoundManager::PlayFromResource( IDSOUND_DROP_PAGE); TSoundManager::PlayFromResource( IDSOUND_NEW_ITEM); ASSERT( pPageModelAdded); pPageModelAdded->setTitle( lTitle ); bResult = TRUE; } TGlobalsDB::getLibraryDBManager()->commitTransaction(); if (pMime) lEntry->addHeader(L"Content-Type", T2CW(pMime)); lEntry->commit(); return S_OK; } } lEntry->remove(); } } return E_FAIL; } ///////////////////////////////////////////////////////////////////////////// // CKbTreeWnd message menu handlers void CKbChapterToc::OnInitMenuPopup( CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) { CKbTreeTocWnd::OnInitMenuPopup( pPopupMenu, nIndex, bSysMenu); if( IsModifyProtected()) { VERIFY( pPopupMenu->EnableMenuItem( IDM_TOC_NEWCHAPTER, MF_BYCOMMAND | MF_GRAYED) != -1); VERIFY( pPopupMenu->EnableMenuItem( IDM_TOC_NEWURL, MF_BYCOMMAND | MF_GRAYED) != -1); VERIFY( pPopupMenu->EnableMenuItem( IDM_TOC_NEWOSFILES, MF_BYCOMMAND | MF_GRAYED) != -1); } } void CKbChapterToc::OnTocRename() { TRACE( _T("CKbChapterToc::OnTocRename\n")); HTREEITEM hTiToEdit; if( m_treeCtrl.m_hTiRButtonDown) { hTiToEdit = m_treeCtrl.m_hTiRButtonDown; } else { ASSERT( m_treeCtrl.m_listHtiSelected.GetCount() == 1); hTiToEdit = (HTREEITEM) m_treeCtrl.m_listHtiSelected.GetHead(); } (void) m_treeCtrl.EditLabel( hTiToEdit); } void CKbChapterToc::OnTocNewChapter() { TRACE( _T("CKbChapterToc::OnTocNewChapter\n")); HTREEITEM hTi = m_treeCtrl.m_hTiRButtonDown ? m_treeCtrl.m_hTiRButtonDown : TVI_LAST; m_treeCtrl.ClearSelection(); BOOL bResult = OnTocDropChapter( hTi, NULL); if (!bResult) TSoundManager::PlayFromResource( IDSOUND_ALERT); } void CKbChapterToc::OnTocNewOsFiles() { TRACE( _T("CKbChapterToc::OnTocNewOsFiles\n")); // --- get the page model for this item HTREEITEM hTi = m_treeCtrl.m_hTiRButtonDown; TModelPtr pPageModel; if( hTi) { CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTi); pPageModel = pItem->GetPageModel(); // --- open the item if it's a colappe chapter if( pItem->IsItemContainer() && !m_treeCtrl.IsItemExpanded( hTi)) { m_treeCtrl.Expand( hTi, TVE_EXPAND); } } m_treeCtrl.ClearSelection(); // --- call the dialog AFX_MANAGE_STATE( AfxGetAppModuleState()); TBooxFrame::GetActiveBooxView()->OnFileFile( pPageModel); } void CKbChapterToc::OnTocNewUrl() { TRACE( _T("CKbChapterToc::OnTocNewUrl\n")); // --- get the page model for this item TModelPtr pPageModel; if( m_treeCtrl.m_hTiRButtonDown) { CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( m_treeCtrl.m_hTiRButtonDown); pPageModel = pItem->GetPageModel(); } m_treeCtrl.ClearSelection(); // --- call the dialog AFX_MANAGE_STATE( AfxGetAppModuleState()); TBooxFrame::GetActiveBooxView()->OnFileNavigate( pPageModel); } void CKbChapterToc::OnEditCopy() { TRACE( _T("CKbChapterToc::OnEditCopy\n")); CKbTreeTocWnd::OnEditCopy(); } void CKbChapterToc::OnEditCut() { TRACE( _T("CKbChapterToc::OnEditCut\n")); CKbTreeTocWnd::OnEditCut(); } void CKbChapterToc::OnEditPaste() { TRACE( _T("CKbChapterToc::OnEditPaste\n")); CKbTreeTocWnd::OnEditPaste(); } void CKbChapterToc::OnEditDel() { TRACE( _T("CKbChapterToc::OnEditDel\n")); CKbTreeTocWnd::OnEditDel(); } ///////////////////////////////////////////////////////////////////////////// // CKbTreeWnd listener handlers LRESULT CKbChapterToc::OnChapterAddPage( WPARAM wParam, LPARAM lParam) { LRESULT lResult = TRUE; TPageModel* pPageModel = (TPageModel*) lParam; TChapterModel* pChapterModel = (TChapterModel*) wParam; TRACE( _T("### CKbChapterToc::OnChapterAddPage (%s)\n"), pPageModel->getTitle()); /* // --- get the parent model, TModelPtr pChapterModel; pPageModel->getParentChapter( (TPageModel **) &pChapterModel); ASSERT( pChapterModel); */ // --- then the parent item HTREEITEM hTiParent = GetItemFromModel( pChapterModel); if( hTiParent == NULL) hTiParent = TVI_ROOT; HTREEITEM hTiInserted; if (hTiParent == TVI_ROOT || pChapterModel == m_pChapterModel || m_treeCtrl.IsItemExpanded( hTiParent)) { // --- get the page model after this new, then item HTREEITEM hTiAfter = m_treeCtrl.GetChildItem( hTiParent); if( hTiAfter == NULL) { // --- there no child, so just insert it hTiAfter = TVI_LAST; // --- and reset the chid flag to have the indent button if (hTiParent != TVI_ROOT) m_treeCtrl.SetItemChildren( hTiParent, 1); } else { // --- parent has children, so search the insertion position int nRef = m_pBookModel->getPageIndex( pPageModel); HTREEITEM hTiCur = hTiAfter; HTREEITEM hTiBefore = TVI_FIRST; hTiAfter = TVI_LAST; do { if (m_dropEffectPage == DROPEFFECT_MOVE) { // --- don't use item candidate to move because // --- I'm not sure that they will be at the right place du to the asynchronous event bool bIsFound = false; int nMax = m_treeCtrl.m_arrayHtiDragged.GetSize(); for (int n=0; nGetPageModel(); int nCur = m_pBookModel->getPageIndex( pPageModelCur); TRACE( _T("*** ::OnChapterAddPage Browse %d (%s)\n"), nCur, pItem->GetSubText(0)); if( nCur >= nRef+1) { hTiAfter = hTiBefore; break; } hTiBefore = hTiCur; } while ((hTiCur = m_treeCtrl.GetNextSiblingItem( hTiCur)) != NULL); } // --- item can be visible, so do changement hTiInserted = InsertItem( pPageModel, hTiParent, hTiAfter); if (hTiInserted) { // --- check if this item is a chapter CKbModelItem *pItem = (CKbModelItem *) m_treeCtrl.GetKbItemData( hTiInserted); if (pItem->IsItemContainer()) { AddPagesIntoChapter( hTiInserted); } // --- check if this item is to edit //if( hTiParent != TVI_ROOT) m_treeCtrl.Expand( hTiParent, TVE_EXPAND); if (pPageModel == m_pPageToEdit.p) { m_treeCtrl.SelectItem( hTiInserted); m_treeCtrl.EditLabel( hTiInserted); } else { // --- auto selected the new page m_treeCtrl.SetItemSelected( hTiInserted, true); } } } else { // --- item is collapsed, so set the flag to refresh his children if (hTiParent != TVI_ROOT) { m_treeCtrl.SetItemExpandedOnce( hTiParent, FALSE); m_treeCtrl.SetItemChildren( hTiParent, 1); } hTiInserted = hTiParent; } // --- release the page to edit if any if (pPageModel == m_pPageToEdit.p) m_pPageToEdit.Release(); // --- now reset the page number while ((hTiInserted = m_treeCtrl.GetNextItem( hTiInserted)) != NULL) { // --- get the page number CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiInserted); TPageModel* pPageModel = pItem->GetPageModel(); int nPage = m_pBookModel->getPageIndex( pPageModel); pItem->SetSubInteger( 1, nPage); m_treeCtrl.RedrawItem( hTiInserted); } // --- now reset the parent annotation flag long lAnnoPage, lAnnoParent; pPageModel->getGlobalSubAnnotationsCount( &lAnnoPage); if (pChapterModel) pChapterModel->getGlobalSubAnnotationsCount( &lAnnoParent); if (lAnnoPage >= 1L) { // --- a new annotation has been inserted, so update the parent while( hTiParent != TVI_ROOT && hTiParent != NULL) { CKbModelItem *pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiParent); pItem->SetSubInteger( 2, ANNOTATION); m_treeCtrl.RedrawItem( hTiParent); hTiParent = m_treeCtrl.GetParentItem( hTiParent); } } // --- remove empty sticker if any { AFX_MANAGE_STATE( AfxGetAppModuleState()); if (m_pPostItWnd) { m_pPostItWnd->SendMessage( WM_CLOSE); m_pPostItWnd = NULL; // --- delete is made by Destroy Window Invalidate(); } } // --- As this is a MESSAGE posting, an AddRef has been done before sending it, // --- so we'll have to Release it when the processing is over. pPageModel->Release(); if (pChapterModel) pChapterModel->Release(); return lResult; } LRESULT CKbChapterToc::OnChapterRemovePage( WPARAM wParam, LPARAM lParam) { LRESULT lResult = 0; TPageModel* pPageModel = (TPageModel*) lParam; TChapterModel* pChapterModel = (TChapterModel*) wParam; TRACE( _T("### CKbChapterToc::OnChapterRemovePage (%s)\n"), pPageModel->getTitle()); HTREEITEM hTiPage = GetItemFromModel( pPageModel); if (pChapterModel) { HTREEITEM hTiParent = GetItemFromModel( pChapterModel); if( hTiParent == NULL) hTiParent = TVI_ROOT; TVITEM item; item.hItem = hTiParent; item.mask = TVIF_CHILDREN; item.cChildren = pChapterModel->getPageCount() != 0; m_treeCtrl.SendMessage(TVM_SETITEM, 0, (LPARAM)&item); } // --- if the item is not found, it's because a tree was deleted if (hTiPage) { // --- now reset the page number HTREEITEM hTiInc = hTiPage; while ((hTiInc = m_treeCtrl.GetNextItem( hTiInc)) != NULL) { // --- get the page number CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiInc); TPageModel* pPageModel = pItem->GetPageModel(); int nPage = m_pBookModel->getPageIndex( pPageModel); pItem->SetSubInteger( 1, nPage); TRACE( _T("*** ::OnChapterRemovePage Update %d (%s)\n"), nPage, pItem->GetSubText(0)); m_treeCtrl.RedrawItem( hTiInc); } // --- delete branch if the item is in the first level or on a chapter expanded HTREEITEM hTiParent = m_treeCtrl.GetParentItem( hTiPage); if (hTiParent == NULL || m_treeCtrl.IsItemExpanded( hTiParent)) { // --- item can be visible, so do changement if (hTiPage) m_treeCtrl.DeleteBranch( hTiPage); // --- check if the chapter is now empty, to reset the expandedOnce flag if (hTiParent && m_treeCtrl.GetChildItem( hTiParent) == NULL) { // --- collapse the chapter to redraw icons m_treeCtrl.Expand( hTiParent, TVE_COLLAPSE); // --- and force the item to be collapsed, even when it has no children m_treeCtrl.SetItemExpanded( hTiParent, false); } } else { // --- item is collapsed, so set the flag to refresh his children m_treeCtrl.SetItemExpandedOnce( hTiPage, TRUE); } // --- now reset the parent annotation flag if (hTiParent != NULL) { long lAnnoPage, lAnnoParent; pPageModel->getGlobalSubAnnotationsCount( &lAnnoPage); if( lAnnoPage >= 1) { // --- all annotations has been deleted, so update the parent while( hTiParent != TVI_ROOT && hTiParent != NULL) { CKbModelItem *pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiParent); TModelPtr pPageModel; pPageModel = pItem->GetPageModel(); pPageModel->getGlobalSubAnnotationsCount( &lAnnoParent); pItem->SetSubInteger( 2, lAnnoParent >= 1L ? ANNOTATION : NONE); m_treeCtrl.RedrawItem( hTiParent); hTiParent = m_treeCtrl.GetParentItem( hTiParent); } } } } // --- set empty sticker if this chapter is empty if (m_treeCtrl.GetCount() == 0) CreateSticker(); // --- As this is a MESSAGE posting, an AddRef has been done before sending it, // --- so we'll have to Release it when the processing is over. pPageModel->Release(); if (pChapterModel) pChapterModel->Release(); return lResult; } void CKbChapterToc::CreateSticker() { // --- don't create sticker in a system chapter (ie trash) AFX_MANAGE_STATE( AfxGetAppModuleState()); if (::IsModifyProtected(m_pBookModel) || ::IsSystem(m_pBookModel)) return; CRect rect( 0, 0, 219, 199); m_pPostItWnd = new CKbStickerTocWnd( m_pChapterModel->isInstanceOf( T_SUMMARY_MODEL_NAME) ? IDS_STICKER_EMPTY_TOC : IDS_STICKER_EMPTY_CHAPTER ); m_pPostItWnd->setLogicalPoint( rect.TopLeft()); m_pPostItWnd->setLogicalSize( rect.Size()); m_pPostItWnd->setLogicalSpace( rect.Size()); m_pPostItWnd->SetNotifyWnd( this); VERIFY( m_pPostItWnd->Create( rect, &m_treeCtrl, IDC_POSTIT)); } bool CKbChapterToc::IsModifyProtected( void) { return ::IsModifyProtected( m_pBookModel) == TRUE; } void CKbChapterToc::DelSelection( void) { // --- call by the activeX OnEditDel(); } void CKbChapterToc::SetAnnotationVisibility( bool bIsVisible) { CWaitCursor wait; // --- for each page set his annotation visiblity property TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE); boolean bSet = bIsVisible; HTREEITEM hTiInc; for( hTiInc = m_treeCtrl.GetRootItem(); hTiInc; hTiInc = m_treeCtrl.GetNextItem( hTiInc)) { // --- set the visibility of the page CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiInc); ASSERT( pItem); TModelPtr pPageModel; pPageModel = pItem->GetPageModel(); ASSERT( pPageModel); TModelPtr pPropModel; pPageModel->getDefaultProperty( &pPropModel); ASSERT( pPropModel); pPropModel->putBooleanField( T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY, bSet); // --- set an overlay image pItem->SetSubOverlay( 2, bIsVisible ? 0 : 1); } // --- add the chapter itshelf TModelPtr pPropModel; m_pChapterModel->getDefaultProperty( &pPropModel); pPropModel->putBooleanField( T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY, bSet); TGlobalsDB::getLibraryDBManager()->commitTransaction(); } int CKbChapterToc::GetNbSubAnnotation() { long lCount = 0; m_pChapterModel->getGlobalSubAnnotationsCount( &lCount); return (int) lCount; } // // To Remove when the transition to the new Toolbar Button // is complete // void CKbChapterToc::SendEvent( LPCTSTR szEvent) { CKbTreeTocWnd::SendEvent( szEvent); if( strcmp( szEvent, T_EVENT_NEW_CHAPTER) == 0) { // --- Create a new chapter AddNewChapter(); } else { // --- no interesting event return; } // --- update only interesting item for( HTREEITEM hTiVisible = m_treeCtrl.GetFirstVisibleItem(); hTiVisible; hTiVisible = m_treeCtrl.GetNextVisibleItem( hTiVisible)) { int nImageList = m_treeCtrl.GetItemInteger( hTiVisible, 2); if( nImageList == ANNOTATION) m_treeCtrl.RedrawItem( hTiVisible); } } LONG CKbChapterToc::OnNewChapter(LONG, LONG) { // --- Create a new chapter AddNewChapter(); // --- update only interesting item for( HTREEITEM hTiVisible = m_treeCtrl.GetFirstVisibleItem(); hTiVisible; hTiVisible = m_treeCtrl.GetNextVisibleItem( hTiVisible)) { int nImageList = m_treeCtrl.GetItemInteger( hTiVisible, 2); if( nImageList == ANNOTATION) m_treeCtrl.RedrawItem( hTiVisible); } return S_OK; } void CKbChapterToc::AddNewChapter() { // --- select an item to insert a chapter BOOL bIsSelEmpty = m_treeCtrl.m_listHtiSelected.IsEmpty(); HTREEITEM hTiSelected = NULL, hTiParent = NULL; if( bIsSelEmpty) { // --- get the item just before this one, because the insertion is made after a reference HTREEITEM hTiFirstVisible = m_treeCtrl.GetFirstVisibleItem(); hTiSelected = m_treeCtrl.GetPrevSiblingItem( hTiFirstVisible); if( hTiSelected) { hTiParent = m_treeCtrl.GetParentItem( hTiSelected); } else { hTiSelected = TVI_FIRST; hTiParent = m_treeCtrl.GetParentItem( hTiFirstVisible); } TRACE( _T("Selected (%s)\n"), m_treeCtrl.GetItemText( hTiSelected)); TRACE( _T("Parent (%s)\n"), m_treeCtrl.GetItemText( hTiParent)); } else { // --- select the item with the lowerpage number in the selection POSITION pos; int nPage; int nPageMax = INT_MAX; for( pos = m_treeCtrl.m_listHtiSelected.GetHeadPosition(); pos != NULL; ) { HTREEITEM hTi = (HTREEITEM) m_treeCtrl.m_listHtiSelected.GetNext( pos); ASSERT( hTi); nPage = m_treeCtrl.GetItemInteger( hTi, 1); if( nPage < nPageMax) { nPageMax = nPage; hTiSelected = hTi; } } TRACE( _T("CKbChapterToc::AddNewChapter PageSelected %d\n"), m_treeCtrl.GetItemInteger( hTiSelected, 1)); hTiParent = m_treeCtrl.GetParentItem( hTiSelected); // --- copy the selection in a separate list. // --- Don't use m_arrayHtiDragged because element are not use to place the new chapter m_listHtiToInsert.RemoveAll(); m_listHtiToInsert.AddTail( &(m_treeCtrl.m_listHtiSelected)); } // --- insert the chapter m_treeCtrl.ClearSelection(); while (!OnTocDropChapter( hTiSelected, hTiParent)) { if (hTiSelected == TVI_FIRST) hTiSelected = m_treeCtrl.GetFirstVisibleItem(); else hTiSelected = m_treeCtrl.GetNextItem(hTiSelected, TVGN_NEXTVISIBLE); if (hTiSelected == NULL) break; } } void CKbChapterToc::AddPagesIntoChapter( HTREEITEM hTiTarget) { ASSERT( hTiTarget); if( m_listHtiToInsert.IsEmpty()) return; // --- get the chapter controler CComPtr pChapterControler; HRESULT hResult = pChapterControler.CoCreateInstance( CLSID_TChapterControler); if( FAILED( hResult)) { TSoundManager::PlayFromResource( IDSOUND_ALERT); return; } // --- get item data CKbModelItem* pItem = (CKbModelItem*) m_treeCtrl.GetKbItemData( hTiTarget); ASSERT( pItem); TModelPtr pPageSelected; pPageSelected = pItem->GetPageModel(); pChapterControler->put_chapter( (long) pPageSelected.p); // --- translate item to insert into insert to dragged m_treeCtrl.SetDraggedSelection( &m_listHtiToInsert); SortModelItem( m_treeCtrl.m_arrayHtiDragged); m_listHtiToInsert.RemoveAll(); // --- prepare the progress dialog CPtrArray ptrArray; ptrArray.Append( m_treeCtrl.m_arrayHtiDragged); m_treeCtrl.m_arrayHtiDragged.RemoveAll(); // TBooxFrame::GetMainWnd()->EnableWindow( FALSE); long lPosition = 1; int nMax = ptrArray.GetSize(); CProgressDlg dlg; CString stgFormatStep, stgFormatComment; { AFX_MANAGE_STATE( AfxGetAppModuleState()); VERIFY( dlg.Create( _T("CProgressDlg"), WS_CHILD/* | WS_VISIBLE*/, CRect( 0, 0, 10, 10), AfxGetMainWnd(), 1 )); CString stgTmp; VERIFY( KBLoadString( IDS_PROGDLG_MOVE_FILE_TITLE, stgTmp)); dlg.SetTitle( stgTmp); VERIFY( KBLoadString( IDS_CANCEL, stgTmp)); dlg.SetCancel( stgTmp); KBLoadString( IDS_PROGDLG_STEP, stgFormatStep); dlg.ChangeAnimation( 2 /*FILEMOVE*/); KBLoadString( IDS_PROGDLG_MOVE_FILE_NAME, stgFormatComment); dlg.SetUpper( nMax); } // --- browse all page CWaitCursor waitCursor; TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE); for( int n = 0; n < nMax; n++) { HTREEITEM hTi = (HTREEITEM) ptrArray[n]; CKbModelItem *pItem = (CKbModelItem *) m_treeCtrl.GetKbItemData( hTi); TModelPtr pPageModel; pPageModel = pItem->GetPageModel(); // --- update the progress dialog { // AFX_MANAGE_STATE( AfxGetAppModuleState()); if( dlg.IsProcessCanceled()) break; CString stgTmp; stgTmp.FormatMessage( stgFormatComment, (LPCTSTR) pPageModel->getTitle()); dlg.SetComment( stgTmp); stgTmp.FormatMessage( stgFormatStep, lPosition, nMax); dlg.SetStep( stgTmp); dlg.SetPosition( lPosition++); } // --- move it in the database CComVariant varChapter( (long) pPageModel.p); hResult = pChapterControler->Move( varChapter, 0); } TGlobalsDB::getLibraryDBManager()->commitTransaction(); // --- close the progress bar { // AFX_MANAGE_STATE( AfxGetAppModuleState()); dlg.DestroyWindow(); } // TBooxFrame::GetMainWnd()->EnableWindow( TRUE); }/*------------ TBaseWBPageletCtl.cpp ------------*/ #include "StdAfx.h" #include "mshtmcid.h" #include "Dom.h" #include "Controler.h" // TBaseWBPageletCtl.cpp : Implementation of the TBaseWebBrowserPageletCtrl ActiveX Control class. #include "Pagelet.h" #include "PageletCtrl.h" #include "TBaseWBPageletCtl.h" #include "TPageletDll.h" #include "TPageModel.h" #include "TChapterModel.h" #include "TContentModel.h" #include "TAnnotationModel.h" #include "TContentsBagModel.h" #include "TStickerModel.h" #include "TMetaManager.h" #include "TModelNames.h" #include "TModelHelpers.h" #include "TModelPtr.h" #include "TPageNumbering.h" #include "TBooxFrame.h" #include "TPreferences.h" #include "TUrl.h" #include "SharedResource.h" #include "TPageletSearchView.h" #include "TWebToolBar.h" #include "TUserMessage.h" #include "PropertyChangeEvent.h" #include "TPropertyObjectModel.h" #include "TPagePropertiesConstants.h" #include "TContentPropertiesConstants.h" #include "TKeeBooKeyController.h" #include "TWebBrowser.h" #include "TErr.h" #include "TAppVersionInfo.h" #include "TAppBrandingInfo.h" #include "TWBDropTarget.h" #include "TWBStretchSink.h" #include "Net.h" #include "IEVersion.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNAMIC(TBaseWebBrowserPageletCtrl, TPageletCtrl) // **************************************************************** // Message map BEGIN_MESSAGE_MAP(TBaseWebBrowserPageletCtrl, TPageletCtrl) // Window ON_WM_SIZE() ON_WM_DESTROY() // Ole ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) // User Message ON_MESSAGE(WM_USER_SET_CONTENT, OnSetContent) ON_MESSAGE(WM_USER_ADD_ANNOTATION, OnAddAnnotation) ON_MESSAGE(WM_USER_CHANGE_ANNOTATION_VISIBILITY, OnChangeAnnotationVisibility) ON_MESSAGE(WM_USER_RELOAD_PAGE, OnReloadPage) ON_MESSAGE(WM_USER_REMOVE_PAGE, OnRemovePage) ON_MESSAGE(WM_USER_NEED_DESTROY_PAGELET, OnNeedDestroy) ON_MESSAGE(WM_USER_LOAD_URL, OnLoadUrl) ON_MESSAGE(WM_USER_REDIRECT, OnRedirect) ON_MESSAGE(WM_USER_REMOVE_SUB_BROWSER, OnRemoveSubBrowser) ON_COMMAND_RANGE( IDM_UNKNOWN, IDM_JUSTIFYNONE, OnWebBrowserCommand) ON_COMMAND_RANGE( IDM_OPEN, IDM_MENUEXT_COUNT, OnWebBrowserCommand) ON_COMMAND(IDM_PAGELET_NEXT, OnPageletNext) ON_COMMAND(IDM_PAGELET_PREVIOUS, OnPageletPrevious) ON_COMMAND(IDM_PAGELET_VIEWINBROWSER, OnPageletViewInBrowser) END_MESSAGE_MAP() // **************************************************************** // Dispatch map BEGIN_DISPATCH_MAP(TBaseWebBrowserPageletCtrl, TPageletCtrl) END_DISPATCH_MAP() // **************************************************************** // Event map BEGIN_EVENT_MAP(TBaseWebBrowserPageletCtrl, TPageletCtrl) END_EVENT_MAP() // **************************************************************** // TBaseWebBrowserPageletCtrl interfaces BEGIN_INTERFACE_MAP(TBaseWebBrowserPageletCtrl, TPageletCtrl) INTERFACE_PART(TBaseWebBrowserPageletCtrl, IID_IPageletWebBrowser, WebBrowser) INTERFACE_PART(TBaseWebBrowserPageletCtrl, IID_IPageletHighlight, Highlight) INTERFACE_PART(TBaseWebBrowserPageletCtrl, IID_IPageletSticker, Sticker) END_INTERFACE_MAP() // **************************************************************** // // Description: // TBaseWebBrowserPageletCtrl - Constructor. // // Set all default variable values // TBaseWebBrowserPageletCtrl::TBaseWebBrowserPageletCtrl() : m_bIsCreated(FALSE), m_bFirstNavigate(TRUE), m_bReload(FALSE), m_bUserClick(FALSE), m_bRedirected(FALSE), m_bDoStretch(FALSE), m_bDoImageFit(FALSE), m_bReloadForBmp(FALSE), m_bAnnotationAllowed(FALSE), m_bNoStretch(FALSE), m_bStoreTitle(TRUE), m_bDynamicPage(FALSE), m_bCanceling(FALSE), m_bFullStaticKeeBook(FALSE), m_bNeedReload(FALSE), m_bStopReload(FALSE), fWebBrowser(NULL), m_DropTarget(NULL), fContentListener(NULL), m_RefreshForce(0), m_RootDispatch(NULL), m_pNetStatus(NULL), m_StretchSink(NULL), m_ExternalAdBanner(0), m_NavigateCount(0), m_pDropTarget(NULL) { SetLoaded(FALSE); m_pEvents = NULL; } // **************************************************************** // // Description: // TBaseWebBrowserPageletCtrl - Destructor // TBaseWebBrowserPageletCtrl::~TBaseWebBrowserPageletCtrl() { #ifdef DEBUG_PAGELET_LEAK TRACE(_T(" ~TBaseWebBrowserPageletCtrl(0x%x)\n"), this); #endif } // ************************************************************************************************ // // Description: // This function is a CCmdTarget hook to allow implementation of COM // interface without adding them to the INTERFACE_MAP. // // It is used here to // /* LPUNKNOWN TBaseWebBrowserPageletCtrl::GetInterfaceHook(const void* piid) { GUID* lIID = (GUID*)piid; // if (InlineIsEqualGUID(*lIID, IID_IDropTarget)) // return &m_xDropTarget; // if (InlineIsEqualGUID(*lIID, IID_IPageletWebBrowser)) // return &m_xWebBrowser; return TPageletCtrl::GetInterfaceHook(piid); } */ // ************************************************************************************************ // // Description: // Call during the Windows Destroy process, in response to WM_DESTROY message. // // Should free all GDI ressources associated with this Control, // and optionaly other resources. // void TBaseWebBrowserPageletCtrl::OnDestroy() { #ifdef DEBUG_PAGELET_LEAK CString lWndName(GetRuntimeClass()->m_lpszClassName); TRACE(_T(" TBaseWebBrowserPageletCtrl(%s)::OnDestroy (0x%x)\n"), lWndName, this); #endif if (m_StretchSink && m_StretchSink->getStretching()) { m_StretchSink->setStretching(FALSE); } m_DropTarget.Release(); if (fModel) removeListeners(); if (fWebBrowser) { fWebBrowser->Stop(); fWebBrowser = NULL; } m_pNetStatus.Release(); m_BrowserTree.Release(); m_SoftReloadTree.Release(); #if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL) m_BeforeTree.Release(); #endif long lCount; lCount = m_AdBannerList.GetSize(); while (lCount) { CWnd* lWnd; lCount--; lWnd = m_AdBannerList[0]; if (lWnd && lWnd->m_hWnd) { lWnd = lWnd->GetParent(); if (lWnd && (lWnd != this)) lWnd->DestroyWindow(); } if (m_AdBannerList.GetSize() && (lWnd == m_AdBannerList[0])) m_AdBannerList.RemoveAt(0); } TPageletCtrl::OnDestroy(); } LRESULT TBaseWebBrowserPageletCtrl::OnRemoveSubBrowser(WPARAM pHwnd, LPARAM) { long lCount; lCount = m_AdBannerList.GetSize(); while (lCount) { CWnd* lWnd; lCount--; lWnd = m_AdBannerList[lCount]; if (lWnd && lWnd->m_hWnd == (HWND)pHwnd) { m_AdBannerList.RemoveAt(lCount); return S_OK; } } return S_FALSE; } #ifdef _DEBUG // **************************************************************** // // Description: // Creating function. // // Just here for debug purpose ( to set break point !!!) // int TBaseWebBrowserPageletCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { return TPageletCtrl::OnCreate(lpCreateStruct); } // **************************************************************** // TBaseWebBrowserPageletCtrl::OnDraw - Drawing function // void TBaseWebBrowserPageletCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) { TPageletCtrl::OnDraw(pdc, rcBounds, rcInvalid); } // **************************************************************** // TBaseWebBrowserPageletCtrl::OnResetState - Reset control to default state void TBaseWebBrowserPageletCtrl::OnResetState() { TPageletCtrl::OnResetState(); // Resets defaults found in DoPropExchange // TODO: Reset any other control state here. } // ************************************************************************************************ // // // void TBaseWebBrowserPageletCtrl::ReportResult(long pResult) { TPageletCtrl::ReportResult(pResult); // fIsLoaded = TRUE; } // ************************************************************************************************ // // // void TBaseWebBrowserPageletCtrl::OnSize(UINT nType, int cx, int cy) { TPageletCtrl::OnSize(nType, cx, cy); } #endif BOOL TBaseWebBrowserPageletCtrl::PreTranslateMessage(MSG* pMsg) { if ((pMsg->message >= WM_MOUSEFIRST) && (pMsg->message <= WM_MOUSELAST) && MinimumIEVersion(5, 5)) { if (pMsg->message == WM_LBUTTONUP) UserClick(); } /* AfxLockTempMaps(); BOOL lIsDialogMsg = IsDialogMessage(pMsg); AfxUnlockTempMaps(); if (lIsDialogMsg) { //TRACE( "\n{AC} ISDialogMessage true\n" ); return TRUE; } else */ { return TPageletCtrl::PreTranslateMessage(pMsg); } } // **************************************************************** // // Description: // Create Browser function // void TBaseWebBrowserPageletCtrl::CreateBrowser() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CRect lLogicalRect; CRect lDeviceRect; CComBSTR lUserAgentExtension; lLogicalRect = GetPageletLogicalRect(); lDeviceRect = lLogicalRect; LPtoDP(&lDeviceRect); fWebBrowser = new TWebBrowser(0); fWebBrowser->setLogicalPoint(lLogicalRect.TopLeft()); fWebBrowser->setLogicalSize(lLogicalRect.Size()); fWebBrowser->setLogicalSpace(lLogicalRect.Size()); #ifdef T_NEW_WEB_EVENT_HANDLER fWebBrowser->SetBrowserEventsSink(m_pEvents); #else // T_NEW_WEB_EVENT_HANDLER fWebBrowser->SetBrowserEventsSink(this); #endif // T_NEW_WEB_EVENT_HANDLER fWebBrowser->Create(NULL, "web_browser_control", WS_CHILD|WS_VISIBLE, lDeviceRect, this, 0); CComPtr lUnk; InternalQueryInterface(&IID_IUnknown, (void**)&lUnk); fWebBrowser->GetControlSite()->setPageletControl(lUnk); TAppVersionInfo lAppInfo; lUserAgentExtension = lAppInfo.GetSKU(); #ifdef T_ADD_PARTNER_SKU_TO_USER_AGENT TAppBrandingInfo lBrandingInfo; lUserAgentExtension.Append("/"); lUserAgentExtension.Append(lBrandingInfo.GetPartnerID()); #endif fWebBrowser->SetUserAgentExtension(lUserAgentExtension); fWebBrowser->SetRegisterAsDropTarget(TRUE); insertChildAt(fWebBrowser, GetBrowserPos()); SetResizable(*fWebBrowser); showView(*fWebBrowser); m_bIsCreated = true; } LONG TBaseWebBrowserPageletCtrl::GetBrowserPos() { return childCount(); } void TBaseWebBrowserPageletCtrl::DestroyBrowser() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); removeChild(fWebBrowser); if (fWebBrowser) fWebBrowser->DestroyWindow(); fWebBrowser = NULL; m_bIsCreated = false; } // **************************************************************** // TBaseWebBrowserPageletCtrl::DoPropExchange - Persistence support void TBaseWebBrowserPageletCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); TPageletCtrl::DoPropExchange(pPX); // TODO: Call PX_ functions for each persistent custom property. } // **************************************************************** // // Description: // Signal the navigation stop. // HRESULT TBaseWebBrowserPageletCtrl::Stop() { ReportResult(S_FALSE); m_bAnnotationAllowed = TRUE; return S_OK; } // **************************************************************** // // Description: // // HTMLFocusPlacement TBaseWebBrowserPageletCtrl::FindRealActiveElementOnContent( IHTMLDocument2* pDocument ) { USES_CONVERSION; CComPtr lActive; if( pDocument->get_activeElement( &lActive ) == S_OK ) { VARIANT_BOOL lIsTextEdit = FALSE; CComBSTR lTagName; lActive->get_tagName( &lTagName ); #ifdef _DEBUG // for( int k = 0;k < lNbDecal;k++ ) { TRACE( " " ); } TRACE( "Element actif classe %s\n", W2CT( lTagName ) ); #endif // directly test if it is a text edit lActive->get_isTextEdit( &lIsTextEdit ); if( lIsTextEdit && !(lTagName == CComBSTR( _T("BODY") ))) { return OnEditElement; } // no : test if t's an input or a select : To complete CComBSTR lActiveTagName; lActive->get_tagName( &lActiveTagName ); if( (lActiveTagName == CComBSTR( _T("SELECT") )) ||(lActiveTagName == CComBSTR( "INPUT" )) ) { return OnEditElement; } // to detect strange objects : not text CComQIPtr lInput( lActive ); if( lInput != NULL ) { CComBSTR lInputType; // ex : text textarea password lInput->get_type( &lInputType ); TRACE( "input Type %s\n", W2CT( lInputType ) ); return OnEditElement; } // Test other objects who can eat keys CComQIPtr lObject( lActive ); if( lObject != NULL ) // It's something like an ActiveX { CComBSTR lType; long lState; lObject->get_type( &lType ); // An object can eat all keys If it is ready to do it TRACE( "Object Type %s\n", W2CT( lType ) ); lObject->get_readyState( &lState ); if( (lState == READYSTATE_INTERACTIVE) || (lState == READYSTATE_COMPLETE) ) { return OnObjectElement; } } } return NotOnEditElement; } // **************************************************************** // // Description: // Search for the current focused element in a web page if any. // // Remarks: // This custom version of a Frame Crawler should be replaced by // a standard one. This one is not able of of crawling frames in // different domain names, for security reason. // HTMLFocusPlacement TBaseWebBrowserPageletCtrl::FindRealActiveElementOnFrame( IHTMLDocument2* pDocument ) { bool lNoFrame = false; CComPtr lCollec2; long lNbItems = 0; #ifdef _DEBUG static lNbDecal = 0; #endif if( (pDocument->get_frames( &lCollec2 ) != S_OK) || !lCollec2 ) { lNoFrame = true; } else { if( (lCollec2->get_length( &lNbItems ) != S_OK) || (lNbItems <= 0) ) { lNoFrame = true; } } if( lNoFrame ) { // Return the final decision; return FindRealActiveElementOnContent( pDocument ); } // Don't forget the case where there is frame but the active element is not on a frame HTMLFocusPlacement lRes = FindRealActiveElementOnContent( pDocument ); if( lRes != NotOnEditElement ) { return lRes; } CComVariant lI; for( short i = 0; i < lNbItems;i++,lI = i ) { CComVariant lFrameVariant; #ifdef _DEBUG static lNbDecal = 0; for( int k = 0;k < lNbDecal;k++ ) { TRACE( " " ); } TRACE( "%d / %d\n",i,lNbItems ); #endif if( (lCollec2->item( &lI,&lFrameVariant) == S_OK) && (lFrameVariant.vt == VT_DISPATCH) ) { CComPtr lDispFrame = lFrameVariant.pdispVal; CComQIPtr lWinFrame( lDispFrame ); if( lWinFrame ) { CComPtr lFrameDocument; if( (lWinFrame->get_document( &lFrameDocument ) == S_OK) && lFrameDocument && !lFrameDocument.IsEqualObject( pDocument ) ) { #ifdef _DEBUG lNbDecal++; #endif lRes = FindRealActiveElementOnFrame( lFrameDocument ); #ifdef _DEBUG lNbDecal--; #endif if( lRes != NotOnEditElement ) { return lRes; } } } } } return NotOnEditElement; } HTMLFocusPlacement TBaseWebBrowserPageletCtrl::FocusPlacement( void ) { if( !m_IsLoaded ) { return CannotFind; // TKeeBooKeyController::OnStandardWebPage; } // Get the ITHMLDocument2 CComPtr lDispatch; if( fWebBrowser->GetHtmlDocument( &lDispatch ) != S_OK) { TRACE( "Ce n'est pas un document html\n" ); return CannotFind; } CComQIPtr lDoc(lDispatch); if( lDoc == NULL ) return CannotFind; return FindRealActiveElementOnFrame( lDoc ); } // ************************************************************************************************ // // Description: // Get all the accelerator information for the sub-control. // // This is called by the container framework. // void TBaseWebBrowserPageletCtrl::OnGetControlInfo(LPCONTROLINFO pControlInfo) { if (fWebBrowser) { IUnknown* lUnk = fWebBrowser->GetControlUnknown(); CComQIPtr lControl(lUnk); if (lControl) { lControl->GetControlInfo(pControlInfo); } } else { TPageletCtrl::OnGetControlInfo(pControlInfo); } } // ************************************************************************************************ // // Description: // Hook to get the opportunity to change the drop target of a pagelet // // We store the old // // Inputs: // pDropTarget - The original drop target // ppDropTarget - The new drop target if we want to change it. // // Return Value: // S_OK - A new drop target was specified // STDMETHODIMP TBaseWebBrowserPageletCtrl::GetDropTarget(IDropTarget* pDropTarget, IDropTarget** ppDropTarget) { HRESULT lResult; if (m_DropTarget == NULL) { lResult = CComObject::CreateInstance(&m_pDropTarget); if (FAILED(lResult)) return lResult; ATLASSERT(m_pDropTarget); lResult = m_pDropTarget->QueryInterface(&m_DropTarget); if (FAILED(lResult)) return lResult; ATLASSERT(m_DropTarget); m_pDropTarget->m_Pagelet = this; lResult = InternalQueryInterface(&IID_IPageletLoadControl, (void**)&m_pDropTarget->m_PageletLoadControl); ATLASSERT(SUCCEEDED(lResult)); } if (m_pDropTarget) { m_pDropTarget->m_Page = fModel; m_pDropTarget->m_StubDropTarget = pDropTarget; } *ppDropTarget = m_DropTarget; (*ppDropTarget)->AddRef(); return S_OK; } // ************************************************************************************************ // // Description: // Called in response to a WM_USER_NEED_DESTROY_PAGELET message. // This is to make sure the web browser interface are release before this control // is destroy. // LRESULT TBaseWebBrowserPageletCtrl::OnNeedDestroy(UINT wParam, LONG lParam) { m_BrowserTree.Release(); return TPageletCtrl::OnNeedDestroy(wParam, lParam); } // ************************************************************************************************ // // Description: // Add the page listener to the model // void TBaseWebBrowserPageletCtrl::addListeners() { ASSERT(fModel); if (fModel == NULL) return ; if (fMode == 0) return ; if (fMode == T_PRINT_MODE) return ; fContentListener = new TBaseWebContentListener(); fContentListener->fThis = this; fModel->addPropertyChangeListener(fContentListener); TModelPtr lProperty; fModel->getDefaultProperty(&lProperty); ASSERT(lProperty); if (lProperty != NULL) { lProperty->addPropertyChangeListener(fContentListener); } } // ************************************************************************************************ // // Description: // Remove the page listener to the model // void TBaseWebBrowserPageletCtrl::removeListeners() { if (fContentListener == NULL) return ; ASSERT(fModel); if (fModel == NULL) return ; fContentListener->fThis = NULL; fModel->removePropertyChangeListener(fContentListener); TModelPtr lProperty; fModel->getDefaultProperty(&lProperty); ASSERT(lProperty); if (lProperty != NULL) { lProperty->removePropertyChangeListener(fContentListener); } fContentListener->setInvalid(); fContentListener = NULL; } // ************************************************************************************************ // // Description: // Hook function to add some processing before loading a page // // The default implementation do nothing // void TBaseWebBrowserPageletCtrl::beforeLoad() { #ifdef ALLOW_PDF_FILE m_PdfObject.Release(); #endif // ALLOW_PDF_FILE } // **************************************************************** // // Description: // AddRef, Release and QueryInterface stuff for the IPageletWebBrowser interface // T_IMPLEMENT_EXTERNAL_INTERFACE(TBaseWebBrowserPageletCtrl, WebBrowser) // **************************************************************** // // Description: // This function Search in the pagelet the focused object // // Inputs: // pPlacement - possible return value: CannotFind / NotOnEditElement / OnEditElement / OnObjectElement // // Return Value: // E_INVALIDARG - If the argument is invalid // S_OK - If the web browser is available // S_FALSE - If the web browser is not available !!! ( should be E_FAIL ? ) // HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::FocusPlacement( int* pPlacement ) { ASSERT( pPlacement ); if( pPlacement == NULL ) return E_INVALIDARG; METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser); if (pThis->fWebBrowser ) { *pPlacement = (int)pThis->FocusPlacement(); return S_OK; } return S_FALSE; } HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::IsInternalPage(BOOL* pResult, BSTR* pType) { ASSERT( pResult ); if( pResult == NULL ) return E_INVALIDARG; METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser); if (pThis->fWebBrowser ) { *pResult = pThis->CheckIsInternalPage(pType) == S_OK ? TRUE : FALSE; return S_OK; } return E_FAIL; } // **************************************************************** // // Description: // This function retrieve the selected text in a pagelet web browser // // Remarks: // This function is not FRAME compatible !!!! // // We should make this Pagelet specific, not WebBrowser specific // // Inputs: // pSelectedText - A pointer to the returned BSTR // // Return Value: // E_FAIL - If fail // S_OK - If the text was retrieved // HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::get_SelectedText( BSTR* pSelectedText ) { USES_CONVERSION; CComPtr lDispatch; METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser); if (pThis->fWebBrowser->GetHtmlDocument(&lDispatch) == S_OK ) { CComQIPtr lDoc(lDispatch); if (lDoc ) { // get the active selection CComPtr lSelection; lDoc->get_selection( &lSelection ); if (lSelection ) { CComPtr lRangeDispatch; lSelection->createRange( &lRangeDispatch ); if (lRangeDispatch ) { CComQIPtr lRange( lRangeDispatch ); lRange->get_text( pSelectedText ); TRACE( "Texte selectionne %s\n", W2CT( *pSelectedText ) ); return S_OK; } } } } return E_FAIL; } // **************************************************************** // // Description: // // STDMETHODIMP TBaseWebBrowserPageletCtrl::XWebBrowser::GetDropTarget(IDropTarget* pDropTarget, IDropTarget** ppDropTarget) { METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser); return pThis->GetDropTarget(pDropTarget, ppDropTarget); } // **************************************************************** // // Description: // // HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::UserClick() { METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser); return pThis->UserClick(); } // **************************************************************** // // Description: // // HRESULT TBaseWebBrowserPageletCtrl::XWebBrowser::TranslateUrl(BSTR pUrl, BSTR* pUrlOut) { METHOD_PROLOGUE(TBaseWebBrowserPageletCtrl, WebBrowser); return pThis->TranslateUrl(pUrl, pUrlOut); } // **************************************************************** // // Description: // Called in response to WM_USER_SET_CONTENT message. // // Reload the pagelet if the WParam is TRUE // // Return Value: // Always S_OK !!!! // LRESULT TBaseWebBrowserPageletCtrl::OnSetContent(WPARAM wParam, LPARAM) { if (wParam) Reload(REFRESH_NORMAL); return S_OK; } // **************************************************************** // // Description: // Called in response to WM_USER_RELOAD_PAGE message. // // Force the Reload of the pagelet. // The refresh rate is specified in the WParam. // // Return Value: // Always S_OK !!!! // LRESULT TBaseWebBrowserPageletCtrl::OnReloadPage(WPARAM pRefreshRate, LPARAM) { Reload(pRefreshRate); return S_OK; } LRESULT TBaseWebBrowserPageletCtrl::OnRemovePage(WPARAM , LPARAM) { TModelPtr lPage; TModelPtr lBook; lPage = getModel(); ATLASSERT(lPage); if (lPage == NULL) return E_FAIL; lPage->getBook(&lBook); ATLASSERT(lBook); if (lBook == NULL) return E_FAIL; CComPtr lBookControl; lBookControl.CoCreateInstance(CLSID_TBookControler); ASSERT(lBookControl); if (lBookControl == NULL) return E_FAIL; lBookControl->put_book((long)lBook.p); return lBookControl->Remove(CComVariant((LONG)lPage.p)); } // **************************************************************** // // Description: // Called in response to WM_USER_REDIRECT message. // // Inputs: // pDisp - An IDispatch pointer ( must implemente the IWebBrowser2 interface ) // pBstr - The redirected URL // // Return Value: // E_INVALIDARG - if any parameter is invalid // S_OK - else // LRESULT TBaseWebBrowserPageletCtrl::OnRedirect(WPARAM pDisp, LPARAM pBstr) { USES_CONVERSION; ATLASSERT(pDisp); ATLASSERT(pBstr); if ((pDisp == NULL) || (pBstr == NULL)) return E_INVALIDARG; IDispatch* lDispatch = (IDispatch*)pDisp; CComQIPtr lBrowser(lDispatch); ATLASSERT(lBrowser); if (lBrowser == NULL) return E_INVALIDARG; CComBSTR lUrl; lUrl.Attach((BSTR)pBstr); #ifdef DEBUG_EXTENDED_URL TUrl lBaseUrl(lUrl); CString lScheme = lBaseUrl.getScheme(); if (StorableProtocol(lScheme)) ATLASSERT(lBaseUrl.getExtendedInfo() != NULL); #endif InitFlags(lDispatch); m_bRedirected = TRUE; DWORD lNavOptions; lNavOptions = getNavigationFlags(); if (fWebBrowser->m_pBrowserApp == lBrowser) Navigate(W2CT(lUrl), lNavOptions); else { CComVariant lFlags(lNavOptions, VT_I4); lBrowser->Navigate(lUrl, &lFlags, NULL, NULL, NULL); } lDispatch->Release(); return S_OK; } #include "mshtml.h" // **************************************************************** // // // LRESULT TBaseWebBrowserPageletCtrl::OnAddAnnotation(WPARAM pAnnotation, LPARAM) { if (m_BrowserTree == NULL) return S_FALSE; TAnnotationModel* lAnnotation; LRESULT lResult; // As this is a MESSAGE posting, an AddRef has been done on pAnnotation // before sending it, so we'll have to Release it when the processing is over. lAnnotation = (TAnnotationModel*)pAnnotation; ASSERT(lAnnotation); lResult = AddAnnotation(m_BrowserTree, lAnnotation); ASSERT(SUCCEEDED(lResult)); lAnnotation->Release(); return lResult; } // **************************************************************** // // // LRESULT TBaseWebBrowserPageletCtrl::OnChangeAnnotationVisibility(WPARAM pField, LPARAM) { BSTR lField = (BSTR)pField; TPageModel* lPage; TModelPtr lProp; boolean lBool; lPage = getModel(); ATLASSERT(lPage); lPage->getDefaultProperty(&lProp); ATLASSERT(lProp); lProp->getBooleanField(CString(lField), &lBool); ::SysFreeString(lField); if (lBool) showAnnotation(TRUE); else hideAnnotation(TRUE); return S_OK; } void TBaseWebBrowserPageletCtrl::OnModeChange(long pMode) { #ifdef USE_IE_ZOOM if (MinimumIEVersion(5,5)) { doStretch(); } else #endif // USE_IE_ZOOM { if ((m_bDoStretch == NeedStretch())) // && (m_bDoImageFit == NeedImageFit())) return ; if (m_StretchSink) { m_StretchSink->setStretching(FALSE); PostMessage(WM_USER_RELOAD_PAGE, REFRESH_NORMAL); } else { Reload(REFRESH_NORMAL); } } } void TBaseWebBrowserPageletCtrl::Reload(long pRefreshForce) { m_bReloadForBmp = FALSE; m_RefreshForce = pRefreshForce; m_bReload = TRUE; initPagelet(); if (fWebBrowser) fWebBrowser->Stop(); if (m_StretchSink) { m_StretchSink->setStretching(FALSE); // TO DO: we might need an Asynchrone Reload here ???? } /* if (fRefreshForce == REFRESH_COMPLETELY) { HRESULT lResult; CString lStrUrl = "about:sevenix"; // get url can be hooked lResult = getUrl(lStrUrl); if (lResult != S_OK) return ; TModelPtr lContentsBag; TModelPtr lContent; TUrl lUrl(lStrUrl); TMetaManager::createModelInstance(T_CONTENTS_BAG_MODEL_NAME, (void**)&lContentsBag); lContentsBag->getContent( lUrl.extendedUrlString(), &lContent); ASSERT( lContent); fModel->setContent( lContent, true); } else */ { if (MinimumIEVersion(5,5)) { DestroyBrowser(); CreateBrowser(); } Load(); } m_bReload = FALSE; } //IMPLEMENT_DYNAMIC(TBaseWebContentListener, TPropertyChangeListener); // ************************************************************************************************ // // // void TBaseWebContentListener::propertyChange(TPropertyChangeEvent *evt) { if (!fThis) return ; CString lEvent = evt->getPropertyName(); if (!lEvent.Compare(TPageModel::T_SET_CONTENT_PROPERTY)) { fThis->PostMessage(WM_USER_SET_CONTENT, !fThis->m_bInDocumentComplete); } if (!lEvent.Compare(TPageModel::T_ADD_ANNOTATION_PROPERTY)) { TAnnotationModel* lAnnotation = (TAnnotationModel*)evt->getNewValue(); lAnnotation->AddRef(); fThis->PostMessage(WM_USER_ADD_ANNOTATION, (UINT)lAnnotation); } else if (!lEvent.Compare(TPropertyObjectModel::T_PUT_FIELD_PROPERTY)) { CString lField = evt->getNewStringValue(); if (lField == T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY) { fThis->PostMessage(WM_USER_CHANGE_ANNOTATION_VISIBILITY, (UINT)lField.AllocSysString()); } } } STDMETHODIMP TBaseWebBrowserPageletCtrl::OnNewBackWnd(HWND hWnd) { if (!m_bIsCreated) { CreateBrowser(); fWebBrowser->SetRegisterAsBrowser(TRUE); } fWebBrowser->setViewToRefresh(hWnd); return S_OK; } BOOL TBaseWebBrowserPageletCtrl::NeedStretch() { BOOL bResult = FALSE; if (IsStretchable(fModel) && !m_bNoStretch) { TPreferences lPref("Stretcher"); // We can desactivate Stretching ... int lBool; if (fMode == T_BOOK_MODE) { // if key present and active if ((lPref.GetInt("Book", &lBool) == S_OK) && lBool) bResult = TRUE; } else if (fMode == T_BOOK_STAND_MODE) { // if key present and active if ((lPref.GetInt("BookStand", &lBool) == S_OK) && lBool) bResult = TRUE; } else if (fMode == T_PAGE_MODE) { // if key present and active if ((lPref.GetInt("Page", &lBool) == S_OK) && lBool) bResult = TRUE; } } return bResult; } BOOL TBaseWebBrowserPageletCtrl::NeedImageFit() { if (IsStretchable(fModel)) { TPreferences lPref("Stretcher"); // We can desactivate Stretching ... int lBool; if (fMode == T_BOOK_MODE) { // if key present and active if ((lPref.GetInt("BookImage", &lBool) == S_OK) && lBool) return TRUE; } else if (fMode == T_BOOK_STAND_MODE) { // if key present and active if ((lPref.GetInt("BookStandImage", &lBool) == S_OK) && lBool) return TRUE; } else if (fMode == T_PAGE_MODE) { // if key present and active if ((lPref.GetInt("PageImage", &lBool) == S_OK) && lBool) return TRUE; } } return FALSE; } BOOL TBaseWebBrowserPageletCtrl::IsPostPage(TContentModel* pContentModel) { TModelPtr lContent(pContentModel); if (lContent == NULL) { getModel()->getContent(&lContent); if (lContent == NULL) return FALSE; } TModelPtr lNetworkProp; CString lPostData; GetModelProperty(lContent, T_CONTENT_NETWORK_PROPERTIES, &lNetworkProp); // // Is this a Post if (lNetworkProp && lNetworkProp->getStringField(T_CONTENT_NETWORK_POST_DATA, &lPostData)) return TRUE; return FALSE; } BOOL TBaseWebBrowserPageletCtrl::CanReload() { TModelPtr lContent; getModel()->getContent(&lContent); if (lContent == NULL) return FALSE; // // Is this a Post if (IsPostPage(lContent)) return FALSE; CString lUrlString; TUrl lUrl; lUrlString = lContent->getUrl(); lUrl = lUrlString; #ifdef T_GENERIC_CHECK_LOCAL_RELOAD DWORD lUseNetwork = 1; DWORD lSize; DWORD lAccess; HRESULT lResult; lResult = CoInternetQueryInfo(CComBSTR(m_CurrentUrl), QUERY_USES_NETWORK, 0, &lUseNetwork, sizeof(lUseNetwork), &lSize, 0); if (FAILED(lResult)) lUseNetwork = 0; if (!lUseNetwork) { lResult = CheckDocumentLocalAccessibility(CComBSTR(m_CurrentUrl), &lAccess); // and if we do not have the document. if (!(lAccess & DOCUMENT_CAN_ACCESS)) { // TO DO } } #endif if (lUrl.getScheme() == "file") { CString lFileName; CFileStatus lStatus; lFileName = lUrl.getFile(); if (CFile::GetStatus(lFileName, lStatus)) { return TRUE; } return FALSE; } return TRUE; } // **************************************************************** HRESULT TBaseWebBrowserPageletCtrl::Hide() { TPageletCtrl::Hide(); if (fWebBrowser) fWebBrowser->SetSilent(TRUE); return S_OK; } // **************************************************************** HRESULT TBaseWebBrowserPageletCtrl::Show() { TPageletCtrl::Show(); if (fWebBrowser) fWebBrowser->SetSilent(FALSE); return S_OK; } void TBaseWebBrowserPageletCtrl::OnWebBrowserCommand(UINT nID) { ASSERT(fWebBrowser); if (fWebBrowser) fWebBrowser->GetDescendantWindow(0)->SendMessage(WM_COMMAND, nID); } void TBaseWebBrowserPageletCtrl::OnPageletNext() { CComPtr lBookControler; lBookControler.CoCreateInstance(CLSID_TBookControler); lBookControler->ChangePageTo(T_CPT_NEXT_PAGE, T_SIDE_SECONDARY, CComVariant(1)); } void TBaseWebBrowserPageletCtrl::OnPageletPrevious() { CComPtr lBookControler; lBookControler.CoCreateInstance(CLSID_TBookControler); lBookControler->ChangePageTo(T_CPT_PREV_PAGE, T_SIDE_PRIMARY, CComVariant(1)); } void TBaseWebBrowserPageletCtrl::OnPageletViewInBrowser() { TBooxFrame::GetActiveBooxView()->SendMessage(WM_COMMAND, IDM_VIEW_INBROWSER); }/*------------ TBaseWBPageletCtl.h ------------*/ #ifndef T_BASE_WEBBROWSER_PAGELET_CTL #define T_BASE_WEBBROWSER_PAGELET_CTL // --- STL #include "xstddef" #pragma warning(disable: 4663) #pragma warning(disable: 4244) #pragma warning(disable: 4018) #include "vector" #include using namespace std; // --- End STL #include "TPageletCtl.h" #include "mshtml.h" #include "PropertyChangeListener.h" //#include "Dom.h" #include "TKeeBooKeyController.h" #include "TBaseWebBrowserEvents.h" #include "TWebBrowser.h" //#define SEARCH_FOR_HIDDEN_EVENT #define NEW_NET_INTERFACE #define WM_USER_LOAD_URL WM_USER + 461 #define WM_USER_REDIRECT WM_USER + 462 #define WM_USER_RELOAD_PAGE WM_USER + 463 class TPageletSearchView; class TWebBrowser; class TPageModel; class TBookModel; class TContentModel; class TAnnotationModel; class TString; class TStringToPtrHashTable; class TStickerModel; class THighlighterModel; class TWebContentListener; class TBaseWebBrowserPageletCtrl; interface IInternetStatus; interface IWebBrowserTreeNode; interface IDomAnnotationInfo; class TWebBrowserStretchSink; // // Description: // Listener for PageModel events // class TBaseWebContentListener : public TPropertyChangeListener { public: virtual void propertyChange(TPropertyChangeEvent *evt); TBaseWebBrowserPageletCtrl* fThis; }; enum AdviseType { Advise, Unadvise }; ///////////////////////////////////////////////////////////////////////////// // TBaseWebBrowserPageletCtrl : See TBaseWBPageletCtl.cpp for implementation. // // Description: // This is the base class for Web Pagelet Control. // It does not instanciate any toolbar, as the toolbar should become // a separate service. // // It just handle basic navigation. // // Some Hook function are available to customize this class: // * beforeLoad(): // * OnModeChange(long): // * BeforeNavigate(LPDISPATCH , VARIANT* , VARIANT* , VARIANT* , VARIANT* , VARIANT* , BOOL* ) // * NeedStretch(): return a BOOL telling if stretch is needed. // default implementation return the preferences mode flag // class TBaseWebBrowserPageletCtrl : public TPageletCtrl, TWebBrowserEvents { DECLARE_DYNAMIC(TBaseWebBrowserPageletCtrl) DECLARE_INTERFACE_MAP(); DECLARE_MESSAGE_MAP() DECLARE_DISPATCH_MAP() DECLARE_EVENT_MAP() friend class TBaseWebContentListener; friend class TWebBrowser; friend class TWBDropTarget; // Constructor public: TBaseWebBrowserPageletCtrl(); // Overrides public: #ifdef _DEBUG afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid); virtual void OnResetState(); afx_msg void OnSize(UINT nType, int cx, int cy); #endif // _DEBUG afx_msg void OnDestroy(); virtual void DoPropExchange(CPropExchange* pPX); virtual BOOL PreTranslateMessage(MSG* pMsg); virtual void addListeners(); virtual void removeListeners(); // User messages LRESULT OnSetContent(WPARAM , LPARAM); LRESULT OnAddAnnotation(WPARAM , LPARAM); LRESULT OnChangeAnnotationVisibility(WPARAM , LPARAM); LRESULT OnReloadPage(WPARAM , LPARAM); LRESULT OnRemovePage(WPARAM, LPARAM); LRESULT OnLoadUrl(WPARAM, LPARAM); LRESULT OnRedirect(WPARAM, LPARAM); LRESULT OnRemoveSubBrowser(WPARAM, LPARAM); LRESULT OnNeedDestroy(UINT, LONG); STDMETHOD(OnNewBackWnd)(HWND hWnd); void OnWebBrowserCommand(UINT nID); void OnPageletNext(); void OnPageletPrevious(); void OnPageletViewInBrowser(); virtual BOOL NeedImageFit(); virtual BOOL NeedStretch(); virtual BOOL CanReload(); BOOL IsPostPage(TContentModel* = NULL); // Implementation protected: virtual ~TBaseWebBrowserPageletCtrl(); void CreateBrowser(); void DestroyBrowser(); virtual LONG GetBrowserPos(); #ifdef ALLOW_PDF_FILE HRESULT CheckPDFFile(); #endif // ALLOW_PDF_FILE HTMLFocusPlacement FindRealActiveElementOnContent( IHTMLDocument2* pDocument ); HTMLFocusPlacement FindRealActiveElementOnFrame( IHTMLDocument2* pDocument ); // Sink maps virtual void OnWebProgressChange(long Progress, long ProgressMax); virtual void OnWebDownloadBegin(); virtual void OnWebDownloadComplete(); virtual void OnWebBeforeNavigate2(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel); virtual void OnWebNavigateComplete2(LPDISPATCH pDisp, VARIANT FAR* URL); virtual void OnWebDocumentComplete(LPDISPATCH pDisp, VARIANT FAR* URL); virtual void OnWebStatusTextChange(LPCTSTR Text); virtual void OnWebCommandStateChange(long Command, BOOL Enable); virtual void OnWebTitleChange(LPCTSTR Text); virtual void OnWebPropertyChange(LPCTSTR szProperty); virtual void OnWebNewWindow2(LPDISPATCH FAR* ppDisp, BOOL FAR* Cancel); virtual void OnWebQuit(); virtual void OnWebVisible(BOOL Visible); virtual void OnWebToolBar(BOOL ToolBar); virtual void OnWebMenuBar(BOOL MenuBar); virtual void OnWebStatusBar(BOOL StatusBar); virtual void OnWebFullScreen(BOOL FullScreen); virtual void OnWebTheaterMode(BOOL TheaterMode); virtual void OnWebMouseMove(short a, short b, long x, long y); #ifdef SEARCH_FOR_HIDDEN_EVENT virtual void OnEmpty(); virtual void OnBstr(LPCTSTR lString); #endif // SEARCH_FOR_HIDDEN_EVENT // Hook virtual void beforeLoad(); virtual void OnModeChange(long pMode); virtual void BeforeNavigate(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel); virtual void Reload(long pRefreshForce); void OnGetControlInfo(LPCONTROLINFO pControlInfo); public: STDMETHOD(OnNewPageModel)(); STDMETHOD(Hide)(); STDMETHOD(Show)(); STDMETHOD(PrintPage)( int nCmd); STDMETHOD(Load)(); STDMETHOD(UserClick)(); STDMETHOD(TranslateUrl)(BSTR pUrl, BSTR* pUrlOut); STDMETHOD(getUrl)(CString& pUrl); virtual DWORD getNavigationFlags(); BEGIN_INTERFACE_PART(Highlight, IPageletHighlight) STDMETHOD(HighlightSelection)(DWORD pColor); STDMETHOD(RemoveSelectionHighlight)(); END_INTERFACE_PART(Highlight) BEGIN_INTERFACE_PART(Sticker, IPageletSticker) STDMETHOD(AddSticker)(DWORD pColor); END_INTERFACE_PART(Sticker) BEGIN_INTERFACE_PART(WebBrowser, IPageletWebBrowser) STDMETHOD(get_SelectedText)( BSTR* pSelectedText ); STDMETHOD(FocusPlacement)(int*); STDMETHOD(IsInternalPage)(BOOL* , BSTR* pType); STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget); STDMETHOD(UserClick)(); STDMETHOD(TranslateUrl)(BSTR pUrl, BSTR* pUrlOut); END_INTERFACE_PART(WebBrowser) public: STDMETHOD(Stop)(); STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget); #ifdef _DEBUG virtual void ReportResult(long pResult); #endif TWebBrowser* GetWebBrowser() { return fWebBrowser; } void hideAnnotation(BOOL pForce = FALSE); void showAnnotation(BOOL pForce = FALSE); BOOL NeedCreateNewPage(IWebBrowser2* pBrowser, BSTR, long, BSTR, VARIANT*, BSTR, BOOL* ); void CreateNewPage(IWebBrowser2* pBrowser, BSTR URL, long Flags, BSTR TargetFrameName, VARIANT* PostData, BSTR Headers); void webAddTrashImage(IHTMLDocument2* pDocument); void webAddAnnotations(BSTR pUrl); void webUpdateContent(CString pUrl); HRESULT MakeAnnotationInfo(TAnnotationModel* pAnnotation, IDomAnnotationInfo** pInfo); HRESULT AddAnnotation(IWebBrowserTreeNode* pNode, TAnnotationModel* pAnnotation, BOOL = TRUE); HRESULT Highlight(long pColor); HRESULT UpdateHighlight(IWebBrowserTreeNode* pNode); HRESULT CreateSticker(CPoint pPosition, long pColor); CString CheckTargetFrame(IWebBrowser2* pBrowser, CString pUrl, CString pTarget); HRESULT CheckIsInternalPage(BSTR* pType); HRESULT CheckMetaTags(); HRESULT CheckBaseHref(IHTMLDocument2* pDocument, LPCTSTR pUrl, BOOL* pBaseHref); void webSaveSubContentsInDb(IWebBrowser2* pBrowser); HRESULT doStretch(DWORD pFlags = PI_FORCE_ASYNC); BOOL TryReloadForBmp(IWebBrowser2* pBrowser, LPCTSTR pUrl); void InitFlags(IDispatch* = NULL); void Navigate(LPCTSTR pUrl, DWORD pFlags = -1, LPCTSTR pTargetName = NULL, LPCTSTR pHeaders = NULL, LPVOID pPost = NULL); // Special Case for Dynamic KeeBook // Added in 2.2 HRESULT HookDynamicKeeBook(IWebBrowser2* pBrowser, BOOL* pCancel); void LaunchExportDynamicKeeBook(BSTR pUrl, BSTR pCode); virtual HTMLFocusPlacement FocusPlacement( void ); // [AC] // Need a special test for IE 5.5 BOOL IsAutomaticRenavigation(BSTR*); HRESULT GetMetaCollection(IHTMLElementCollection** pCollec, IHTMLDocument2* = NULL); void ManageAnchorsEventSink(AdviseType adviseType); HRESULT GetConnectionPoint(LPUNKNOWN pUnk, REFIID riid, LPCONNECTIONPOINT* ppCP); // Picture Handler // Added in 2.3 HRESULT CheckPicturePage(IHTMLDocument2* pDocument); void RedirectTo(LPCTSTR pUrl, IWebBrowser2* pBrowser = NULL); void RemoveBanner(CWnd* pBanner) { m_AdBannerList.Remove(pBanner); m_ExternalAdBanner--; } public: BOOL m_bFirstNavigate:2; BOOL m_bUserClick:2; BOOL m_bInDocumentComplete:2; BOOL m_bDoStretch:2; BOOL m_bDynamicPage:2; BOOL m_bDoImageFit:2; BOOL m_bFullStaticKeeBook:2; protected: TWebBrowser* fWebBrowser; TBaseWebContentListener* fContentListener; TBaseWebBrowserEvents* m_pEvents; CString m_InitialUrl; CString m_CurrentUrl; long m_RefreshForce; DWORD m_StretchFlags; WORD m_ExternalAdBanner; WORD m_NavigateCount; CComObject* m_pDropTarget; CComPtr m_DropTarget; CComPtr m_pNetStatus; CComPtr m_RootDispatch; CComPtr m_SoftReloadTree; CComPtr m_BrowserTree; #if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL) CComPtr m_BeforeTree; #endif CSimpleArray m_NavigatingFramesList; CSimpleArray m_AdBannerList; stack _stackAnchorCookies; // Cannot use a bit field for this one, // has it is passed by reference in function call TWebBrowserStretchSink* m_StretchSink; #ifdef ALLOW_PDF_FILE CComDispatchDriver m_PdfObject; #endif // ALLOW_PDF_FILE BOOL m_bRedirected:2; BOOL m_bIsCreated:2; BOOL m_bReload:2; BOOL m_bReloadForBmp:2; BOOL m_bAnnotationAllowed:2; BOOL m_bStoreTitle:2; BOOL m_bPictureChecked:2; BOOL m_bNoStretch:2; BOOL m_bCanceling:2; BOOL m_bNeedReload:2; BOOL m_bStopReload:2; }; #endif // T_BASE_WEBBROWSER_PAGELET_CTL/*------------ TBrowserModeView.cpp ------------*/ #include "StdAfx.h" #include "TBrowserModeView.h" #include "TLibraryModeView.h" #include "PropertyChangeEvent.h" #include "TContextModel.h" #include "TModelNames.h" #include "TMetaManager.h" #include "TMediaLibraryModel.h" #include "TPageModel.h" #include "TUserMessage.h" #include "TBookModel.h" #include "TPageModel.h" #include "TMain.h" #include "BackGround.h" #include "TCustomPalette.h" #include "BookBrowser.h" #include "PrintingCmd.h" #include "TSoundManager.h" #include "SharedSoundAndFeelRes.h" #include "ArrowBand.h" // *** TO DO : remove --- TEST DRAWING ON MODE VIEW #include "TPageEditor.h" #include "Pagelet.h" #include "Controler.h" #include "ResBookMode.h" #include "SharedResource.h" #include "SharedLookAndFeelRes.h" #include "LookHelpMapId.h" IMPLEMENT_DYNAMIC(TBrowserModeView, TBooxView) BEGIN_MESSAGE_MAP(TBrowserModeView, TBooxView) //{{AFX_MSG_MAP(TBrowserModeView) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_SETFOCUS() ON_COMMAND(IDA_BOOK_NEXT_PAGE, OnBookNextPage) ON_COMMAND(IDA_BOOK_PREV_PAGE, OnBookPrevPage) ON_COMMAND(IDA_BOOK_SUMMARY, OnBookSummary) ON_COMMAND(IDA_BOOK_INDEX, OnBookIndex) ON_COMMAND(IDA_BOOK_NEXT_CHAPTER, OnBookNextChapter) ON_COMMAND(IDA_BOOK_PREV_CHAPTER, OnBookPrevChapter) ON_COMMAND(IDA_PAGE_PARENT_CHAPTER, OnPageParentChapter) ON_COMMAND(IDA_PAGE_FIRST_SUB_CHAPTER, OnPageFirstSubChapter) ON_COMMAND(IDA_DOC_SCROLL_UP, OnDocScrollUp) ON_COMMAND(IDA_DOC_SCROLL_DOWN, OnDocScrollDown) ON_COMMAND(IDA_DOC_PAGE_UP, OnDocPageUp) ON_COMMAND(IDA_DOC_PAGE_DOWN, OnDocPageDown) ON_COMMAND(IDA_DOC_BEGIN, OnDocBegin) ON_COMMAND(IDA_DOC_END, OnDocEnd) ON_COMMAND(IDA_NAVIGATE, OnFileNavigate) ON_COMMAND(IDA_SEARCH, OnEditFind) ON_COMMAND(IDA_HIGHLIGHTER, OnEditHighlighter) ON_COMMAND(IDA_STICKER, OnEditSticker) ON_COMMAND(IDM_FILE_NAVIGATE, OnFileNavigate) ON_COMMAND(IDM_VIEW_URL, OnFileNavigate) ON_COMMAND(IDM_FILE_NEWDOC, OnNewDoc) ON_COMMAND(IDM_FILE_CLOSE, OnCloseBook) ON_COMMAND(IDM_EDIT_HIGHLIGHT, OnEditHighlighter) ON_COMMAND(IDM_EDIT_STICKER, OnEditSticker) ON_COMMAND(IDM_EDIT_MODIFY, OnEditModify) ON_COMMAND(IDM_FILE_PRINT, OnFilePrint) ON_COMMAND(IDA_PRINT, OnFilePrint) ON_COMMAND(IDM_EDIT_FIND, OnEditFind) ON_COMMAND(IDM_EDIT_PAGEFIND, OnEditPageFind) ON_COMMAND(IDM_EDIT_BOOKFIND, OnEditBookFind) //}}AFX_MSG_MAP END_MESSAGE_MAP() // // TBrowserModeView Constructor // TBrowserModeView::TBrowserModeView() : TBooxView() { m_pBackGround = NULL; m_pBookBrowser = NULL; m_NewBrowser = FALSE; m_FirstActivation = TRUE; // --- initialize resource Id m_nIdIcon = IDI_BOOK_ICON; m_nIdTitle = IDS_BOOK_TITLE; m_nModeView = T_BOOK_MODE; // --- initialize contextuel help static const DWORD dwTabHelpIds[] = { AFX_IDW_PANE_FIRST, HIDC_MAIN_MODE_BOOK, 0, 0 }; m_pDwHelpIds = (DWORD *) dwTabHelpIds; m_ContextListener = NULL; m_pContextControl.CoCreateInstance(CLSID_TContextControler); ASSERT(m_pContextControl); } // // TBrowserModeView Destructor // TBrowserModeView::~TBrowserModeView() { if (m_ContextListener) { // *** Verify global context exists ASSERT(TContextModel::gContext); // *** Subscribe to context listener TContextModel::gContext->removePropertyChangeListener(m_ContextListener); m_ContextListener->setInvalid(); m_ContextListener = NULL; } } // ************************************************************************************************ int TBrowserModeView::OnCreate(LPCREATESTRUCT lpCreateStruct) { int result; if ((result = TBooxView::OnCreate(lpCreateStruct)) != 0) return result; createContextListener(); if (m_ContextListener) { // *** Verify global context exists ASSERT(TContextModel::gContext); // *** Subscribe to context listener TContextModel::gContext->addPropertyChangeListener(m_ContextListener); } m_pBookControler.CoCreateInstance(CLSID_TBookControler); ASSERT(m_pBookControler); if (m_pBookControler == NULL) { DestroyWindow(); return -1; } m_pBookControler->RegisterAsListener(); CDC* lDC = GetDC(); ASSERT_VALID(lDC); setDCMappingMode(lDC); createBookBrowser(lDC); createArrowBand(lDC); ReleaseDC(lDC); CheckBook(); VERIFY(m_OleDropTarget.Register(this)); return result; } // ************************************************************************************************ void TBrowserModeView::OnDestroy() { m_OleDropTarget.Revoke(); TBooxView::OnDestroy(); } // ************************************************************************************************ void TBrowserModeView::createArrowBand(CDC* pDC) { CSize lSize; // --- Arrow Band CRect lArrowBandRect(CPoint(m_BookBrowserLogicalRect.left, m_BookBrowserLogicalRect.bottom), m_ArrowBandSize); TArrowBand* lArrowBand = new TArrowBand(); lArrowBand->setArrow(T_PRIMARY, m_pPrimaryArrow); lArrowBand->setArrow(T_SECONDARY, m_pSecondaryArrow); lArrowBand->setArrowLogicalRect(T_PRIMARY, m_PrimaryArrowLogicalRect); lArrowBand->setArrowLogicalRect(T_SECONDARY, m_SecondaryArrowLogicalRect); ASSERT(m_pBookControler); lArrowBand->setBookControler(m_pBookControler); lSize = lArrowBandRect.Size(); lArrowBand->setLogicalSpace(lSize); lArrowBand->setLogicalPoint(lArrowBandRect.TopLeft()); lArrowBand->setLogicalSize(lSize); // --- CtrlID may be change by the HtmlHelpHook lArrowBand->Create(NULL, NULL, WS_CHILD | WS_VISIBLE, lArrowBandRect, this, 0); addChild(lArrowBand); lArrowBand->logicalResizeAndPos(pDC); lArrowBand->setViewToRefresh(this); } void TBrowserModeView::createBookBrowser(CDC* pDC) { // *** Create the book browser if (m_pBookBrowser == NULL) { m_pBookBrowser = new TBookBrowser(); m_NewBrowser = TRUE; } ASSERT(m_pBookControler); m_pBookBrowser->setBookControler(m_pBookControler); CSize lSize; lSize = m_BookBrowserLogicalRect.Size(); m_pBookBrowser->setLogicalPoint(m_BookBrowserLogicalRect.TopLeft()); m_pBookBrowser->setLogicalSize(lSize); if (m_NewBrowser) { m_pBookBrowser->Create(NULL, NULL, WS_CHILD | WS_VISIBLE, CRect(CPoint(0, 0), getLogicalSize()), this, 0); } else { m_pBookBrowser->SetParent(this); } m_pBookBrowser->PostMessage(ID_UM_CHANGE_ACTIVE_VIEW, GetActiveMode()); addChild(m_pBookBrowser); m_pBookBrowser->logicalResizeAndPos(pDC); // m_pBookBrowser->setViewToRefresh(this); } // ---------------------------------------------------------------------- // afx message handler void TBrowserModeView::OnFilePrint() { TPageEditor* lPageEditor; lPageEditor = getSelectedPageEditor(); ASSERT(lPageEditor); if (lPageEditor) { lPageEditor->printPage( CPrintingCmd::PROMPT_USER); } } void TBrowserModeView::OnPrint( CDC* pDC, CPrintInfo* pInfo ) { ASSERT_VALID(pDC); OnFilePrint(); } void TBrowserModeView::OnEditPageFind() { TPageEditor* lPageEditor; TModelPtr lPage; lPageEditor = getSelectedPageEditor(); lPage = lPageEditor->getPage(); // Try to show Search view IUnknown* lUnk = lPageEditor->getPageletControl(); BOOL lResult = FALSE; CComQIPtr lPagelet(lUnk); if (lPagelet) { if (lPagelet->ShowSearch() == S_OK) lResult = TRUE; } } void TBrowserModeView::OnEditBookFind() { // --- put in the page mode TContextModel::gContext->setCurrentModeNumber( T_PAGE_MODE); m_pBookControler->ChangePageTo(T_CPT_INDEX, T_SIDE_SECONDARY, CComVariant(1)); } void TBrowserModeView::OnEditFind() { TPageEditor* lPageEditor; TModelPtr lPage; lPageEditor = getSelectedPageEditor(); lPage = lPageEditor->getPage(); if( lPage == NULL || lPage->isInstanceOf(T_INDEX_MODEL_NAME)) { // Go to Thesaurus TModelPtr lCatalogBook; TModelPtr mlm; mlm = (TMediaLibraryModel *)TMetaManager::createModelInstance(T_MEDIA_LIBRARY_MODEL_NAME); lCatalogBook = (TBookModel*)mlm->getSpecialMediumInLibrary(TMediaLibraryModel::E_CATALOG_BOOK); if (lCatalogBook) { CComPtr lBookControler; lBookControler.CoCreateInstance(CLSID_TBookControler); // --- put in the page mode TContextModel::gContext->setCurrentModeNumber( T_PAGE_MODE); lBookControler->put_book((long)lCatalogBook.p); lBookControler->ChangePageTo(T_CPT_INDEX, T_SIDE_SECONDARY, CComVariant(1)); TContextModel::gContext->setCurrentBook(lCatalogBook); } } else { // Try to show Search view IUnknown* lUnk = lPageEditor->getPageletControl(); BOOL lResult = FALSE; CComQIPtr lPagelet(lUnk); if (lPagelet) { if (lPagelet->ShowSearch() == S_OK) lResult = TRUE; } // If show search fail, // search is already shown // so go to index page if (!lResult) { // --- put in the page mode TContextModel::gContext->setCurrentModeNumber( T_PAGE_MODE); m_pBookControler->ChangePageTo(T_CPT_INDEX, T_SIDE_SECONDARY, CComVariant(1)); } } } void TBrowserModeView::OnBookNextPage() { m_pBookControler->ChangePageTo(T_CPT_NEXT_PAGE, T_SIDE_SECONDARY, CComVariant(1)); } void TBrowserModeView::OnBookPrevPage() { m_pBookControler->ChangePageTo(T_CPT_PREV_PAGE, T_SIDE_PRIMARY, CComVariant(1)); } void TBrowserModeView::OnBookSummary() { m_pBookControler->ChangePageTo(T_CPT_SUMMARY, T_SIDE_SECONDARY, CComVariant(1)); } void TBrowserModeView::OnBookIndex() { m_pBookControler->ChangePageTo(T_CPT_INDEX, T_SIDE_SECONDARY, CComVariant(1)); } void TBrowserModeView::OnBookNextChapter() { m_pBookControler->ChangePageTo(T_CPT_NEXT_IN_HIERARCHIE, T_SIDE_SECONDARY, CComVariant(1)); } void TBrowserModeView::OnBookPrevChapter() { m_pBookControler->ChangePageTo(T_CPT_PREV_IN_HIERARCHIE, T_SIDE_PRIMARY, CComVariant(1)); } void TBrowserModeView::OnPageParentChapter() { m_pBookControler->ChangePageTo(T_CPT_PARENT_CHAPTER, T_SIDE_PRIMARY, CComVariant(1)); } void TBrowserModeView::OnPageFirstSubChapter() { m_pBookControler->ChangePageTo(T_CPT_FIRST_SUB_CHAPTER, T_SIDE_SECONDARY, CComVariant(1)); } void TBrowserModeView::OnDocScrollUp() { // TODO: Add your command handler code here TRACE("TBrowserModeView::DocScrollUp\n"); } void TBrowserModeView::OnDocScrollDown() { // TODO: Add your command handler code here TRACE("TBrowserModeView::DocScrollDown\n"); } void TBrowserModeView::OnDocPageUp() { // TODO: Add your command handler code here TRACE("TBrowserModeView::DocPageUp\n"); } void TBrowserModeView::OnDocPageDown() { // TODO: Add your command handler code here TRACE("TBrowserModeView::DocPageDown\n"); } void TBrowserModeView::OnDocBegin() { // TODO: Add your command handler code here TRACE("TBrowserModeView::DocBegin\n"); } void TBrowserModeView::OnDocEnd() { // TODO: Add your command handler code here TRACE("TBrowserModeView::DocEnd\n"); } void TBrowserModeView::OnNewHighlighter( WORD wFilter) { TPageEditor* lPageEditor; lPageEditor = getSelectedPageEditor(); newHighlighter(lPageEditor, wFilter); } void TBrowserModeView::OnNewSticker( WORD wFilter) { TPageEditor* lPageEditor; lPageEditor = getSelectedPageEditor(); newSticker(lPageEditor, wFilter); } void TBrowserModeView::SetOldBooxView(TBooxView* pView) { if (pView->IsKindOf(RUNTIME_CLASS(TBrowserModeView))) { m_pBookBrowser = ((TBrowserModeView*)pView)->getBookBrowser(); } if (pView->IsKindOf(RUNTIME_CLASS(TLibraryModeView))) { m_pBookBrowser = ((TLibraryModeView*)pView)->getBookBrowser(); if (m_pBookBrowser) { TModelPtr lBook; TContextModel::gContext->getCurrentBook(&lBook); m_pBookBrowser->setBook(lBook); } } } void TBrowserModeView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView ) { /* TBooxView::OnActivateView(bActivate, pActivateView, pDeactiveView ); if (m_pBookBrowser && bActivate) { if (m_FirstActivation) { m_pBookBrowser->ModeChange(GetActiveMode()); m_FirstActivation = FALSE; } } */ } HRESULT TBrowserModeView::ChangeBook(TBookModel* pBook) { if (m_pBookBrowser) { if (pBook) pBook->AddRef(); m_pBookBrowser->PostMessage(WM_USER_CHANGE_BOOK, (WPARAM)pBook); return S_OK; } return S_FALSE; } void TBrowserModeView::CheckBook() { TModelPtr lCurrentBook; TContextModel::gContext->getCurrentBook(&lCurrentBook); if (lCurrentBook && m_NewBrowser && !TContextModel::gContext->isBeforeFire()) { ChangeBook(lCurrentBook); } } void TBrowserModeView::createContextListener() { } TPageEditor* TBrowserModeView::getSelectedPageEditor() { ASSERT(m_pBookBrowser); return m_pBookBrowser->getSelectedPageEditor(); } void TBrowserModeView::OnSetFocus(CWnd* pOldWnd) { if( TCustomPalette::m_pPalette) { m_pBookBrowser->getPageEditor(T_PRIMARY)->Invalidate(); m_pBookBrowser->getPageEditor(T_SECONDARY)->Invalidate(); } } /*------------ TPageEditor.cpp ------------*/ #include "StdAfx.h" // *** MAIN INCLUDE #include "TPageEditor.h" // *** OTHER INCLUDE #include "TChapterModel.h" #include "TContextModel.h" #include "TContentModel.h" #include "TAnnotationModel.h" #include "TBookModel.h" #include "TIndexModel.h" #include "TPageModel.h" #include "TSummaryModel.h" #include "TModelIterator.h" #include "TModelNames.h" #include "TModelHelpers.h" #include "TMetaManager.h" #include "TPropertyObjectModel.h" #include "BackGround.h" #include "BookBrowser.h" #include "TBrowseDir.h" //#include "CreateBookWizard.h" #include "DragAndDropPageData.h" #include "TOleDataObject.h" #include "NameEdit.h" #include "NameStatic.h" #include "PageletToolbar.h" #include "PropertyChangeEvent.h" #include "SharedLookAndFeelRes.h" #include "TabsViewer.h" #include "TBooxFrame.h" #include "TGlobalsDB.h" #include "TPageletContainerView.h" #include "TPageletViewManager.h" #include "TPagePropertiesConstants.h" #include "TPropertyObjectModel.h" #include "Dib.h" #include "IconView.h" #include "IconView.h" #include "ResButtonInfo.h" #include "ProgressDlg.h" #include "TUrl.h" #include "TTFont.h" #include "MemDC.h" #include "TString.h" #include "TCustomPalette.h" #include "InPlaceEdit.h" #include "PrintingEngine.h" #include "TSoundManager.h" #include "SharedSoundAndFeelRes.h" #include "SharedLookAndFeelRes.h" #include "SharedResource.h" #include "TShellUtils.h" #include "Controler.h" #include "TUserMessage.h" //#define ID_NAME_EDIT 100 // TEMP // this is the space betwen the binding and the page #define T_BINDING_MARGE 5 #define T_TITLE_MARGIN 8 #define T_TITLE_HEIGHT (29 + T_TITLE_MARGIN) #define TIMER_EDIT_TITLE 1 class TPEBookListener : public TPropertyChangeListener { TPageEditor* m_pPageEditor; public: TPEBookListener(TPageEditor* pPageEditor); ~TPEBookListener(); virtual void propertyChange(TPropertyChangeEvent *evt); }; class TPEPageListener : public TPropertyChangeListener { TPageEditor* m_pPageEditor; public: TPEPageListener(TPageEditor* pPageEditor); ~TPEPageListener(); virtual void propertyChange(TPropertyChangeEvent *evt); }; #define IDC_EDIT_INPLACE 100 // ************************************************************************************************ IMPLEMENT_DYNAMIC(TPageEditor, TWnd) // *** Message map BEGIN_MESSAGE_MAP(TPageEditor, TWnd) //{{AFX_MSG_MAP(CChildFrame) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_CTLCOLOR() ON_WM_MOUSEMOVE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_ERASEBKGND() ON_WM_LBUTTONDBLCLK() ON_WM_SIZE() ON_WM_TIMER() ON_WM_SETFOCUS() ON_WM_MOUSEACTIVATE() ON_EN_KILLFOCUS( IDC_EDIT_INPLACE, OnEnKillFocus) //}}AFX_MSG_MAP ON_MESSAGE(WM_USER_UPDATE_TITLE, OnUpdateTitle) ON_MESSAGE(WM_USER_REMOVE_CHILD, OnRemoveChild) ON_MESSAGE(WM_USER_REFRESH_PAGE_CONTENT, OnRefreshPageContent) END_MESSAGE_MAP() // ************************************************************************************************ // *** PageEditor Constructor TPageEditor::TPageEditor() : TWnd(), fNeedTabBody(FALSE), fShowContent(TRUE), fFlying(FALSE), fSelected(TRUE), fIsIndex(FALSE), fIsSummary(FALSE), fIsProperty(FALSE), fIsChapter(FALSE), m_Side(T_SECONDARY), m_pBkgnd(NULL), m_pTopBkgnd(NULL), m_pTitleBkgnd(NULL), fPageListener(NULL), fBookListener(NULL), m_PageView(NULL), fPageIndex(-1), fTabIndex(0), m_HaveToolbar(FALSE), m_pBookBrowser(NULL), m_bIsAlreadySelected( FALSE), m_TabsViewerComputed(FALSE), m_InMouseDown(FALSE), m_JustCloseEdit(FALSE), #ifdef DO_NOT_DISPLAY_AUTHOR_TITLE m_bIsAuthorPage(FALSE), #endif // DO_NOT_DISPLAY_AUTHOR_TITLE m_pInPlaceEditCtrl(NULL), m_pTitleFont(NULL), m_pNumberFont(NULL), m_BackBrushID(0), m_BkColor(0), m_Behaviour(0), m_pPrintingEngine(NULL), fPageCount(0) { initResources(); m_TitleRect.SetRectEmpty(); setOpaque(true); m_bIsDblClk = false; m_TitleNormalColor = RGB(0,0,0); m_TitleSelectedColor = RGB(0,0,0); } // ************************************************************************************************ // *** PageEditor Destructor TPageEditor::~TPageEditor() { exitResources(); // *** Delete pagelet manager // if (fPageletManager) // delete fPageletManager; removePage(); } // ************************************************************************************************ int TPageEditor::OnCreate(LPCREATESTRUCT lpCreateStruct ) { if (TWnd::OnCreate(lpCreateStruct) == -1) return -1; addToolTip(); m_xLogicalSpaceConstraint.fThis = this; // *** Create and select font // m_pTitleFont = new CTTFont( IDS_FONT_PAGE_TITLE); // VERIFY( m_pTitleFont->CreateFontFromString()); return 0; } // ************************************************************************************************ void TPageEditor::OnDestroy( ) { // --- if the tooltips control is not yet deleted CToolTipCtrl* pToolTip = TBooxFrame::GetToolTip(); if( pToolTip && ::IsWindow( pToolTip->m_hWnd) ) { // --- remove this from the tooltip list // pToolTip->DelTool( this); } delete m_pTopBkgnd; m_pTopBkgnd = NULL; delete m_pBkgnd; m_pBkgnd = NULL; delete m_pTitleBkgnd; m_pTitleBkgnd = NULL; delete m_pTitleFont; m_pTitleFont = NULL; delete m_pNumberFont; m_pNumberFont = NULL; removePageletView(); TWnd::OnDestroy(); } // ************************************************************************************************ void TPageEditor::addToolTip() { CToolTipCtrl* pToolTip = TBooxFrame::GetToolTip(); if( pToolTip) { /* CRect lDeviceRect; GetClientRect(&lDeviceRect); CRect lClientRect; GetClientRect(&lClientRect); lDeviceRect.left += T_BINDING_MARGE; lDeviceRect.right -= T_BINDING_MARGE; CRect lLogicalRect = lDeviceRect; DPtoLP(&lLogicalRect); long lWidth; lWidth = GetPageNumberWidth(pDC); if (getPageSide() == T_SECONDARY) lLogicalRect.left = lLogicalRect.right - lWidth; else lLogicalRect.right = lLogicalRect.left + lWidth; lLogicalRect.bottom = lLogicalRect.top + gTitleBkgnd->getHeight(); LPtoDP(&lLogicalRect); pToolTip->AddTool( this, "Ici, bientôt le numéro de la page...", &lClientRect, 2123); */ } } // ************************************************************************************************ void TPageEditor::excludeCustomRgn(CDC* pDC, CWnd* pWndTo) { if (m_PageView) { //m_PageView->excludeCustomRgn(pDC, pWndTo); /* ATLASSERT(pDC->GetSafeHdc()); ATLASSERT(pWndTo->GetSafeHwnd()); CRect lRect = CRect(m_PageView->getLogicalPoint(), m_PageView->getLogicalSize()); MapWindowPoints(pWndTo, &lRect); //pDC->Rectangle(lRect); if (pDC->RectVisible(lRect)) { TRACE(" *** TPageEditor::excludeCustomRgn lRect t %d, l %d, b %d, r %d\n", lRect.top, lRect.left, lRect.bottom, lRect.right); pDC->ExcludeClipRect(lRect); } */ } } // ************************************************************************************************ t_view_mode TPageEditor::getMode() { return (t_view_mode) TBooxFrame::GetActiveMode(); } // ************************************************************************************************ STDMETHODIMP TPageEditorConstraint::ConstraintLogicalResize(HDC pDC) { if (fThis) { ((TPageEditor*)fThis)->constraintLogicalResize(); return S_OK; } return S_FALSE; } // ************************************************************************************************ LPUNKNOWN TPageEditor::GetInterfaceHook(const void* piid) { if (InlineIsEqualGUID(*(GUID*)piid, IID_ILogicalSpaceConstraint)) return &m_xLogicalSpaceConstraint; return TWnd::GetInterfaceHook(piid); } // *** Overrides logicalResizeAndPos from TView because we need to set constraints void TPageEditor::constraintLogicalResize() { } void TPageEditor::logicalResizeAndPos(CDC* pDC) { logicalResize(pDC); if (m_pBookBrowser) { /* if ((getPageSide() == T_SECONDARY) && (!fFlying)) { TPageEditor* lPage = m_pBookBrowser->getPrimaryPageEditor(); getDevicePoint().x = lPage->getDevicePoint().x + lPage->getDeviceSize().cx; } */ } setLogicalWindowPos(); } // ************************************************************************************************ void TPageEditor::OnSetFocus( CWnd* pOldWnd ) { TWnd::OnSetFocus(pOldWnd); } // ************************************************************************************************ void TPageEditor::OnMouseActivate( CWnd* pDesktopWnd, UINT nHitTest, UINT message ) { ATLASSERT(m_pBookBrowser); if (m_pBookBrowser) { CComPtr lBookControler; m_pBookBrowser->getBookControler(&lBookControler); ATLASSERT(lBookControler); if (lBookControler) { ePageSide2 lSide; lSide = m_Side == T_PRIMARY ? T_SIDE_PRIMARY : T_SIDE_SECONDARY; lBookControler->ChangePageTo(T_CPT_SELECTED_PAGE, lSide, CComVariant(1)); } } TWnd::OnMouseActivate(pDesktopWnd, nHitTest, message ); } // ************************************************************************************************ void TPageEditor::OnLButtonDown( UINT nFlags, CPoint point) { TRACE("TPageEditor::OnLButtonDown\n"); m_InMouseDown = TRUE; m_bIsDblClk = false; TWnd::OnLButtonDown( nFlags, point); m_bIsAlreadySelected = fSelected; if( !onBeginDragPage()) { // --- generate a button up, because DoDragDrop eat it PostMessage( WM_LBUTTONUP, (WPARAM) nFlags, MAKELPARAM( point.x, point.y)); } } void TPageEditor::OnLButtonDblClk( UINT nFlags, CPoint point ) { TRACE( _T("*** TPageEditor::OnLButtonDblClk\n")); m_bIsDblClk = true; CRect lRect; lRect = m_TitleRect; LPtoDP(&lRect); if (lRect.PtInRect(point)) { if (TContextModel::gContext->getCurrentModeNumber() == T_BOOK_STAND_MODE) TContextModel::gContext->setCurrentModeNumber(T_BOOK_MODE); else if (TContextModel::gContext->getCurrentModeNumber() == T_BOOK_MODE) TContextModel::gContext->setCurrentModeNumber(T_PAGE_MODE); } } void TPageEditor::OnLButtonUp( UINT nFlags, CPoint point) { TRACE("TPageEditor::OnLButtonUp\n"); m_InMouseDown = FALSE; TWnd::OnLButtonUp( nFlags, point); // --- if no drag and drop made, check for edition CRect rectTitle( CPoint(0, 0), CSize (getLogicalSize().cx, T_TITLE_HEIGHT)); LPtoDP(&rectTitle); if( m_bIsAlreadySelected && rectTitle.PtInRect( point)) { // --- put in selected mode if( isSummary() || isIndex() || isPropertyPage() || ::IsSystem< TPageModel>( m_Page)) { TSoundManager::PlayFromResource( IDSOUND_ALERT); } else { if (!m_JustCloseEdit) { TRACE("TPageEditor::OnLButtonUp Call SetTimer(TIMER_EDIT_TITLE)\n"); // --- delay the edition in case where a double click follow if( SetTimer( TIMER_EDIT_TITLE, 500, NULL) != TIMER_EDIT_TITLE) { // --- no more timer is available, so edit immediatly EditTitle(); } } } } m_JustCloseEdit = FALSE; } // ************************************************************************************************ TBackGround* TPageEditor::getBkgnd() { if (!isFlying()) return m_pBkgnd; return m_pBkgnd; } // ************************************************************************************************ BOOL TPageEditor::canSetPage(TPageModel* pPage, BOOL pForced) { BOOL lCanSetPage = FALSE; if ((m_Page != pPage) || pForced) lCanSetPage = TRUE; ATLASSERT(m_pBookBrowser); if (m_pBookBrowser == NULL) return lCanSetPage; lCanSetPage = lCanSetPage && (m_pBookBrowser->getBook() || (pPage == NULL)); if (m_pBookBrowser->GetSupportFlying()) lCanSetPage = lCanSetPage && !m_pBookBrowser->isFlying(pPage); return lCanSetPage; } void TPageEditor::refreshPageContent() { if (m_pBookBrowser) { if (fShowContent && IsWindowVisible()) refresh(); loadPagelet(); m_JustCloseEdit = FALSE; // SetDlgItemText(ID_NAME_EDIT, m_Page->getTitle()); } } void TPageEditor::getPageletLogicalRect(CRect& pRect) { CRect lDeviceContentRect; GetClientRect(&lDeviceContentRect); CRect lLogicalContentRect = lDeviceContentRect; DPtoLP(&lLogicalContentRect); #ifdef DO_NOT_DISPLAY_AUTHOR_TITLE if (!m_bIsAuthorPage) #endif // DO_NOT_DISPLAY_AUTHOR_TITLE lLogicalContentRect.top += T_TITLE_HEIGHT; // lLogicalContentRect.bottom -= 5; // lLogicalContentRect.right -= 3; pRect = lLogicalContentRect; if (fNeedTabBody) { long lBobyWidth = 0; lBobyWidth = TTabsViewer::gTabBodyLeft->getWidth(); if (getPageSide() == T_PRIMARY) pRect.left += lBobyWidth; else pRect.right -= lBobyWidth; } } // ************************************************************************************************ void TPageEditor::Select(BOOL pActive) { if (fSelected != pActive) { fSelected = pActive; if (IsWindowVisible()) { // *** Refresh title bar CRect lTitleRect(CPoint(0, 0), CSize (getLogicalSize().cx, T_TITLE_HEIGHT)); LPtoDP(&lTitleRect); refresh(&lTitleRect); } } // *** If the page is active, we need to update the context // *** Should always be done, even if the page stay in the same state } // ************************************************************************************************ void TPageEditor::setPageViewParent(TPageModel* pPage) { TPageletContainerView* lPagelet = getPageletManager()->findPageletViewFor(pPage); if (lPagelet) { TWnd* lView = (TWnd*) lPagelet->GetParent(); ATLASSERT(lView-IsKindOf(RUNTIME_CLASS(TWnd))); lView->removeChild(lPagelet); lPagelet->SetParent(this); m_PageView = lPagelet; addChild(lPagelet); } } // ************************************************************************************************ // *** EVENTS HANDLER ON PAGE PROPERTIES CHANGE // ************************************************************************************************ // ************************************************************************************************ void TPageEditor::sendEvent(LPCTSTR pEvt) { } // ************************************************************************************************ TPageletViewManager* TPageEditor::getPageletManager() { TPageletViewManager* lManager; lManager = m_pBookBrowser->getPageletManager(); ATLASSERT(lManager); return lManager; } // ************************************************************************************************ // ************************************************************************************************ void TPageEditor::initResources() { } // ************************************************************************************************ void TPageEditor::exitResources() { delete m_pTitleBkgnd; m_pTitleBkgnd = NULL; } BOOL TPageEditor::RectVisible(CDC* pDC, LPRECT pRect) { /* CRect lRect; if (m_pPaintStruct) lRect = m_pPaintStruct->rcPaint; else GetClientRect(&lRect); // TRACE("(x:%d, y:%d, w:%d, h:%d)\n", lRect.left, lRect.top, lRect.Width(), lRect.Height()); lRect.IntersectRect(pRect, lRect); return !lRect.IsRectEmpty(); */ return TRUE; // pDC->RectVisible(pRect); } // ************************************************************************************************ void TPageEditor::OnDraw(CDC* pDC) { ATLASSERT(pDC->GetSafeHdc()); #ifndef DRAW_ON_BACKGROUND drawBookSheet(pDC); #endif if (m_Page) { CRect lTitleRect; GetTitleRect( lTitleRect); #ifdef DO_NOT_DISPLAY_AUTHOR_TITLE_TEXT if (!fIsProperty) #endif DO_NOT_DISPLAY_AUTHOR_TITLE_TEXT if (!lTitleRect.IsRectEmpty() && RectVisible(pDC, lTitleRect)) drawTitle(pDC, &lTitleRect); if (fNeedTabBody) { TBackGround* lTabBodyBack; CRect lTabBodyRect; lTabBodyBack = GetTabBody(); lTabBodyRect = GetTabBodyRect(lTabBodyBack); if (lTabBodyBack && RectVisible(pDC, &lTabBodyRect)) drawTabBody(pDC, lTabBodyBack, &lTabBodyRect); } CRect lPageNumberRect; GetPageNumRect(lPageNumberRect); if (RectVisible(pDC, &lPageNumberRect)) drawPageNumber(pDC, &lPageNumberRect); } /* #ifdef DEBUG_BOOK_WND_POSITION CRect lRect; GetClientRect(&lRect); pDC->DPtoLP(&lRect); pDC->FrameRect(lRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); #endif */ } // ************************************************************************************************ void TPageEditor::GetTitleRect( CRect& rect) { #ifdef DO_NOT_DISPLAY_AUTHOR_TITLE if (m_bIsAuthorPage) { rect.SetRectEmpty(); return ; } #endif // DO_NOT_DISPLAY_AUTHOR_TITLE GetClientRect( &rect); long lWidth; lWidth = GetPageNumberWidth(); DPtoLP(&rect); if (getPageSide() == T_PRIMARY) rect.left += lWidth; else rect.right -= lWidth; rect.left += T_BINDING_MARGE; rect.right -= T_BINDING_MARGE; rect.top = T_TITLE_MARGIN; rect.bottom = T_TITLE_HEIGHT; LPtoDP(&rect); } void TPageEditor::drawTitle(CDC* pDC, LPRECT pTitleRect) { AFX_MANAGE_STATE(AfxGetAppModuleState()); ASSERT_VALID(pDC); // *** Prepare the device context int nSavedDC = pDC->SaveDC(); (void) pDC->SetMapMode( MM_TEXT); (void) pDC->SelectObject( m_pTitleFont); (void) pDC->SetBkMode(TRANSPARENT); COLORREF lTextColor; if (isSelected()) lTextColor = m_TitleSelectedColor; else lTextColor = m_TitleNormalColor; (void) pDC->SetTextColor(lTextColor); // *** draw it pDC->DrawText( m_Page->getTitle(), pTitleRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX | DT_WORD_ELLIPSIS ); #ifdef DEBUG_BOOK_WND_POSITION pDC->FrameRect(pTitleRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); #endif // *** Restore the DC VERIFY( pDC->RestoreDC( nSavedDC)); } // ************************************************************************************************ long TPageEditor::GetPageNumberWidth(CDC* pDC) { CDC* lDC = pDC; int lSavedDC = 0; if (lDC == NULL) { lDC = GetDC(); // *** Initialize the DC lSavedDC = lDC->SaveDC(); (void) lDC->SelectObject( m_pNumberFont); (void) lDC->SetMapMode( MM_TEXT); } CSize lSize; lSize = lDC->GetTextExtent(GetPageNumberString()); if (lSavedDC) { VERIFY( lDC->RestoreDC( lSavedDC)); ReleaseDC(lDC); } DPtoLP(&lSize); long lOffset = 0; if (fNeedTabBody) lOffset = GetTabBodyRect(NULL).Width(); return lSize.cx + lOffset + 3; } void TPageEditor::GetPageNumRect( CRect& rect, CDC* pDC) { GetClientRect( &rect); long lWidth; DPtoLP(&rect); lWidth = GetPageNumberWidth(pDC); if (getPageSide() == T_PRIMARY) rect.right = rect.left + lWidth; else rect.left = rect.right - lWidth; rect.top = T_TITLE_MARGIN; rect.bottom = T_TITLE_HEIGHT; LPtoDP(&rect); } CString TPageEditor::GetPageNumberString() { // *** Get page number CString lNumStr; if (!isPropertyPage() && !isIndex()) { int lNum; lNum = fPageIndex; lNumStr.Format("%d/%d", lNum, fPageCount); } return lNumStr; } void TPageEditor::drawPageNumber(CDC* pDC, LPRECT pPageNumberRect) { ASSERT_VALID(pDC); // *** Initialize the DC int nSavedDC = pDC->SaveDC(); (void) pDC->SetMapMode( MM_TEXT); (void) pDC->SelectObject( m_pNumberFont); (void) pDC->SetBkMode(TRANSPARENT); COLORREF lTextColor; if (isSelected()) lTextColor = m_TitleSelectedColor; else lTextColor = m_TitleNormalColor; (void) pDC->SetTextColor(lTextColor); // *** Get page number CString lNumStr; long lJustify = DT_CENTER; lNumStr = GetPageNumberString(); if (getPageSide() == T_SECONDARY) lJustify = DT_LEFT; else lJustify = DT_RIGHT; pDC->DrawText(lNumStr, pPageNumberRect, lJustify | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX); #ifdef DEBUG_BOOK_WND_POSITION pDC->FrameRect(pPageNumberRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); #endif // *** Restore the DC VERIFY( pDC->RestoreDC( nSavedDC)); } // ************************************************************************************************ TBackGround* TPageEditor::GetTabBody() { TBackGround* lBody = NULL; if (isIndex() || isSummary()) { lBody = TTabsViewer::gTabBodyLeft; } else { long lTabNb; TTabDesc* lTabDesc; ATLASSERT(fTabIndex >= 0); if (fTabIndex < 0) fTabIndex = 0; lTabNb = fTabIndex % TTabsViewer::gNbDifferentTabs; lTabDesc = (TTabDesc*)TTabsViewer::gTabsDesc->elementAt(lTabNb); ATLASSERT(lTabDesc); if (lTabDesc) { if (lTabDesc->fBkgndBody == NULL) lTabDesc->fBkgndBody = new TBackGround(lTabDesc->m_TabDesc.fIDBodyLeft); lBody = lTabDesc->fBkgndBody; } } ATLASSERT(lBody); return lBody; } CRect TPageEditor::GetTabBodyRect(TBackGround* pBody) { if (pBody == NULL) pBody = GetTabBody(); CRect lRect(0,0,0,0); if (pBody == NULL) return lRect; long lLeft = 0; if (getPageSide() != T_PRIMARY) { lLeft = getLogicalSize().cx - pBody->getWidth(); if (m_pBookBrowser && (m_pBookBrowser->GetModeView() == T_PAGE_MODE)) lLeft = lLeft / 2; } // WARN: top Should be in the Resources !!!! lRect.top = 8; lRect.bottom = getLogicalSize().cy; // {PS (A quoi ça sert ?)} - getLogicalPoint().y; lRect.left = lLeft; // lTabsViewer->getLogicalPoint().x + lOffset; lRect.right = lRect.left + pBody->getWidth(); return lRect; } void TPageEditor::drawTabBody(CDC* pDC, TBackGround* pBody, LPRECT pRect) { ASSERT_VALID(pDC); ATLASSERT(m_Page); // *** Trace body tab, if this page is a top level chapter, and if it stands in // *** a book browser // *** Need to find the index of this chapter in order to get coordinates of tab if (pBody == NULL) return ; WORD lMode = BK_NORMAL; CRect lRect(*pRect); if (getPageSide() != T_PRIMARY) { long lWidth; lMode = BK_REVERSE_Y_AXIS; if (getBookBrowser()->GetModeView() == T_PAGE_MODE) lWidth = pBody->getWidth() / 2 + 1; else lWidth = pBody->getWidth(); lRect.left += lWidth; lRect.right += lWidth; } pBody->stretch(pDC, lRect, lMode); // Draw a Black Frame arrond the tab body #ifdef DEBUG_BOOK_WND_POSITION if (getPageSide() != T_PRIMARY) { lRect.right = lRect.left; lRect.left = lRect.left - pBody->getWidth(); } pDC->FrameRect(lRect, CBrush::FromHandle((HBRUSH)GetStockObject(GRAY_BRUSH))); #endif // DEBUG_BOOK_WND_POSITION } // ************************************************************************************************ // // see in PageEditor // long TPageEditor::GetDrawClipRect(CDC* pDC, LPRECT pClipRect) { CRect lClipRect; CRect lClientRect; int lClipResult; lClipResult = pDC->GetClipBox(&lClipRect); if (lClipResult == NULLREGION) return lClipResult; GetClientRect(&lClientRect); pDC->DPtoLP(&lClientRect); if (lClipResult == ERROR) { lClipRect = lClientRect; lClipResult = SIMPLEREGION; } else { CRect lUnionRect; // Due to a problem of refresh !!!!! lClipRect.InflateRect(4, 4); lUnionRect.UnionRect(lClientRect, lClipRect); if (!lUnionRect.EqualRect(lClientRect)) lClipRect = lClientRect; } #ifdef _DEBUG CRect lUnionRect; lUnionRect.UnionRect(lClientRect, lClipRect); ATLASSERT(lUnionRect.EqualRect(lClientRect)); #endif *pClipRect = lClipRect; return lClipResult; } // ************************************************************************************************ void TPageEditor::drawBackground(CDC* pDC) { drawBookSheet(pDC); } // ************************************************************************************************ void TPageEditor::drawBookSheet(CDC* pDC) { // *** Draw the sheet ASSERT_VALID(pDC); ATLASSERT(m_pTitleBkgnd); CPalette* lOldPalette = NULL; if( TCustomPalette::m_pPalette) lOldPalette = pDC->SelectPalette( TCustomPalette::m_pPalette, TRUE); CRect lRect; if (m_pBkgnd) { GetClientRect(&lRect); DPtoLP(&lRect); m_pBkgnd->stretch(pDC, lRect); } else { if (GetDrawClipRect(pDC, &lRect) != NULLREGION) pDC->FillSolidRect(lRect, m_BkColor | 0x02000000); } CRect lTopRect(CPoint(0, 0), CSize(getLogicalSize().cx, m_pTopBkgnd->getHeight())); // LPtoDP(&lTopRect); if (m_pTopBkgnd && RectVisible(pDC, &lTopRect)) m_pTopBkgnd->stretch(pDC, lTopRect); if (isSelected() #ifdef DO_NOT_DISPLAY_AUTHOR_TITLE && !m_bIsAuthorPage #endif // DO_NOT_DISPLAY_AUTHOR_TITLE && RectVisible(pDC, &m_TitleRect)) m_pTitleBkgnd->stretch(pDC, m_TitleRect); if (lOldPalette) pDC->SelectPalette(lOldPalette, TRUE); } // ************************************************************************************************ void TPageEditor::showContent(BOOL pShow) { if (fShowContent == pShow) return; fShowContent = pShow; if (fShowContent) { ShowWindow(SW_SHOW); //m_PageView->ShowWindow(SW_SHOW); } else { ShowWindow(SW_HIDE); //m_PageView->ShowWindow(SW_HIDE); } } // ************************************************************************************************ HBRUSH TPageEditor::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CWnd::OnCtlColor(pDC, pWnd, nCtlColor); if (nCtlColor == CTLCOLOR_STATIC) { pDC->SetBkMode(TRANSPARENT); CBrush lBrush; lBrush.CreateStockObject(NULL_BRUSH); return (HBRUSH)lBrush; } // TODO: Change any attributes of the DC here // TODO: Return a different brush if the default is not desired return hbr; } // ************************************************************************************************ class TPageDropSource : public COleDropSource { public: TPageDropSource() : m_First(TRUE) {} virtual SCODE GiveFeedback( DROPEFFECT dropEffect ); protected: BOOL m_First:2; }; SCODE TPageDropSource::GiveFeedback( DROPEFFECT dropEffect ) { // Play sound when beginning to drag the page if (m_First) { TSoundManager::PlayFromResource( IDSOUND_DRAG_PAGE); m_First = FALSE; } return COleDropSource::GiveFeedback(dropEffect); } BOOL TPageEditor::onBeginDragPage() { ATLASSERT(m_Page); // *** Verify, it is not property page, summary or index if (/*isSummary() || */isIndex() || isPropertyPage()) return FALSE; // *** Create an OLE data source, Fill with the page TDragAndDropPageData data; TModelPtr lChapter; m_Page->getChapter(&lChapter); data.setChapter(lChapter); data.addPage( m_Page); // --- Allocate global memory for the data STGMEDIUM lKeeBooStg; memset( (void*) &lKeeBooStg, 0, sizeof( STGMEDIUM)); lKeeBooStg.tymed = TYMED_HGLOBAL; UINT uSize = sizeof( TDragAndDropPageData); lKeeBooStg.hGlobal = ::GlobalAlloc( GMEM_SHARE, uSize); memcpy( lKeeBooStg.hGlobal, &data, uSize); TOleDataSource lDataSource; lDataSource.CacheDataType( E_DATA_TYPE_KEEBOO_PAGE, &lKeeBooStg); TModelPtr lContent; TUrl lUrl; CString lStringUrl; HGLOBAL lUrlGlobal; HGLOBAL lNBookmarkGlobal; HGLOBAL lTextGlobal; m_Page->getContent(&lContent); if (lContent) { lUrl = lContent->getUrl(); lStringUrl = lUrl.simpleUrlString(); if (lStringUrl.GetLength()) { lUrlGlobal = ::GlobalAlloc( GMEM_SHARE, lStringUrl.GetLength() + 1); memcpy( lUrlGlobal, lStringUrl.GetBuffer(0), lStringUrl.GetLength() + 1); lNBookmarkGlobal = ::GlobalAlloc( GMEM_SHARE, lStringUrl.GetLength() + 1); memcpy( lNBookmarkGlobal, lStringUrl.GetBuffer(0), lStringUrl.GetLength() + 1); lTextGlobal = ::GlobalAlloc( GMEM_SHARE, lStringUrl.GetLength() + 1); memcpy( lTextGlobal, lStringUrl.GetBuffer(0), lStringUrl.GetLength() + 1); lStringUrl.ReleaseBuffer(); lDataSource.CacheGlobalDataType( E_DATA_TYPE_BROWSER_URL, lUrlGlobal); lDataSource.CacheGlobalDataType( E_DATA_TYPE_BROWSER_BOOKMARK, lNBookmarkGlobal); lDataSource.CacheGlobalData( CF_TEXT, lTextGlobal); } } TPageDropSource lDropSource; // *** Do the drag and drop... DROPEFFECT lDropEffect = lDataSource.DoDragDrop(DROPEFFECT_MOVE | DROPEFFECT_COPY, NULL, &lDropSource); // ::GlobalFree(lHGlobal); return lDropEffect == DROPEFFECT_NONE ? FALSE : TRUE; } // ************************************************************************************************ void TPageEditor::OnSize( UINT nType, int cx, int cy ) { delete m_pTitleFont; m_pTitleFont = new CTTFont( IDS_FONT_PAGE_TITLE); CPoint point( 0, T_TITLE_HEIGHT - T_TITLE_MARGIN); LPtoDP( &point); m_pTitleFont->SetHeight( point.y); VERIFY( m_pTitleFont->CreateFontFromString()); delete m_pNumberFont; m_pNumberFont = new CTTFont( IDS_FONT_PAGE_NUMBER); m_pNumberFont->SetHeight((point.y * 3) / 4); VERIFY( m_pNumberFont->CreateFontFromString()); TWnd::OnSize( nType, cx, cy); } // ************************************************************************************************ BOOL TPageEditor::isBookModifiable() { if (m_Page) { TModelPtr lBook; m_Page->getBook(&lBook); if (lBook) { if (!IsModifyProtected(lBook)) return true; } } return false; } // ************************************************************************************************ long TPageEditor::getPageIndex() { if (!m_Page) return 0; if (isIndex()) return -1; TModelPtr lBook; m_Page->getBook(&lBook); long lIndex = lBook->getPageIndex(m_Page); return lIndex; // return fPageIndex; } // ************************************************************************************************ void TPageEditor::setPageAndSelect(TPageModel* pPage, BOOL pActive) { // *** Should be done in this order setPage(pPage); Select(pActive); } // ************************************************************************************************ void TPageEditor::changeWritable(BOOL pWritable) { /* // *** Must change the state of the binder CRect lRect; if (getPageSide() == T_PRIMARY) lRect = CRect(getLogicalSize().cx - gRWBinderBkgnd->getWidth(), 0, getLogicalSize().cx, getLogicalSize().cy); else lRect = CRect(0, 0, gRWBinderBkgnd->getWidth(), getLogicalSize().cy); LPtoDP(&lRect); refresh(&lRect); */ } // ************************************************************************************************ void TPageEditor::removePage() { if (m_Page) { // *** Remove listener if (fPageListener) { //delete fListener; m_Page->removePropertyChangeListener(fPageListener); fPageListener->setInvalid(); fPageListener = NULL; } m_Page = NULL; if (fBookListener) { //delete fListener; m_Book->removePropertyChangeListener(fBookListener); fBookListener->setInvalid(); fBookListener = NULL; } m_Book = NULL; removePageletView(); } } // ************************************************************************************************ LRESULT TPageEditor::OnRemoveChild(WPARAM wParam, LPARAM lParam) { if ((CWnd*)wParam == m_PageView) { removePageletView(); return S_OK; } return S_FALSE; } void TPageEditor::removePageletView() { // This clean the last Pagelet we had in this View if ((m_PageView == NULL) || (m_PageView->m_hWnd == NULL)) return ; if (m_PageView->GetParent() == this) m_PageView->quitParent(); else m_PageView->Release(); removeChild(m_PageView); m_PageView = NULL; } void TPageEditor::setPage(TPageModel* pPage, BOOL pForced) { if (!canSetPage(pPage, pForced)) return ; removePage(); m_Page = pPage; if (pPage == NULL) { refresh(); return; } fPageIndex = -1; fPageCount = 0; // Retrieve the persistance property TModelPtr lProp; m_Page->getDefaultProperty(&lProp); lProp->getLongField(T_PAGE_PROPERTY_PERSISTANCE, &m_Behaviour); // *** Store page index to be more efficient during navigation m_Page->getBook(&m_Book); ATLASSERT(m_Book); TModelID lPageID = m_Page->getID(); fIsIndex = (lPageID == T_INDEX_MODEL_NAME); fIsSummary = (lPageID == T_SUMMARY_MODEL_NAME); fIsProperty = m_Book->isPageBeforeSummary(m_Page); fIsChapter = m_Page->isInstanceOf(T_CHAPTER_MODEL_NAME); #ifdef DO_NOT_DISPLAY_AUTHOR_TITLE m_bIsAuthorPage = fIsProperty; #endif // DO_NOT_DISPLAY_AUTHOR_TITLE if (!isIndex()) fPageIndex = m_Book->getPageIndex(m_Page); fPageCount = m_Book->getPageCount(); // *** Add new listener fPageListener = new TPEPageListener(this); m_Page->addPropertyChangeListener(fPageListener); // *** 10/12/98 Add listener on the book in order to update the page number // *** Set in TPageEditor::setPage and TPageEditor::setPage // *** remove in TPageEditor::removePage() // *** We need to keep a reference on the book model, because when a page is removed // *** it is no more attached to a book but we need to retreive it in order to remove the listener. // *** It will be released in TPageEditor::removePage() fBookListener = new TPEBookListener(this); m_Book->addPropertyChangeListener(fBookListener); TModelPtr lChapter; TModelPtr lSummary; m_Page->getChapter(&lChapter); m_Book->getSummary(&lSummary); ATLASSERT(lSummary); fNeedTabBody = ((fIsChapter && (lChapter == lSummary)) || (fIsSummary) || (fIsIndex)); if (fNeedTabBody) { fTabIndex = 0; // *** 0-based TModelIterator* lPages; lSummary->getPages(&lPages); // int i = 0; if (isSummary()) { fTabIndex = -1; } else { if (lPages != NULL) { while (lPages->hasMoreElements()) { TModelPtr lPageModel; lPages->nextElement((TObjectModel**)&lPageModel); if (lPageModel->getID() == T_CHAPTER_MODEL_NAME) { if (lPageModel == m_Page) break; fTabIndex++; } } } } delete lPages; } PostMessage(WM_USER_REFRESH_PAGE_CONTENT); } LRESULT TPageEditor::OnRefreshPageContent(WPARAM, LPARAM) { // *** Refresh the page content refreshPageContent(); return 0; } /* void TPageEditor::Select(BOOL pActive) { } */ // ************************************************************************************************ /* void TPageEditor::setPageViewParent(TPageModel* pPage) { TPageletContainerView* lPagelet = fPageletManager->findPageletViewFor(pPage); if (lPagelet) { TWnd* lView = (TWnd*) lPagelet->GetParent(); ATLASSERT(lView-IsKindOf(RUNTIME_CLASS(TWnd))); lView->removeChild(lPagelet); lPagelet->SetParent(this); m_PageView = lPagelet; addChild(lPagelet); } } */ // ************************************************************************************************ BOOL TPageEditor::isSummary() { return fIsSummary; } // ************************************************************************************************ BOOL TPageEditor::isIndex() { return fIsIndex; } // ************************************************************************************************ BOOL TPageEditor::isChapter() { return fIsChapter; } // ************************************************************************************************ BOOL TPageEditor::isPropertyPage() { return fIsProperty; } long TPageEditor::GetPageBehaviour() { return m_Behaviour; } // ************************************************************************************************ // *** EVENTS HANDLER ON PAGE PROPERTIES CHANGE // ************************************************************************************************ // *** Listen to associated page changes // ************************************************************************************************ /* void TPageEditor::sendEvent(LPCTSTR pEvt) { } */ // ************************************************************************************************ // ************************************************************************************************ // *** // *** DRAG AND DROP MESSAGE HANDLERS // *** // ************************************************************************************************ BOOL TPageEditor::addPageFromOsDrop(HDROP pDrop) { CString lFileName; CFileStatus lStat; // *** get the number of file dropped int lFileNumber = DragQueryFile( pDrop, 0xFFFFFFFF, NULL, 0); ATLASSERT(m_Page); TModelPtr lBook; TModelPtr lSummary; TModelPtr lIndex; m_Page->getBook(&lBook); ATLASSERT(lBook); lBook->getSummary(&lSummary); ATLASSERT(lSummary); lBook->getIndex(&lIndex); ATLASSERT(lIndex); // --- prepare the progress dialog CProgressDlg* pDlg; // TBooxFrame::GetMainWnd()->EnableWindow( FALSE); CString stgFormatStep; long lPosition; { AFX_MANAGE_STATE( AfxGetAppModuleState()); pDlg = new CProgressDlg(); VERIFY( pDlg->Create( _T("CProgressDlg"), WS_CHILD/* | WS_VISIBLE*/, CRect( 0, 0, 10, 10), AfxGetMainWnd(), 1 )); CString stgTmp; VERIFY( stgTmp.LoadString( IDS_PROGDLG_COPY_FILE_TITLE)); pDlg->SetTitle( stgTmp); VERIFY( stgTmp.LoadString( IDS_CANCEL)); pDlg->SetCancel( stgTmp); stgFormatStep.LoadString( IDS_PROGDLG_STEP); pDlg->ChangeAnimation( 1 /*FILECOPY*/); pDlg->SetUpper( lFileNumber); lPosition = 1; } TGlobalsDB::getLibraryDBManager()->beginTransaction(t_transaction_types::TRANSACTION_UPDATE); // *** insert all the pages for(int i = 0; i < lFileNumber; i++) { // *** get the filename LPTSTR lBuffer = lFileName.GetBuffer( _MAX_PATH); DragQueryFile( pDrop, i, lBuffer, _MAX_PATH); lFileName.ReleaseBuffer(); // --- update the progress dialog { AFX_MANAGE_STATE( AfxGetAppModuleState()); if( pDlg->IsProcessCanceled()) break; // --- get the kind of the file UINT uStringId = IDS_PROGDLG_COPY_FILE_NAME; CFileStatus fileStatus; if( CFile::GetStatus( lFileName, fileStatus)) { if( fileStatus.m_attribute & CFile::directory) { uStringId = IDS_PROGDLG_COPY_DIR_NAME; } } CString stgTmp; stgTmp.LoadString( uStringId); stgTmp.FormatMessage( stgTmp, (LPCTSTR) lFileName); pDlg->SetComment( (LPCTSTR) stgTmp); stgTmp.FormatMessage( stgFormatStep, lPosition, lFileNumber); pDlg->SetStep( stgTmp); pDlg->SetPosition( lPosition++); } TBrowseDir lBrowser; // !!!! lBrowser.SetCallback(NULL); lBrowser.Reset(); lBrowser.Run(lFileName, m_Page); } TGlobalsDB::getLibraryDBManager()->commitTransaction(); // --- close the progress bar { AFX_MANAGE_STATE( AfxGetAppModuleState()); pDlg->DestroyWindow(); pDlg = NULL; } // TBooxFrame::GetMainWnd()->EnableWindow( TRUE); // *** Go one the last inserted page // *** One page at least has been created // *** --> Active page becomes the one previous current page int lPageIndex = lBook->getPageIndex(m_Page); TModelPtr lActivePage; lBook->getPage(lPageIndex - 1, &lActivePage); CComPtr lBookControl; lBookControl.CoCreateInstance(CLSID_TBookControler); ATLASSERT(lBookControl); if (lBookControl) { // Cast because model are not COM interface !!! CComVariant lPageVariant((long)lActivePage.p); lBookControl->ChangePageTo(T_CPT_PAGE, T_SIDE_SECONDARY, lPageVariant); } return true; } // ************************************************************************************************ // *** Note : 'point' are client coordinates void TPageEditor::OnDragLeave( ) { } // ************************************************************************************************ DROPEFFECT TPageEditor::OnDragEnter( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point ) { if (!isBookModifiable()) return DROPEFFECT_NONE; ATLASSERT(pDataObject); if( pDataObject->IsDataAvailable(CF_HDROP)) { if (!isSummary() && !isPropertyPage()) { // *** Set target active ATLASSERT(m_pBookBrowser); if (m_pBookBrowser) { CComPtr lBookControler; m_pBookBrowser->getBookControler(&lBookControler); ATLASSERT(lBookControler); if (lBookControler) { ePageSide2 lSide; lSide = m_Side == T_PRIMARY ? T_SIDE_PRIMARY : T_SIDE_SECONDARY; lBookControler->ChangePageTo(T_CPT_SELECTED_PAGE, lSide, CComVariant(1)); } } return DROPEFFECT_COPY; } } return DROPEFFECT_NONE; } // ************************************************************************************************ DROPEFFECT TPageEditor::OnDragOver( COleDataObject* pDataObject, DWORD dwKeyState, CPoint point ) { if (!isBookModifiable()) return DROPEFFECT_NONE; ATLASSERT(pDataObject); if( pDataObject->IsDataAvailable(CF_HDROP)) { if (!isSummary() && !isPropertyPage()) return DROPEFFECT_COPY; } return DROPEFFECT_NONE; } // ************************************************************************************************ BOOL TPageEditor::OnDrop( COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point ) { if (!isBookModifiable()) return FALSE; ATLASSERT(pDataObject); if( pDataObject->IsDataAvailable(CF_HDROP)) { // *** The files are inserted before the drop page --> we can not drop on a summary if (!isSummary() && !isPropertyPage()) { // *** Drop files from OS in the shelf HGLOBAL hGlobal = pDataObject->GetGlobalData( CF_HDROP); HDROP hDrop = (HDROP) GlobalLock( hGlobal); // --- expand dir link HGLOBAL hGlobalDropExpanded = NULL; TShellExpandDroppedDirLink( hDrop, &hGlobalDropExpanded); HDROP hDropExpanded = (HDROP) GlobalLock( hGlobalDropExpanded); addPageFromOsDrop( hDropExpanded); GlobalUnlock( hGlobalDropExpanded); GlobalFree( hGlobalDropExpanded); GlobalUnlock( hGlobal); return TRUE; } } return FALSE; } // ************************************************************************************************ /* void TPageEditor::OnShowToolbar() { if (!m_PageView || !m_HaveToolbar) return ; if (m_ToolbarUp) m_PageView->showToolbar(); else m_PageView->hideToolbar(); m_ToolbarUp = !m_ToolbarUp; ChangeToolbarTooltip(); CRect lArrowRect = m_ArrowRect; LPtoDP(&lArrowRect); refresh(&lArrowRect); } */ BOOL TPageEditor::showToolbar() { if (m_PageView) return m_PageView->showToolbar(); return FALSE; } BOOL TPageEditor::hideToolbar() { if (m_PageView) return m_PageView->hideToolbar(); return FALSE; } CPrintingEngine* TPageEditor::GetPrintingEngine() { if (m_pBookBrowser) return m_pBookBrowser->GetPrintingEngine(); if (m_pPrintingEngine == NULL) { m_pPrintingEngine = new CPrintingEngine(); VERIFY(m_pPrintingEngine->Create( this, 1)); } return m_pPrintingEngine; } void TPageEditor::printPage( int nCmd) { if (m_PageView) { CPrintingEngine* lEngine; lEngine = GetPrintingEngine(); lEngine->PrintPage(m_PageView, nCmd); } } void TPageEditor::showSearch() { if (m_PageView) m_PageView->showSearchView(); } IUnknown* TPageEditor::getPageletControl() { if (m_PageView) return m_PageView->getPageletControl(); return NULL; } // User messages LRESULT TPageEditor::OnUpdateTitle(WPARAM , LPARAM) { if (m_pInPlaceEditCtrl) { m_pInPlaceEditCtrl->SendMessage(WM_KILLFOCUS); m_JustCloseEdit = FALSE; } if (m_Book) { fPageCount = m_Book->getPageCount(); if (m_Page && (!isIndex())) fPageIndex = m_Book->getPageIndex(m_Page); } CRect lTitleRect(CPoint(0, 0), CSize (getLogicalSize().cx, T_TITLE_HEIGHT)); LPtoDP(&lTitleRect); refresh(&lTitleRect); return S_OK; } LRESULT TPageEditor::OnSetChapter(WPARAM , LPARAM) { TRACE("(TPageEditor) : handle set chapter event\n"); return E_NOTIMPL; } LRESULT TPageEditor::OnAddAnnotation(WPARAM , LPARAM) { TRACE("(TPageEditor) : handle add annotation event\n"); return E_NOTIMPL; } LRESULT TPageEditor::OnRemoveAnnotation(WPARAM , LPARAM) { TRACE("(TPageEditor) : handle remove annotation event\n"); return E_NOTIMPL; } LRESULT TPageEditor::OnSetContent(WPARAM , LPARAM) { TRACE("(TPageEditor) : handle set content event\n"); return E_NOTIMPL; } LRESULT TPageEditor::OnPageDestroy(WPARAM , LPARAM) { TRACE("(TPageEditor) : handle destroy page event\n"); return E_NOTIMPL; } // ************************************************************************************************ BOOL TPageEditor::OnEraseBkgnd(CDC* pDC) { #ifdef DRAW_ON_BACKGROUND OnPrepareDC(pDC); drawBackground(pDC); return TRUE; #else return TWnd::OnEraseBkgnd(pDC); #endif } // ------------------------------------------------------------------------------ // // void TPageEditor::OnModeChange(long pMode) { IUnknown* lUnknown = NULL; lUnknown = getPageletControl(); if (lUnknown) { CComQIPtr lPagelet(lUnknown); if (lPagelet) lPagelet->put_Mode(pMode); } if (m_pInPlaceEditCtrl) m_pInPlaceEditCtrl->SendMessage(WM_KILLFOCUS); m_JustCloseEdit = FALSE; } void TPageEditor::LoadBackground(tBookBrowserRes* pRes) { AFX_MANAGE_STATE(AfxGetAppModuleState()); if (pRes->m_TopBitmap) { m_pTopBkgnd = new TBackGround(pRes->m_TopBitmap); ATLASSERT(m_pTopBkgnd != NULL); } if (pRes->m_MiddleBitmap) { m_pBkgnd = new TBackGround(pRes->m_MiddleBitmap); ATLASSERT(m_pBkgnd != NULL); } m_BackBrushID = pRes->m_BackBrush; if (pRes->m_TitleBitmap) { m_pTitleBkgnd = new TBackGround(pRes->m_TitleBitmap); ATLASSERT(m_pTitleBkgnd != NULL); } m_TitleRect = CRect(CPoint(3, 9), CSize(getLogicalSize().cx - 6, 28)); m_BkColor = pRes->m_MiddleColor; m_TitleNormalColor = pRes->m_TitleNormalColor; m_TitleSelectedColor = pRes->m_TitleSelectedColor; } void TPageEditor::OnTimer( UINT nIDEvent) { if( nIDEvent == TIMER_EDIT_TITLE) { TRACE( _T("TPageEditor::OnTimer\n")); if( !m_bIsDblClk) EditTitle(); KillTimer( nIDEvent); } else { TWnd::OnTimer( nIDEvent); } } void TPageEditor::EditTitle() { if (!m_Page) return ; TRACE("TPageEditor::EditTitle\n"); // --- create a edit control auto deleted m_stgInPlaceEditBuffer = m_Page->getTitle(); m_bInPlaceEditIsEscaped = false; LOGFONT logFont; m_pTitleFont->GetLogFont( &logFont); CRect rectTitle; GetTitleRect( rectTitle); if (rectTitle.IsRectEmpty()) return ; m_pInPlaceEditCtrl = new CInPlaceEdit( m_stgInPlaceEditBuffer, m_bInPlaceEditIsEscaped, &logFont); m_pInPlaceEditCtrl->Create( WS_CHILD | WS_VISIBLE, rectTitle, this, IDC_EDIT_INPLACE); } void TPageEditor::OnEnKillFocus() { if( m_bInPlaceEditIsEscaped ) { // --- need a refresh CRect rectTitle; GetTitleRect( rectTitle); refresh( &rectTitle); } else { // --- refresh by the listener if (m_Page) { m_Page->setTitle( m_stgInPlaceEditBuffer); AddBehaviour(m_Page, F_PAGE_DEFINED_TITLE); } } TRACE("TPageEditor::OnEnKillFocus\n"); m_JustCloseEdit = TRUE; m_pInPlaceEditCtrl = NULL; } // ---------------------------------------------------------------------------- // ------------------------------- Listener ---------------------------------- // ---------------------------------------------------------------------------- TPEBookListener::TPEBookListener(TPageEditor* pPageEditor) { m_pPageEditor = pPageEditor; } TPEBookListener::~TPEBookListener() { m_pPageEditor = NULL; } void TPEBookListener::propertyChange(TPropertyChangeEvent *evt) { ATLASSERT(evt); // *** Event should not be null ATLASSERT(m_pPageEditor); ATLASSERT(getValidState()); if ((m_pPageEditor == NULL) || !getValidState()) return ; TString lPropertyName(evt->getPropertyName()); if ((lPropertyName == TBookModel::T_ADD_PAGE_PROPERTY) || (lPropertyName == TBookModel::T_INSERT_PAGE_PROPERTY) || (lPropertyName == TBookModel::T_REMOVE_PAGE_PROPERTY)) { // *** listener on the book in order to update the page number m_pPageEditor->PostMessage(WM_USER_UPDATE_TITLE); // changePageTitleEvt(NULL); } } TPEPageListener::TPEPageListener(TPageEditor* pPageEditor) { m_pPageEditor = pPageEditor; } TPEPageListener::~TPEPageListener() { m_pPageEditor = NULL; } void TPEPageListener::propertyChange(TPropertyChangeEvent *evt) { ATLASSERT(evt); // *** Event should not be null ATLASSERT(m_pPageEditor); ATLASSERT(getValidState()); if ((m_pPageEditor == NULL) || !getValidState()) return ; TString lPropertyName(evt->getPropertyName()); if (lPropertyName == TPageModel::T_SET_TITLE_PROPERTY) { m_pPageEditor->PostMessage(WM_USER_UPDATE_TITLE); } }/*------------ TPageletCtl.cpp ------------*/ // PageletCtl.cpp : Implementation of the TPageletCtrl ActiveX Control class. #include "StdAfx.h" #include "Pagelet.h" #include "TPageletCtl.h" #include "TPageletDll.h" #include "ColorPaletteHook.h" #include "TMetaManager.h" #include "eViewMode.h" #include "MfcOccImpl.h" #include "TPageModel.h" #include "TUserMessage.h" #include "TAppInfo.h" #include "TBookModel.h" #include "TPath.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif IMPLEMENT_DYNAMIC(TPageletCtrl, TOleControl) ///////////////////////////////////////////////////////////////////////////// // Message map BEGIN_MESSAGE_MAP(TPageletCtrl, TOleControl) ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_NCDESTROY() ON_MESSAGE(WM_USER_NEED_DESTROY_PAGELET, OnNeedDestroy) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Dispatch map BEGIN_DISPATCH_MAP(TPageletCtrl, TOleControl) DISP_STOCKFUNC_REFRESH() DISP_STOCKPROP_CAPTION() DISP_STOCKPROP_BACKCOLOR() DISP_STOCKPROP_APPEARANCE() DISP_STOCKPROP_BORDERSTYLE() DISP_STOCKPROP_READYSTATE() END_DISPATCH_MAP() ///////////////////////////////////////////////////////////////////////////// // Event map BEGIN_EVENT_MAP(TPageletCtrl, TOleControl) END_EVENT_MAP() ///////////////////////////////////////////////////////////////////////////// // Interface map BEGIN_INTERFACE_MAP(TPageletCtrl, TOleControl) INTERFACE_PART(TPageletCtrl, IID_IPageletControl, PageletControl) INTERFACE_PART(TPageletCtrl, IID_IPageletWnd, PageletWnd) INTERFACE_PART(TPageletCtrl, IID_IPageletLoadControl, PageletLoadControl) END_INTERFACE_MAP() #ifdef DEBUG_PAGELET_LEAK LONG gPageletCount = 0; class TPageletCounter { public: ~TPageletCounter() { ATLASSERT(gPageletCount == 0); } }; TPageletCounter gCounter; #endif ///////////////////////////////////////////////////////////////////////////// // TPageletCtrl::TPageletCtrl - Constructor TPageletCtrl::TPageletCtrl() { #ifdef DEBUG_PAGELET_LEAK CString lWndName(GetRuntimeClass()->m_lpszClassName); TRACE(_T("+ TPageletCtrl(%s)\n"), lWndName); #endif fCreateLoadTabDone = false; fMode = 0; m_pColorPaletteHook = NULL; m_Resizable = NULL; m_InPreTanslate = FALSE; m_IsLoaded = FALSE; fState = 0; initPagelet(); #ifdef DEBUG_PAGELET_LEAK gPageletCount++; #endif } void TPageletCtrl::initPagelet() { fReportResultDone = false; } ///////////////////////////////////////////////////////////////////////////// // TPageletCtrl::~TPageletCtrl - Destructor TPageletCtrl::~TPageletCtrl() { #ifdef DEBUG_PAGELET_LEAK CString lWndName(GetRuntimeClass()->m_lpszClassName); TRACE(_T("- TPageletCtrl(%s)\n"), lWndName); #endif #ifdef DEBUG_PAGELET_LEAK gPageletCount--; #endif } int TPageletCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (TOleControl::OnCreate(lpCreateStruct) == -1) return -1; // --- handle the colorpalette changement m_pColorPaletteHook = new CColorPaletteHook(); ATLASSERT(m_pColorPaletteHook); m_pColorPaletteHook->HookWindow( this); return 0; } void TPageletCtrl::OnDestroy() { #ifdef DEBUG_PAGELET_LEAK CString lWndName(GetRuntimeClass()->m_lpszClassName); TRACE(_T(" TPageletCtrl(%s)::OnDestroy (0x%x)\n"), lWndName, this); #endif if (m_pColorPaletteHook) { // --- unregister the color palette m_pColorPaletteHook->HookWindow( NULL); delete m_pColorPaletteHook; m_pColorPaletteHook = NULL; } fModel = NULL; TOleControl::OnDestroy(); } void TPageletCtrl::PostNcDestroy() { #ifdef DEBUG_PAGELET_LEAK CString lWndName(GetRuntimeClass()->m_lpszClassName); TRACE(_T(" TPageletCtrl(%s)::PostNcDestroy\n"), lWndName); #endif TOleControl::PostNcDestroy(); ExternalRelease(); } ///////////////////////////////////////////////////////////////////////////// // TPageletCtrl::OnDraw - Drawing function void TPageletCtrl::OnDraw(CDC* pDC, const CRect& rcBounds, const CRect& rcInvalid) { TOleControl::OnDraw(pDC, rcBounds, rcInvalid); #ifdef DEBUG_BOOK_WND_POSITION CRect lRect; GetClientRect(&lRect); // DPtoLP(&lRect); pDC->FrameRect(lRect, CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH))); #endif } ///////////////////////////////////////////////////////////////////////////// // TPageletCtrl::DoPropExchange - Persistence support void TPageletCtrl::DoPropExchange(CPropExchange* pPX) { ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); // TODO: Call PX_ functions for each persistent custom property. } ///////////////////////////////////////////////////////////////////////////// // TPageletCtrl::OnResetState - Reset control to default state void TPageletCtrl::OnResetState() { COleControl::OnResetState(); // Resets defaults found in DoPropExchange // TODO: Reset any other control state here. } // ************************************************************************************************ // // // LPUNKNOWN TPageletCtrl::GetInterfaceHook(const void* piid) { GUID* lIID = (GUID*)piid; if (InlineIsEqualGUID(*lIID, IID_IPageletControl)) return &m_xPageletControl; if (InlineIsEqualGUID(*lIID, IID_IPageletLoadControl)) return &m_xPageletLoadControl; return TOleControl::GetInterfaceHook(piid); } void TPageletCtrl::OnFinalRelease() { TOleControl::OnFinalRelease(); } void TPageletCtrl::OnEventAdvise( BOOL bAdvise ) { TOleControl::OnEventAdvise(bAdvise); } // ************************************************************************************************ // // // HRESULT TPageletCtrl::Stop() { return S_OK; } // ************************************************************************************************ // // // void TPageletCtrl::CreateLoadTab() { if (fCreateLoadTabDone) return ; if (!m_PageletSink) m_PageletSink = m_pControlSite; if (m_PageletSink) { m_PageletSink->CreateLoadTab(&m_xPageletLoadControl); fCreateLoadTabDone = true; } } // ************************************************************************************************ // // // void TPageletCtrl::ReportProgress(long pProgress, long pMax) { if (!m_PageletSink) m_PageletSink = m_pControlSite; if (m_PageletSink) { m_PageletSink->ReportProgress(pProgress, pMax); } } // ************************************************************************************************ // // // void TPageletCtrl::SetStatus(LPCTSTR pStatus) { if (!m_PageletSink) m_PageletSink = m_pControlSite; if (m_PageletSink) m_PageletSink->put_Status(CComBSTR(pStatus)); } // ************************************************************************************************ // // // void TPageletCtrl::ReportResult(long pResult) { // if (fReportResultDone) // return ; if (pResult == S_OK) SetLoaded(TRUE); if (!m_PageletSink) m_PageletSink = m_pControlSite; if (m_PageletSink) { m_PageletSink->ReportResult(pResult); // fReportResultDone = true; } } // ************************************************************************************************ // // // STDMETHODIMP TPageletCtrl::GetDropTarget(IDropTarget* pDropTarget, IDropTarget** ppDropTarget) { ATLASSERT(ppDropTarget); if (ppDropTarget == NULL) return E_INVALIDARG; *ppDropTarget = NULL; return E_NOTIMPL; } ///////////////////////////////////////////////////////////////////////////// // TPageletCtrl message handlers // AddRef, Release and QueryInterface stuff .... T_IMPLEMENT_EXTERNAL_INTERFACE(TPageletCtrl, PageletControl) // **************************************************************** HRESULT TPageletCtrl::XPageletControl::put_PageModel(long pModel) { METHOD_PROLOGUE(TPageletCtrl, PageletControl); HRESULT lResult = S_FALSE; if (TMetaManager::checkModelPointerValidity((void*)pModel)) { pThis->fModel = (TPageModel*)pModel; // TEMP // As sometime, there's still one more release on a PageModel, // add a ref on this model so that the destruction don't crash ((TPageModel*)pModel)->AddRef(); // TEMP lResult = S_OK; } else { pThis->fModel = NULL; ATLASSERT(NULL); TRACE(_T("\n-- TPageletCtrl::put_PageModel: Invalid Model Pointer\n")); } pThis->OnNewPageModel(); return lResult; } // **************************************************************** HRESULT TPageletCtrl::XPageletControl::get_PageModel(long* pModel) { ATLASSERT(pModel); if (pModel == NULL) return E_INVALIDARG; METHOD_PROLOGUE(TPageletCtrl, PageletControl); // Cast because model are not COM interface !!! *pModel = (long)pThis->getModel(); if (*pModel) { // Cast because model are not COM interface !!! ((TObjectModel*)*pModel)->AddRef(); return S_OK; } return S_FALSE; } // **************************************************************** HRESULT TPageletCtrl::XPageletControl::put_Selected(BOOL pBool) { METHOD_PROLOGUE(TPageletCtrl, PageletControl); return pThis->put_Selected(pBool); } // **************************************************************** HRESULT TPageletCtrl::XPageletControl::put_Current(BOOL pBool) { METHOD_PROLOGUE(TPageletCtrl, PageletControl); return pThis->put_Current(pBool); } // **************************************************************** HRESULT TPageletCtrl::XPageletControl::Hide() { METHOD_PROLOGUE(TPageletCtrl, PageletControl); return pThis->Hide(); } // **************************************************************** HRESULT TPageletCtrl::XPageletControl::Show() { METHOD_PROLOGUE(TPageletCtrl, PageletControl); return pThis->Show(); } // **************************************************************** HRESULT TPageletCtrl::XPageletControl::PrintPage( int nCmd) { METHOD_PROLOGUE(TPageletCtrl, PageletControl); return pThis->PrintPage( nCmd); } // **************************************************************** HRESULT TPageletCtrl::XPageletControl::put_Mode(long pMode) { METHOD_PROLOGUE(TPageletCtrl, PageletControl); long lOldMode = pThis->fMode; if ((pMode != T_UNDEFINED_MODE) && (pThis->fMode != pMode)) { pThis->fMode = pMode; if (lOldMode != T_UNDEFINED_MODE) pThis->OnModeChange(pMode); pThis->removeListeners(); pThis->addListeners(); } return S_OK; } // **************************************************************** /* HRESULT TPageletCtrl::XPageletControl::get_Mode(long* pMode) { METHOD_PROLOGUE(TPageletCtrl, PageletControl); *pMode = pThis->fMode; return S_OK; } */ // **************************************************************** HRESULT TPageletCtrl::XPageletControl::Load() { METHOD_PROLOGUE(TPageletCtrl, PageletControl); return pThis->Load(); } // **************************************************************** HRESULT TPageletCtrl::XPageletControl::Unload() { METHOD_PROLOGUE(TPageletCtrl, PageletControl); return pThis->Unload(); } // AddRef, Release and QueryInterface stuff .... T_IMPLEMENT_EXTERNAL_INTERFACE(TPageletCtrl, PageletWnd) // **************************************************************** HRESULT TPageletCtrl::XPageletWnd::Destroy() { METHOD_PROLOGUE(TPageletCtrl, PageletWnd); return pThis->DestroyWindow(); } HRESULT TPageletCtrl::XPageletWnd::PreTranslateMessage(MSG* pMsg, BOOL* pRetVal) { ATLASSERT(pRetVal); if (pRetVal == NULL) return E_INVALIDARG; METHOD_PROLOGUE(TPageletCtrl, PageletWnd); *pRetVal = pThis->PreTranslateMessage(pMsg); return S_OK; } HRESULT TPageletCtrl::XPageletWnd::put_BackgroundWnd(HWND hWnd) { METHOD_PROLOGUE(TPageletCtrl, PageletWnd); return pThis->OnNewBackWnd(hWnd); } BOOL TPageletCtrl::PreTranslateMessage(MSG* pMsg) { BOOL lResult = FALSE; if (!m_InPreTanslate) { m_InPreTanslate = TRUE; lResult = WalkPreTranslateTree(GetSafeHwnd(), pMsg); if (!lResult) { if (m_xOleInPlaceActiveObject.TranslateAccelerator(pMsg) == S_OK) { m_InPreTanslate = FALSE; return TRUE; } } m_InPreTanslate = FALSE; } else { lResult = TOleControl::PreTranslateMessage(pMsg); } return lResult; } // **************************************************************** // **************************************************************** HRESULT TPageletCtrl::OnNewPageModel() { return S_OK; } // **************************************************************** HRESULT TPageletCtrl::put_Selected(BOOL pBool) { if (pBool) fState |= PAGELET_SELECTED; else fState &= ~PAGELET_SELECTED; return S_OK; } // **************************************************************** HRESULT TPageletCtrl::put_Current(BOOL pBool) { if (pBool) fState |= PAGELET_CURRENT; else fState &= ~PAGELET_CURRENT; return S_OK; } // **************************************************************** HRESULT TPageletCtrl::Hide() { m_PageletSink.Release(); return E_NOTIMPL; } // **************************************************************** HRESULT TPageletCtrl::Show() { return E_NOTIMPL; } // **************************************************************** HRESULT TPageletCtrl::PrintPage( int nCmd) { return E_NOTIMPL; } // **************************************************************** HRESULT TPageletCtrl::Load() { return E_NOTIMPL; } // **************************************************************** HRESULT TPageletCtrl::Unload() { return E_NOTIMPL; } // **************************************************************** // **************************************************************** // AddRef, Release and QueryInterface stuff .... T_IMPLEMENT_EXTERNAL_INTERFACE(TPageletCtrl, PageletLoadControl) // **************************************************************** HRESULT TPageletCtrl::XPageletLoadControl::Stop() { METHOD_PROLOGUE(TPageletCtrl, PageletLoadControl); HRESULT hr = (HRESULT)pThis->Stop(); return hr; } // **************************************************************** HRESULT TPageletCtrl::XPageletLoadControl::get_IsLoaded(BOOL* pBool) { ATLASSERT(pBool); if (pBool == NULL) return E_INVALIDARG; METHOD_PROLOGUE(TPageletCtrl, PageletLoadControl); *pBool = pThis->m_IsLoaded; return S_OK; } // **************************************************************** // // // void TPageletCtrl::resizeWnd(CWnd* pWnd, CRect pRect) { CComPtr lLogicalSpace; if (pWnd->InternalQueryInterface(&IID_ILogicalSpace, (void**)&lLogicalSpace) == S_OK) { DPtoLP(&pRect); lLogicalSpace->put_LogicalSize(pRect.Size()); lLogicalSpace->put_LogicalPoint(pRect.TopLeft()); lLogicalSpace->put_LogicalSpace(pRect.Size()); CDC* lDC = GetDC(); ASSERT_VALID(lDC); OnPrepareDC(lDC); lLogicalSpace->LogicalResizeAndPos(lDC->m_hDC); ReleaseDC(lDC); } else { pWnd->SetWindowPos(NULL, pRect.left, pRect.top, pRect.Width(), pRect.Height(), SWP_NOZORDER | SWP_NOCOPYBITS); } } void TPageletCtrl::refreshWnd(CWnd* pWnd) { CComPtr lOpacity; if (pWnd->InternalQueryInterface(&IID_IOpacity, (void**)&lOpacity) == S_OK) { HWND lBackgroundWnd = NULL; lOpacity->get_BackgroundWnd(&lBackgroundWnd); if (lBackgroundWnd) { CRect lBgRect; ::GetClientRect(lBackgroundWnd,&lBgRect); lOpacity->UpdateBackground(lBgRect); } } else { CRect lClientRect; pWnd->GetClientRect(&lClientRect); pWnd->InvalidateRect(lClientRect); pWnd->UpdateWindow(); } } // **************************************************************** // // BOOL TPageletCtrl::showView(HWND pWnd) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); ATLASSERT(m_Resizable); long lIndex = IndexOfChild(pWnd); long lResizableViewIndex = IndexOfChild(m_Resizable); ATLASSERT(lIndex >= 0); if (lIndex < 0) return FALSE; if (IsWndVisible(lIndex)) return TRUE; CWnd* lToBeShownWnd = CWnd::FromHandle(pWnd); ATLASSERT(lToBeShownWnd); if (lToBeShownWnd == NULL) return FALSE; CRect lToBeShownRect; long lToBeShownHeight; lToBeShownWnd->GetWindowRect(&lToBeShownRect); lToBeShownHeight = lToBeShownRect.Height(); CRect lPageletRect; GetClientRect(&lPageletRect); long lCount; long ii; lCount = childCount(); // First, we check if everything can fit in the parent view long lUsedHeight; long lNeededHeight; lUsedHeight = UsedHeight(); if (IsResizable(pWnd)) lNeededHeight = lUsedHeight; else lNeededHeight = lUsedHeight + lToBeShownHeight; if (lNeededHeight > lPageletRect.Height()) { // We have not enough space to show this view // so it will not be shown. ATLASSERT(FALSE); return FALSE; } long lAvailableHeight; lAvailableHeight = lPageletRect.Height() - lUsedHeight; // Here we know that there will be enough place CRect lAvailableRect = lPageletRect; long lVerticalOffset = 0; // long lTop = 0; // First, let's handle child views above the resizable view for (ii = 0; ii < lResizableViewIndex; ii++) { CWnd* lCurChildWnd = getChildAt(ii); ATLASSERT(lCurChildWnd); if ( IsWndVisible(ii) || (ii == lIndex)) { CRect lRect; ATLASSERT(lCurChildWnd->GetParent() == this); lCurChildWnd->GetWindowRect(&lRect); ScreenToClient(&lRect); if ( IsWndVisible(ii)) { if (lVerticalOffset != 0) { lRect.OffsetRect(0,lVerticalOffset); resizeWnd(lCurChildWnd, lRect); } } else if (ii == lIndex) { lRect.OffsetRect(-lRect.left,-lRect.top); lRect.OffsetRect(lAvailableRect.left,lAvailableRect.top); lVerticalOffset += lRect.Height(); resizeWnd(lCurChildWnd, lRect); lCurChildWnd->ShowWindow(SW_SHOW); } lAvailableRect.top += lRect.Height(); } } lVerticalOffset = 0; // Then, let's handle child views under the resizable view for (ii = (lCount - 1); ii > lResizableViewIndex; ii--) { CWnd* lCurChildWnd = getChildAt(ii); ATLASSERT(lCurChildWnd); if ( IsWndVisible(ii) || (ii == lIndex)) { CRect lRect; ATLASSERT(lCurChildWnd->GetParent() == this); lCurChildWnd->GetWindowRect(&lRect); ScreenToClient(&lRect); if ( IsWndVisible(ii)) { if (lVerticalOffset != 0) { lRect.OffsetRect(0,lVerticalOffset); resizeWnd(lCurChildWnd, lRect); } } else if (ii == lIndex) { lRect.OffsetRect(-lRect.left,-lRect.top); lRect.OffsetRect(lAvailableRect.left,lAvailableRect.bottom - lRect.Height()); lVerticalOffset -= lRect.Height(); resizeWnd(lCurChildWnd, lRect); lCurChildWnd->ShowWindow(SW_SHOW); } lAvailableRect.bottom -= lRect.Height(); } } // Then, let's handle the resizable view CWnd* lResizableChildWnd = getChildAt(lResizableViewIndex); if (IsWndVisible(lResizableViewIndex)) { resizeWnd(lResizableChildWnd, lAvailableRect); } else { if (lResizableViewIndex == lIndex) { resizeWnd(lResizableChildWnd, lAvailableRect); lResizableChildWnd->ShowWindow(SW_SHOW); } } refreshWnd(lToBeShownWnd); m_Visibility.SetAt(lIndex, 1); return TRUE; } // **************************************************************** // // // BOOL TPageletCtrl::hideView(HWND pWnd) { ATLASSERT(m_Resizable); long lIndex = IndexOfChild(pWnd); long lResizableViewIndex = IndexOfChild(m_Resizable); ATLASSERT(lIndex >= 0); if (lIndex < 0) return FALSE; if (!IsWndVisible(lIndex)) return TRUE; CWnd* lToBeHideWnd = CWnd::FromHandle(pWnd); ATLASSERT(lToBeHideWnd); if (lToBeHideWnd == NULL) return FALSE; CRect lToBeHideRect; long lToBeHideHeight; lToBeHideWnd->GetWindowRect(&lToBeHideRect); lToBeHideHeight = lToBeHideRect.Height(); CRect lPageletRect; GetClientRect(&lPageletRect); long lUsedHeight; long lAvailableHeight; long lVerticalOffset = 0; long lCount; int ii = 0; lCount = childCount(); lUsedHeight = UsedHeight(); lAvailableHeight = lPageletRect.Height() - lUsedHeight; CRect lAvailableRect = lPageletRect; // First, let's handle child views above the resizable view for (ii = 0; ii < lResizableViewIndex; ii++) { CWnd* lCurChildWnd = getChildAt(ii); ATLASSERT(lCurChildWnd); if ( IsWndVisible(ii) ) { CRect lRect; lCurChildWnd->GetWindowRect(&lRect); if (ii == lIndex) { lCurChildWnd->ShowWindow(SW_HIDE); lVerticalOffset -= lRect.Height(); } else { ATLASSERT(lCurChildWnd->GetParent()); ScreenToClient(&lRect); if (lVerticalOffset != 0) { lRect.OffsetRect(0, lVerticalOffset); resizeWnd(lCurChildWnd, lRect); } lAvailableRect.top += lRect.Height(); } } } lVerticalOffset = 0; // Then, let's handle child views under the resizable view for (ii = (lCount - 1); ii > lResizableViewIndex; ii--) { CWnd* lCurChildWnd = getChildAt(ii); ATLASSERT(lCurChildWnd); if ( IsWndVisible(ii) ) { CRect lRect; lCurChildWnd->GetWindowRect(&lRect); if (ii == lIndex) { lCurChildWnd->ShowWindow(SW_HIDE); lVerticalOffset += lRect.Height(); } else { ScreenToClient(&lRect); if (lVerticalOffset != 0) { lRect.OffsetRect(0,lVerticalOffset); resizeWnd(lCurChildWnd, lRect); } lAvailableRect.bottom -= lRect.Height(); } } } // Then, let's handle the resizable view // which is always visible CWnd* lResizableChildWnd = getChildAt(lResizableViewIndex); resizeWnd(lResizableChildWnd, lAvailableRect); m_Visibility.SetAt(lIndex, 0); return TRUE; } void TPageletCtrl::OnModeChange(long pMode) { } LRESULT TPageletCtrl::OnNeedDestroy(UINT, LONG) { DestroyWindow(); return S_OK; } CRect TPageletCtrl::GetPageletLogicalRect() { CRect lLogicalRect(CPoint(0,0), getLogicalSize()); lLogicalRect.DeflateRect(__min(lLogicalRect.Width()/2, 2), __min(lLogicalRect.Height()/2, 2)); return lLogicalRect; } STDMETHODIMP TPageletCtrl::OnNewBackWnd(HWND hWnd) { return E_NOTIMPL; } void TPageletCtrl::OnAddChild(CWnd* pChild, long pIndex) { BYTE lDefault = 0; m_Visibility.InsertAt(pIndex, lDefault); } void TPageletCtrl::OnRemoveChild(CWnd* pChild, long pIndex) { if (pIndex < 0) { long lIndex = childCount(); while (lIndex) { if (pChild == getChildAt(lIndex - 1)) { pIndex = lIndex - 1; break; } lIndex--; } if (lIndex == 0) return ; } m_Visibility.RemoveAt(pIndex); } BOOL TPageletCtrl::IsWndVisible(long pIndex) { return m_Visibility.GetAt(pIndex); } long TPageletCtrl::IndexOfChild(HWND pWnd) { long lIndex = childCount() - 1; while (lIndex >= 0) { if ((HWND)(*getChildAt(lIndex)) == pWnd) return lIndex; lIndex--; } return lIndex; } void TPageletCtrl::SetResizable(HWND pWnd) { m_Resizable = pWnd; } BOOL TPageletCtrl::IsResizable(HWND pWnd) { if (m_Resizable == pWnd) return TRUE; return FALSE; } long TPageletCtrl::UsedHeight() { long lTotalNonResizableChildrenHeight = 0; long lCount; long ii; lCount = childCount(); for (ii = 0; ii < lCount; ii++) { if (IsWndVisible(ii)) { CWnd* lCurChildWnd = getChildAt(ii); ATLASSERT(lCurChildWnd); if (!IsResizable(*lCurChildWnd)) { CRect lRect; lCurChildWnd->GetWindowRect(&lRect); ScreenToClient(&lRect); lTotalNonResizableChildrenHeight += lRect.Height(); } } } return lTotalNonResizableChildrenHeight; } void TPageletCtrl::SetLoaded(BOOL pLoaded) { m_IsLoaded = pLoaded; } CString TPageletCtrl::GetMyDocumentsFolder() { TAppInfo lAppInfo; CString stgPath; stgPath = lAppInfo.GetSessionNewDocumentPath(); // --- get the documents directory name TModelPtr pBookModel; fModel->getBook(&pBookModel); ATLASSERT( pBookModel); CString stgBookName = pBookModel->getName(); TPath::ReplaceForbiddenCharsInFileName(stgBookName, CString(_T('_'))); // --- concat the 2 paths LPTSTR szPath = stgPath.GetBuffer( MAX_PATH); VERIFY( PathAppend( szPath, (LPCTSTR) stgBookName)); stgPath.ReleaseBuffer(); // --- create the directory TPath lPathHelper(stgPath); BOOL lCreated = lPathHelper.CreateDirectory(); ATLASSERT(lCreated); return stgPath; }/*------------ TPageletCtl.h ------------*/ #ifndef T_PAGELET_CTL #define T_PAGELET_CTL #include "TOleControl.h" #include "Pagelet.h" #include "TModelPtr.h" #include "TGenericArray.h" #include "TIntIterator.h" class TPageModel; class CColorPaletteHook; class TPageletCtrl : public TOleControl { DECLARE_DYNAMIC(TPageletCtrl) DECLARE_INTERFACE_MAP(); DECLARE_MESSAGE_MAP() DECLARE_DISPATCH_MAP() DECLARE_EVENT_MAP() // Constructor public: TPageletCtrl(); virtual ~TPageletCtrl(); // Overrides public: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnDestroy(); afx_msg void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid); afx_msg void DoPropExchange(CPropExchange* pPX); afx_msg void OnResetState(); LRESULT OnNeedDestroy(UINT, LONG); virtual LPUNKNOWN GetInterfaceHook(const void* piid); virtual void OnEventAdvise( BOOL bAdvise ); virtual void PostNcDestroy(); virtual BOOL PreTranslateMessage(MSG* pMsg); virtual void OnFinalRelease(); // Implementation public: enum { PAGELET_CURRENT = 1, PAGELET_SELECTED }; public: TPageModel* getModel() { return fModel; } long getState() { return fState; } BEGIN_INTERFACE_PART(PageletControl, IPageletControl) STDMETHOD(put_PageModel)(long pPage); STDMETHOD(get_PageModel)(long* pPage); STDMETHOD(put_Selected)(BOOL pVal); STDMETHOD(put_Current)(BOOL pVal); STDMETHOD(put_Mode)(long pMode); // STDMETHOD(get_Mode)(long* pMode); STDMETHOD(Hide)(); STDMETHOD(Show)(); STDMETHOD(PrintPage)( int nCmd); STDMETHOD(Load)(); STDMETHOD(Unload)(); END_INTERFACE_PART(PageletControl) BEGIN_INTERFACE_PART(PageletWnd, IPageletWnd) STDMETHOD(Destroy)(); STDMETHOD(PreTranslateMessage)(MSG* pMsg, BOOL* pRetVal); STDMETHOD(put_BackgroundWnd)(HWND); END_INTERFACE_PART(PageletWnd) BEGIN_INTERFACE_PART(PageletLoadControl, IPageletLoadControl) STDMETHOD(get_IsLoaded)(BOOL *pVal); STDMETHOD(Stop)(); END_INTERFACE_PART(PageletLoadControl) public: DWORD GetControlFlags() { return TOleControl::GetControlFlags(); } virtual void CreateLoadTab(); virtual void ReportProgress(long pProgress, long pMax); virtual void ReportResult(long pResult); virtual void SetStatus(LPCTSTR pStatus); virtual void OnModeChange(long pMode); STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget, IDropTarget** ppDropTarget); STDMETHOD(Stop)(); STDMETHOD(OnNewPageModel)(); STDMETHOD(OnNewBackWnd)(HWND hWnd); STDMETHOD(put_Selected)(BOOL pVal); STDMETHOD(put_Current)(BOOL pVal); STDMETHOD(Hide)(); STDMETHOD(Show)(); STDMETHOD(PrintPage)( int nCmd); STDMETHOD(Load)(); STDMETHOD(Unload)(); BOOL hideView(HWND pWnd); BOOL showView(HWND pWnd); void resizeWnd(CWnd* pWnd, CRect pRect); void refreshWnd(CWnd* pWnd); void initPagelet(); CRect GetPageletLogicalRect(); virtual void addListeners() {} virtual void removeListeners() {} virtual void OnAddChild(CWnd* pChild, long pIndex); virtual void OnRemoveChild(CWnd* pChild, long pIndex = -1); long IndexOfChild(HWND pWnd); BOOL IsWndVisible(long pIndex); void SetResizable(HWND pWnd); BOOL IsResizable(HWND pWnd); long UsedHeight(); void SetLoaded(BOOL pLoaded); CString GetMyDocumentsFolder(); protected: CColorPaletteHook* m_pColorPaletteHook; CByteArray m_Visibility; HWND m_Resizable; TModelPtr fModel; CComQIPtr m_PageletSink; long fState; long fMode; BOOL fReportResultDone:2; BOOL fCreateLoadTabDone:2; BOOL m_InPreTanslate:2; BOOL m_IsLoaded:2; }; //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // T_PAGELET_CTL/*------------ TWBPageletCtl_WebEvent.cpp ------------*/ #include "StdAfx.h" #include "TBaseWBPageletCtl.h" #include "TWBPageletCtl_Utils.h" #include "PageletCtrl.h" //#include "TDispatchInfoDlg.h" #include "TMetaManager.h" #include "TModelNames.h" #include "TAllModel.h" #include "TPageModel.h" #include "TChapterModel.h" #include "TContentModel.h" #include "TContentsBagModel.h" #include "TPageNumbering.h" #include "TModelHelpers.h" #include "SharedResource.h" #include "TWebBrowser.h" #include "TUrl.h" #include "TSevenixUrlInfo.h" #include "TSevenixUrl.h" #include "TInteger.h" #include "TTime.h" #include "TErr.h" // Net Stuff #include "TNetHelpers.h" #include "IEVersion.h" #include "Net.h" #include "Dom.h" //#include "TDomStretcher.h" #include "TWBStretchSink.h" #include "TNewHtmlWindow.h" #include "eViewMode.h" #include "TBackgroundIndexer.h" #include "TTrash.h" #include "mshtml.h" #include "mshtmcid.h" #ifndef IE5_ZOOM #define IDM_ZOOMRATIO 2344 #define IDM_GETZOOMNUMERATOR 2345 #define IDM_GETZOOMDENOMINATOR 2346 #endif // IE5_ZOOM #define T_MAX_NEW_WINDOW 3 #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif void findHTMLInterface(IDispatch* pDispatch); // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::BeforeNavigate(LPDISPATCH pDisp, VARIANT FAR* URL, VARIANT FAR* Flags, VARIANT FAR* TargetFrameName, VARIANT FAR* PostData, VARIANT FAR* Headers, BOOL FAR* Cancel) { } BOOL CancelUrl(LPCTSTR pUrl) { if (!_tcsnicmp(_T("res://"), pUrl, 6) && _tcsstr(pUrl, _T("navcancl.htm"))) return TRUE; return FALSE; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebBeforeNavigate2(LPDISPATCH pDisp, VARIANT* pURL, VARIANT* pFlags, VARIANT* pTargetFrameName, VARIANT* pPostData, VARIANT* pHeaders, BOOL* pCancel) { CString lUrl(pURL->bstrVal); #ifdef _DEBUG KB_LOG_INFO2(_T("[0x%1!x!]::BeforeNavigate(%2)"), pDisp, lUrl); #endif // _DEBUG m_bCanceling = CancelUrl(lUrl); if (m_bCanceling) return ; // Let's keep the passed webBrowser for future use CComQIPtr lBrowser(pDisp); ATLASSERT(lBrowser); ATLASSERT(pCancel); TUrl lBaseUrl(lUrl); CString lScheme; lBaseUrl.canonicalize(); lScheme = lBaseUrl.getScheme(); // This Protocol will be stored into the base if (StorableProtocol(lScheme)) { // It does not have a extended scheme if ((lBaseUrl.getExtendedInfo() == NULL)) { // But it'is the wait we want it !!! if ( (m_InitialUrl != lUrl) && (TUrl(m_InitialUrl).getExtendedInfo() != NULL) ) { // try a cancel -> navigate TUrl lCurrentUrl(m_CurrentUrl); TSevenixUrlInfo* lInfo; long lID = 0; lInfo = (TSevenixUrlInfo*)lCurrentUrl.getExtendedInfo(); ATLASSERT(lInfo); if (lInfo) lID = lInfo->getID(); TSevenixUrl lNewUrl(lUrl, lID); RedirectTo(lNewUrl.extendedUrlString(), lBrowser); *pCancel = TRUE; #ifdef _DEBUG KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp); #endif // _DEBUG return ; } } } // If we navigate here for the first time if (m_RootDispatch == NULL) { // store the IDispatch to know in the Document Complete // that this is the main Frame m_RootDispatch = pDisp; m_bFirstNavigate = TRUE; TRACE(_T(" >> >> First Before Nav with : this(0x%x), Disp(0x%x)\n"), this, lBrowser); if (m_pNetStatus == NULL) { m_pNetStatus.CoCreateInstance(CLSID_TInternetStatus); } m_NavigatingFramesList.RemoveAll(); } BOOL lRenavigateBeforeComplete = FALSE; if (m_NavigatingFramesList.Find(lBrowser.p) < 0) m_NavigatingFramesList.Add(lBrowser.p); else lRenavigateBeforeComplete = TRUE; m_NavigateCount = m_NavigatingFramesList.GetSize(); CComVariant lPostData; if (pPostData) lPostData = *pPostData->pvarVal; // Special Case for Dynamic KeeBook // Added in 2.2 if (lPostData.vt != VT_EMPTY) { if (m_bUserClick || MinimumIEVersion(5, 5)) { if (lScheme != "internal") HookDynamicKeeBook(lBrowser, pCancel); if (*pCancel == TRUE) { #ifdef _DEBUG KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp); #endif // _DEBUG return ; } } } CComBSTR lBstrUrl; CComBSTR lBstrTarget; CComBSTR lBstrHeaders; long lFlags = 0; if (pURL) lBstrUrl = pURL->bstrVal; if (pTargetFrameName) lBstrTarget = pTargetFrameName->bstrVal; if (pHeaders) lBstrHeaders = pHeaders->bstrVal; if (pFlags) lFlags = pFlags->lVal; if (NeedCreateNewPage(lBrowser, lBstrUrl, lFlags, lBstrTarget, pPostData, lBstrHeaders, pCancel)) { TUrl lCurrentUrl(m_CurrentUrl); CString lNewExtra = lBaseUrl.getExtra(); CString lOldExtra = lCurrentUrl.getExtra(); BOOL lNewHaveOffset = lNewExtra.GetLength() && (lNewExtra[0] == '#'); BOOL lOldHaveOffset = lOldExtra.GetLength() && (lOldExtra[0] == '#'); CString lNewStrippedUrl = lUrl; CString lOldStrippedUrl = m_CurrentUrl; if (lNewHaveOffset) lNewStrippedUrl = lUrl.Left(lUrl.GetLength() - lNewExtra.GetLength()); if (lOldHaveOffset) lOldStrippedUrl = m_CurrentUrl.Left(m_CurrentUrl.GetLength() - lOldExtra.GetLength()); if (lNewStrippedUrl == lOldStrippedUrl) { #ifdef _DEBUG if (*pCancel) KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp); #endif // _DEBUG return ; } CreateNewPage(lBrowser, lBstrUrl, lFlags, lBstrTarget, pPostData, lBstrHeaders); // do not load in page *pCancel = TRUE; } else { if (m_RootDispatch == pDisp) { // We might have a redirection on a IFRAME // for some kind of pub reload // so we must be in the root document to set this flag SetLoaded(FALSE); } BeforeNavigate(pDisp, pURL, pFlags, pTargetFrameName, pPostData, pHeaders, pCancel); // If we do not cancel navigation, // we store the interface so that we can use it // for annotations and navigation in frames. ATLASSERT(lBrowser); if (lBrowser == NULL) { #ifdef _DEBUG if (*pCancel) KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp); #endif // _DEBUG return ; } // if in Root CComPtr lDispatch; lBrowser->get_Parent(&lDispatch); if (lDispatch == NULL) { #ifdef UPDATE_SCROLL_AFTER_SOFT_RELOAD BOOL lValue = FALSE; if (m_BrowserTree && SUCCEEDED(m_BrowserTree->IsSoftReload(&lValue)) && lValue) m_SoftReloadTree = m_BrowserTree; #endif // UPDATE_SCROLL_AFTER_SOFT_RELOAD if (!lRenavigateBeforeComplete) { // Clean-up all sub reference m_BrowserTree.Release(); #if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL) m_BeforeTree.Release(); #endif } } TRACE(_T(" + Adding Ref WebBrowser(0x%x)\n"), lBrowser); #if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL) HRESULT lResult; if (m_BeforeTree == NULL) { lResult = m_BeforeTree.CoCreateInstance(CLSID_WebBrowserTreeRoot); ATLASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) { #ifdef _DEBUG if (*pCancel) KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp); #endif // _DEBUG return ; } } ATLASSERT(m_BeforeTree); lResult = m_BeforeTree->Add(lBrowser, CComBSTR(lBaseUrl.extendedUrlString())); // ATLASSERT(SUCCEEDED(lResult)); #endif } #ifdef _DEBUG if (*pCancel) KB_LOG_INFO1(_T("[0x%1!x!]::BeforeNavigate Cancel"), pDisp); #endif // _DEBUG } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebProgressChange(long Progress, long ProgressMax) { if (Progress == 0) { CreateLoadTab(); } ReportProgress(Progress, ProgressMax); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebNavigateComplete2(LPDISPATCH pDisp, VARIANT* URL) { ATLASSERT(URL); ATLASSERT(URL->vt == VT_BSTR); HRESULT lResult; CString lUrlString(URL->bstrVal); #ifdef _DEBUG KB_LOG_INFO2(_T("[0x%1!x!]::NavigateComplete(%2)"), pDisp, lUrlString); #endif // _DEBUG if (lUrlString.GetLength() == 0) return ; CComQIPtr lBrowser(pDisp); TUrl lUrl(lUrlString); BOOL lStorable; lUrl.canonicalize(); ATLASSERT(lBrowser); lStorable = StorableProtocol(lUrl.getScheme()); if (lStorable) { if (lUrl.getExtendedInfo() == NULL) { TUrl lBaseUrl(m_InitialUrl); if (lBaseUrl.getExtendedInfo()) { lUrl.setExtendedInfo(lBaseUrl.getExtendedInfo()->clone()); m_CurrentUrl.Empty(); m_CurrentUrl = lUrl.extendedUrlString(); if (lStorable && (m_RootDispatch == pDisp)) { // Update DB webUpdateContent(m_CurrentUrl); } RedirectTo(m_CurrentUrl, lBrowser); return ; } } // #if defined(_DEBUG) && defined(COMPARE_BEFORE_AND_AFTER_URL) CComPtr lTree; ATLASSERT(m_BeforeTree); lResult = m_BeforeTree->FindUrl(CComBSTR(lUrl.extendedUrlString()), &lTree); ATLASSERT(lResult == S_OK); #endif } #if _INDEX_SEARCH_USE_INDEXER_DLL ///////////// // INDEXATION CString lExtUrl = lUrl.extendedUrlString(); if (lStorable) { TBackgroundIndexer::addContent(lExtUrl); } ///////////// #endif // _INDEX_SEARCH_USE_INDEXER_DLL /* if (m_RootDispatch == pDisp) { CComPtr lDispatch; CComQIPtr lDocument; lResult = fWebBrowser->GetHtmlDocument(&lDispatch); lDocument = lDispatch; if (lDocument) { CheckPicturePage(lDocument); } } */ if (m_BrowserTree == NULL) { lResult = m_BrowserTree.CoCreateInstance(CLSID_WebBrowserTreeRoot); ATLASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) return ; m_BrowserTree->EnableSoftReload(!m_bDynamicPage); } ATLASSERT(m_BrowserTree); lResult = m_BrowserTree->Add(lBrowser, CComBSTR(lUrl.extendedUrlString())); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebDocumentComplete(LPDISPATCH pDisp, VARIANT* URL) { // ATLASSERT(m_BrowserTree); m_bInDocumentComplete = TRUE; // pDisp == IWebBrowser2 CComQIPtr lLocalWebBrowser(pDisp); CComPtr lDocumentDispatch; ATLASSERT(lLocalWebBrowser); m_NavigatingFramesList.Remove(lLocalWebBrowser.p); m_NavigateCount = m_NavigatingFramesList.GetSize(); lLocalWebBrowser->get_Document(&lDocumentDispatch); ATLASSERT(URL); ATLASSERT(URL->vt == VT_BSTR); CComBSTR lBstrUrl(URL->bstrVal); CString lUrlString(URL->bstrVal); TUrl lUrl(lUrlString); BOOL lStorable; HRESULT lResult; #ifdef _DEBUG KB_LOG_INFO2(_T("[0x%1!x!]::DocumentComplete(%2)"), pDisp, lUrlString); #endif // _DEBUG if (m_BrowserTree) { CComQIPtr lRootNode(m_BrowserTree); ATLASSERT(lRootNode); // Very important: in order to add correctly annotations, we have to know at node level // that we are in the document complete state if (lRootNode) lRootNode->SetState(lLocalWebBrowser, T_NODE_STATE_COMPLETE); } lStorable = StorableProtocol(lUrl.getScheme()); if (lStorable) { if (lUrl.getExtendedInfo() == NULL) { TUrl lBaseUrl(m_InitialUrl); if (lBaseUrl.getExtendedInfo()) lUrl.setExtendedInfo(lBaseUrl.getExtendedInfo()->clone()); } } lUrl.canonicalize(); CString lExtUrl = lUrl.extendedUrlString(); CString lSimpleUrl = lUrl.simpleUrlString(); lBstrUrl = lExtUrl; CComQIPtr lLocalDocument(lDocumentDispatch); if ((lLocalDocument == NULL) || (lBstrUrl.Length() == 0)) { m_bInDocumentComplete = FALSE; return ; } BOOL lBaseHref = FALSE; CheckBaseHref(lLocalDocument, lExtUrl, &lBaseHref); // ATLASSERT(!lBaseHref); if (lBaseHref) { // Reload(REFRESH_NORMAL); // return ; } // Check url if (TTrash::isPageInTrash(fModel)) { webAddTrashImage(lLocalDocument); } if (m_NavigateCount > 0) { m_bInDocumentComplete = FALSE; return ; } // Add Annotations webAddAnnotations(lBstrUrl); // We're in a Root WebBrowser if (m_RootDispatch == pDisp) { m_bAnnotationAllowed = TRUE; // CheckPicturePage(lLocalDocument); CheckMetaTags(); // Stretch m_bDoStretch = NeedStretch(); if (m_bDoStretch) { lResult = doStretch(); // If fail, do not store in DB if (FAILED(lResult)) lStorable = FALSE; } if (lStorable) { // Update DB webUpdateContent(lExtUrl); webSaveSubContentsInDb(lLocalWebBrowser); } #ifdef ALLOW_PDF_FILE CheckPDFFile(); #endif // ALLOW_PDF_FILE #ifdef UPDATE_SCROLL_AFTER_SOFT_RELOAD if (m_SoftReloadTree) { m_SoftReloadTree->AfterReloadUpdate(m_BrowserTree); m_SoftReloadTree = NULL; } #endif // UPDATE_SCROLL_AFTER_SOFT_RELOAD SetLoaded(TRUE); ReportResult(S_OK); } m_bInDocumentComplete = FALSE; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebTitleChange(LPCTSTR pText) { // modify the title only if not already present if (!HaveUserDefinedTitle(getModel()) && m_bStoreTitle && !m_bCanceling) { CString lText(pText); if (lText.Find(':') > 0) { TUrl lUrl(lText); if (lUrl.getScheme(true).GetLength() == 0) { lText = lUrl.simpleUrlString(); if (lText.Find("internal:") == 0) lText = " "; } else lText.Empty(); } if (lText.GetLength()) getModel()->setTitle(lText); } } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebNewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel) { TNewHtmlWindow* lNewView; if (m_ExternalAdBanner < T_MAX_NEW_WINDOW) { lNewView = new TNewHtmlWindow(getModel(), m_bUserClick); if (lNewView->CreateBrowser(this, WS_CHILD)) { m_ExternalAdBanner++; // HRESULT lResult; // lResult = m_BrowserTree->AddAdjacentTree(lNewView->m_pBrowserApp); // ATLASSERT(SUCCEEDED(lResult)); CWnd* lWnd = lNewView; m_AdBannerList.Add(lWnd); *ppDisp = lNewView->m_pBrowserApp; (*ppDisp)->AddRef(); *Cancel = FALSE; return ; } } *Cancel = TRUE; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebStatusTextChange(LPCTSTR Text) { SetStatus(Text); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebDownloadComplete() { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebDownloadBegin() { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebPropertyChange(LPCTSTR szProperty) { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebCommandStateChange(long Command, BOOL Enable) { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebQuit() { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebVisible(BOOL Visible) { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebToolBar(BOOL ToolBar) { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebMenuBar(BOOL MenuBar) { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebStatusBar(BOOL StatusBar) { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebFullScreen(BOOL FullScreen) { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebTheaterMode(BOOL TheaterMode) { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnWebMouseMove(short a, short b, long x, long y) { } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // HRESULT TBaseWebBrowserPageletCtrl::doStretch(DWORD pFlags) { m_StretchFlags = pFlags; HRESULT lResult = S_FALSE; if (!m_BrowserTree) return E_FAIL; CComPtr lDocument; CComPtr lDomUtils; if (FAILED(m_BrowserTree->get_Document(&lDocument))) return E_FAIL; lResult = lDomUtils.CoCreateInstance(CLSID_DomUtils); ATLASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) return lResult; TRACE(_T(" -----------------------------\n")); TRACE(_T(" ------ Starting Stretch -----\n")); TRACE(_T(" -----------------------------\n")); CComObject* lStretchSink; CComPtr lSink; CComObject::CreateInstance(&lStretchSink); lStretchSink->setDom(lDocument); lStretchSink->setPagelet(this); lStretchSink->setStretching(TRUE); m_StretchSink = lStretchSink; lSink = lStretchSink; lResult = lDomUtils->DomStretcher(m_BrowserTree, 0, lSink); #ifndef USE_OLE_ZOOM CComCmdTarget lTarget(lDocument); ATLASSERT(lTarget); // CComQIPtr lDoc(lDocument); if (lTarget && lStretchSink->getStretching()) { // Should be available under IE 5.5 if (lTarget.IsSupported(IDM_ZOOMRATIO, &CGID_MSHTML)) { CComVariant lFactor(0.5f); lResult = lTarget.Exec(IDM_ZOOMRATIO, OLECMDEXECOPT_DONTPROMPTUSER, &lFactor, NULL, &CGID_MSHTML); } else if (lTarget.IsSupported(OLECMDID_ZOOM)) { VARIANT lVariant; lResult = lTarget.Exec(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, NULL, &lVariant); if (lResult == S_OK) { CComVariant lValue(lVariant); if (lValue.ChangeType(VT_I4) == S_OK) { long lZoom = lValue.lVal; if (lZoom) { lZoom--; lValue.lVal = lZoom; lValue.Detach(&lVariant); lResult = lTarget.Exec(OLECMDID_ZOOM, OLECMDEXECOPT_DONTPROMPTUSER, &lVariant, NULL); } } } } } #endif // USE_OLE_ZOOM TRACE(_T(" ----------------------------\n")); TRACE(_T(" ----- Stopping Stretch -----\n")); TRACE(_T(" ----------------------------\n")); lStretchSink->setStretching(FALSE); m_StretchSink = NULL; return lResult; } #ifdef SEARCH_FOR_HIDDEN_EVENT // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnEmpty() { ATLASSERT(NULL); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::OnBstr(LPCTSTR lString) { ATLASSERT(NULL); } #endif // SEARCH_FOR_HIDDEN_EVENT/*------------ TWBPageletCtl_WebUtils.cpp ------------*/ #include "StdAfx.h" #include "ProductName.h" #include "mshtml.h" #include "TBaseWBPageletCtl.h" #include "TWBPageletCtl_Utils.h" #include "PageletCtrl.h" #include "TGlobalsDB.h" #include "TDBManager.h" #include "TMetaManager.h" #include "TModelNames.h" #include "TBookModel.h" #include "TSummaryModel.h" #include "TContentModel.h" #include "TContextModel.h" #include "TContentsBagModel.h" #include "TStickerModel.h" #include "THighlighterModel.h" #include "TPropertyObjectModel.h" #include "TModelPtr.h" #include "TPageNumbering.h" #include "TModelIterator.h" #include "TContentPropertiesConstants.h" #include "TModelHelpers.h" #include "SharedLookAndFeelRes.h" #include "TPageletResource.h" #include "MultipleButton.h" #include "TWebToolbar.h" #include "TWebBrowser.h" #include "TScriptFunction.h" #include "TWizardHelper.h" #include "TStringToPtrHashTable.h" #include "TInteger.h" #include "TSevenixUrlInfo.h" #include "TSevenixUrl.h" #include "TUrl.h" #include "TTime.h" #include "TPoint.h" #include "TLookAndFeel.h" #include "TLanguage.h" #include "TErr.h" #include "TUserMessage.h" #include "TAppInfo.h" #include "IEVersion.h" #include "Net.h" #define _MIDL_USE_GUIDDEF_ //#include "Net_i.c" #include "TNetHelpers.h" #include "Dom.h" #define _MIDL_USE_GUIDDEF_ //#include "Dom_i.c" //#include "TFrameTargetGenerator.h" //#include "TDomFrameCrawler.h" #include "TDomHelper.h" //#include "TDomSaver.h" #include "TWBSaveFrameSink.h" #include "TDeleteCacheEntryCallback.h" #include "Controler.h" //#include "Script.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // **************************************************************** #ifdef _DEBUG void FindInterface(IUnknown* pDispatch); #endif void CallOnload(IDispatch* pDisp) { CComQIPtr lBrowser(pDisp); CComPtr lDocDisp; CComQIPtr lDoc; CComPtr lBodyElem; CComQIPtr lBody; CComVariant lOnloadVal; lBrowser->get_Document(&lDocDisp); lDoc = lDocDisp; if (lDoc) lDoc->get_body(&lBodyElem); lBody = lBodyElem; if (lBody) lBody->get_onload(&lOnloadVal); DISPPARAMS pdp; CComVariant lResult; EXCEPINFO lExcep; UINT lErr; if (lOnloadVal.vt == VT_DISPATCH) lOnloadVal.pdispVal->Invoke(0, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &pdp, &lResult, &lExcep, &lErr); } BOOL TBaseWebBrowserPageletCtrl::IsAutomaticRenavigation(BSTR* pUrl) { // On IE 5.5 ( And after ? ) // Automatic renavigation must be handle in an other way !!! // if (!m_bFirstNavigate || m_IsLoaded) // && MinimumIEVersion(5,5)) { CComQIPtr lCollec; CComQIPtr lMetaElement; CComPtr lDispatch; HRESULT lResult; long lIndex = 0; long lLength = 0; lResult = GetMetaCollection(&lCollec); if (SUCCEEDED(lResult) && lCollec) { lResult = lCollec->get_length(&lLength); ASSERT(SUCCEEDED(lResult)); } while (lIndex < lLength) { if (lCollec) { lResult = lCollec->item(CComVariant(lIndex), CComVariant(), &lDispatch); lMetaElement = lDispatch; lDispatch = NULL; ASSERT(SUCCEEDED(lResult) && lMetaElement); } if (SUCCEEDED(lResult) && lMetaElement) { // Get the HTTP-EQUIV command CComBSTR lValue; lResult = lMetaElement->get_httpEquiv(&lValue); // If it's a Refresh if (SUCCEEDED(lResult) && lValue && !wcsicmp(L"REFRESH", lValue)) { LPCWSTR lUrl; CComBSTR lContent; // If it contain and URL (ie: the string is of type "time; URL=url") lResult = lMetaElement->get_content(&lContent); if (SUCCEEDED(lResult) && lContent) { // USES_CONVERSION; // KB_LOG_INFO1(_T("HTTP Refresh: %1"), W2CT(lContent)); lUrl = wcschr(lContent, L';'); if (lUrl && (lUrl - lContent <= 1)) { lUrl++; while (*lUrl == L' ') lUrl++; if (!wcsnicmp(L"URL=", lUrl, 4)) lUrl += 4; else lUrl = NULL; if (lUrl && (*lUrl != L'\0')) { *pUrl = ::SysAllocString(lUrl); return TRUE; } } } } } lIndex++; } // if (MinimumIEVersion(5,5)) return FALSE; } // automatic renavigation // return (!m_bFirstNavigate && !m_bUserClick); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // BOOL TBaseWebBrowserPageletCtrl::NeedCreateNewPage(IWebBrowser2* pBrowser, BSTR pUrl, long pFlags, BSTR pTargetFrameName, VARIANT* pPostData, BSTR pHeaders, BOOL* pCancel) { USES_CONVERSION; CString lUrl(pUrl); CString lHeaders(pHeaders); CString lTargetFrame(pTargetFrameName); CComVariant lPostData; if (pPostData) lPostData = *pPostData->pvarVal; TUrl lUrlClass(lUrl); CString lScheme = lUrlClass.getScheme(); ATLTRACE(_T(" >> BeforeNavigate: %s (%s)\n"), lUrl, lTargetFrame); CComBSTR lRedirectUrl; // automatic renavigation if (IsAutomaticRenavigation(&lRedirectUrl)) { CComQIPtr lDispatch(pBrowser); if (!lUrlClass.equals(W2CT(lRedirectUrl))) { lUrlClass.CombineUrl(W2CT(lRedirectUrl)); // KB_LOG_INFO1(_T("RedirectTo: %1"), lUrlClass.extendedUrlString()); RedirectTo(lUrlClass.extendedUrlString(), pBrowser); *pCancel = TRUE; return FALSE; } // Is this the Root document ? if (m_RootDispatch == lDispatch) { // Case of HTTP redirection ? m_CurrentUrl.Empty(); m_CurrentUrl = lUrl; m_bRedirected = TRUE; } // Do not create a new page return FALSE; } if (m_NavigateCount > 1) return FALSE; TModelPtr lNetworkProp; TModelPtr lContent; boolean lPropBool; getModel()->getContent(&lContent); ATLASSERT(lContent); if (lContent) GetModelProperty(lContent, T_CONTENT_NETWORK_PROPERTIES, &lNetworkProp); // // Is this a Post if (!m_bUserClick && (lPostData.vt != VT_EMPTY) && lNetworkProp && !m_bRedirected) { m_bDynamicPage = TRUE; // If do have flag first time nav if (lNetworkProp->getBooleanField("first-nav", &lPropBool) && lPropBool) { // Remove flag has this is not the first time anymore !!! lNetworkProp->putBooleanField("first-nav", FALSE); lNetworkProp->putStringField(T_CONTENT_NETWORK_POST_DATA, "null"); // lNetworkProp->removeField(T_CONTENT_NETWORK_HEADERS); } else { // Post UnAvailable // IDR_HTML_ABOUT_POST_NOT_CACHED CString lRedirectUrl(KEEBOO_NETWORK_PROTOCOL":internal://language/10023?"); lRedirectUrl += lUrlClass.getHost(); RedirectTo(lRedirectUrl); m_bRedirected = TRUE; m_bStoreTitle = FALSE; *pCancel = TRUE; return FALSE; } } ATLASSERT(m_pNetStatus != NULL); if ((m_pNetStatus != NULL) && (StorableProtocol(lScheme) || HaveNetworkFlags(getModel(), F_CONTENT_NETWORK_REMOTE_DATA))) { CComBSTR lBstrUrl(lUrlClass.extendedUrlString()); BOOL lBool = FALSE; LONG lAskCount = 0; HRESULT lResult; lResult = m_pNetStatus->GetOnline(&lBool); // if we're offline if (lBool == FALSE) { DWORD lAccess; int lChoice = 0; lResult = CheckDocumentLocalAccessibility(lBstrUrl, &lAccess); // and if we do not have the document. if (!(lAccess & DOCUMENT_CAN_ACCESS)) { lResult = m_pNetStatus->GetOnline(&lBool, &lAskCount); if (lAskCount == 1) { AFX_MANAGE_STATE(AfxGetAppModuleState()); // Ask the user if he wants to switch online CDialog lDlg(IDD_SWITCH_ONLINE); lChoice = lDlg.DoModal(); } else lChoice = IDCANCEL; } if (lChoice == IDOK) { TModelPtr lContext; m_pNetStatus->SetOnline(TRUE); TMetaManager::createModelInstance(T_CONTEXT_MODEL_NAME, (void**)&lContext); lContext->setCurrentOnLineSwitch(TRUE); } else if (lChoice == IDCANCEL) { // was KEEBOO_NETWORK_PROTOCOL":about:OfflineInformation" // IDR_HTML_ABOUT_OFFLINE CString lRedirectUrl(KEEBOO_NETWORK_PROTOCOL":internal://language/10022"); // and if we do not have the document. if (!(lAccess & DOCUMENT_CAN_ACCESS)) { CComPtr lEntry; // check if we have an older version. lResult = CacheGetEntry(lBstrUrl, T_NETWORK_CACHE_NAME, &lEntry, T_CACHE_FRESHEST_ELEMENT); if (SUCCEEDED(lResult) && lEntry) { CComBSTR lEntryUrl; lEntry->getUrl(&lEntryUrl); lRedirectUrl = lEntryUrl; } } if (!m_bUserClick && !m_bRedirected) { RedirectTo(lRedirectUrl); } m_bStoreTitle = FALSE; *pCancel = TRUE; return FALSE; } } else { // we're online if (lNetworkProp && lNetworkProp->getBooleanField("online-reload", &lPropBool) && lPropBool) { PostMessage(WM_USER_RELOAD_PAGE, REFRESH_COMPLETELY); lNetworkProp->removeField("online-reload"); return FALSE; } else if (lNetworkProp && lNetworkProp->getBooleanField("online-flush", &lPropBool) && lPropBool) { CComPtr lCache; // check if we have an older version. lResult = GetCache(T_NETWORK_CACHE_NAME, &lCache); if (SUCCEEDED(lResult) && lCache) { lResult = lCache->deleteEntry(lBstrUrl); if (SUCCEEDED(lResult)) lNetworkProp->removeField("online-flush"); } } } } // If we've just click on an URL link // this pointer is == -1 // We don't want to follow scripting link. // We don't want to follow mailto link. if (!m_bFirstNavigate && StorableProtocol(lScheme)) { TRACE(_T(" >> >> Not First Before Nav with : this(0x%x), Disp(0x%x), fDisp(0x%x)\n"), this, pBrowser, m_RootDispatch); return TRUE; } return FALSE; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::CreateNewPage(IWebBrowser2* pBrowser, BSTR URL, long Flags, BSTR TargetFrameName, VARIANT* PostData, BSTR Headers) { TModelPtr lContentsBag; TModelPtr lContent; TModelPtr lNewPage; TModelPtr lBook; TString lUrl(URL); TString lHeaders(Headers); CString lTargetFrame(TargetFrameName); BOOL lForceGotoPage = FALSE; BOOL lGeneratedPage = FALSE; HRESULT lResult; ePageSide2 lSide = T_SIDE_SECONDARY; CString lPostStr; // If the user click on a link // the target is a frame if (m_bUserClick && lTargetFrame.GetLength()) { // // Generate a frameset in the Cache // For the new page // CComPtr lDomUtils; CComBSTR lNewUrl; lResult = lDomUtils.CoCreateInstance(CLSID_DomUtils); ASSERT(SUCCEEDED(lResult)); if (SUCCEEDED(lResult)) { lResult = lDomUtils->GenerateTargetFrameSet(m_BrowserTree, CComBSTR(m_CurrentUrl), URL, TargetFrameName, &lNewUrl); // S_FALSE == 'No change' // // If the new Frameset was generated // change the URL // if (lResult == S_OK) { lUrl = lNewUrl; lGeneratedPage = TRUE; } } } // Get the content bag ( the list of content ) TMetaManager::createModelInstance(T_CONTENTS_BAG_MODEL_NAME, (void**)&lContentsBag); ASSERT(lContentsBag); TUrl lFindContentUrl(lUrl); // ????? // Do we allready have this page in the list lContentsBag->findContent(lFindContentUrl.extendedUrlString(), &lContent); long lPostDim = 0; if (PostData) { CComVariant lPostData; lPostData = *PostData->pvarVal; if (lPostData.vt & VT_ARRAY) { COleSafeArray lArray((VARIANT&)lPostData); lPostDim = lArray.GetDim(); if (lPostDim) { ASSERT(lPostDim == 1); long lSize = lArray.GetOneDimSize(); LPTSTR lBuffer; long lIndex = 0; lArray.PtrOfIndex(&lIndex, (void**)&lBuffer); lPostStr = CString(lBuffer, lSize); } } } // If Content exist and we have a Post Data // We need to check if the data are equal if ((lContent != NULL) && lPostDim) { TModelPtr lProp; BOOL lSamePost = FALSE; GetModelProperty(lContent, T_CONTENT_NETWORK_PROPERTIES, &lProp, TRUE); if (lProp != NULL) { TString lStoredPostStr; if (lProp->getStringField(T_CONTENT_NETWORK_POST_DATA, &lStoredPostStr)) { if (lStoredPostStr == lPostStr) lSamePost = TRUE; } } if (!lSamePost) { TUrl lNewUrl(lUrl); TSevenixUrlInfo* lInfo; lContent = NULL; lInfo = (TSevenixUrlInfo*)lNewUrl.getExtendedInfo(); lInfo->setUniqueID(); lUrl = lNewUrl.extendedUrlString(); } } getModel()->getBook(&lBook); ASSERT(lBook); if (lContent != NULL) { lBook->findFirstPageOfContent(lContent, &lNewPage); lForceGotoPage = ((lNewPage == NULL) ? FALSE : TRUE); if (!(getState() & PAGELET_CURRENT)) lSide = T_SIDE_SECONDARY; else lSide = T_SIDE_PRIMARY; } CComPtr lBookControl; lResult = lBookControl.CoCreateInstance(CLSID_TBookControler); ASSERT(SUCCEEDED(lResult) && lBookControl); // This is for Release Build // So that we don't crash !!!!! if (lBookControl == NULL) return ; if (lNewPage == NULL) { CComBSTR lBstrUrl = lUrl; CComVariant lUrlVariant(lBstrUrl); lSide = T_SIDE_SECONDARY; // Cast because model are not COM interface !!! lResult = lBookControl->Add(lUrlVariant, T_POS_CURRENT, (long*)&lNewPage); ASSERT(SUCCEEDED(lResult) && lNewPage); if (FAILED(lResult) || (lNewPage == NULL)) return ; long lBehaviour = 0; if (lGeneratedPage) { lBehaviour |= F_PAGE_GENERATED; } // set the temporary persistance info AddBehaviour(lNewPage, lBehaviour | F_PAGE_TEMPORARY); if (lPostDim) { TModelPtr lProp; lContent = 0; lNewPage->getContent(&lContent); GetModelProperty(lContent, T_CONTENT_NETWORK_PROPERTIES, &lProp, TRUE); ASSERT(lProp); if (lProp != NULL) { lProp->putStringField(T_CONTENT_NETWORK_POST_DATA, lPostStr); lProp->putStringField(T_CONTENT_NETWORK_HEADERS, lHeaders); lProp->putBooleanField("first-nav", TRUE); } } } if (lNewPage) { // Cast because model are not COM interface !!! CComVariant lPageVariant((long)lNewPage.p); lResult = lBookControl->ChangePageTo(T_CPT_PAGE, lSide, lPageVariant); } } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::webAddTrashImage(IHTMLDocument2* pDocument) { ASSERT(pDocument); if (pDocument == NULL) return ; CComPtr lElement; if (FAILED(pDocument->get_body(&lElement))) return ; CComQIPtr lBody(lElement); if (lBody) { CString lPath; CString lImg; if (TLookAndFeel::GetCurrentLookAndFeelDllPath(lPath)) { lImg.FormatMessage("res://%1/%2!d!", lPath, IDG_TRASH_BACKGROUND); HRESULT lResult; lResult = lBody->put_background(CComBSTR(lImg)); ASSERT(lResult == S_OK); } } } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::webUpdateContent(CString pUrl) { UpdatePageContent(getModel(), pUrl); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::webAddAnnotations(BSTR pUrl) { // Check if we need annotation TModelPtr lProp; TModelIterator* lIterator = NULL; HRESULT lResult; boolean lBool = true; long lIndex = 0; TUrl lUrl(pUrl); ASSERT(m_BrowserTree != NULL); if (m_BrowserTree == NULL) return; CComPtr lNode; lResult = m_BrowserTree->FindUrl(pUrl, &lNode); if ( (!SUCCEEDED(lResult)) || (!lNode) ) lNode = m_BrowserTree; // --- open a transaction TDBManager *dbm = TGlobalsDB::getLibraryDBManager(); dbm->beginTransaction(t_transaction_types::TRANSACTION_READONLY); getModel()->getDefaultProperty(&lProp); if (lProp && !lProp->getBooleanField(T_PAGE_DEFAULT_PROPERTY_ANNOTATION_VISIBILITY, &lBool)) lBool = true; lIterator = getModel()->getAnnotations(); while (lIterator->hasMoreElements()) { TModelPtr lAnnotation; TUrl lContentUrl; lIterator->nextElement((TObjectModel**)&lAnnotation); lContentUrl = lAnnotation->getContent(); if (lContentUrl.equals(lUrl, FALSE)) { lResult = AddAnnotation(lNode, lAnnotation, lBool); ASSERT(SUCCEEDED(lResult)); } else { ASSERT(lContentUrl.simpleUrlString().GetLength()); if (lContentUrl.simpleUrlString().GetLength() == 0) lResult = E_FAIL; } if (FAILED(lResult) && lAnnotation->isInstanceOf(T_HIGHLIGHTER_MODEL_NAME)) { #ifdef WARN_USER_BEFORE_DELETING_HIGHLIGHT // Ask the user if it want to keep the annotation. CDialog lDialog(IDD_HIGHLIGHTER_NOT_FOUND); long lAction = lDialog.DoModal(); if (lAction == IDOK) #endif // WARN_USER_BEFORE_DELETING_HIGHLIGHT { getModel()->removeAnnotation(lAnnotation); delete lIterator; lIterator = getModel()->getAnnotations(); lIterator->skip(lIndex); continue; } } lIndex++; } delete lIterator; // --- close the transaction dbm->commitTransaction(); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::webSaveSubContentsInDb(IWebBrowser2* pBrowser) { HRESULT lResult; // ASSERT(m_BrowserTree.m_Document != NULL); ASSERT(m_BrowserTree); if (m_BrowserTree == NULL) return ; m_BrowserTree->Add(pBrowser, NULL); // --- open a transaction TDBManager *dbm = TGlobalsDB::getLibraryDBManager(); dbm->beginTransaction(t_transaction_types::TRANSACTION_READONLY); TModelPtr lContent; getModel()->getContent(&lContent); CArray< TContentModel*, TContentModel*> lData; CComObject* lSaveSink; CComPtr lSink; CComPtr lDomUtils; lResult = lDomUtils.CoCreateInstance(CLSID_DomUtils); ASSERT(SUCCEEDED(lResult)); lResult = CComObject::CreateInstance(&lSaveSink); ASSERT(SUCCEEDED(lResult)); if (lSaveSink) { lSaveSink->SetBase(m_CurrentUrl); lResult = lSaveSink->QueryInterface(&lSink); ASSERT(SUCCEEDED(lResult)); } lData.Add(lContent); lResult = lDomUtils->FrameCrawler(m_BrowserTree, lSink, CComVariant((long)&lData, VT_I4)); ASSERT(SUCCEEDED(lResult)); // --- close the transaction dbm->commitTransaction(); } HRESULT TBaseWebBrowserPageletCtrl::GetMetaCollection(IHTMLElementCollection** pCollec, IHTMLDocument2* pDocument) { CComPtr lDispatch; CComQIPtr lDocument; HRESULT lResult; if (pDocument == NULL) { if (!m_BrowserTree) return E_FAIL; lResult = m_BrowserTree->get_Document(&lDispatch); lDocument = lDispatch; lDispatch = NULL; ASSERT(SUCCEEDED(lResult) && lDocument); if (FAILED(lResult) || (lDocument == NULL)) return E_FAIL; } else { lDocument = pDocument; } CComPtr lCollec; lResult = lDocument->get_all(&lCollec); ASSERT(SUCCEEDED(lResult) && lCollec); if (FAILED(lResult) || (lCollec == NULL)) return E_FAIL; lResult = lCollec->tags(CComVariant("META"), &lDispatch); return lDispatch->QueryInterface(pCollec); } HRESULT TBaseWebBrowserPageletCtrl::CheckMetaTags() { CComQIPtr lCollec; CComQIPtr lMetaElement; CComPtr lDispatch; HRESULT lResult; long lIndex = 0; long lLength = 1; lResult = GetMetaCollection(&lCollec); if (SUCCEEDED(lResult) && lCollec) { lResult = lCollec->get_length(&lLength); ASSERT(SUCCEEDED(lResult)); } while (lIndex < lLength) { if (lCollec) { lResult = lCollec->item(CComVariant(lIndex), CComVariant(), &lDispatch); lMetaElement = lDispatch; lDispatch = NULL; ASSERT(SUCCEEDED(lResult) && lMetaElement); } if (SUCCEEDED(lResult) && lMetaElement) { // CComBSTR lName; lResult = lMetaElement->get_name(&lName); if (SUCCEEDED(lResult) && lName && (!wcsicmp(CComBSTR(KEEBOO_PRODUCT_NAME), lName) || !wcsicmp(CComBSTR(KEEBOO_COMPANY), lName))) { CComBSTR lMetaContent; lResult = lMetaElement->get_content(&lMetaContent); if (SUCCEEDED(lResult) && lMetaContent) { if (!wcsicmp(L"no-stretch", lMetaContent)) { m_bNoStretch = TRUE; } else if (!wcsicmp(L"no-cache", lMetaContent)) { CComQIPtr lPageletSink(m_pControlSite); if (lPageletSink) { CComObject* lCallback; CComQIPtr lCBInterface; CComObject::CreateInstance(&lCallback); lCallback->SetPage(getModel()); lCBInterface = lCallback; lPageletSink->SetDestroyCallback(lCallback); } } else { TModelPtr lProp; TModelPtr lContentModel; if (!wcsicmp(L"online-reload", lMetaContent)) { getModel()->getContent(&lContentModel); GetModelProperty(lContentModel, T_CONTENT_NETWORK_PROPERTIES, &lProp, TRUE); ASSERT(lProp); if (lProp) lProp->putBooleanField("online-reload", true); } else if (!wcsicmp(L"online-flush", lMetaContent)) { getModel()->getContent(&lContentModel); GetModelProperty(lContentModel, T_CONTENT_NETWORK_PROPERTIES, &lProp, TRUE); ASSERT(lProp); if (lProp) lProp->putBooleanField("online-flush", true); } } } } } lIndex++; } return S_OK; } HRESULT TBaseWebBrowserPageletCtrl::CheckIsInternalPage(BSTR* pType) { CComQIPtr lCollec; CComQIPtr lMetaElement; CComPtr lDispatch; HRESULT lResult; long lIndex = 0; long lLength = 1; lResult = GetMetaCollection(&lCollec); if (SUCCEEDED(lResult) && lCollec) { lResult = lCollec->get_length(&lLength); ASSERT(SUCCEEDED(lResult)); } BOOL lIsError = FALSE; while (lIndex < lLength) { CComQIPtr lMetaElement; if (lCollec) { lResult = lCollec->item(CComVariant(lIndex), CComVariant(), &lDispatch); lMetaElement = lDispatch; lDispatch = NULL; ASSERT(SUCCEEDED(lResult) && lMetaElement); } if (SUCCEEDED(lResult) && lMetaElement) { // CComBSTR lValue; lResult = lMetaElement->get_name(&lValue); if (SUCCEEDED(lResult) && lValue) { if (!wcsicmp(CComBSTR(KEEBOO_PRODUCT_NAME), lValue) || !wcsicmp(CComBSTR(KEEBOO_COMPANY), lValue)) { lValue.Empty(); lResult = lMetaElement->get_content(&lValue); if (SUCCEEDED(lResult) && lValue && (!wcsicmp(L"internal", lValue) || !wcsicmp(L"error", lValue))) // For compatibility { lIsError = TRUE; } } if (!wcsicmp(L"Type", lValue)) { lValue.Empty(); lResult = lMetaElement->get_content(&lValue); if (SUCCEEDED(lResult) && lIsError) { return CComBSTR(lValue).CopyTo(pType); } } } } lIndex++; } if (lIsError) return S_OK; return S_FALSE; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // HRESULT TBaseWebBrowserPageletCtrl::CheckBaseHref(IHTMLDocument2* pDocument, LPCTSTR pUrl, BOOL* pBaseHref) { HRESULT lResult = S_OK; ASSERT(pBaseHref); if (pBaseHref == NULL) return E_INVALIDARG; *pBaseHref = FALSE; ASSERT(pDocument); if (pDocument == NULL) return E_INVALIDARG; // TEMP // --- Check the that BASE Tag is not present // If present, warn us that this page is not reliable CComPtr lCollec; lResult = pDocument->get_all(&lCollec); ATLASSERT(SUCCEEDED(lResult) && lCollec); if (FAILED(lResult)) return lResult; COleVariant lVariant("BASE"); CComPtr lBase; lResult = lCollec->tags(lVariant, &lBase); if (FAILED(lResult)) return lResult; CComQIPtr lCollec2(lBase); if (lCollec2) { long lLength; lCollec2->get_length(&lLength); lBase.Release(); if (lLength) { COleVariant lNullVariant((long)0); lResult = lCollec2->item(lNullVariant, lNullVariant, &lBase); } } CComQIPtr lBaseElement(lBase); if (lBaseElement) { CComBSTR lHref; lBaseElement->get_href(&lHref); if (lHref.Length()) { TUrl lTestUrl(lHref); if (lTestUrl.getExtendedInfo()) return S_OK; CComPtr lEntry; lResult = CacheGetEntry(CComBSTR(pUrl), T_NETWORK_CACHE_NAME, &lEntry); if (SUCCEEDED(lResult) && lEntry) { CComPtr lDomUtils; CComBSTR lFileName; lResult= lEntry->getFileName(&lFileName); lResult = lDomUtils.CoCreateInstance(CLSID_DomUtils); ASSERT(SUCCEEDED(lResult) && lDomUtils); if (SUCCEEDED(lResult) && lDomUtils) { TSevenixUrl lNewUrl(pUrl); lNewUrl.CombineUrl(CString(lHref)); CComBSTR lUrl(lNewUrl.extendedUrlString()); lResult = lBaseElement->put_href(lUrl); ASSERT(SUCCEEDED(lResult)); lResult = lDomUtils->DomSaver(pDocument, lFileName, NULL, CComVariant()); ASSERT(SUCCEEDED(lResult)); *pBaseHref = TRUE; return lResult; } } } } return S_OK; } LONG CheckKeeBooVersion(BSTR pVersion) { int lMinMajor; int lMinMinor; int lMinBuild; int lMinFix; if (swscanf(pVersion, L"%d.%d.%d.%d", &lMinMajor, &lMinMinor, &lMinFix, &lMinBuild) != 4) return -1; TAppInfo lInfo; if (lMinMajor > lInfo.GetMajorVersion()) return 1; if (lMinMinor > lInfo.GetMinorVersion()) return 1; if ((lMinMajor == 2) && (lMinMinor == 4)) return -1; if (lMinFix > lInfo.GetFixVersion()) return 1; if (lMinBuild > lInfo.GetBuild()) return 1; return 0; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // HRESULT GetDocumentForm(IHTMLDocument2* pDocument, BSTR pName, IHTMLFormElement** pForm) { ATLASSERT(pDocument); if (pDocument == NULL) return E_INVALIDARG; ATLASSERT(pForm); if (pForm == NULL) return E_INVALIDARG; CComPtr lCollec; LONG lLength; HRESULT lResult; lResult = pDocument->get_forms(&lCollec); ATLASSERT(SUCCEEDED(lResult) && lCollec); if (FAILED(lResult)) return lResult; lResult = lCollec->get_length(&lLength); ATLASSERT(SUCCEEDED(lResult) && lLength); if (FAILED(lResult)) return lResult; CComPtr lDispatch; CComVariant lName; CComVariant lIndex(0); if (pName) lName = pName; else lName = (LONG)0; lResult = lCollec->item(lName, lIndex, &lDispatch); ATLASSERT(SUCCEEDED(lResult) && lDispatch); if (FAILED(lResult)) return lResult; return lDispatch->QueryInterface(pForm); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // HRESULT GetFormInputField(IHTMLFormElement* pForm, BSTR pName, BSTR* pValue) { ATLASSERT(pForm); if (pForm == NULL) return E_INVALIDARG; ATLASSERT(pValue); if (pValue == NULL) return E_INVALIDARG; CComPtr lDispatch; LONG lLength; HRESULT lResult; lResult = pForm->get_length(&lLength); ATLASSERT(SUCCEEDED(lResult)); lResult = pForm->item(CComVariant(pName), CComVariant(0), &lDispatch); ATLASSERT(SUCCEEDED(lResult)); CComQIPtr lInput; lInput = lDispatch; if (lInput == NULL) return E_FAIL; return lInput->get_value(pValue); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // HRESULT TBaseWebBrowserPageletCtrl::HookDynamicKeeBook(IWebBrowser2* pBrowser, BOOL* pCancel) { CComPtr lWindow; CComQIPtr lDocument; CComPtr lDisp; HRESULT lResult; // Check if we have a GenerateTOC function lResult = pBrowser->get_Document(&lDisp); lDocument = lDisp; if (!lDocument) return E_FAIL; lResult = lDocument->get_parentWindow(&lWindow); ATLASSERT(SUCCEEDED(lResult) && lWindow); if (!lWindow) return E_FAIL; CComDispatchDriver lDriver(lWindow); LONG lDispID = 0; lResult = lDriver.GetIDOfName(L"GenerateTOC", &lDispID); if (SUCCEEDED(lResult) && lDispID >= 0) { CComVariant lMinVersion; CComVariant lGeneratorVar; lResult = lDriver.GetPropertyByName(L"_minKeeBooVer", &lMinVersion); if (FAILED(lResult) || lMinVersion.vt != VT_BSTR) lMinVersion = CComVariant("2.1.0.0"); LONG lCmp = CheckKeeBooVersion(lMinVersion.bstrVal); if (lCmp == 0) { // the 'Generator' and 'GeneratorProduct' variables were not present // in older version of KeeBooks, so let's reset our test flag only if // we find it... lResult = lDriver.GetPropertyByName(L"Generator", &lGeneratorVar); if (SUCCEEDED(lResult) && lGeneratorVar.vt == VT_BSTR) lCmp = -1; lGeneratorVar.Clear(); lResult = lDriver.GetPropertyByName(L"GeneratorProduct", &lGeneratorVar); if (SUCCEEDED(lResult) && lGeneratorVar.vt == VT_BSTR) { USES_CONVERSION; // We found the 'GeneratorProduct' variable, so let's reset the test // flag and go on with the test sequence. lCmp = -1; // We will accept importation only if the product that generated this // KeeBook ('GeneratorProduct') is KeeBook Creator // Remark: please do not use the global define KEEBOO_PRODUCT_NAME since // we may change it afterwards and it would make any keebook generated before // unimportable!!! // Remark: if we happen to change the product name, we should extend the // test to the new names as well if ( wcsicmp(lGeneratorVar.bstrVal, L"KeeBook Creator") == 0 ) lCmp = 0; /* if ( wcsicmp(lGeneratorVar.bstrVal, L"KeeBook Creator New Name") == 0 ) lCmp = 0; */ } else { if (lCmp != 0) { // We found 'Generator', but we did not found 'GeneratorProduct' // -> In theory we should parse the 'Generator' string which has the following // syntax (sample): "KeeBook Creator® 2.3.0.51" and check if the generating app is // "KeeBook Creator". // But keebooks having 'Generator' and not 'GeneratorProduct' are // keebooks < 2.5.x.x and we can import them all, except keebooks == 2.4.x.x // but such keebooks have already been filtered out by the CheckKeeBooVersion() // call. Therefore we consider that at this point we always are able to import // such keebooks. lCmp = 0; } else { // We found neither 'Generator' nor 'GeneratorProduct' !! // -> we consider that we are able to import this keebook // since the _minKeeBooVer has been validated... lCmp = 0; } } } if (lCmp != 0) { // Display and Error Message CString lRedirectUrl; if (lCmp > 0) // IDR_HTML_BAD_KEEBOOK_VERSION lRedirectUrl = KEEBOO_NETWORK_PROTOCOL":internal://language/10027?"; else // IDR_HTML_KEEBOOK_VERSION_NOT_SUPPORTED lRedirectUrl = KEEBOO_NETWORK_PROTOCOL":internal://language/10029?"; lRedirectUrl += lMinVersion.bstrVal; RedirectTo(lRedirectUrl); *pCancel = TRUE; return E_FAIL; } // If so Cancel Navigation *pCancel = TRUE; // And launch Export of Dynamic KeeBook CComVariant lValue; lResult = lDriver.GetProperty(lDispID, &lValue); ATLASSERT(SUCCEEDED(lResult) && lValue.vt == VT_DISPATCH); if (lValue.vt == VT_DISPATCH) { CComDispatchDriver lGeneratedTOCDriver(lValue.pdispVal); CComVariant lToStringResult; lResult = lGeneratedTOCDriver.Invoke0(L"toString", &lToStringResult); ATLASSERT(SUCCEEDED(lResult) && lToStringResult.vt == VT_BSTR); CComPtr lForm; CComBSTR lCode(lToStringResult.bstrVal); lResult = GetDocumentForm(lDocument, NULL, &lForm); if (SUCCEEDED(lResult) && lForm) { CComBSTR lAuthorUser; CComBSTR lAuthorPartner; lResult = GetFormInputField(lForm, L"AuthorUser", &lAuthorUser); lResult = GetFormInputField(lForm, L"AuthorPartner", &lAuthorPartner); if (lAuthorUser || lAuthorPartner) { lCode[lCode.Length() - 1] = L' '; lCode.Append(L"if (book)\n\tbook.KBSetAuthorID('"); lCode.AppendBSTR(lAuthorUser); lCode.Append(L"', '"); lCode.AppendBSTR(lAuthorPartner); lCode.Append(L"');\n}"); } } CComVariant lDocLocation; BSTR lUrl = NULL; lResult = lDriver.GetPropertyByName(L"_docLocation", &lDocLocation); if (SUCCEEDED(lResult) && lDocLocation.vt == VT_BSTR) lUrl = lDocLocation.bstrVal; CComVariant lEnginePath; lResult = lDriver.GetPropertyByName(L"EnginePath", &lEnginePath); if (SUCCEEDED(lResult) && (lEnginePath.vt == VT_BSTR) && lEnginePath.bstrVal && (wcscmp(L"./", lEnginePath.bstrVal))) { lCode.Append(L"var enginePath=\""); lCode.Append(lEnginePath.bstrVal); lCode.Append(L"\";"); } LaunchExportDynamicKeeBook(lUrl, lCode); } } return lResult; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::LaunchExportDynamicKeeBook(BSTR pUrl, BSTR pCode) { USES_CONVERSION; HRESULT lResult; LPCTSTR lDocumentUrl; if (pUrl) lDocumentUrl = W2CT(pUrl); else lDocumentUrl = m_CurrentUrl; TUrl lUrl(lDocumentUrl); DECLARE_BOOK_WIZARD(lWizard); lResult = lWizard->ImportFromWebBook(CComBSTR(lUrl.simpleUrlString()), pCode); // Then Remove Page if (SUCCEEDED(lResult)) PostMessage(WM_USER_REMOVE_PAGE); } ///////////////////////////////////////////////////////////////////////////// // // TBaseWebBrowserPageletCtrl::AdviseAnchorsEventSink() // // Description: We must sink events for all anchors on the page. This is // needed due to the fact that when a link is clicked it // automatically navigates in the band window. We can't // change the navigation in the BeforeNavigate2 event handler // because there are some things we want to navigate in the // current window, such as the search results. Certain // anchors contain a target frame name that the Internet // Explorer Search Band uses to determine where the // navigation should occur. However, we don't get this // target frame name. Internet Explorer doesn't pass it to us. // ///////////////////////////////////////////////////////////////////////////// void TBaseWebBrowserPageletCtrl::ManageAnchorsEventSink(AdviseType adviseType) { if (adviseType == Unadvise && _stackAnchorCookies.empty()) return ; if (GetWebBrowser()->m_pBrowserApp == NULL) return ; // Sink Anchor Events CComPtr pDisp; if (FAILED(GetWebBrowser()->m_pBrowserApp->get_Document(&pDisp)) || (pDisp == NULL)) return ; CComQIPtr pDoc(pDisp); pDisp.Release(); if (pDoc == NULL) return; HRESULT hr; // // Advise all the anchors on the page so that we can get the onclick events. // For the search pages, the anchors collection is empty. Therefore, // we have to iterate through the entire all collection and advise // each anchor tag. // CComQIPtr pElemColl; hr = pDoc->get_all(&pElemColl); pDoc.Release(); if (FAILED(hr)) return; CComVariant vtTagName(L"A"); hr = pElemColl->tags(vtTagName, &pDisp); pElemColl = pDisp; long lNumElems = 0; pElemColl->get_length(&lNumElems); for (int i = 0; i < lNumElems; i++) { CComVariant vtItem((long)i), vtEmpty; hr = pElemColl->item(vtItem, vtEmpty, &pDisp); if (FAILED(hr)) break; // Get the IHTMLElement interface. CComQIPtr pElem(pDisp); pDisp.Release(); if (pElem == NULL) break; LPCONNECTIONPOINT pCP = NULL; if (SUCCEEDED(GetConnectionPoint(pElem, DIID_HTMLAnchorEvents, &pCP))) { if (adviseType == Advise) { DWORD dwCookie; // Connect the event sink. // hr = pCP->Advise(static_cast(GetWebBrowser()), &dwCookie); if (SUCCEEDED(hr)) _stackAnchorCookies.push(dwCookie); } else if (!_stackAnchorCookies.empty()) { // Disconnect the event sink. hr = pCP->Unadvise(_stackAnchorCookies.top()); _stackAnchorCookies.pop(); } pCP->Release(); } } } /////////////////////////////////////////////////////////////////////////// // // TBaseWebBrowserPageletCtrl::GetConnectionPoint() // /////////////////////////////////////////////////////////////////////////// HRESULT TBaseWebBrowserPageletCtrl::GetConnectionPoint(LPUNKNOWN pUnk, REFIID riid, LPCONNECTIONPOINT* ppCP) { _ASSERT(GetWebBrowser()); HRESULT hr = E_FAIL; IConnectionPointContainer* pCPC; if (GetWebBrowser()) { hr = pUnk->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pCPC); if (FAILED(hr)) return hr; hr = pCPC->FindConnectionPoint(riid, ppCP); pCPC->Release(); } return hr; } HRESULT SF_SetPictureCodeIfNeeded(LPVOID pDoc, WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarResult); typedef struct { TBaseWebBrowserPageletCtrl* m_pPage; IHTMLDocument2* m_pDocument; } picture_data; // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // HRESULT TBaseWebBrowserPageletCtrl::CheckPicturePage(IHTMLDocument2* pDocument) { HRESULT lResult = S_OK; /* m_bDoImageFit = NeedImageFit(); if (!m_bDoImageFit) return S_OK; */ ASSERT(pDocument); if (pDocument == NULL) return E_INVALIDARG; CComBSTR lReadyState; lResult = pDocument->get_readyState(&lReadyState); if (FAILED(lResult)) return E_FAIL; picture_data* lData; lData = new picture_data; lData->m_pPage = this; lData->m_pDocument = pDocument; if (/*wcscmp(lReadyState, L"interactive") &&*/ wcscmp(lReadyState, L"complete")) { CComVariant lFunctionVar; CComObject* lFunction; CComPtr lDisp; lResult = CComObject::CreateInstance(&lFunction); lFunction->SetFunction(SF_SetPictureCodeIfNeeded); lFunction->SetData(lData, TRUE); lResult = lFunction->QueryInterface(&lDisp); lFunctionVar = lDisp; return pDocument->put_onreadystatechange(lFunctionVar); } return SF_SetPictureCodeIfNeeded(lData, DISPATCH_METHOD, NULL, NULL); } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // HRESULT SF_SetPictureCodeIfNeeded(LPVOID pData, WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarResult) { if (wFlags != DISPATCH_METHOD) return E_FAIL; picture_data* lData; TBaseWebBrowserPageletCtrl* lPagelet; CComPtr lDisp; CComQIPtr pDocument; HRESULT lResult = S_OK; lData = (picture_data*)pData; ATLASSERT(pData); if (pData == NULL) return E_INVALIDARG; lPagelet = lData->m_pPage; pDocument = lData->m_pDocument; ATLASSERT(pDocument && lPagelet); if ((pDocument == NULL) || (lPagelet == NULL)) return E_INVALIDARG; CComBSTR lReadyState; lResult = pDocument->get_readyState(&lReadyState); if (FAILED(lResult)) return E_FAIL; if (/*wcscmp(lReadyState, L"interactive") &&*/ wcscmp(lReadyState, L"complete")) return S_OK; CComPtr lElement; lResult = pDocument->get_body(&lElement); ATLASSERT(SUCCEEDED(lResult) && lElement); if (FAILED(lResult) || lElement == NULL) return E_FAIL; lDisp.Release(); CComQIPtr lChildrens; lResult = lElement->get_children(&lDisp); lChildrens = lDisp; lDisp.Release(); if (FAILED(lResult) || lChildrens == NULL) return E_FAIL; LONG lLength; lResult = lChildrens->get_length(&lLength); if (lLength == 1) { lResult = lChildrens->item(CComVariant(0), CComVariant(), &lDisp); if (SUCCEEDED(lResult) && lDisp != NULL) { CComQIPtr lImage(lDisp); CComQIPtr lElement2(lDisp); if (lElement2 && lImage) { CComBSTR lName; lElement2->get_tagName(&lName); if (!wcsicmp(lName, L"IMG")) { CComBSTR lSrc; lImage->get_src(&lSrc); lPagelet->RedirectTo("internal://neutral/picture.htm"); } } } } CComVariant lFunctionVar; lFunctionVar.vt = VT_NULL; lResult = pDocument->put_onreadystatechange(lFunctionVar); ATLASSERT(SUCCEEDED(lResult)); return S_OK; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // HRESULT TBaseWebBrowserPageletCtrl::UserClick() { m_bFirstNavigate = FALSE; m_bUserClick = TRUE; if (GetKeyState(VK_CONTROL) < 0) { m_bFirstNavigate = TRUE; // m_bUserClick = FALSE; } return S_OK; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // HRESULT TBaseWebBrowserPageletCtrl::TranslateUrl(BSTR pUrl, BSTR* pUrlOut) { if (!MinimumIEVersion(5,50)) UserClick(); // Handle the BASE HREF click case !!!! TUrl lUrlIn(pUrl); CComBSTR lUrlOut; if (lUrlIn.getScheme().Find("script") >= 0) { lUrlOut = lUrlIn.simpleUrlString(); } else { TSevenixUrlInfo* lInfo; lInfo = (TSevenixUrlInfo*)lUrlIn.getExtendedInfo(); if (lInfo == NULL) { long lBaseID = 0; TUrl lBaseUrl(m_CurrentUrl); lInfo = (TSevenixUrlInfo*)lBaseUrl.getExtendedInfo(); if (lInfo) lBaseID = lInfo->getID(); lUrlIn = TSevenixUrl(pUrl, lBaseID); lUrlOut = lUrlIn.extendedUrlString(); } else if (MinimumIEVersion(5,50)) { if (!lInfo->haveProperty(T_ROOT_PROPERTY)) { lInfo->addProperty(T_ROOT_PROPERTY); lUrlOut = lUrlIn.extendedUrlString(); } // Static KeeBook under IE 5.5 // need no Root flag on sub frames if ((wcsstr(pUrl, L"importlab.htm") != NULL) || m_bFullStaticKeeBook) { if (wcsstr(pUrl, L"index.htm") == NULL) { lInfo->removeProperty(T_ROOT_PROPERTY); lUrlOut = lUrlIn.extendedUrlString(); m_bFullStaticKeeBook = TRUE; } } } } if (lUrlOut) *pUrlOut = lUrlOut.Detach(); return S_OK; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // BOOL TBaseWebBrowserPageletCtrl::TryReloadForBmp(IWebBrowser2* pBrowser, LPCTSTR pUrl) { if (m_bReloadForBmp) return FALSE; RedirectTo(pUrl); m_bReloadForBmp = TRUE; return TRUE; } // **************************************************************** // // Description: // // // Inputs: // // // Return Value: // // // Remarks: // // void TBaseWebBrowserPageletCtrl::RedirectTo(LPCTSTR pUrl, IWebBrowser2* pBrowser) { CComBSTR lBstrUrl(pUrl); if (pBrowser == NULL) pBrowser = fWebBrowser->m_pBrowserApp; // Stop navigation on top Browser if (pBrowser == fWebBrowser->m_pBrowserApp) pBrowser->Stop(); pBrowser->AddRef(); PostMessage(WM_USER_REDIRECT, (WPARAM)pBrowser, (LPARAM)lBstrUrl.Detach()); } #ifdef ALLOW_PDF_FILE HRESULT TBaseWebBrowserPageletCtrl::CheckPDFFile() { if (m_PdfObject) return S_OK; CComQIPtr lCollec; CComQIPtr lEmbedElement; CComPtr lDispatch; CComQIPtr lDocument; HRESULT lResult; long lIndex = 0; long lLength = 1; if (!m_BrowserTree) return E_FAIL; lResult = m_BrowserTree->get_Document(&lDispatch); lDocument = lDispatch; lDispatch = NULL; ASSERT(SUCCEEDED(lResult) && lDocument); if (FAILED(lResult) || (lDocument == NULL)) return E_FAIL; #ifdef _DEBUG CComPtr lBodyElem; CComBSTR lSrc; lResult = lDocument->get_body(&lBodyElem); if (lBodyElem) lResult = lBodyElem->get_outerHTML(&lSrc); #endif // CComPtr lCollec; lResult = lDocument->get_all(&lCollec); ASSERT(SUCCEEDED(lResult) && lCollec); if (FAILED(lResult) || (lCollec == NULL)) return E_FAIL; lResult = lCollec->tags(CComVariant("EMBED"), &lDispatch); lCollec.Release(); lResult = lDispatch->QueryInterface(&lCollec); if (SUCCEEDED(lResult) && lCollec) { lResult = lCollec->get_length(&lLength); ASSERT(SUCCEEDED(lResult)); } while (lIndex < lLength) { if (lCollec) { lDispatch = NULL; lResult = lCollec->item(CComVariant(lIndex), CComVariant(), &lDispatch); lEmbedElement = lDispatch; lDispatch = NULL; ASSERT(SUCCEEDED(lResult) && lEmbedElement); } if (SUCCEEDED(lResult) && lEmbedElement) { m_PdfObject = lEmbedElement; // CComVariant lValue; // lResult = m_PdfObject.GetPropertyByName(L"src", &lValue); // lResult = m_PdfObject.Invoke0(L"gotoLastPage"); // CComVariant lZoomValue("content"); // lResult = m_PdfObject.Invoke1(L"setView", &lZoomValue); // CComVariant lShowToolbarValue(FALSE); // lResult = m_PdfObject.Invoke1(L"setShowToolbar", &lShowToolbarValue); return S_OK; } lIndex++; } return S_OK; } #endif // ALLOW_PDF_FILE/*------------ TInternalProtocol.cpp ------------*/ // TInternalProtocol.cpp : Implementation of TInternalProtocol #include "StdAfx.h" #include "ProductName.h" #include "TInternalProtocol.h" #include "TNetGlobals.h" #include "TNetUtils.h" #include "TNetHelpers.h" #include "TInteger.h" #include "TSevenixUrl.h" #include "TSevenixUrlInfo.h" #include "TLanguage.h" #include "TLookAndFeel.h" #include "THTMLString.h" #include "TGlobalResource.h" #include "TRegKey.h" #include "TAppInfo.h" #include "TErr.h" #include "Branding.h" #define _MIDL_USE_GUIDDEF_ #include "Branding_i.c" ///////////////////////////////////////////////////////////////////////////// // TInternalProtocol // // Constructor of the protocol class // TInternalProtocol::TInternalProtocol() { m_Data = NULL; } // // Destructor of the protocol class // TInternalProtocol::~TInternalProtocol() { if (m_Data) delete m_Data; } // ========================================================================== // // Description: // It's a function Description comment // // Inputs: // wstrURLIn - Url to parse // // Return Value: // It's the function return value comment // // Remarks: // It's the Remarks comment // HRESULT TInternalProtocol::OnParse(LPCWSTR wstrURLIn) { wchar_t* pPathStart; int len; int lCompare; HRESULT hr = S_OK; // default is success // Remove everything preceding first ":" pPathStart = wcschr(wstrURLIn, ':'); if (NULL != pPathStart) { pPathStart++; len = pPathStart - wstrURLIn - 1; lCompare = wcsncmp(L"internal", wstrURLIn, len); } else { pPathStart = (LPWSTR)wstrURLIn; lCompare = -1; } // Dummy Check - shouldn't ever fail this ASSERT(lCompare == 0); if (lCompare == 0) { m_SubUrl = pPathStart; m_Url = wstrURLIn; } else hr = INET_E_UNKNOWN_PROTOCOL; return hr; } #define T_DLL_REDIRECT 1 #define T_FILE_REDIRECT 2 #define T_URL_REDIRECT 3 // ========================================================================== // // Description: // It's a function Description comment // // Return Value: // It's the function return value comment // // Remarks: // It's the Remarks comment // HRESULT TInternalProtocol::OnStart() { USES_CONVERSION; m_CurrentRead = 0; long lRedirect = 0; CString lDll; CString lFile; CComBSTR lSubSection; long lSize = 0; CString lNewUrl; // TErr::trace(TErr::D_LOG, TErr::G_INF, TErr::NO_ID, "Internal", __LINE__, W2CT(m_Url)); // // - First Web redirect // lSubSection = "//web/"; if (!lRedirect && !wcsncmp(lSubSection, m_SubUrl, lSubSection.Length())) { TAppInfo lInfo; lNewUrl = lInfo.BuildKeeBooWebUrl("/" + CString(m_SubUrl + lSubSection.Length())); lRedirect = T_URL_REDIRECT; } // // - Registery Hook // if (!lRedirect && CheckHook(lNewUrl)) lRedirect = T_URL_REDIRECT; // // - Best match // does not work under IE 4 // lSubSection = "///"; if (!lRedirect && !wcsncmp(lSubSection, m_SubUrl, lSubSection.Length())) { lSize = lSubSection.Length(); lRedirect = T_DLL_REDIRECT; } lSubSection = "//language/"; if (!lRedirect && !wcsncmp(lSubSection, m_SubUrl, lSubSection.Length())) { TLanguage::GetCurrentLanguageDllPath(lDll); lSize = lSubSection.Length(); lRedirect = T_DLL_REDIRECT; } lSubSection = "//skin/"; if (!lRedirect && !wcsncmp(lSubSection, m_SubUrl, lSubSection.Length())) { TLookAndFeel::GetCurrentLookAndFeelDllPath(lDll); lSize = lSubSection.Length(); lRedirect = T_DLL_REDIRECT; } #ifdef _DEBUG lSubSection = "//look/"; if (!lRedirect && !wcsncmp(lSubSection, m_SubUrl, lSubSection.Length())) { // // We shouldn't have this type of url !!! // Please locate it and rename it to "skin" // ASSERT(NULL); TLookAndFeel::GetCurrentLookAndFeelDllPath(lDll); lSize = lSubSection.Length(); lRedirect = T_DLL_REDIRECT; } #endif lSubSection = "//neutral/"; if (!lRedirect && !wcsncmp(lSubSection, m_SubUrl, lSubSection.Length())) { TLanguage::GetNeutralLanguageDllPath(lDll); lSize = lSubSection.Length(); lRedirect = T_DLL_REDIRECT; } lSubSection = "//branding/"; if (!lRedirect && !wcsncmp(lSubSection, m_SubUrl, lSubSection.Length())) { CComPtr lBrandingInfo; lBrandingInfo.CoCreateInstance(CLSID_TBrandingInfo); ATLASSERT(lBrandingInfo); if (lBrandingInfo) { CComBSTR lPath; lBrandingInfo->get_BrandingFullPath(&lPath); lDll = lPath; lSize = lSubSection.Length(); lRedirect = T_DLL_REDIRECT; } } lSubSection = "//help"; if (!lRedirect && !wcsncmp(lSubSection, m_SubUrl, lSubSection.Length())) { if (GetItsUrl(m_SubUrl + lSubSection.Length(), lNewUrl)) lRedirect = T_URL_REDIRECT; } lSubSection = "//cache/"; if (!lRedirect && !wcsncmp(lSubSection, m_SubUrl, lSubSection.Length())) { return LoadCacheData(); } switch (lRedirect) { case T_DLL_REDIRECT: return LoadDllData(CComBSTR(lDll), CComBSTR((LPCWSTR)m_SubUrl + lSize)); case T_FILE_REDIRECT: return LoadFileData(CComBSTR(lFile)); case T_URL_REDIRECT: return RedirectTo(lNewUrl); } return RedirectTo("about:NavigationCanceled"); } BOOL TInternalProtocol::GetItsUrl(BSTR pSubUrl, CString& pNewUrl) { TAppInfo lInfo; CComBSTR lSubSection; CString lPath; BOOL lFound = TRUE; pNewUrl = "its:"; if (pSubUrl[0] == L':') { lSubSection = ":starting/"; if (!wcsncmp(lSubSection, pSubUrl, lSubSection.Length())) lPath = lInfo.GetGettingStartedFilePath(); else { lSubSection = ":welcome/"; if (!wcsncmp(lSubSection, pSubUrl, lSubSection.Length())) lPath = lInfo.GetWelcomeFilePath(); else lFound = FALSE; } } else lPath = lInfo.GetHelpFilePath(); if (lFound) { pNewUrl += lPath; ::PathRemoveFileSpec(lPath.GetBuffer(0)); lPath.ReleaseBuffer(); ::SetCurrentDirectory(lPath); pNewUrl += "::" + CString(pSubUrl).Mid(lSubSection.Length() - 1); } return lFound; } BOOL TInternalProtocol::IsHooked() { CString lNewUrl; return CheckHook(lNewUrl); } BOOL TInternalProtocol::CheckHook(CString& pNewUrl) { USES_CONVERSION; TRegKey lKey; TRegKey lKey2; DWORD result; // Open PROTOCOLS\Handler key result = lKey.Open(HKEY_CURRENT_USER, _T(KEEBOO_NET_REGISTRY_NAME"\\Protocols\\Hooks"), KEY_READ); if (result != ERROR_SUCCESS) return FALSE; // Open PROTOCOLS\Handler\xxx key result = lKey2.Open(lKey, "internal", KEY_READ); if (result != ERROR_SUCCESS) return FALSE; CString lResName(m_SubUrl); LONG lPos; lPos = lResName.Find('?'); if (lPos != -1) lResName = lResName.Mid(0, lPos); result = lKey2.QueryValue(pNewUrl, lResName); if (result != ERROR_SUCCESS) return FALSE; return TRUE; } // ========================================================================== // // Description: // It's a function Description comment // // Inputs: // szParam1 - It's a function first parameter comment // nParam2 - It's a function second parameter comment // // Return Value: // It's the function return value comment // // Remarks: // It's the Remarks comment // HRESULT TInternalProtocol::LoadFileData(BSTR pFile) { USES_CONVERSION; HRESULT lResult; CFile lFile; lResult = E_FAIL; if (lFile.Open(W2CT(pFile), CFile::modeRead)) { DWORD lSize; DWORD lRead; LPBYTE lData; lSize = lFile.GetLength(); lData = new BYTE[lSize]; lRead = lFile.Read(lData, lSize); ASSERT(lRead == lSize); SetData(lData, lRead, FALSE); lResult = AllDataAvailable(); } return lResult; } HRESULT TInternalProtocol::LoadDllData(BSTR pDll, BSTR pData) { if (pData == NULL || *pData == 0) return S_FALSE; USES_CONVERSION; HRESULT lResult; HMODULE lModule; HRSRC lResource; LPCTSTR lData; HGLOBAL lGlobal; BOOL lLoadedDll; // long lSize; long lNum; long lRscSize; lData = W2CT(pData); CString lResName(lData); LONG lPos; lPos = lResName.Find('?'); if (lPos != -1) lResName = lResName.Mid(0, lPos); lData = lResName.GetBuffer(0); lNum = atoi(lData); if (lNum) lData = (LPCTSTR)lNum; else if (lData[0] == '&') lData = (LPCTSTR)atoi(lData + 1); if (wcslen(pDll) == 0) { lModule = KBFindResourceHandle(lData, RT_HTML); lLoadedDll = FALSE; } else { lModule = ::LoadLibrary(W2CT(pDll)); lLoadedDll = TRUE; } ASSERT(lModule); if (lModule == NULL) return E_FAIL; lResource = ::FindResource(lModule, lData, RT_HTML); ATLASSERT(lResource != NULL); if (lResource != NULL) { lGlobal = ::LoadResource(lModule, lResource); ATLASSERT(lGlobal != NULL); if (lGlobal != NULL) { lRscSize = ::SizeofResource(lModule, lResource); LPBYTE lSource = new BYTE[lRscSize + 1]; memcpy(lSource, ::LockResource(lGlobal), lRscSize); lSource[lRscSize] = 0; SetData(lSource, lRscSize); delete lSource; if (lLoadedDll) ::FreeLibrary(lModule); lResult = AllDataAvailable(); return S_OK; } } if (lLoadedDll) ::FreeLibrary(lModule); return RedirectTo("about:NavigationCanceled"); } HRESULT TInternalProtocol::LoadCacheData() { CComPtr lEntry; // Get Cache Entry if (SUCCEEDED(CacheGetEntry(m_Url, T_NETWORK_CACHE_NAME, &lEntry, T_CACHE_BEST_ELEMENT))) { CComBSTR lFileName; // Get Cache File if (SUCCEEDED(lEntry->getFileName(&lFileName))) return LoadFileData(lFileName); } return E_FAIL; } void TInternalProtocol::SetData(LPBYTE pData, DWORD dwSize, BOOL pFormatAllowed) { HRESULT lResult; LPWSTR lSugestion; m_Data = new CByteArray(); lResult = FindMimeFromData(NULL, NULL, pData, dwSize, L"text/html", 0, &lSugestion, 0); if (SUCCEEDED(lResult) && pFormatAllowed && !wcsncmp(L"text/", lSugestion, 5)) { THTMLString lString; lString.StdFormat((LPCTSTR)pData); LONG lSize; lSize = lString.GetLength(); m_Data->SetSize(lSize); memcpy(m_Data->GetData(), lString.GetBuffer(0), lSize); lString.ReleaseBuffer(); dwSize = lSize; // m_ErrorHtmlString = lString; } else { m_Data->SetSize(dwSize); memcpy(m_Data->GetData(), pData, dwSize); } m_TotalSize = dwSize; lResult = ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, lSugestion); // m_MimeType = lSugestion; } HRESULT TInternalProtocol::OnAbort(HRESULT hrReason, DWORD dwOptions) { return S_PROXY_CALL; } HRESULT TInternalProtocol::OnTerminate(DWORD dwOptions) { return S_PROXY_CALL; } HRESULT TInternalProtocol::OnSuspend() { return S_PROXY_CALL; } HRESULT TInternalProtocol::OnResume() { return S_PROXY_CALL; } HRESULT TInternalProtocol::OnContinue(PROTOCOLDATA *pProtocolData) { return S_PROXY_CALL; } HRESULT TInternalProtocol::OnRead(void *pData, ULONG pToRead, ULONG* pReaded) { if (IsProxy()) return S_PROXY_CALL; if ((m_CurrentRead >= m_TotalSize) || (m_Data == NULL)) return S_FALSE; ULONG lToRead = min(m_TotalSize - m_CurrentRead, pToRead); memcpy(pData, m_Data->GetData() + m_CurrentRead, lToRead); *pReaded = lToRead; m_CurrentRead += lToRead; return S_OK; } HRESULT TInternalProtocol::OnLock(DWORD) { return S_PROXY_CALL; } HRESULT TInternalProtocol::OnUnlock() { return S_PROXY_CALL; } HRESULT TInternalProtocol::OnSeek(LARGE_INTEGER , DWORD , ULARGE_INTEGER*) { // Cannot seek yet ASSERT(NULL); return E_NOTIMPL; } HRESULT TInternalProtocol::OnParseUrl(LPCWSTR pwzUrl, PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved) { return E_NOTIMPL; } HRESULT TInternalProtocol::OnCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved) { ASSERT(pcchResult); if (pcchResult == NULL) return E_INVALIDARG; #ifdef _DEBUG CString lFlagsString; if (dwCombineFlags & ICU_BROWSER_MODE) lFlagsString += "Browser Mode, "; if (dwCombineFlags & ICU_ENCODE_SPACES_ONLY) lFlagsString += "Encode Spaces Only, "; if (dwCombineFlags & ICU_NO_ENCODE) lFlagsString += "No Encode, "; if (dwCombineFlags & ICU_NO_META) lFlagsString += "No Meta, "; #endif LPCWSTR lScheme = pwzRelativeUrl; while (iswalpha(*lScheme)) lScheme++; if ((*lScheme == ':') && (lScheme != pwzRelativeUrl)) { wcscpy(pwzResult, pwzRelativeUrl); *pcchResult = wcslen(pwzResult) + 1; return S_OK; } OnParse(pwzBaseUrl); LPCWSTR lStop = m_SubUrl; long lIndex = -1; if (*pwzRelativeUrl == '/') { lIndex = 3; pwzRelativeUrl++; } while (lIndex) { PCWSTR lNewStop; PCWSTR lDieseStop; PCWSTR lQuestionStop; lNewStop = wcschr(lStop, '/'); lDieseStop = wcschr(lStop, '#'); lQuestionStop = wcschr(lStop, '?'); if (lDieseStop) lNewStop = lDieseStop > lNewStop ? lNewStop : NULL; if (lQuestionStop) lNewStop = lQuestionStop > lNewStop ? lNewStop : NULL; lIndex--; if (lNewStop == NULL) lIndex = 0; else { lStop = lNewStop; lStop++; } } *pcchResult = 9 + (lStop - m_SubUrl) + (wcslen(pwzRelativeUrl) + 1); if (cchResult < *pcchResult) return S_FALSE; wcscpy(pwzResult, L"internal:"); wcsncat(pwzResult, m_SubUrl, (lStop - m_SubUrl)); wcscat(pwzResult, pwzRelativeUrl); return S_OK; } HRESULT TInternalProtocol::OnCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags) { return E_NOTIMPL; } HRESULT TInternalProtocol::OnQueryUrlInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved) { if (QueryOption == QUERY_USES_NETWORK) { if (wcsstr(pwzUrl, L"//web/")) *(BOOL*)pBuffer = TRUE; else *(BOOL*)pBuffer = FALSE; *pcbBuf = cbBuffer; return S_OK; } /* if (QueryOption == QUERY_IS_SECURE) { *(BOOL*)pBuffer = TRUE; *pcbBuf = cbBuffer; return S_OK; } */ return E_NOTIMPL; } HRESULT TInternalProtocol::OnQueryHttpInfo(DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,DWORD *pdwReserved) { return E_NOTIMPL; } HRESULT TInternalProtocol::OnQueryOption(DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf) { return E_NOTIMPL; } HRESULT TInternalProtocol::OnReportData(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) { return E_NOTIMPL; } HRESULT TInternalProtocol::OnReportProgress(ULONG ulStatusCode, LPCWSTR szStatusText) { return E_NOTIMPL; } HRESULT TInternalProtocol::OnReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { return E_NOTIMPL; } HRESULT TInternalProtocol::OnSwitch(PROTOCOLDATA *pPROTOCOLDATA) { return E_NOTIMPL; } HRESULT TInternalProtocol::OnQueryService(REFGUID guidService, REFIID riid, void** ppvObject) { return E_NOTIMPL; } HRESULT TInternalProtocol::OnError(HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { return E_NOTIMPL; }/*------------ TInternetProtocol.cpp ------------*/ // TInternetProtocol.cpp : Implementation of TInternetProtocol #include "StdAfx.h" #include "xstddef" #pragma warning(disable: 4663) #pragma warning(disable: 4244) #pragma warning(disable: 4018) #include using namespace std ; #include "TNetDebug.h" #include "TInternetProtocol.h" #include "TNetGlobals.h" #include "TNetHelpers.h" #include "TNetUtils.h" #include "THTMLString.h" #include "TErr.h" #include "atlconv.h" #include "SharedResource.h" DWORD TInternetProtocol::gNbConnection = 0; DWORD TInternetProtocol::gProtocolInstance = 0; BOOL TInternetProtocol::gBlockingState = FALSE; #ifdef _DEBUG list* gList2 = NULL; #endif #ifndef RT_HTML #define RT_HTML MAKEINTRESOURCE(23) #endif #ifdef _DEBUG class TGlobalUninit2 { public: ~TGlobalUninit2(); }; TGlobalUninit2::~TGlobalUninit2() { if (gList2) { if (gList2->size()) { TRACE(_T("Protocol Instance Left: %d\n"), gList2->size()); /* list::iterator lIterator = gList2->begin(); while (lIterator != gList2->end()) { TInternetProtocol* lProtocol = (TInternetProtocol*)*lIterator; lProtocol->Dump(); lIterator++; } */ } delete gList2; } } TGlobalUninit2 gGlobalTruc2; #endif ///////////////////////////////////////////////////////////////////////////// // TInternetProtocol // // Constructor of the protocol class // TInternetProtocol::TInternetProtocol() : m_FirstRead(TRUE), m_IsLocked(FALSE), m_DoNotLoad(FALSE), m_HaveAbort(FALSE), m_HaveReportResult(FALSE), m_HandleError(FALSE), m_IsTerminate(FALSE), m_UsedForInfo(FALSE), m_IsProxy(FALSE), m_IsPending(FALSE), m_TotalSize(0), m_CurrentProgress(0), m_CurrentRead(0), m_ThreadId(0), // m_StatusCode(0), m_ErrorState(S_OK) { #ifdef DEBUG_PROTOCOL // For Debug // m_BlockingState = gBlockingState; // gBlockingState = m_BlockingState; m_BlockingState = FALSE; gBlockingState = m_BlockingState; if (gBlockingState) DumpAll(); #endif gProtocolInstance++; #ifdef _DEBUG if (gList2 == NULL) gList2 = new list(); gList2->push_back(this); #endif } // // Destructor of the protocol class // TInternetProtocol::~TInternetProtocol() { // ASSERT(m_IsTerminate); gProtocolInstance--; #ifdef _DEBUG gList2->remove(this); if (gList2->size() == 0) { delete gList2; gList2 = NULL; } #endif if (m_StubProtocol != NULL) { InterlockedDecrement((LONG*)&gNbConnection); m_StubProtocol.Release(); } } HRESULT WINAPI TInternetProtocol::InternalQuery(void* pv, REFIID riid, LPVOID* ppv, DWORD dw) { TInternetProtocol* pThis = (TInternetProtocol*)pv; *ppv = NULL; // if (pThis->IsInfoSupplier()) { if (riid == IID_IInternetProtocolInfo) { *ppv = (IInternetProtocolInfo*)pThis; ((IInternetProtocolInfo*)pThis)->AddRef(); return S_OK; } if (riid == IID_IWinInetInfo) { *ppv = (IWinInetInfo*)pThis; ((IWinInetInfo*)pThis)->AddRef(); return S_OK; } } if (pThis->IsProxy()) { if (riid == IID_IInternetBindInfo) { *ppv = (IInternetBindInfo*)pThis; ((IInternetBindInfo*)pThis)->AddRef(); return S_OK; } if (riid == IID_IInternetProtocolSink) { *ppv = (IInternetProtocolSink*)pThis; ((IInternetProtocolSink*)pThis)->AddRef(); return S_OK; } /* ASSERT(pThis->m_StubProtocol); if (pThis->m_StubProtocol != NULL) { return pThis->m_StubProtocol->QueryInterface(riid, ppv); } */ } return S_FALSE; } LONG TInternetProtocol::TranslateError(HRESULT hrResult, DWORD dwError) { static LONG gErrorTranslationTable[] = { INET_E_INVALID_URL, 0, IDR_HTML_PROTOCOL_INVALID_URL, INET_E_NO_SESSION, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_CANNOT_CONNECT, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_RESOURCE_NOT_FOUND, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_OBJECT_NOT_FOUND, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_DATA_NOT_AVAILABLE, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_DOWNLOAD_FAILURE, 0, IDR_HTML_PROTOCOL_DOWNLOAD_FAILURE, INET_E_AUTHENTICATION_REQUIRED, 0, 0, INET_E_NO_VALID_MEDIA, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_CONNECTION_TIMEOUT, 0, IDR_HTML_PROTOCOL_CONNECTION_TIMEOUT, INET_E_INVALID_REQUEST, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_UNKNOWN_PROTOCOL, 0, IDR_HTML_PROTOCOL_UNKNOWN, CLASS_E_CLASSNOTAVAILABLE, 0, IDR_HTML_PROTOCOL_UNKNOWN, INET_E_SECURITY_PROBLEM, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_CANNOT_LOAD_DATA, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_CANNOT_INSTANTIATE_OBJECT, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_REDIRECT_FAILED, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, INET_E_REDIRECT_TO_DIR, 0, 0, INET_E_CANNOT_LOCK_REQUEST, 0, IDR_HTML_PROTOCOL_GENERIC_ERROR, E_ABORT, 0, 0, }; for (long lIndex = 0; lIndex < sizeof(gErrorTranslationTable) / sizeof(LONG); lIndex += 3) { if (gErrorTranslationTable[lIndex] == hrResult) { if ((gErrorTranslationTable[lIndex + 1] == 0) || (gErrorTranslationTable[lIndex + 1] == dwError)) return gErrorTranslationTable[lIndex + 2]; } } return 0; } HRESULT TInternetProtocol::HandleError(HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { LONG lErrorID; HRESULT lResult; #ifdef DEBUG_PROTOCOL // we do not use the protocol // if (fID) // InterlockedDecrement((LONG*)&gNbConnection); #endif m_ErrorState = hrResult; lErrorID = TranslateError(hrResult, dwError); if (lErrorID == 0) { m_HandleError = FALSE; return S_FALSE; } if (m_StubProtocol) { m_HandleError = TRUE; m_StubProtocol->LockRequest(0); m_StubProtocol->Terminate(0); m_StubProtocol->UnlockRequest(); m_StubProtocol.Release(); } if (m_CurrentRead != 0) return hrResult; if (m_SupSink == NULL) return hrResult; m_HandleError = TRUE; ASSERT(m_CurrentRead == 0); m_CurrentRead = 0; THTMLString lErrorString; if ((szResult) || (lErrorID == IDR_HTML_PROTOCOL_GENERIC_ERROR)) { lErrorString.StdFormat(lErrorID, hrResult, (LPCTSTR)CString(szResult)); } else { lErrorString.StdFormat(lErrorID); } m_ErrorHtmlString = lErrorString; ASSERT(m_SupSink); lResult = m_SupSink->ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, L"text/html"); m_TotalSize = m_ErrorHtmlString.GetLength(); lResult = AllDataAvailable(); return lResult; } HRESULT TInternetProtocol::AllDataAvailable() { HRESULT lResult = E_FAIL; // All the data is here... we won't notify again if (m_SupSink) lResult = m_SupSink->ReportData(BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE | BSCF_LASTDATANOTIFICATION, m_TotalSize, m_TotalSize); // This occured on 'application/octet-stream' // ie, when the Dialog Save As open if (m_SupSink == NULL) return S_OK; BSTR lErrorString = NULL; if (lResult != S_OK) { lResult = INET_E_DOWNLOAD_FAILURE; lErrorString = L"ReportData Error"; } lResult = m_SupSink->ReportResult(lResult, 0, lErrorString); return lResult; } HRESULT TInternetProtocol::RedirectTo(CString pUrl) { CComPtr lStubProtocol; TUrl lUrl(pUrl); CString lScheme; HRESULT lResult; m_Url = pUrl; lScheme = lUrl.getScheme(); lResult = CreateInstanceForProtocol(A2CT(lScheme), IID_IInternetProtocol, (void**)&lStubProtocol); ASSERT(lResult == S_OK); if (FAILED(lResult)) return lResult; return ProxyTo(lStubProtocol); } #ifdef _DEBUG void TInternetProtocol::Dump() { CString lDumpMessage; CString lDumpMsgEnd; lDumpMessage.FormatMessage("\nTInternetProtocol(0x%1!x!):\n\ - Instance=%2!d!\n\ - Url: %3!s!\n\n", this, fID, (LPCTSTR)CString(m_Url)); if (m_UsedForInfo) { lDumpMessage += " ----------------------------\n"; TRACE(lDumpMessage); return ; } if (!(m_dwRef & 0xFFFF0000)) { lDumpMsgEnd.FormatMessage(" - Count Ref=%1!d!\n", m_dwRef); lDumpMessage += lDumpMsgEnd; } if (m_ErrorState != S_OK) { lDumpMsgEnd.FormatMessage(" - Error State: 0x%1!x!\n", m_ErrorState); lDumpMessage += lDumpMsgEnd; } lDumpMsgEnd.FormatMessage("%1!s!%2!s!%3!s!%4!s!%5!s!", (!m_IsTerminate && m_FirstRead ? CString(" * First Read\n") : CString("")), (m_IsLocked ? CString(" * Is Locked\n") : CString("")), (!m_HaveAbort && m_IsTerminate ? CString(" * Is Terminate\n") : CString("")), (!m_IsTerminate && m_IsPending ? CString(" * Is Pending\n") : CString("")), (m_HaveAbort ? CString(" * Have Abort\n") : CString(""))); if (m_DoNotLoad) lDumpMsgEnd += " * Do Not Load\n"; /* if (fLocalFile) lDumpMsgEnd += CString(" - Local File: ") + fLocalFile->GetFileName() + "\n"; */ lDumpMessage += lDumpMsgEnd; // Stub Protocol if (m_StubProtocol) { lDumpMsgEnd.FormatMessage(" - Stub Protocol (0x%1!x!)\n", m_StubProtocol); lDumpMessage += lDumpMsgEnd; } /* if (m_StubHttpInfo) { lDumpMsgEnd.FormatMessage(" - HTTP Stub Info (0x%1!x!)\n", m_StubHttpInfo); lDumpMessage += lDumpMsgEnd; } */ if (fAddedHeader.GetLength()) { lDumpMsgEnd.FormatMessage(" - HTTP Added Headers: %1!s!\n", fAddedHeader); lDumpMessage += lDumpMsgEnd; } /* if (fStatusCode) { lDumpMsgEnd.FormatMessage(" - HTTP Result Status Code: %1!d!\n", fStatusCode); lDumpMessage += lDumpMsgEnd; } */ #ifdef DEBUG_PROTOCOL if (m_TotalSize) { lDumpMsgEnd.FormatMessage(" - Total Size: %1!d!\n", m_TotalSize); lDumpMessage += lDumpMsgEnd; } if (m_CurrentProgress) { lDumpMsgEnd.FormatMessage(" - Current Progress: %1!d!\n", m_CurrentProgress); lDumpMessage += lDumpMsgEnd; } #endif DEBUG_PROTOCOL // UrlMon if (m_SupSink) { lDumpMsgEnd.FormatMessage(" - Sup Sink (0x%1!x!)\n", m_SupSink); lDumpMessage += lDumpMsgEnd; } if (m_SupBindInfo) { lDumpMsgEnd.FormatMessage(" - Sup Bind Info (0x%1!x!)\n", m_SupBindInfo); lDumpMessage += lDumpMsgEnd; } // DWORD fBindFlag; // BINDINFO fBindInfo; // Cache /* lDumpMsgEnd.FormatMessage(" - Cache Entry %1!s!Available\n", (m_CacheEntryAvailable ? CString("") : CString("Not "))); lDumpMessage += lDumpMsgEnd; if (m_CacheEntryAvailable) { lDumpMsgEnd.FormatMessage(" - Originale Cache Entry (0x%1!x!)\n", m_CurrentCacheEntry); lDumpMessage += lDumpMsgEnd; } if (fFromFilterCache) { lDumpMsgEnd.FormatMessage(" - Cache Entry From Filter\n"); lDumpMessage += lDumpMsgEnd; } lDumpMsgEnd.FormatMessage(" - New Cache Entry %1!s!Checked\n", (m_NewEntryChecked ? CString("") : CString("Not "))); lDumpMessage += lDumpMsgEnd; */ /* if (m_NewEntryChecked) { lDumpMsgEnd.FormatMessage(" - New Cache Entry (0x%1!x!)\n", m_NewCacheEntry); lDumpMessage += lDumpMsgEnd; } */ // DWORD m_ThreadId; // DWORD m_GrfPI; #ifdef DEBUG_PROTOCOL // Just for Debug !!! // BOOL m_BlockingState:2; #endif lDumpMessage += " ----------------------------\n"; TRACE(lDumpMessage); // TErr::setLogMaxMessage(-1); // TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, lDumpMessage); } void TInternetProtocol::DumpAll() { if (gProtocolInstance && gList2) { TErr::trace(TErr::D_LOG | TErr::D_OUT, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, _T("\n *** Protocol Instance Left: %1!d! ***\n\n"), gProtocolInstance); list::iterator lIterator = gList2->begin(); while (lIterator != gList2->end()) { TInternetProtocol* lProtocol = (TInternetProtocol*)*lIterator; lProtocol->Dump(); lIterator++; } } } #endif _DEBUG/*------------ TInternetProtocol.h ------------*/ // TInternetProtocol.h : Declaration of the TInternetProtocol #ifndef T_INTERNET_PROTOCOL #define T_INTERNET_PROTOCOL #include "Net.h" #include "TUrl.h" #define S_PROXY_CALL MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_ITF, 0x400) ///////////////////////////////////////////////////////////////////////////// // TInternetProtocol //template class ATL_NO_VTABLE TInternetProtocol : public CComObjectRootEx, public IInternet, public IInternetProtocol, public IInternetProtocolSink, public IInternetPriority, public IServiceProvider, public IInternetProtocolInfo, public IInternetBindInfo, public IWinInetInfo { friend class TGlobalUninit; public: TInternetProtocol(); virtual ~TInternetProtocol(); BEGIN_COM_MAP(TInternetProtocol) COM_INTERFACE_ENTRY(IInternet) COM_INTERFACE_ENTRY2(IUnknown, IInternet) COM_INTERFACE_ENTRY_FUNC_BLIND(0, InternalQuery) COM_INTERFACE_ENTRY(IInternetProtocolRoot) COM_INTERFACE_ENTRY(IInternetProtocol) COM_INTERFACE_ENTRY(IInternetPriority) COM_INTERFACE_ENTRY(IServiceProvider) // If Proxy COM_INTERFACE_ENTRY_FUNC(IID_IInternetBindInfo, 0, InternalQuery) COM_INTERFACE_ENTRY_FUNC(IID_IInternetProtocolSink, 0, InternalQuery) // If Info supply COM_INTERFACE_ENTRY_FUNC(IID_IInternetProtocolInfo, 0, InternalQuery) COM_INTERFACE_ENTRY_FUNC(IID_IWinInetInfo, 0, InternalQuery) END_COM_MAP() static HRESULT WINAPI InternalQuery(void* pv, REFIID riid, LPVOID* ppv, DWORD dw); // IInternetProtocolRoot STDMETHOD(Start)(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, DWORD dwReserved); STDMETHOD(Continue)(PROTOCOLDATA *pProtocolData); STDMETHOD(Abort)(HRESULT hrReason, DWORD dwOptions); STDMETHOD(Terminate)(DWORD dwOptions); STDMETHOD(Suspend)(); STDMETHOD(Resume)(); // IInternetProtocol : public IInternetProtocolRoot STDMETHOD(Read)(void *pv, ULONG cb, ULONG *pcbRead); STDMETHOD(Seek)(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition); STDMETHOD(LockRequest)(DWORD dwOptions); STDMETHOD(UnlockRequest)(); // IInternetProtocolInfo STDMETHOD(ParseUrl)(LPCWSTR pwzUrl, PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved); STDMETHOD(CombineUrl)(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved); STDMETHOD(CompareUrl)(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags); STDMETHOD(QueryInfo)(LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved); // IWininetInfo STDMETHOD(QueryOption)(DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf); // IInternetPriority STDMETHOD(SetPriority)(LONG nPriority); STDMETHOD(GetPriority)(LONG *pnPriority); // IInternetBindInfo STDMETHOD(GetBindInfo)(DWORD *grfBINDF, BINDINFO *pbindinfo); STDMETHOD(GetBindString)(ULONG ulStringType, LPOLESTR *ppwzStr, ULONG cEl, ULONG *pcElFetched); // IServiceProvider STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void** ppvObject); // IInternetProtocolSink STDMETHOD(ReportData)(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax); STDMETHOD(ReportProgress)(ULONG ulStatusCode, LPCWSTR szStatusText); STDMETHOD(ReportResult)(HRESULT hrResult, DWORD dwError, LPCWSTR szResult); STDMETHOD(Switch)(PROTOCOLDATA *pPROTOCOLDATA); virtual HRESULT OnRead(void *, ULONG , ULONG*); virtual HRESULT OnLock(DWORD); virtual HRESULT OnUnlock(); virtual HRESULT OnSeek(LARGE_INTEGER , DWORD , ULARGE_INTEGER*); virtual HRESULT OnStart(); virtual HRESULT OnAbort(HRESULT , DWORD ); virtual HRESULT OnTerminate(DWORD ); virtual HRESULT OnSuspend(); virtual HRESULT OnResume(); virtual HRESULT OnContinue(PROTOCOLDATA*); virtual HRESULT OnParseUrl(LPCWSTR pwzUrl, PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved); virtual HRESULT OnCombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved); virtual HRESULT OnCompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags); virtual HRESULT OnQueryUrlInfo(LPCWSTR pwzUrl, QUERYOPTION OueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD *pcbBuf, DWORD dwReserved); virtual HRESULT OnQueryHttpInfo(DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,DWORD *pdwReserved); virtual HRESULT OnQueryOption(DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf); virtual HRESULT OnReportData(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax); virtual HRESULT OnReportProgress(ULONG ulStatusCode, LPCWSTR szStatusText); virtual HRESULT OnReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR szResult); virtual HRESULT OnSwitch(PROTOCOLDATA *pPROTOCOLDATA); virtual HRESULT OnParse(LPCWSTR); virtual HRESULT OnError(HRESULT hrResult, DWORD dwError = 0, LPCWSTR szResult = NULL); virtual HRESULT OnQueryService(REFGUID guidService, REFIID riid, void** ppvObject); HRESULT RedirectTo(CString pUrl); HRESULT ProxyTo(IInternetProtocol* ); HRESULT GetStubProtocol(IInternetProtocol** ); BOOL IsPending(); BOOL IsTerminate(); BOOL IsAborted(); BOOL IsProxy(); BOOL IsLocked(); #ifdef _DEBUG void Dump(); void DumpAll(); #endif _DEBUG static DWORD gProtocolInstance; static BOOL gBlockingState; protected: HRESULT HandleError(HRESULT hrResult, DWORD dwError, LPCWSTR szResult); LONG TranslateError(HRESULT hrResult, DWORD dwError); HRESULT AllDataAvailable(); static DWORD WINAPI threadEntryPoint(LPVOID pData); static DWORD gNbConnection; static DWORD gID; DWORD m_ThreadId; DWORD m_GrfPI; BOOL m_IsProxy:2; BOOL m_IsTerminate:2; BOOL m_HaveAbort:2; BOOL m_IsPending:2; BOOL m_IsLocked:2; // UrlMon CComPtr m_SupSink; CComPtr m_SupBindInfo; // Stub Protocol CComQIPtr m_StubProtocol; CComQIPtr m_StubProtocolInfo; CComQIPtr m_StubInfo; CComBSTR m_SubUrl; CComBSTR m_Url; CString fAddedHeader; CString m_ErrorHtmlString; DWORD fID; HRESULT m_ErrorState; DWORD m_TotalSize; DWORD m_CurrentProgress; DWORD m_CurrentRead; BOOL m_FirstRead:2; BOOL m_HaveReportResult:2; BOOL m_HandleError:2; BOOL m_DoNotLoad:2; BOOL m_UsedForInfo:2; #ifdef DEBUG_PROTOCOL // Just for Debug !!! BOOL m_BlockingState:2; #endif }; inline BOOL TInternetProtocol::IsPending() { return m_IsPending; } inline BOOL TInternetProtocol::IsTerminate() { return m_IsTerminate; } inline BOOL TInternetProtocol::IsAborted() { return m_HaveAbort; } inline BOOL TInternetProtocol::IsProxy() { return m_IsProxy; } inline BOOL TInternetProtocol::IsLocked() { return m_IsLocked; } #define BEGIN_PROGRESS_STATUS_MAP(status, text, result) \ { \ LPCWSTR _text = text; \ ULONG _status = status; \ CComBSTR _new_text; \ HRESULT& _result = result; \ BOOL _proxy = TRUE; \ switch (status) \ { #define PROGRESS_STATUS_ENTRY(id, func) \ case id: \ _result = func(_text, &_new_text, _proxy); \ break; #define END_PROGRESS_STATUS_MAP(endfunc) \ default: \ ATLTRACE("!! Unhandled Status : %d\n", _status); \ } \ if (_proxy) \ _result = endfunc(_status, _new_text ? _new_text : _text); \ } #endif // T_INTERNET_PROTOCOL/*------------ TInternetStatus.cpp ------------*/ #include "StdAfx.h" #include "shlwapi.h" #include "wininet.h" #include "atlbase.h" //You may derive a class from CComModule and use it if you want to override //something, but do not change the name of _Module extern CComModule _Module; #include "atlcom.h" #include "TInternetStatus.h" #include "TNetGlobals.h" #include "TNetUtils.h" #include "TGlobalResource.h" #include "Script.h" #define _MIDL_USE_GUIDDEF_ #include "Script_i.c" #include "TRegKey.h" #include "TPreferences.h" #include "TPath.h" #include "TErr.h" TInternetStatus::TInternetStatus() { gOnline = TRUE; gAskCount = 0; gInitCount = 0; } CComObject* TInternetStatus::gStatus = NULL; void TInternetStatus::FinalRelease() { gStatus = NULL; } // **************************************************************************** // **************************** Interface ******************************* // **************************************************************************** STDMETHODIMP TInternetStatus::put_UserAgent(BSTR pUserAgent) { m_UserAgent = pUserAgent; return S_OK; } STDMETHODIMP TInternetStatus::get_UserAgent(BSTR* pUserAgent) { ASSERT(pUserAgent); if (pUserAgent == NULL) return E_INVALIDARG; return m_UserAgent.CopyTo(pUserAgent); } STDMETHODIMP TInternetStatus::IsConnectionConfigured(BOOL* pBool) { ASSERT(pBool); if (pBool == NULL) return E_INVALIDARG; if (IsConnectionConfigured() || HaveAOL()) *pBool = TRUE; else *pBool = FALSE; return S_OK; } STDMETHODIMP TInternetStatus::IsConnectionOpen(BOOL* pBool) { ASSERT(pBool); if (pBool == NULL) return E_INVALIDARG; *pBool = IsConnected(); return S_OK; } STDMETHODIMP TInternetStatus::ConfigureConnection() { TRegKey lRegKey; if (lRegKey.Open( HKEY_LOCAL_MACHINE,_T("Software\\Microsoft\\Internet Connection Wizard"),KEY_READ ) == ERROR_SUCCESS) { CString lStgPath;// --- get the wizard path if( lRegKey.QueryValue( lStgPath, _T("InstallationDirectory")) == ERROR_SUCCESS) { STARTUPINFO lStartupInfo; PROCESS_INFORMATION lProcessInfo; TPath::AddPath( lStgPath,_T("icwconn1.exe" ) ); memset( &lStartupInfo,0,sizeof( STARTUPINFO ) ); lStartupInfo.cb = sizeof( STARTUPINFO ); if (CreateProcess( (LPCTSTR)lStgPath,NULL,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&lStartupInfo,&lProcessInfo)) { ::CloseHandle(lProcessInfo.hProcess); ::CloseHandle(lProcessInfo.hThread); return S_OK; } } } return E_FAIL; } STDMETHODIMP TInternetStatus::GetOnline(BOOL* pOnline, LONG* pAskCount) { ASSERT(pOnline); if (pOnline == NULL) return E_INVALIDARG; *pOnline = !IsGlobalOffline(); if (pAskCount) { gAskCount++; *pAskCount = gAskCount; } return S_OK; } STDMETHODIMP TInternetStatus::SetOnline(BOOL pOnline, BOOL* pConnected) { // IE offline state BOOL lOffLineState = IsGlobalOffline(); // if we want to change IE state if (lOffLineState == pOnline) { // change it SetGlobalOffline(!pOnline); // update context so that listener // should know the current state (ie, refresh the UI) CComPtr lContext; if (lContext.CoCreateInstance(CLSID_TScriptContext) == S_OK) { lContext->put_online(pOnline); } } // Store our internal state gOnline = pOnline; // reset the ask count gAskCount = 0; if (pConnected != NULL) { *pConnected = IsConnected(); } return S_OK; } STDMETHODIMP TInternetStatus::OpenConnection() { if (!IsConnectionConfigured()) return E_FAIL; if (IsGlobalOffline()) return E_FAIL; if (IsConnected()) return S_OK; HRESULT lResult = E_FAIL; DWORD lConnection = 0; BOOL lUseAOL; BOOL lUseModem; UseConnection(T_AOL_CONNECTION, &lUseAOL); UseConnection(T_MODEM_CONNECTION, &lUseModem); if (HaveAOL() && !lUseAOL && !lUseModem) lUseAOL = TRUE; if (HaveAOL() && lUseAOL) { if (lUseAOL) { HANDLE lProcess; lProcess = LaunchAOL(); if (lProcess) { WaitInternetAccessWithAOL(lProcess); ::CloseHandle(lProcess); } return IsConnected() ? S_OK : E_FAIL; } } if (IsConnectedByModem()) { lResult = InternetDial(NULL, NULL, INTERNET_AUTODIAL_FORCE_ONLINE | INTERNET_DIAL_SHOW_OFFLINE, &lConnection, NULL ); if (lResult != ERROR_SUCCESS) { CComPtr lContext; if (lContext.CoCreateInstance(CLSID_TScriptContext) == S_OK) { lContext->put_online(FALSE); } } } else { ASSERT(IsConnectedByLAN()); lResult = S_OK; } return lResult; } STDMETHODIMP TInternetStatus::HaveConnection(LONG pFlag, BOOL* pBool) { ATLASSERT(pBool); if (pBool == NULL) return E_INVALIDARG; switch (pFlag) { case T_AOL_CONNECTION: *pBool = HaveAOL(); break; case T_MODEM_CONNECTION: *pBool = IsConnectedByModem(); break; case T_LAN_CONNECTION: *pBool = IsConnectedByLAN(); break; } return S_OK; } STDMETHODIMP TInternetStatus::UseConnection(LONG pFlag, BOOL* pBool) { ATLASSERT(pBool); if (pBool == NULL) return E_INVALIDARG; CRegKey keyCur; DWORD lConnection = 0; HRESULT res; res = keyCur.Open(HKEY_CURRENT_USER, KEEBOO_NET_REGISTRY_NAME, KEY_READ); if (res == ERROR_SUCCESS) { if (keyCur.QueryValue(lConnection, "Connection") != ERROR_SUCCESS) { if (HaveAOL()) lConnection = T_AOL_CONNECTION; else lConnection = T_MODEM_CONNECTION | T_LAN_CONNECTION; } } *pBool = lConnection & pFlag; return S_OK; } STDMETHODIMP TInternetStatus::SetConnection(LONG pFlag) { CRegKey keyCur; HRESULT res; res = keyCur.Open(HKEY_CURRENT_USER, KEEBOO_NET_REGISTRY_NAME, KEY_WRITE); if (res == ERROR_SUCCESS) keyCur.SetValue(pFlag, "Connection"); return S_OK; } // **************************************************************************** // ************************* Other functions **************************** // **************************************************************************** int TInternetStatus::GetTimingOption( int pStandardValue,LPCTSTR pOptionName ) { int lValue = pStandardValue; int lSpecialValue = 0; TPreferences lPref( _T("InternetSession") ); lPref.GetInt( pOptionName,&lSpecialValue ); switch( lSpecialValue ) { case -1: // Special value : 'infinite' number of tests lValue = 32000; break; case 0: break; default: lValue = lSpecialValue; } return lValue; } /* void TInternetStatus::StartWaiting( void ) { CWnd* lMain = AfxGetMainWnd(),*lPalette = NULL; CMenu* lMenu = NULL; if( lMain ) { lMenu = lMain->GetMenu(); if( lMenu ) { int i; for( i = 0;i< lMenu->GetMenuItemCount();i++ ) { lMenu->EnableMenuItem( i,MF_BYPOSITION | MF_DISABLED | MF_GRAYED ); } lMain->DrawMenuBar(); } lPalette = lMain->FindWindow( NULL,_T("Panel") ); if( lPalette && lPalette->IsWindowVisible() ) { lPalette->ShowWindow( SW_HIDE ); } else { lPalette = NULL; } } } void TInternetStatus::StopWaiting( void ) { CWnd* lMain = AfxGetMainWnd(),*lPalette = NULL; CMenu* lMenu = NULL; if( lMain ) { lMenu = lMain->GetMenu(); if( lMenu ) { int i; for( i = 0;i< lMenu->GetMenuItemCount();i++ ) { lMenu->EnableMenuItem( i,MF_BYPOSITION | MF_ENABLED ); } lMain->DrawMenuBar(); } lPalette = lMain->FindWindow( NULL,_T("Panel") ); if( lPalette && lPalette->IsWindowVisible() ) { lPalette->ShowWindow( SW_SHOW ); } else { lPalette = NULL; } } gNoUI = false; } */ BOOL TInternetStatus::NoInternetConfig( void ) { TRegKey regKeyCuser; if( regKeyCuser.Open( HKEY_CURRENT_USER, _T("Software\\Microsoft\\Internet Connection Wizard"), KEY_READ | KEY_SET_VALUE ) == ERROR_SUCCESS) { // --- check if the connection wizard has been successfully called DWORD dwValue = 0; if( regKeyCuser.QueryValue( dwValue, _T("Completed")) == ERROR_SUCCESS) { if( dwValue > 0 ) { return FALSE; // Yeah there is a connection } } } return TRUE; /* don't use that InternetGetConnectedState reflect the state of IE properties ie. it says that there is an active connection with a modem as the propertie panel even if there is no modem at all and even if the connecton wizard have never be called */ /* DWORD lState = 0; int lRes = InternetGetConnectedState( &lState,0 ); if( lRes ) { return FALSE; // there is an ACTIVE internet connexion; } else { return TRUE; } return lState & ( INTERNET_CONNECTION_MODEM | INTERNET_CONNECTION_LAN | INTERNET_CONNECTION_PROXY ) == 0; */ } #define AOL_CURRENT_VERSION_KEY _T( "Software\\America Online\\AOL\\CurrentVersion" ) BOOL TInternetStatus::HaveAOL() { CRegKey lAOLReg; if (lAOLReg.Open( HKEY_LOCAL_MACHINE, AOL_CURRENT_VERSION_KEY,KEY_READ ) == ERROR_SUCCESS) return TRUE; if (lAOLReg.Open( HKEY_CURRENT_USER, AOL_CURRENT_VERSION_KEY,KEY_READ ) == ERROR_SUCCESS) return TRUE; return FALSE; } HANDLE TInternetStatus::LaunchAOL( void ) { TRegKey lAOLReg; HKEY lRootKey = HKEY_CURRENT_USER; CString lKeyPath; lKeyPath = AOL_CURRENT_VERSION_KEY; while (lRootKey) { if (lAOLReg.Open( lRootKey, lKeyPath, KEY_READ ) == ERROR_SUCCESS ) { CString lAOLPath; if (lAOLReg.QueryValue( lAOLPath,_T( "AppPath" ) ) == ERROR_SUCCESS ) { STARTUPINFO lStartupInfo; PROCESS_INFORMATION lProcessInfo; TPath::AddPath( lAOLPath, _T("AOL.exe" ) ); memset( &lStartupInfo,0,sizeof( STARTUPINFO ) ); lStartupInfo.cb = sizeof( STARTUPINFO ); if (CreateProcess( (LPCTSTR)lAOLPath,NULL,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&lStartupInfo,&lProcessInfo)) { ::CloseHandle(lProcessInfo.hThread); return lProcessInfo.hProcess; } } } lAOLReg.Close(); if (lRootKey == HKEY_CURRENT_USER) lRootKey = HKEY_LOCAL_MACHINE; else lRootKey = NULL; } return NULL; } // // Check that we have an internet configuration (LAN | Modem | AOL) // for this computer. // // This is used by the put_Online function. // We can only switch online if we have an internet configuration. // BOOL TInternetStatus::InternetConfigured( void ) { return !NoInternetConfig() || HaveAOL(); } BOOL TInternetStatus::LaunchConnectionWizard( void ) { TRegKey lRegKey; if( lRegKey.Open( HKEY_LOCAL_MACHINE,_T("Software\\Microsoft\\Internet Connection Wizard"),KEY_READ ) == ERROR_SUCCESS) { CString lStgPath;// --- get the wizard path if( lRegKey.QueryValue( lStgPath, _T("InstallationDirectory")) == ERROR_SUCCESS) { STARTUPINFO lStartupInfo; PROCESS_INFORMATION lProcessInfo; TPath::AddPath( lStgPath,_T("icwconn1.exe" ) ); memset( &lStartupInfo,0,sizeof( STARTUPINFO ) ); lStartupInfo.cb = sizeof( STARTUPINFO ); if (CreateProcess( (LPCTSTR)lStgPath,NULL,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&lStartupInfo,&lProcessInfo)) { ::CloseHandle(lProcessInfo.hProcess); ::CloseHandle(lProcessInfo.hThread); return TRUE; } } } return FALSE; } static BOOL gInTest = FALSE; static BOOL gQuitTest = FALSE; BOOL TInternetStatus::TestInternetAccess(DWORD pNbMaxTests ) { DWORD lNbTests = 0; // ASSERT( lInTest == false ); if (gInTest) return FALSE; gQuitTest = FALSE; gInTest = TRUE; AFX_MANAGE_STATE( AfxGetAppModuleState( ) ); CWaitCursor lwait; while (!gQuitTest && (lNbTests < pNbMaxTests) && !IsConnected()) { MSG lMsg; if (gQuitTest) TErr::trace(TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, "Need to Quit Test"); while (!gQuitTest && ::PeekMessage( &lMsg,NULL,0,0,PM_NOREMOVE ) ) { BOOL lResult; lResult = ::GetMessage( &lMsg, NULL, 0, 0 ); if (lResult == -1) continue; if ( (!lResult) || (lMsg.message == WM_CLOSE) || (lMsg.message == WM_QUIT)) { TRACE( "\n Arret au niveau bas\n" ); gQuitTest = TRUE; ::PostMessage(lMsg.hwnd, lMsg.message, lMsg.lParam, lMsg.wParam); } else { ::TranslateMessage( &lMsg ); ::DispatchMessage( &lMsg ); } } ::Sleep( 10 ); lNbTests++; } gInTest = FALSE; return IsConnected(); } HRESULT TInternetStatus::StopAction() { TErr::trace(TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, "Stop Action"); gQuitTest = TRUE; return S_OK; } BOOL TInternetStatus::WaitInternetAccessWithAOL( HANDLE pProcess ) { DWORD lTime; lTime = GetTimingOption( 90, _T("AOLMaxDelay") ); TErr::trace(TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, "Waiting for AOL(%1!d!)", lTime); gQuitTest = FALSE; while (lTime) { if (TestInternetAccess(100) || gQuitTest) break; lTime--; // // It seems that AOL launch a second process as we've got // an exit code as soon as the AOL window appear // // DWORD lExitCode; // if (::GetExitCodeProcess(pProcess, &lExitCode) && (lExitCode != STILL_ACTIVE)) // break; } TErr::trace(TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, "Ending AOL Wait"); return IsConnected(); } /* BOOL TInternetStatus::WaitStandardInternetAccess( void ) { DWORD lState; InternetGetConnectedState( &lState,0 ); // with a lan , the internet is supposed to be quick return WaitInternetAccess( GetTimingOption( lState & INTERNET_CONNECTION_LAN ? 3 : 60,_T("StandardMaxDelay") ) ); } BOOL TInternetStatus::WaitInternetConfiguredWithStandardProvider( void ) { return WaitInternetAccess( GetTimingOption( 60,_T("MaxDelayToConfigure") ) ); } */ BOOL TInternetStatus::BypassCheckConfig( void ) { TPreferences lPref( _T("InternetSession") ); int lBypassCheckConfig = 0; lPref.GetInt( _T("BypassCheckConfig"),&lBypassCheckConfig ); return lBypassCheckConfig != 0; } HRESULT TInternetStatus::GetHostName() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 0 ); err = WSAStartup( wVersionRequested, &wsaData ); if (err == 0) { char szHostName[128]; if( gethostname(szHostName, 128) == 0) { m_HostName = szHostName; TRACE(_T("\n @@ Host name: %s @@\n"), m_HostName); // Get host adresses struct hostent* pHost; int i; pHost = gethostbyname(szHostName); for( i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ ) { CString str; int j; for( j = 0; j < pHost->h_length; j++ ) { CString addr; if( j > 0 ) str += "."; addr.Format("%u", (unsigned int)((unsigned char*)pHost->h_addr_list[i])[j]); str += addr; } m_IpAddr.Add(str); TRACE(_T(" @Ip: %s \n"), str); } TRACE(_T("\n")); } WSACleanup(); } return S_OK; } BOOL TInternetStatus::IsConnectionConfigured() { if (HaveAOL()) return TRUE; LPCTSTR lpszKeyName; HKEY hKey = NULL; lpszKeyName = _T("Software\\Microsoft\\Internet Connection Wizard"); LONG lRes = RegOpenKeyEx(HKEY_CURRENT_USER, lpszKeyName, 0, KEY_READ, &hKey); if (lRes == ERROR_SUCCESS) { // --- check if the connection wizard has been successfully called DWORD dwValue = 0; DWORD dwType = NULL; DWORD dwCount = sizeof(DWORD); lRes = RegQueryValueEx(hKey, _T("Completed"), NULL, &dwType, (LPBYTE)&dwValue, &dwCount); if( lRes == ERROR_SUCCESS) { if( dwValue > 0 ) { RegCloseKey(hKey); return TRUE; // Yeah there is a connection } } } RegCloseKey(hKey); return FALSE; } BOOL TInternetStatus::IsConnected() { DWORD lConnection; return InternetGetConnectedState(&lConnection, NULL); } // INTERNET_CONNECTION_CONFIGURED 0x000040 // INTERNET_CONNECTION_LAN 0x000002 // INTERNET_CONNECTION_MODEM 0x000001 // INTERNET_CONNECTION_MODEM_BUSY 0x000008 // INTERNET_CONNECTION_OFFLINE 0x000020 // INTERNET_CONNECTION_PROXY 0x000004 // INTERNET_RAS_INSTALLED 0x000010 BOOL TInternetStatus::IsConnectedByModem() { DWORD lConnection; InternetGetConnectedState(&lConnection, NULL); if ((lConnection & INTERNET_CONNECTION_MODEM) )// || (lConnection & INTERNET_RAS_INSTALLED)) { CComBSTR lName; // if IE 4 or have a connection if (!GetConnectionName(&lName) || lName.Length()) return TRUE; } return FALSE; } BOOL TInternetStatus::IsConnectedByLAN() { DWORD lConnection; InternetGetConnectedState(&lConnection, NULL); return lConnection & INTERNET_CONNECTION_LAN; } typedef BOOL (STDAPICALLTYPE *LPINTERNETGETCONNECTEDSTATEEX)(LPDWORD, LPTSTR, DWORD, DWORD ); BOOL TInternetStatus::GetConnectionName(BSTR* pName) { // If other connection TCHAR lConnectionName[128]; DWORD lConnection; BOOL bResult = FALSE; lConnectionName[0] = 0; HINSTANCE hInetLibrary; hInetLibrary = ::LoadLibrary("WININET.DLL"); if (hInetLibrary) { // ENTRY POINTS LPINTERNETGETCONNECTEDSTATEEX _InternetGetConnectedStateEx; _InternetGetConnectedStateEx = (LPINTERNETGETCONNECTEDSTATEEX)GetProcAddress(hInetLibrary, "InternetGetConnectedStateEx"); if (_InternetGetConnectedStateEx) { _InternetGetConnectedStateEx(&lConnection, lConnectionName, 128, NULL); CComBSTR(lConnectionName).CopyTo(pName); bResult = TRUE; } ::FreeLibrary(hInetLibrary); } return bResult; }/*------------ TInternetStatus.h ------------*/ #ifndef T_INTERNET_STATUS #define T_INTERNET_STATUS #include "Net.h" class ATL_NO_VTABLE TInternetStatus : public CComObjectRootEx, public CComCoClass, public IInternetStatus2 { public: DECLARE_REGISTRY(CLSID_TInternetStatus, KEEBOO_COMPANY".Internet.Status.1", KEEBOO_COMPANY".Internet.Status", 0, THREADFLAGS_BOTH ) BEGIN_COM_MAP(TInternetStatus) COM_INTERFACE_ENTRY(IInternetStatus) COM_INTERFACE_ENTRY(IInternetStatus2) END_COM_MAP() public: TInternetStatus(); void FinalRelease(); public: // Code for CheckConnection STDMETHOD(get_UserAgent)(BSTR*); STDMETHOD(put_UserAgent)(BSTR); STDMETHOD(GetOnline)(BOOL*, LONG* = NULL); STDMETHOD(IsConnectionConfigured)(BOOL* ); STDMETHOD(IsConnectionOpen)(BOOL* ); STDMETHOD(OpenConnection)(); STDMETHOD(ConfigureConnection)(); STDMETHOD(StopAction)(); STDMETHOD(SetOnline)(BOOL, BOOL* = NULL); STDMETHOD(HaveConnection)(LONG, BOOL* ); STDMETHOD(UseConnection)(LONG, BOOL* ); STDMETHOD(SetConnection)(LONG ); BOOL gOnline:2; LONG gAskCount; LONG gInitCount; CComBSTR m_UserAgent; static CComObject* gStatus; private: int GetTimingOption( int pStandardValue,LPCTSTR pOptionName ); // To access to InternetSession Section // void StartWaiting( void ); // void StopWaiting( void ); BOOL NoInternetConfig( void ); BOOL LaunchConnectionWizard( void ); // BOOL WaitGhostInternetConnection( void ); // BOOL WaitInternetAccess( int pNbSecs ); // wait pNbSecs secs // BOOL WaitStandardInternetAccess( void ); // wait 60 s // BOOL WaitInternetConfiguredWithStandardProvider( void ); // need to full configure : wait 5 min BOOL BypassCheckConfig( void ); BOOL TestInternetAccess(DWORD ); BOOL InternetConfigured( void ); BOOL IsConnected(); BOOL IsConnectedByModem(); BOOL IsConnectedByLAN(); BOOL IsConnectionConfigured(); BOOL GetConnectionName(BSTR* pName); // AOL specific BOOL HaveAOL(); HANDLE LaunchAOL( void ); BOOL WaitInternetAccessWithAOL( HANDLE ); // wait 90 s protected: HRESULT GetHostName(); CString m_HostName; CArray m_IpAddr; }; #endif // T_INTERNET_STATUS /*------------ TSCacheEntry.cpp ------------*/ #include "StdAfx.h" #include "TNetDebug.h" // MAIN INCLUDE #ifndef T_SEVENIX_CACHE #include "TSevenixCache.h" #endif #include "TSCacheEntry.h" // OTHER INCLUDES #include "TNetGlobals.h" #include "TSCacheEntryList.h" #include "TStringToStringHashTable.h" #include "TStringIterator.h" #include "TPreferences.h" #include "TInteger.h" #include "TTime.h" #include "TErr.h" #include "TRandomString.h" #include "TSevenixUrlInfo.h" #include "TUrl.h" /**************************/ /** class TSCacheEntry **/ /**************************/ // METHODS // --------------------------------------------------------------------- // // TSCacheEntry::TSCacheEntry() : m_pCache(NULL), fCanModify(TRUE), fIsValid(TRUE), m_pEntryList(NULL) { C_TRACE(" + new CacheEntry(0x%X)\n", this); // {AC} m_Map = new StringStringBag; // m_Map->clear(); } // --------------------------------------------------------------------- // // TSCacheEntry::~TSCacheEntry() { C_TRACE(" - CacheEntry Destructor(0x%X) Ref: %d\n", this, m_dwRef); // {AC} m_Map->empty(); // m_Map->clear(); if( m_Map != NULL ) { delete m_Map; m_Map = NULL; } if (m_pCache) { ((ISevenixCache*)m_pCache)->Release(); m_pCache = NULL; } if (m_pEntryList) { ((ISevenixCacheEntryList*)m_pEntryList)->Release(); m_pEntryList = NULL; } } // --------------------------------------------------------------------- // // void TSCacheEntry::setCache(TSevenixCache* pCache) { ATLASSERT(pCache); m_pCache = pCache; ((ISevenixCache*)m_pCache)->AddRef(); } // --------------------------------------------------------------------- // // void TSCacheEntry::setEntryList(TSCacheEntryList* pEntryList) { ATLASSERT(pEntryList); m_pEntryList = pEntryList; ((ISevenixCacheEntryList*)m_pEntryList)->AddRef(); } // --------------------------------------------------------------------- // // void TSCacheEntry::setUrl(LPCWSTR pUrl) { ATLASSERT(pUrl); m_Url = pUrl; CreateFileName(); } #pragma optimize("", off) // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::commit() { if ((m_pCache == NULL) || (m_pEntryList == NULL)) return S_FALSE; if (!fCanModify) return S_FALSE; // Get new file size... CComBSTR lFileName; CFileStatus lStatus; BOOL lStatusOk = FALSE; getFileName(&lFileName); lStatusOk = CFile::GetStatus(CString(lFileName), lStatus); if (lStatusOk) addHeader(T_HEADER_SIZE, TInteger(lStatus.m_size).stringValue()); CComBSTR lStrTime; if ((getHeader(T_HEADER_LAST_MODIFIED, 0, &lStrTime) != S_OK) && (getHeader(T_HEADER_DATE, 0, &lStrTime) != S_OK) && (getHeader(T_HEADER_LOCAL_DATE, 0, &lStrTime) != S_OK)) { SYSTEMTIME lSysTime; struct tm* ptm = NULL; char lBuffer[INTERNET_RFC1123_BUFSIZE]; if (lStatusOk) ptm = lStatus.m_mtime.GetGmtTm(NULL); if (lStatusOk && ptm) { // // This code came from the MFC CTime::GetAsSystemTime function // the MFC function use GetLocalTm and not GetGmtTm // // TODO: We have to check what is the right way to do it. // The SystemTime is Local, and the conversion to InternetTime // should be aware of this. // // So we might use the MFC method anyway. // lSysTime.wYear = (WORD) (1900 + ptm->tm_year); lSysTime.wMonth = (WORD) (1 + ptm->tm_mon); lSysTime.wDayOfWeek = (WORD) ptm->tm_wday; lSysTime.wDay = (WORD) ptm->tm_mday; lSysTime.wHour = (WORD) ptm->tm_hour; lSysTime.wMinute = (WORD) ptm->tm_min; lSysTime.wSecond = (WORD) ptm->tm_sec; lSysTime.wMilliseconds = 0; } else { ::GetSystemTime(&lSysTime); } if (::InternetTimeFromSystemTime(&lSysTime, INTERNET_RFC1123_FORMAT, lBuffer, INTERNET_RFC1123_BUFSIZE)) { lStrTime = lBuffer; addHeader(T_HEADER_LOCAL_DATE, lStrTime); } } CComBSTR lStrID; if (getHeader(T_HEADER_URL_ID, 0, &lStrID) != S_OK) { TSevenixUrlInfo* lInfo; CString lStrUrl(m_Url); TUrl lUrl(lStrUrl); long lID = 0; CString lUrlStrID; lInfo = (TSevenixUrlInfo*)lUrl.getExtendedInfo(); if (lInfo) lID = lInfo->getID(); lUrlStrID.Format("%x", lID); lStrID = lUrlStrID; addHeader(T_HEADER_URL_ID, lStrID); } // fWasModified = TRUE; fCanModify = FALSE; long lIncr = 1; Db* lDb = m_pCache->getDb(); ATLASSERT(lDb); if (lDb == NULL) return E_FAIL; CString lUrl(GetIdentifiedUrl()); C_TRACE("Cache: committing [0x%X] (%s)\n", this, lUrl); Dbt lKey((void*)lUrl.GetBuffer(0), lUrl.GetLength()); Dbt lData; // This is for thread safeness lData.set_flags(DB_DBT_MALLOC); if (lDb->get(NULL, &lKey, &lData, 0) == S_OK) { delete lData.get_data(); // the Url/Date is already in the Database lIncr = 0; } BYTE* lDataBytes; long lDataSize; getData(&lDataBytes, &lDataSize); lData.set_data(lDataBytes); lData.set_size(lDataSize); lDb->put(NULL, &lKey, &lData, 0); m_pEntryList->updateInDb(lIncr); // lDb->sync(0); m_pEntryList->Release(); m_pEntryList = NULL; lUrl.ReleaseBuffer(); delete lDataBytes; return S_OK; } #pragma optimize("", on) // --------------------------------------------------------------------- // // CString TSCacheEntry::GetIdentifiedUrl() { CString lTemp(m_Url); TUrl lUrl(lTemp); long lID = 0; CString lStrID; ATLASSERT(lUrl.getExtendedInfo() != NULL); if (lUrl.getExtendedInfo() != NULL) { lID = ((TSevenixUrlInfo*)lUrl.getExtendedInfo())->getID(); } lStrID.Format(" - (%d)", lID); lUrl.canonicalize(); return lUrl.simpleUrlString() + lStrID; } #pragma optimize("", off) // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::remove() { ATLASSERT(m_pCache); if (m_pCache == NULL) return S_FALSE; Db* lDb = m_pCache->getDb(); ATLASSERT(lDb); CString lUrl(GetIdentifiedUrl()); C_TRACE("Cache: removing [0x%X] (%s)\n", this, lUrl); Dbt lKey((void*)lUrl.GetBuffer(0), lUrl.GetLength()); lDb->del(NULL, &lKey, 0); if (m_pEntryList == NULL) { HRESULT lResult; lResult = m_pCache->getUrlEntryList(CString(m_Url), &m_pEntryList); if (FAILED(lResult)) return lResult; } m_pEntryList->updateInDb(-1); // Delete the file... CComBSTR lFileName; getFileName(&lFileName); TRY { CFile::Remove(CString(lFileName)); } CATCH (CFileException, e) { } END_CATCH m_pEntryList->Release(); m_pEntryList = NULL; lUrl.ReleaseBuffer(); return S_OK; } #pragma optimize("", on) // --------------------------------------------------------------------- // // void TSCacheEntry::CreateFileName() { if ((m_pCache == NULL) || !fCanModify) return ; USES_CONVERSION; CComQIPtr lInternal(m_pCache); if (lInternal) { CString lUrlString(m_Url); removeHeader(T_HEADER_LOCAL_FILE); TRandomString lName(6, HashKey(lUrlString) + (time(0) / 5)); CString lExt; BOOL lAddExt = FALSE; lInternal->get_addExtension(&lAddExt); if (lAddExt) { lExt = TUrl(lUrlString).getExtension(); } CString lFileName; lFileName = "c" + lName + lExt; lFileName.MakeLower(); TUrl lUrl(lUrlString); CString lHost = lUrl.getHost(); if (!lHost.GetLength()) lHost = UNKNOWN_HOST_NAME_DIR; CString lPath; lPath = m_pCache->constructPath(lHost); CFileFind lFinder; CString lStrTempFile = lPath; LPTSTR lTempFile = lStrTempFile.GetBuffer(MAX_PATH); PathAppend(lTempFile, lFileName); lStrTempFile.ReleaseBuffer(); while (lFinder.FindFile(lStrTempFile)) { lName.next(); lFileName = "c" + lName + lExt; lFileName.MakeLower(); lStrTempFile = lPath; lTempFile = lStrTempFile.GetBuffer(MAX_PATH); PathAppend(lTempFile, lFileName); lStrTempFile.ReleaseBuffer(); } lStrTempFile = lHost; lTempFile = lStrTempFile.GetBuffer(MAX_PATH); PathAppend(lTempFile, lFileName); lStrTempFile.ReleaseBuffer(); addHeader(T_HEADER_LOCAL_FILE, T2W(lStrTempFile)); } } // --------------------------------------------------------------------- // // // --------------------------------------------------------------------- // // // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::CheckExpirationTime(SYSTEMTIME* pTime, DWORD* pFreshness) { ATLASSERT(pFreshness); if (pFreshness == NULL) return E_INVALIDARG; FILETIME lFileTime; if (SystemTimeToFileTime(pTime, &lFileTime)) return CheckExpirationTime(&lFileTime, pFreshness); return S_FALSE; } HRESULT TSCacheEntry::CheckExpirationTime(FILETIME* pTime, DWORD* pFreshness) { ATLASSERT(pFreshness); if (pFreshness == NULL) return E_INVALIDARG; TTime lNow; FILETIME lFileNow; lNow = CTime::GetCurrentTime(); lNow.GetFileTime(lFileNow); if (CompareFileTime(pTime, &lFileNow) == -1) { // stale *pFreshness = T_CACHE_ENTRY_STALE; } else { // fresh *pFreshness = T_CACHE_ENTRY_FRESH; } return S_OK; } typedef union _LARGE_INTEGER_TIME { FILETIME ft; LONGLONG ll; } LARGE_INTEGER_TIME; // --------------------------------------------------------------------- // // STDMETHODIMP TSCacheEntry::CheckFreshness(DWORD* pFreshness) { ATLASSERT(pFreshness); if (pFreshness == NULL) return E_INVALIDARG; USES_CONVERSION; HRESULT lResult = S_FALSE; CComBSTR lVal; long lIndex = 0; DWORD lRequestFreshness = *pFreshness; #ifdef DEBUG_CHECK_FRESHNESS TRACE(" @@@ Headers for \"%s\" @@@\n", W2CT(m_Url)); long lCount = 0; CComBSTR lKey; while (enumHeader(lCount, &lKey, &lVal) == S_OK) { TRACE(" - %s: %s\n", W2CT(lKey), CString(lVal)); lKey.Empty(); lVal.Empty(); lCount++; } #endif *pFreshness = T_CACHE_ENTRY_UNKNOWN_FRESHNESS; #ifdef CHECK_REMOTE_FRESHNESS // Cache-Control directive: while (getHeader(T_HEADER_CACHE_CONTROL, lIndex, &lVal) == S_OK) { lIndex++; CString lStrVal = lVal; // If (no-cache | must-revalidate) // Expires = now - 1 if ((lStrVal == "must-revalidate") || (lStrVal == "no-cache")) { *pFreshness = T_CACHE_ENTRY_STALE; return S_OK; } // If have max-age // Expires = Date + max-age if (lStrVal.Find("max-age=") == 0) { lVal.Empty(); if (getHeader(T_HEADER_DATE, 0, &lVal) == S_OK) { CString lStrAge = lStrVal.Right(lStrVal.GetLength() - 8); int lAge = atoi(lStrAge); LARGE_INTEGER_TIME lFileDate; if (InternetTimeToFileTime(W2T(lVal), &lFileDate.ft)) { lFileDate.ll += lAge; return CheckExpirationTime(&lFileDate.ft, pFreshness); } } } lVal.Empty(); } // If have Expires header, everything's Ok if (getHeader(T_HEADER_EXPIRES, 0, &lVal) == S_OK) { FILETIME lTime; if (InternetTimeToFileTime(W2T(lVal), &lTime)) { return CheckExpirationTime(&lTime, pFreshness); } } #endif // CHECK_REMOTE_FRESHNESS CComBSTR lDateStr; LARGE_INTEGER_TIME lDate = {0}; CComBSTR lLastModifiedStr; LARGE_INTEGER_TIME lLastModified = {0}; if (getHeader(T_HEADER_DATE, 0, &lDateStr) != S_OK) getHeader(T_HEADER_LOCAL_DATE, 0, &lDateStr); getHeader(T_HEADER_LAST_MODIFIED, 0, &lLastModifiedStr); if (lDateStr) InternetTimeToFileTime(W2T(lDateStr), &lDate.ft); if (lLastModifiedStr) InternetTimeToFileTime(W2T(lLastModifiedStr), &lLastModified.ft); #ifdef CHECK_REMOTE_FRESHNESS // if (lRequestFreshness != T_CACHE_FULL_CHECK) { // Heuristic: (10% of delta between retrieval and last modif) // Expires = Date + ((LastModified - Date) * 0.1) if (lDateStr && lLastModifiedStr) { LONGLONG lDelta; LONGLONG lMinimum; // Minimum 1 minutes lMinimum = 1 * 600000; lDelta = lLastModified.ll - lDate.ll; if (lDelta < lMinimum) lDelta = lMinimum; lDate.ll += lDelta * 0.1; return CheckExpirationTime(&lDate.ft, pFreshness); } } #endif // CHECK_REMOTE_FRESHNESS DWORD lUseNetwork; DWORD lSize = sizeof(DWORD); lResult = CoInternetQueryInfo(m_Url, QUERY_USES_NETWORK, 0, &lUseNetwork, sizeof(lUseNetwork), &lSize, 0); if (FAILED(lResult)) lUseNetwork = 0; if (lUseNetwork) { #ifdef CHECK_REMOTE_FRESHNESS // If remote if (lRequestFreshness == T_CACHE_FULL_CHECK) { // Must do a HEAD request. } #endif // CHECK_REMOTE_FRESHNESS } else { // If local FILETIME lLocalDate; CComPtr lMoniker; CComPtr lBindCtx; lResult = CreateBindCtx(0, &lBindCtx); TUrl lFileUrl(m_Url); if (lFileUrl.getScheme() == "file") { CString lPath; lPath = lFileUrl.getHost() + lFileUrl.getFile(); lResult = CreateFileMoniker(T2CW(lPath), &lMoniker); if (FAILED(lResult)) return E_FAIL; lResult = lMoniker->GetTimeOfLastChange(lBindCtx, NULL, &lLocalDate); if (FAILED(lResult)) return E_FAIL; #ifdef _DEBUG CString lFileString; InternetTimeFromFileTime(&lLocalDate, lFileString.GetBuffer(INTERNET_RFC1123_BUFSIZE)); lFileString.ReleaseBuffer(); #endif // Do not use exact comparaison as date can vary from 1 to 10 seconds. lDate.ll += 0x03000000; if (CompareFileTime(&lDate.ft, &lLocalDate) >= 0) { // cache is fresh *pFreshness = T_CACHE_ENTRY_FRESH; return S_OK; } *pFreshness = T_CACHE_ENTRY_STALE; } } return S_OK; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::getHeader(LPCWSTR pName, long pIndex, BSTR* pVal) { ATLASSERT(pVal); ATLASSERT(pName); if ((pVal == NULL) || (pName == NULL)) return E_INVALIDARG; BOOL lMimeAsked = FALSE; BSTR lLowerName; LPCWSTR lVal; if (!wcscmp(T_HEADER_MIME_TYPE, pName)) { pName = T_HEADER_CONTENT_TYPE; lMimeAsked = TRUE; } lLowerName = wcslwr(::SysAllocString(pName)); StringStringBag::iterator lIterator = m_Map->find(lLowerName); ::SysFreeString(lLowerName); lVal = NULL; while (pIndex-- && (lIterator != m_Map->end())) lIterator++; if (lIterator != m_Map->end()) lVal = (*lIterator).second.data(); if (lVal != NULL) { if (lMimeAsked) { LPCWSTR lFound = wcschr(lVal, ';'); if (lFound != NULL) { ATLASSERT((lFound - lVal) > 0); *pVal = ::SysAllocStringLen(lVal, lFound - lVal); lFound = wcschr(*pVal, ' '); ATLASSERT(lFound == NULL); if (lFound != NULL) { /* LPCWSTR lpsz = *pVal; // Trim left; while (_iswspace(*lpsz)) lpsz = _wcsinc(lpsz); if (lpsz != *pVal) // Trim right */ } return S_OK; } } *pVal = ::SysAllocString(lVal); return S_OK; } *pVal = NULL; return S_FALSE; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::enumHeader(long pCount, BSTR* pName, BSTR* pVal) { ATLASSERT(pName); ATLASSERT(pVal); if ((pName == NULL) || (pVal == NULL)) return E_INVALIDARG; StringStringBag::iterator lIterator = m_Map->begin(); LPCWSTR lName = NULL; LPCWSTR lVal = NULL; while (pCount && (lIterator != m_Map->end())) { lIterator++; pCount--; } if (lIterator != m_Map->end()) { lName = (*lIterator).first.data(); lVal = (*lIterator).second.data(); if (lVal != NULL) { *pVal = ::SysAllocString(lVal); *pName = ::SysAllocString(lName); return S_OK; } } *pVal = NULL; *pName = NULL; return S_FALSE; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::addHeader(LPCWSTR pName, LPCWSTR pVal) { ATLASSERT(pVal); if (pVal == NULL) return E_FAIL; if (!fCanModify) { // This entry can't be modify ATLASSERT(NULL); return S_FALSE; } if (!wcscmp(T_HEADER_MIME_TYPE, pName)) { pName = T_HEADER_CONTENT_TYPE; } // Alloc mem CComBSTR lName = pName; BSTR lLowerName = wcslwr(lName); // Store data StringStringBag::iterator lIterator = m_Map->find(lLowerName); while (lIterator != m_Map->end()) { LPCWSTR lVal; lVal = (*lIterator).second.data(); if (!wcscmp(lVal, pVal)) return S_FALSE; lIterator++; } m_Map->insert(StringStringBag::value_type(lLowerName, pVal)); return S_OK; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::removeHeader(LPCWSTR pName) { if (!fCanModify) { // This entry can't be modify ATLASSERT(NULL); return S_FALSE; } if (!wcscmp(T_HEADER_MIME_TYPE, pName)) { pName = T_HEADER_CONTENT_TYPE; } // Alloc mem CComBSTR lName = pName; BSTR lLowerName = _wcslwr(lName); // Remove data long lFound = m_Map->erase(lLowerName); if (lFound) return S_OK; return S_FALSE; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::countHeader(LPCWSTR pName, long* pCount) { ATLASSERT(pCount); if (pCount == NULL) return E_INVALIDARG; if (pName) *pCount = m_Map->count(pName); else *pCount = m_Map->size(); return S_OK; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::getFileName(BSTR* pFileName) { ATLASSERT(pFileName); if (pFileName == NULL) return E_INVALIDARG; // Init to null *pFileName = NULL; // Get Cache path CComBSTR lPath; TString lfn; ATLASSERT(m_pCache); if (!m_pCache) return E_FAIL; if (!m_pCache || (m_pCache->getCachePath(&lPath) != S_OK)) return S_FALSE; lfn = TString(lPath); // Get local file TString lFileName; CComBSTR lKey; if (getHeader(T_HEADER_LOCAL_FILE, 0, &lKey) != S_OK) return S_FALSE; lFileName = TString(lKey); LPTSTR lFullPath = lfn.GetBuffer(MAX_PATH); PathAppend(lFullPath, lFileName); lfn.ReleaseBuffer(); *pFileName = lfn.AllocSysString(); return S_OK; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::getUrl(BSTR* pUrl) { ATLASSERT(pUrl); if (pUrl == NULL) return E_INVALIDARG; *pUrl = SysAllocString(m_Url); return S_OK; } #define TAG_END_CACHE_ENTRY (0x100 | 0x2) #define TAG_KEY_STRING (0x200 | 0x1) #define TAG_VALUE_STRING (0x200 | 0x2) // --------------------------------------------------------------------- // Serialize the data. // HRESULT TSCacheEntry::setData(BYTE* pData, long pSize) { HRESULT lResult = S_OK; CString lKey; CString lValue; if (pSize) { while (pSize) { if (pSize < sizeof(USHORT)) return E_FAIL; USHORT lTag = *(USHORT*)pData; pData += sizeof(USHORT); pSize -= sizeof(USHORT); switch (lTag) { case TAG_KEY_STRING: lResult = readStringFromData(lKey, pData, pSize); if (lResult != S_OK) return E_FAIL; break; case TAG_VALUE_STRING: lResult = readStringFromData(lValue, pData, pSize); if (lResult != S_OK) return E_FAIL; if (lKey.GetLength()) { addHeader(lKey, lValue); lKey = ""; } break; default: // We should never step here !!!! ATLASSERT(NULL); return E_FAIL; break; } } } fIsValid = TRUE; fCanModify = FALSE; // fWasModified = FALSE; return S_OK; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::getData(BYTE** pData, long* pSize) { ATLASSERT(pData); ATLASSERT(pSize); if ((pData == NULL) || (pSize == NULL)) return E_INVALIDARG; StringStringBag::iterator lIterator; long lSize = 0; LPCWSTR lKey = NULL; LPCWSTR lVal = NULL; lIterator = m_Map->begin(); while (lIterator != m_Map->end()) { lKey = (*lIterator).first.data(); lSize += wcslen(lKey); lVal = (*lIterator).second.data(); lSize += wcslen(lVal); lSize += sizeof(USHORT) * 4; lIterator++; } BYTE* lData = new BYTE[lSize]; BYTE* lDataIndex = lData; lIterator = m_Map->begin(); while (lIterator != m_Map->end()) { *((USHORT*)lDataIndex) = TAG_KEY_STRING; lDataIndex += sizeof(USHORT); lKey = (*lIterator).first.data(); writeStringToData(lDataIndex, lKey); *((USHORT*)lDataIndex) = TAG_VALUE_STRING; lDataIndex += sizeof(USHORT); lVal = (*lIterator).second.data(); writeStringToData(lDataIndex, lVal); lIterator++; } // *((USHORT*)lDataIndex) = TAG_END_CACHE_ENTRY; // lDataIndex += sizeof(USHORT); ATLASSERT((lDataIndex - lData) == lSize); *pData = lData; *pSize = lSize; return S_OK; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::readStringFromData(CString &lString, BYTE*& pData, long& pSize) { long lStringSize; if (pSize < sizeof(USHORT)) return E_FAIL; lStringSize = *(USHORT*)pData; pData += sizeof(USHORT); pSize -= sizeof(USHORT); if (pSize < lStringSize) return E_FAIL; lString = CString((LPCTSTR )pData, lStringSize); pData += lStringSize; pSize -= lStringSize; return S_OK; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::writeStringToData(BYTE*& pData, LPCWSTR pString) { CString lString(pString); long lSize = lString.GetLength(); ATLASSERT(lSize == (USHORT)lSize); *((USHORT*)pData) = lSize; pData += sizeof(USHORT); memcpy(pData, lString.GetBuffer(1), lSize); pData += lSize; return S_OK; } // --------------------------------------------------------------------- // // HRESULT TSCacheEntry::Clone(ISevenixCacheEntry** pEntry) { ATLASSERT(pEntry); if (pEntry == NULL) return E_INVALIDARG; CComObject* lEntry; CComObject::CreateInstance(&lEntry); long lCount = 0; CComBSTR lName; CComBSTR lValue; while (enumHeader(lCount, &lName, &lValue) == S_OK) { lEntry->addHeader(lName, lValue); } lEntry->commit(); lEntry->setCache(m_pCache); lEntry->setUrl(m_Url); *pEntry = lEntry; (*pEntry)->AddRef(); return S_OK; } #ifndef _UNICODE // --------------------------------------------------------------------- // Helper // --------------------------------------------------------------------- // HRESULT TSCacheEntry::getHeader(CString pName, long pIndex, BSTR* pVal) { USES_CONVERSION; return getHeader(T2W(pName), pIndex, pVal); } // --------------------------------------------------------------------- // HRESULT TSCacheEntry::addHeader(CString pName, CString pVal) { USES_CONVERSION; return addHeader(T2W(pName), T2W(pVal)); } // --------------------------------------------------------------------- // HRESULT TSCacheEntry::countHeader(CString pName, long* pCount) { USES_CONVERSION; return countHeader(T2W(pName), pCount); } #endif // _UNICODE #ifdef DEBUG_CACHE LPCTSTR TSCacheEntry::GetCacheName() { ATLASSERT(m_pCache); return m_pCache->GetCacheName(); } #endif/*------------ TSCacheEntryList.cpp ------------*/ // MAIN INCLUDE #include "Stdafx.h" #include "TNetDebug.h" #include "TSevenixCache.h" #include "TSCacheEntryList.h" #include "TSCacheEntry.h" // OTHER INCLUDES #include "TStringToPtrHashTable.h" #include "TStringToStringHashTable.h" #include "TStringIterator.h" #include "TPtrIterator.h" #include "TInteger.h" #include "TUrl.h" #include "TSevenixUrl.h" #include "TSevenixUrlInfo.h" /****************************/ /** class TSCacheEntryList **/ /****************************/ // METHODS // --------------------------------------------------------------------------- // // TSCacheEntryList::TSCacheEntryList() : m_HadChild(FALSE), m_Reseted(FALSE), m_pCache(NULL), m_pCursor(NULL), m_NextCount(0), m_Count(0) { C_TRACE(" + new CacheEntryList(%x)\n", this); } // --------------------------------------------------------------------------- // // TSCacheEntryList::~TSCacheEntryList() { C_TRACE(" - CacheEntryList Destructor(%x) Ref: %d\n", this, m_dwRef); } // --------------------------------------------------------------------------- // // void TSCacheEntryList::FinalRelease() { cleanUp(); } // ----------------------------------------------------------------------------- // cleanUp class members // void TSCacheEntryList::cleanUp() { m_pCache = NULL; Reset(); } // ----------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::createEntry(LPCWSTR pUrl, ISevenixCacheEntry** pEntry) { ASSERT(pEntry); if (pEntry == NULL) return E_INVALIDARG; CString lUrl; HRESULT lResult; lResult = m_pCache->checkUrl(pUrl, lUrl, TRUE); if (FAILED(lResult)) return lResult; // synchronize #ifdef DEBUG_CACHE TComLockPtr<> lLock(this, "(Com) Entry List"); #else TComLockPtr<> lLock(this); #endif CComObject* lEntry; CComObject::CreateInstance(&lEntry); lEntry->setCache(m_pCache); lEntry->setUrl(CComBSTR(lUrl)); lEntry->setEntryList(this); *pEntry = lEntry; lEntry->AddRef(); C_TRACE("Cache: creating (%s)\n", lUrl); return S_OK; } // ----------------------------------------------------------------------------- // // BSTR TSCacheEntryList::getUrl() { return m_Url; } // -------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::getElementAt(LPCWSTR pUrl, ISevenixCacheEntry** pEntry) { CString lUrl; HRESULT lResult; lResult = getElement(pUrl, pEntry, MF_EXACT); #ifdef _DEBUG if (lResult != S_OK) { TRACE(_T(" -*- CACHE Element [%s] not Found -*-\n"), CString(pUrl)); } #endif return lResult; } // -------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::getElement(LPCWSTR pUrl, ISevenixCacheEntry** pEntry, LONG pMatchingFlags) { ASSERT(pEntry); if (pEntry == NULL) return E_INVALIDARG; C_TRACE("Cache: getting (%s)\n", CString(pUrl)); *pEntry = NULL; CComPtr lFoundEntry; CComPtr lBestEntry; // FILETIME lTime; TUrl lUrl(pUrl); long lID; CString lUrlStrID; TSevenixUrlInfo* lInfo; lInfo = (TSevenixUrlInfo*)lUrl.getExtendedInfo(); // ASSERT(lInfo); if (lInfo == NULL) return E_INVALIDARG; lID = lInfo->getID(); lUrlStrID.Format("%x", lID); // synchronize #ifdef DEBUG_CACHE TComLockPtr<> lLock(this, "(Com) Entry List"); #else TComLockPtr<> lLock(this); #endif Reset(); if (GetNextEntry(&lFoundEntry) != S_OK) return E_FAIL; while (lFoundEntry) { CComBSTR lStrID; if (lFoundEntry->getHeader(T_HEADER_URL_ID, 0, &lStrID) == S_OK) { if ((lUrlStrID == CString(lStrID)) && (pMatchingFlags & MF_EXACT)) { *pEntry = lFoundEntry; (*pEntry)->AddRef(); return S_OK; } else if (lUrlStrID < CString(lStrID)) { if (pMatchingFlags & MF_FIRST) { *pEntry = lFoundEntry; (*pEntry)->AddRef(); return S_OK; } else if (pMatchingFlags & MF_JUST_BEFORE) { lBestEntry = lFoundEntry; } } else if (lUrlStrID > CString(lStrID)) { if (pMatchingFlags & MF_JUST_AFTER) { *pEntry = lFoundEntry; (*pEntry)->AddRef(); return S_OK; } else if (pMatchingFlags & MF_LAST) { lBestEntry = lFoundEntry; } } } lFoundEntry.Release(); GetNextEntry(&lFoundEntry); } if (lBestEntry) { *pEntry = lBestEntry; (*pEntry)->AddRef(); return S_OK; } return E_FAIL; } // -------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::getFreshestEntry(ISevenixCacheEntry** pEntry) { ASSERT(pEntry); if (pEntry == NULL) return E_INVALIDARG; *pEntry = NULL; CComPtr lFoundEntry; CComPtr lNextEntry; HRESULT lResult; #ifdef DEBUG_CACHE TComLockPtr<> lLock(this, "(Com) Entry List"); #else TComLockPtr<> lLock(this); #endif Reset(); lResult = GetNextEntry(&lFoundEntry); if (lResult != S_OK) return E_FAIL; while ((lResult == S_OK) && lFoundEntry) { lNextEntry = lFoundEntry; lFoundEntry.Release(); lResult = GetNextEntry(&lFoundEntry); } ASSERT(lNextEntry); if (lNextEntry) { *pEntry = lNextEntry; (*pEntry)->AddRef(); return S_OK; } return E_FAIL; } #pragma optimize("", off) // -------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::GetNextEntry(ISevenixCacheEntry** pEntry) { ASSERT(pEntry); if (pEntry == NULL) return E_INVALIDARG; long lResult; CString lUrl(m_Url); *pEntry = NULL; // --- need a new cursor ? if (m_pCursor == NULL) { lResult = SetCursor(lUrl); if (lResult != S_OK) return E_FAIL; ASSERT(m_pCursor); if (m_pCursor == NULL) return E_FAIL; } if (m_Count <= m_NextCount) { return E_FAIL; } Dbt lKey; Dbt lData; // This is for thread safeness lData.set_flags(DB_DBT_MALLOC); lKey.set_flags(DB_DBT_MALLOC); lResult = m_pCursor->get(&lKey, &lData, DB_NEXT); if (lResult != S_OK) return E_FAIL; CString lKeyUrl((LPCSTR)lKey.get_data(), lKey.get_size()); lUrl += " - ("; ASSERT(lKeyUrl.Find(lUrl) == 0); if (lKeyUrl.Find(lUrl) != 0) { // Try to correct the database m_Count = m_NextCount - 1; // We update of 1 more to be sure it's store. updateInDb(1); return E_FAIL; } CComObject* lEntry; CComObject::CreateInstance(&lEntry); CComBSTR lEntryUrl = RebuildUrl(lKeyUrl); lEntry->setUrl(lEntryUrl); lEntry->setCache(m_pCache); HRESULT lHResult = lEntry->setData((BYTE*)lData.get_data(), lData.get_size()); ASSERT(lHResult == S_OK); #ifdef DEBUG_STORAGE BYTE* lGetData; long lGetSize; lEntry->getData(&lGetData, &lGetSize); ASSERT(lData.get_size() == lGetSize); ASSERT(memcmp(lGetData, lData.get_data(), lGetSize) == 0); delete lGetData; #endif free(lData.get_data()); free(lKey.get_data()); m_NextCount++; *pEntry = lEntry; (*pEntry)->AddRef(); return S_OK; } #pragma optimize("", on) CString TSCacheEntryList::RebuildUrl(CString pUrl) { CString lNewUrl; long lId; int lFound; #ifdef _DEBUG // Make sure the url is canonicalized before the cache is called TString lCanonUrl; lCanonUrl = TUrl::canonicalizedUrlString(pUrl, TRUE); ASSERT(lCanonUrl == pUrl); #endif long lDelim = pUrl.Find(_T(" - (")); ASSERT(lDelim >= 0); if (lDelim >= 0) { CString lIdStr; lNewUrl = pUrl.Mid(0, lDelim); lIdStr = pUrl.Mid(lDelim + 4); lFound = sscanf(lIdStr, "%d", &lId); #ifdef _DEBUG if (lFound != 1) { int lError = GetLastError(); ASSERT(lFound == 1); ASSERT(lError == 0); } #endif if (lFound == 1) { lNewUrl = TSevenixUrl(lNewUrl, lId).extendedUrlString(); } } else { // just in case !!!! // we should never pass here lNewUrl = pUrl; } #ifdef _DEBUG TUrl lUrl(lNewUrl); ASSERT(lUrl.getExtendedInfo() != NULL); #endif return lNewUrl; } #pragma optimize("", off) // -------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::Reset() { // ASSERT(AfxCheckMemory()); // afxMemDF |= checkAlwaysMemDF; if (m_pCursor != NULL) { m_pCursor->close(); m_pCursor = NULL; m_NextCount = 0; m_Reseted = TRUE; } // afxMemDF |= ~checkAlwaysMemDF; // ASSERT(AfxCheckMemory()); return S_OK; } // -------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::SetCursor(CString pUrl) { HRESULT lResult; ASSERT(m_pCache); if (m_pCache == NULL) return E_FAIL; Db* lDb = m_pCache->getDb(); ASSERT(lDb); if (lDb == NULL) return E_FAIL; lResult = lDb->cursor(NULL, &m_pCursor); if (lResult != S_OK) return E_FAIL; m_NextCount = 0; // --- go to the first entry // this is a fake one (the entry count) void* lUrl = pUrl.GetBuffer(0); Dbt lKey(lUrl, pUrl.GetLength()); Dbt lData; // This is for thread safeness lData.set_flags(DB_DBT_MALLOC); lResult = m_pCursor->get(&lKey, &lData, DB_SET); if (lResult != S_OK) { pUrl.ReleaseBuffer(); return E_FAIL; } ASSERT(pUrl.GetLength() == lKey.get_size()); ASSERT(memcmp(lUrl, lKey.get_data(), pUrl.GetLength()) == 0); ASSERT(m_Count == *(long*)lData.get_data()); ASSERT(m_Count > 0); free(lData.get_data()); pUrl.ReleaseBuffer(); return S_OK; } #pragma optimize("", on) // -------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::removeEntry(ISevenixCacheEntry* pEntry) { m_Count--; updateInDb(); return S_OK; } // -------------------------------------------------------------------------- // // /* HRESULT TSCacheEntryList::getCachePath(BSTR* pPath) { if (m_pCache) { m_pCache->getCachePath(pPath); return S_OK; } return E_FAIL; } */ // -------------------------------------------------------------------------- // // void TSCacheEntryList::setUrl(TString pUrl) { #ifdef _DEBUG // Make sure the url is canonicalized before the cache is called TString lCanonUrl; lCanonUrl = TUrl::canonicalizedUrlString(pUrl, TRUE); ASSERT(lCanonUrl == pUrl); #endif ASSERT(!m_Url.Length()); m_Url = TUrl::canonicalizedUrlString(pUrl, TRUE); } // -------------------------------------------------------------------------- // // void TSCacheEntryList::setCache(TSevenixCache* pCache) { ASSERT(pCache); m_pCache = pCache; } // ------------------------------------------------------------------------------- // // long TSCacheEntryList::size() { return m_Count; } #pragma optimize("", off) // ------------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::updateInDb(int pIncr) { ASSERT((pIncr <= 1) && (pIncr >= -1)); ASSERT(m_pCache); if (m_pCache == NULL) return E_FAIL; Db* lDb = m_pCache->getDb(); ASSERT(lDb); if (lDb == NULL) return E_FAIL; if (m_Count || (pIncr > 0)) m_Count += pIncr; ASSERT(m_Count >= 0); CString lUrl(m_Url); Dbt lKey((void*)lUrl.GetBuffer(0), lUrl.GetLength()); long lResult; if ((m_Count > 0) && pIncr) { Dbt lData((void*)&m_Count, sizeof(m_Count)); lResult = lDb->put(NULL, &lKey, &lData, 0); } if (m_Count <= 0) { C_TRACE(("Deleting Cache Entry List for %s\n"), lUrl); lResult = lDb->del(NULL, &lKey, 0); } lUrl.ReleaseBuffer(); lResult = lDb->sync(0); m_pCache->unlock(m_Url); return S_OK; } // ------------------------------------------------------------------------------- // // HRESULT TSCacheEntryList::readFromDb() { ASSERT(m_pCache); if (m_pCache == NULL) return E_FAIL; Db* lDb = m_pCache->getDb(); ASSERT(lDb); if (lDb == NULL) return E_FAIL; CString lUrl(m_Url); Dbt lKey((void*)lUrl.GetBuffer(0), lUrl.GetLength()); Dbt lData; HRESULT lResult; // This is for thread safeness lData.set_flags(DB_DBT_MALLOC); lResult = lDb->get(NULL, &lKey, &lData, 0); lUrl.ReleaseBuffer(); if (lResult == S_OK) { m_Count = *(long*)lData.get_data(); free(lData.get_data()); ASSERT(m_Count > 0); if (m_Count <= 0) { // try to recover the cache count entry m_Count = 0; lResult = Reset(); ASSERT(lResult == S_OK); lResult = SetCursor(lUrl); ASSERT(lResult == S_OK); Dbt lKey; Dbt lData; lUrl += " - ("; while (lResult == S_OK) { lResult = m_pCursor->get(&lKey, &lData, DB_NEXT); if (lResult == S_OK) { CString lKeyUrl((LPCSTR)lKey.get_data(), lKey.get_size()); if (lKeyUrl.Find(lUrl) == 0) m_Count++; else lResult = E_FAIL; } } updateInDb(); } } else m_Count = 0; if (m_Count <= 0) return E_FAIL; return S_OK; } #pragma optimize("", on) #ifdef DEBUG_CACHE LPCTSTR TSCacheEntryList::GetCacheName() { ASSERT(m_pCache); return m_pCache->GetCacheName(); } #endif /*------------ TSevenixCache.cpp ------------*/ // TSevenixCache.cpp : Implementation of TSevenixCache #include "StdAfx.h" #include "TNetDebug.h" #include "TSevenixCache.h" #include "TSCacheEntryList.h" #include "TSCacheEntry.h" #ifdef USE_SUB_FOLDER_NAME #include "Shlwapi.h" #endif #include "TNetUtils.h" #include "TNetGlobals.h" #include "TString.h" #include "TTime.h" #include "TStringToPtrHashTable.h" #include "TStringToStringHashTable.h" #include "TStringIterator.h" #include "TPtrIterator.h" #include "TUrl.h" #include "TSevenixUrlInfo.h" #include "TExtendedUrlInfo.h" #include "TErr.h" #include "TNetHelpers.h" // // GetUrlEntry Flag // #define NO_FAILED 0x1 #define NO_LOCK 0x2 // // Name of the main cache entry // #define URL_CACHE_FILE_NAME "cache.db" ///////////////////////////////////////////////////////////////////////////// // TSevenixCache // ----------------------------------------------------------------------------- // Constructor // TSevenixCache::TSevenixCache() : m_pUrlDb(NULL), m_pDbEnv(NULL), fWasModified(FALSE), fAddExt(FALSE) { // m_critsec.SetTimeout(3); } // ----------------------------------------------------------------------------- // Destructor // TSevenixCache::~TSevenixCache() { #ifdef _DEBUG ATLASSERT(m_Table.size() == 0); TPtrIterator* lIterator; lIterator = m_Table.elements(); while (lIterator->hasMoreElements()) { TSCacheEntryList* lEntryList; lEntryList = (TSCacheEntryList*)lIterator->nextElement(); ATLASSERT(lEntryList); } #endif } // METHODS void TSevenixCache::FinalRelease() { cleanUp(); } // ----------------------------------------------------------------------------- // cleanUp class members // void TSevenixCache::cleanUp() { closeDb(); } // ----------------------------------------------------------------------------- // Db Access #pragma optimize("", off) // ----------------------------------------------------------------------------- // openDb // call most of the time after a setPath // void TSevenixCache::openDb() { CString lCachePath(m_CachePath); CString lUrlDbFileName(lCachePath + URL_CACHE_FILE_NAME); // --- close current Db if any closeDb(); // --- Create a Db Environment m_pDbEnv = new DbEnv(lCachePath, NULL, 0); // --- Set the error model to return val m_pDbEnv->set_error_model(DbEnv::ErrorReturn); // --- Open new Url Db long lResult = Db::open(lUrlDbFileName, DB_BTREE, DB_CREATE /* | DB_THREAD */, 0666, m_pDbEnv, NULL, &m_pUrlDb); ASSERT(lResult == 0); } // ----------------------------------------------------------------------------- // closeDb // void TSevenixCache::closeDb() { // ASSERT(AfxCheckMemory()); // afxMemDF |= checkAlwaysMemDF; if (m_pUrlDb) { m_pUrlDb->close(0); m_pUrlDb = NULL; } if (m_pDbEnv) { delete m_pDbEnv; m_pDbEnv = NULL; } // afxMemDF |= ~checkAlwaysMemDF; // ASSERT(AfxCheckMemory()); } // ----------------------------------------------------------------------------- // // HRESULT TSevenixCache::getUrlEntryList(LPCTSTR pUrl, TSCacheEntryList** pEntry, DWORD pFlags) { ASSERT(pEntry); if (pEntry == NULL) return E_INVALIDARG; Dbt lKey((void*)pUrl, strlen(pUrl)); Dbt lData; BOOL lIsNew = FALSE; CComObject* lEntryList; lEntryList = (CComObject*)m_Table.get(pUrl); if (lEntryList != NULL) { CComObject* lLockedEntryList; lLockedEntryList = lEntryList; if (!(pFlags & NO_LOCK)) { KB_LOG_INFO1("Unlocking Cache Entry [0x%1!x!]", this); // So that we do not have a Dead lock Unlock(); // Wait until lock is removed C_TRACE(" + Locking EntryList : 0x%x\n", lEntryList); lEntryList = (CComObject*)m_Table.get(pUrl); if (lEntryList && lEntryList->m_dwRef) lEntryList->Lock(); // Re-lock this Lock(); KB_LOG_INFO1("Relocking Cache Entry [0x%1!x!]", this); // the entry should be no more valid // so retry .... lEntryList = (CComObject*)m_Table.get(pUrl); } if (lEntryList != NULL) { if (!(pFlags & NO_LOCK)) { ATLASSERT(lLockedEntryList == lEntryList); if ((lLockedEntryList == lEntryList) && (lEntryList->m_dwRef)) { C_TRACE(" - Unlocking EntryList : 0x%x\n", lEntryList); lEntryList->Unlock(); } } *pEntry = lEntryList; (*pEntry)->AddRef(); return S_OK; } /* else { C_TRACE(" - Unlocking EntryList : 0x%x\n", lLockedEntryList); lLockedEntryList->Unlock(); } */ } if (m_pUrlDb->get(NULL, &lKey, &lData, 0) != S_OK) { if (pFlags & NO_FAILED) { lIsNew = TRUE; } else return E_FAIL; } CComObject::CreateInstance(&lEntryList); lEntryList->setCache(this); lEntryList->setUrl(pUrl); if (!lIsNew) { if (FAILED(lEntryList->readFromDb())) return E_FAIL; } if (pFlags & NO_FAILED) { m_Table.put(pUrl, lEntryList); C_TRACE(" + Locking EntryList : 0x%x\n", lEntryList); lEntryList->Lock(); } *pEntry = lEntryList; (*pEntry)->AddRef(); return S_OK; } #pragma optimize("", on) // ----------------------------------------------------------------------------- // // HRESULT TSevenixCache::checkUrl(LPCWSTR pUrl, CString& lResult, BOOL pExtendedUrl) { CString pUrlString(pUrl); TUrl lTmpUrl(pUrlString); lTmpUrl.canonicalize(); #if defined(_DEBUG) && defined (T_CHECK_CANONICAL_URL) // Make sure the url is canonicalized before the cache is called CString lCanonUrl; lCanonUrl = lTmpUrl.extendedUrlString(); ASSERT(lCanonUrl == pUrl); #endif TSevenixUrlInfo* lUrlExtendedInfo = (TSevenixUrlInfo*)lTmpUrl.getExtendedInfo(); if (lUrlExtendedInfo) lUrlExtendedInfo->removeProperty(T_ROOT_PROPERTY); if (pExtendedUrl) lResult = lTmpUrl.extendedUrlString(); else lResult = lTmpUrl.simpleUrlString(); // lResult.MakeLower(); return S_OK; } // ----------------------------------------------------------------------------- // // HRESULT TSevenixCache::createEntry(LPCWSTR pUrl, ISevenixCacheEntry** pEntry) { ASSERT(pEntry); if (pEntry == NULL) return E_INVALIDARG; CString lUrl; HRESULT lResult; lResult = checkUrl(pUrl, lUrl, FALSE); if (FAILED(lResult)) return lResult; // synchronize TComLockPtr< _Cache_Thread_Model > lLock(this); // get the Entry list CComPtr lEntryList; lResult = getUrlEntryList(lUrl, &lEntryList, NO_FAILED); ASSERT(SUCCEEDED(lResult)); lResult = lEntryList->createEntry(pUrl, pEntry); ASSERT(SUCCEEDED(lResult)); C_TRACE(_T("** Create Cache %s entry for %s\n"), SUCCEEDED(lResult) ? "SUCCEED" : "FAIL", CString(pUrl)); return lResult; // unlock is automatic, // Entry list Release is automatic } // ----------------------------------------------------------------------------- // // void TSevenixCache::unlock(LPCWSTR pUrl) { // synchronize TComLockPtr< _Cache_Thread_Model > lLock(this); CString lUrl; HRESULT lResult; lResult = checkUrl(pUrl, lUrl, FALSE); if (FAILED(lResult)) return ; CComPtr lEntryList; lEntryList = (TSCacheEntryList*)m_Table.get(lUrl); if (lEntryList) { C_TRACE(" - Unlocking EntryList : 0x%x\n", lEntryList); lEntryList->Unlock(); m_Table.remove(lUrl); } } // ----------------------------------------------------------------------------- // // HRESULT TSevenixCache::deleteEntry(LPCWSTR pUrl) { CString lUrl; HRESULT lResult; lResult = checkUrl(pUrl, lUrl, FALSE); if (FAILED(lResult)) return lResult; CComPtr lEntry; // synchronize TComLockPtr< _Cache_Thread_Model > lLock(this); CComPtr lList; lResult = getUrlEntryList(lUrl, &lList, NO_LOCK); if (lResult == S_OK) { lResult = lList->getElement(pUrl, &lEntry, MF_EXACT); if (lResult == S_OK) { (static_cast(lEntry.p))->setEntryList(lList); lResult = lEntry->remove(); } } return lResult; } // ----------------------------------------------------------------------------- // // HRESULT TSevenixCache::retrieveEntry(LPCWSTR pUrl, ISevenixCacheEntry** pEntry, LONG pFlags) { ASSERT(pEntry); if (pEntry == NULL) return E_INVALIDARG; CString lUrl; HRESULT lResult; lResult = checkUrl(pUrl, lUrl, FALSE); if (FAILED(lResult)) return lResult; // synchronize TComLockPtr< _Cache_Thread_Model > lLock(this); *pEntry = NULL; CComPtr lList; lResult = getUrlEntryList(lUrl, &lList); if (lResult == S_OK) { if ((pFlags == T_CACHE_EXACT_ELEMENT) || (pFlags == T_CACHE_BEST_ELEMENT)) { // try exact first HRESULT lResult; lResult = lList->getElementAt(pUrl, pEntry); if ((pFlags == T_CACHE_EXACT_ELEMENT) || SUCCEEDED(lResult)) return lResult; } return lList->getFreshestEntry(pEntry); } C_TRACE(_T("** Entry Cache not found %s\n"), lUrl); return lResult; } // ----------------------------------------------------------------------------- // // HRESULT TSevenixCache::getCachePath(BSTR* pPath) { ASSERT(pPath); if (pPath == NULL) return E_INVALIDARG; return m_CachePath.CopyTo(pPath); } // ----------------------------------------------------------------------------- // // void TSevenixCache::setPath(LPCWSTR pPath) { m_CachePath = pPath; openDb(); } // ----------------------------------------------------------------------------- // // CString TSevenixCache::constructPath(CString pHost) { // construct the 'cache + site' path TString lStrPath(m_CachePath); LPTSTR lPath = lStrPath.GetBuffer(MAX_PATH); PathAppend(lPath, pHost); lStrPath.ReleaseBuffer(); if (CreateDirectory(lPath, NULL) || (GetLastError() == ERROR_ALREADY_EXISTS)) { return lPath; } return CString(); } #ifdef DEBUG_CACHE void TSevenixCache::SetCacheName(LPCTSTR pName) { m_Name = pName; } LPCTSTR TSevenixCache::GetCacheName() { return m_Name; } #endif /*------------ TSP_IInternetProtocol.cpp ------------*/ // TSevenixProtocol.cpp : Implementation of TSevenixProtocol #include "StdAfx.h" #include "TNetDebug.h" #include "TSevenixProtocol.h" #include "Net.h" #include "NetResource.h" #include "TNetUtils.h" #include "TNetGlobals.h" #include "TNetHelpers.h" #include "TTime.h" #include "TErr.h" #include "TSevenixUrlInfo.h" #include "TPath.h" #include "TSystemMimeHelper.h" #include "TString.h" #include "shlwapi.h" DWORD gID = 0; // ******************************************************************************** // // Need to inprove the handling of PI flags in the cached part // HRESULT STDMETHODCALLTYPE TSevenixProtocol::Start(LPCWSTR szUrl, IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo, DWORD grfPI, DWORD dwReserved) { // Keep a Ref Count to this !!! CComPtr lThis(static_cast(this)); CHECK_MEMORY(); ATLASSERT(szUrl); ATLASSERT(pOIBindInfo); ATLASSERT(pOIProtSink); USES_CONVERSION; HRESULT lResult = S_OK; #ifdef DEBUG_PROTOCOL P_TRACE(_T("+ Application(IInternetProtocolRoot)(0x%X)::Start(%x) %s\n"), this, GetCurrentThreadId(), W2CT(szUrl)); #else TRACE(_T("+ Loading: %s\n"), W2CT(szUrl)); #endif // Parse URL and store results inside lResult = DoParse(szUrl); if (grfPI & PI_PARSE_URL) { if (FAILED(lResult)) return S_FALSE; else return S_OK; } CString lScheme; lScheme = m_Url.getExtendedScheme(); if (lScheme.Compare(KEEBOO_NETWORK_PROTOCOL)) { #ifdef DEBUG_PROTOCOL // This protocol should not be call for a scheme != "sevenix:" ATLASSERT(NULL); P_TRACE(_T("Invalid Protocol Scheme Request : %s\n -> Using Default Protocol Handler\n"), m_Url.extendedUrlString()); #endif m_ErrorState = INET_E_USE_DEFAULT_PROTOCOLHANDLER; return m_ErrorState; } // Save parameters m_GrfPI = grfPI; m_SupBindInfo = pOIBindInfo; m_SupSink = pOIProtSink; #ifdef DEBUG_PROTOCOL InterlockedIncrement((LONG*)&gID); InterlockedIncrement((LONG*)&gNbConnection); m_ID = gID; P_TRACE(_T(" -->> (0x%X) Connexion : %d / Concurrent : %d <<--\n"), this, m_ID, gNbConnection); // DumpAll(); #endif // DEBUG_PROTOCOL lResult = Load(); CHECK_MEMORY(); #ifdef DEBUG_PROTOCOL ATLASSERT(!m_IsLocked || m_dwRef > 1); #endif // DEBUG_PROTOCOL // TEMP : Should find where this leak !!!! if (m_IsLocked && m_dwRef == 1) AddRef(); return lResult; } // ******************************************************************************** // // Continue a Switch from the ProtocolSink // (this can be call by a MimeFilter ???) // HRESULT STDMETHODCALLTYPE TSevenixProtocol::Continue(PROTOCOLDATA *pProtocolData) { HRESULT lResult = S_OK; P_TRACE(_T("+ Application(IInternetProtocolRoot)::Continue\n")); if (m_StubProtocol != NULL) lResult = m_StubProtocol->Continue(pProtocolData); return lResult; } // ******************************************************************************** // // Abort a file retrieve // HRESULT STDMETHODCALLTYPE TSevenixProtocol::Abort(HRESULT hrReason, DWORD dwOptions) { USES_CONVERSION; HRESULT lResult = S_OK; ATLASSERT(!m_IsTerminate); #ifdef DEBUG_PROTOCOL P_TRACE(_T("- Application(IInternetProtocolRoot)(0x%X)::Abort(%s) Reason: %x\n"), this, W2CT(m_RealUrl), hrReason); if (m_DoNotLoad) { P_TRACE(_T("- We do not want to load this (%s)\n"), W2CT(m_RealUrl)); } if (m_BlockingState) DebugBreak(); // Do we still have a Stub Protocol // ATLASSERT(m_StubProtocol); #endif // Proxy the call if (m_StubProtocol != NULL) { lResult = m_StubProtocol->Abort(hrReason, dwOptions); } m_HaveAbort = TRUE; return lResult; } // ******************************************************************************** // // Clean up everything // HRESULT STDMETHODCALLTYPE TSevenixProtocol::Terminate(DWORD dwOptions) { CHECK_MEMORY(); HRESULT lResult = S_OK; // ATLASSERT(!m_HaveAbort); #ifdef DEBUG_PROTOCOL P_TRACE(_T("- Application(IInternetProtocolRoot)(0x%X)::Terminate %s\n"), this, m_IsLocked ? "Locked":"Unlocked"); #endif #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif // proxy call if (m_StubProtocol != NULL) { lResult = m_StubProtocol->Terminate(dwOptions); } if (!m_IsLocked) { CloseAll(); ReleaseAll(); } m_IsTerminate = TRUE; CHECK_MEMORY(); return lResult; } // ******************************************************************************** // IInternetProtocol : public IInternetProtocolRoot // // Read data in a buffer // HRESULT STDMETHODCALLTYPE TSevenixProtocol::Read(void* pv, ULONG cb, ULONG* pcbRead) { HRESULT lResult = S_FALSE; // By default, we've read nothing *pcbRead = 0; if ((m_IsTerminate && !m_IsLocked) || (m_DoNotLoad)) { P_TRACE(_T("+ Application(0x%X)::Read %d => Aborted\n"), this, cb); return S_FALSE; } P_TRACE(_T("+ Application(0x%X)::Read Request %d\n"), this, cb); if (m_bStorageState && !m_ReadFromCache) { if (m_Redirecting) { // If the data came from the error handler lResult = ReadFromErrorString(pv, cb, pcbRead); if (lResult != S_FALSE) { P_TRACE(_T("+ [0x%X] Read Done %d / %d : Result = %s\n"), this, *pcbRead, cb, lResult == S_OK ? "S_OK" : lResult == E_PENDING ? "E_PENDING" : lResult == S_FALSE ? "S_FALSE" : "Error"); return lResult; } m_Redirecting = FALSE; m_ErrorHtmlString.Empty(); m_CurrentRead = 0; m_bContinueRead = TRUE; } if (m_bContinueRead) { BSTR lUrl = NULL; BSTR lMime = NULL; if (m_RedirectUrl) lUrl = m_RedirectUrl; if (m_RedirectMime) lMime = m_RedirectMime; CheckNewCacheEntry(lUrl, lMime); StubRead(m_CurrentProgress - m_CurrentRead); } P_TRACE(_T("+ [0x%X] Read Done %d / %d : Result = %s\n"), this, *pcbRead, cb, lResult == S_OK ? "S_OK" : lResult == E_PENDING ? "E_PENDING" : lResult == S_FALSE ? "S_FALSE" : "Error"); } else { lResult = OnRead(pv, cb, pcbRead); } return lResult; } HRESULT TSevenixProtocol::OnRead(void* pv, ULONG cb, ULONG* pcbRead) { HRESULT lResult = S_OK; BOOL lReadFromCache = FALSE; // By default, we've read nothing *pcbRead = 0; P_TRACE(_T("+ [0x%X]::OnRead Request %d\n"), this, cb); #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif if (m_IsTerminate && !m_IsLocked) return S_FALSE; if (m_DoNotLoad) return S_FALSE; if ((m_HandleError || m_Redirecting) && !m_bStorageState) { // If the data came from the error handler lResult = ReadFromErrorString(pv, cb, pcbRead); } else if (m_CacheEntryAvailable) { // If the data came from the cache lResult = ReadFromCache(pv, cb, pcbRead); lReadFromCache = TRUE; } else { if (m_FirstRead) { CComQIPtr lHttpInfo(m_StubProtocol); SaveHeaders(lHttpInfo, FALSE); } lResult = ReadFromProtocol(pv, cb, pcbRead); } if ((SUCCEEDED(lResult) || (lResult == E_PENDING)) && m_WriteToCache && !lReadFromCache && (m_NewCacheEntry != NULL) && (*pcbRead != 0)) { ATLASSERT(!lReadFromCache); #ifdef DEBUG_PROTOCOL if (m_Redirecting && m_FirstRead) { P_TRACE(_T(" !! Redirection Saved in Cache\n")); } #endif lResult = WriteToCache(pv, *pcbRead); ATLASSERT(SUCCEEDED(lResult)); } if (*pcbRead) m_FirstRead = FALSE; if ((lReadFromCache || m_Redirecting) && (lResult == S_FALSE) && m_SupSink && (m_CurrentRead == m_TotalSize)) { OnReportResult(S_OK, 0, NULL); CloseAll(); } P_TRACE(_T("+ [0x%X] Read Done %d / %d : Result = %s\n"), this, *pcbRead, cb, lResult == S_OK ? "S_OK" : lResult == E_PENDING ? "E_PENDING" : lResult == S_FALSE ? "S_FALSE" : "Error"); return lResult; } // ******************************************************************************** // // Suspend the current action // HRESULT STDMETHODCALLTYPE TSevenixProtocol::Suspend( void) { // P_TRACE(_T(" Application(IInternetProtocolRoot)::Suspend\n")); // TO DO: in case of cached data #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif if (m_StubProtocol != NULL) return m_StubProtocol->Suspend(); return S_OK; } // ******************************************************************************** // // Resume the current action // HRESULT STDMETHODCALLTYPE TSevenixProtocol::Resume( void) { // P_TRACE(_T(" Application(IInternetProtocolRoot)::Resume\n")); // TO DO: in case of cached data #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif if (m_StubProtocol != NULL) return m_StubProtocol->Resume(); return S_OK; } // ******************************************************************************** // // // HRESULT STDMETHODCALLTYPE TSevenixProtocol::Seek(LARGE_INTEGER pMove, DWORD pOrigin, ULARGE_INTEGER* pNewPosition) { // P_TRACE(_T(" Application(IInternetProtocol)::Seek\n")); // TO DO: in case of cached data #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif if (m_StubProtocol != NULL) return m_StubProtocol->Seek(pMove, pOrigin, pNewPosition); return S_OK; } // ******************************************************************************** // // // HRESULT STDMETHODCALLTYPE TSevenixProtocol::LockRequest(DWORD dwOptions) { #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif P_TRACE(_T(" + Application(0x%X) Locking\n"), this); m_IsLocked = TRUE; if (m_StubProtocol != NULL) return m_StubProtocol->LockRequest(dwOptions); return S_OK; } // ******************************************************************************** // // // HRESULT STDMETHODCALLTYPE TSevenixProtocol::UnlockRequest(void) { CHECK_MEMORY(); HRESULT lResult = S_OK; #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif ATLASSERT(m_IsTerminate); if (m_StubProtocol != NULL) { lResult = m_StubProtocol->UnlockRequest(); } m_IsLocked = FALSE; if (m_IsTerminate) { CloseAll(); ReleaseAll(); P_TRACE(_T(" + Application(0x%X) Unlock, Releasing SupSink and StubHttpInfo\n"), this); } CHECK_MEMORY(); return lResult; } // ******************************************************************************** // ******************************************************************************** // ******************************************************************************** // // // DWORD WINAPI TSevenixProtocol::threadEntryPoint(LPVOID pData) { P_TRACE(_T(" *** New Thread Start ***\n")); TSevenixProtocol* lIProtocol = (TSevenixProtocol*)pData; lIProtocol->m_GrfPI &= ~PI_FORCE_ASYNC; HRESULT lResult = lIProtocol->Load(); lIProtocol->InternalRelease(); return lResult; } // ******************************************************************************** // // // HRESULT TSevenixProtocol::CreateStubProtocol() { ATLASSERT(m_StubProtocol == NULL); CString lScheme; lScheme = m_Url.getScheme(); // we've got to create an InternetProtocol for the sub-protocol m_ErrorState = CreateInstanceForProtocol(lScheme, IID_IInternetProtocol, (void**)&m_StubProtocol); ATLASSERT(SUCCEEDED(m_ErrorState)); if (SUCCEEDED(m_ErrorState)) { m_StubProtocol->QueryInterface(IID_IWinInetInfo, (void**)&m_StubInfo); } else { // Just to be sure !!!! m_StubProtocol = NULL; } return m_ErrorState; } // ******************************************************************************** // // // HRESULT TSevenixProtocol::Load() { USES_CONVERSION; HRESULT lResult = S_OK; if (m_GrfPI == PI_PARSE_URL) { m_ErrorState = CreateStubProtocol(); // if the protocol does not exist if (SUCCEEDED(m_ErrorState)) { CComQIPtr lIBindInfo(this); CComQIPtr lProxySink(this); TUrl lUrl(m_RealUrl); if (lUrl.getScheme() == "http") { lUrl.canonicalize(ICU_BROWSER_MODE|ICU_DECODE|ICU_NO_ENCODE); lUrl.canonicalize(ICU_BROWSER_MODE|ICU_ENCODE_PERCENT); } CComBSTR lStrUrl = lUrl.simpleUrlString(FALSE); m_ErrorState = m_StubProtocol->Start(lStrUrl, lProxySink, lIBindInfo, m_GrfPI, NULL); #ifdef DEBUG_PROTOCOL if (m_ErrorState != S_OK) { P_TRACE(_T("Stub Protocol Error(0x%X) Parsing URL(%s)\n"), lResult, W2CT(m_RealUrl)); } #endif // DEBUG_PROTOCOL } #ifdef DEBUG_PROTOCOL // we do not use the protocol // InterlockedDecrement((LONG*)&gNbConnection); #endif return m_ErrorState; } if ((m_GrfPI & PI_FORCE_ASYNC) && (m_ThreadId == 0)) { P_TRACE(_T(" *** Load Asynchronously ***\n")); InternalAddRef(); HANDLE hInst = CreateThread(NULL, 0, threadEntryPoint, this, 0, &m_ThreadId); ATLASSERT(hInst); if (hInst != NULL) { ::CloseHandle(hInst); m_ErrorState = E_PENDING; return m_ErrorState; } // if failed InternalRelease(); } DWORD lUseNetwork = 1; // DWORD lCanNavigate = 1; DWORD lSize; lResult = CoInternetQueryInfo(m_RealUrl, QUERY_USES_NETWORK, 0, &lUseNetwork, sizeof(lUseNetwork), &lSize, 0); if (FAILED(lResult)) lUseNetwork = 0; m_bLocalFile = !lUseNetwork; #ifdef DEBUG_PROTOCOL if (lResult != S_OK) { P_TRACE(_T("QueryInfo Error(0x%X) for URL(%s)\n"), lResult, W2CT(m_RealUrl)); } #endif // DEBUG_PROTOCOL BOOL lConnected = FALSE; BOOL lIsOnLine = FALSE; CComPtr lNetStatus; lResult = lNetStatus.CoCreateInstance(CLSID_TInternetStatus); ATLASSERT(SUCCEEDED(lResult)); if (SUCCEEDED(lResult)) { BOOL lConfigured = FALSE; lResult = lNetStatus->IsConnectionConfigured(&lConfigured); ATLASSERT(SUCCEEDED(lResult)); if (!lConfigured) lNetStatus->ConfigureConnection(); lResult = lNetStatus->GetOnline(&lIsOnLine); ATLASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) { // Should be an internal Error return HandleError(INET_E_CANNOT_CONNECT, 0, NULL); } } BOOL lNoCache = FALSE; DWORD lBindFlag = 0; BINDINFO lBindInfo; memset(&lBindInfo, 0, sizeof(BINDINFO)); lBindInfo.cbSize = sizeof(BINDINFO); GetBindInfo(&lBindFlag, &lBindInfo); if (lBindFlag & BINDF_OFFLINEOPERATION) m_LoadFromNetwork = FALSE; // if (lBindFlag & BINDF_PRAGMA_NO_CACHE) // lNoCache = TRUE; TSevenixUrlInfo* lInfo; lInfo = (TSevenixUrlInfo*)m_Url.getExtendedInfo(); if (lInfo->haveProperty(T_NO_RELOAD_PROPERTY)) { m_LoadFromNetwork = FALSE; } if (!lNoCache && !lInfo->haveProperty(T_NO_CACHE_PROPERTY)) { CheckLocalData(lIsOnLine, lUseNetwork); } // if this is a remote protocol if (lUseNetwork) { // if we're offline if (!lIsOnLine) { // we don't use the cached file if (!m_CacheEntryAvailable) { m_DoNotLoad = TRUE; m_ErrorState = S_FALSE; } else { m_ErrorState = LoadFromCache(); } } else { // we're online if (!m_CacheEntryAvailable && lNetStatus) { lNetStatus->IsConnectionOpen(&lConnected); if (!lConnected) { lNetStatus->OpenConnection(); lNetStatus->IsConnectionOpen(&lConnected); } } // if we're online (remote protocol) and we don't use the cached file if (!m_CacheEntryAvailable && lConnected && m_LoadFromNetwork) { m_ErrorState = LoadFromProtocol(); } else { // check date // if too old && lConnectionConfigured // LoadFromProtocol if (m_CacheEntryAvailable) m_ErrorState = LoadFromCache(); else { if (m_LoadFromNetwork) m_ErrorState = INET_E_DOWNLOAD_FAILURE; else { // We do not want to report data in this case // so we have a specific Error # to handle this m_ErrorState = INET_E_NO_VALID_MEDIA; } } } } } else // data is local { // do we have a cache entry if (m_CacheEntryAvailable) { m_ErrorState = LoadFromCache(); } // cache is stale if (!m_CacheEntryAvailable) // || FAILED(m_ErrorState)) { // as this is a local protocol, // we do not need to check the connexion m_WriteToCache = FALSE; m_ErrorState = LoadFromProtocol(); CHECK_MEMORY(); } } if (m_ErrorState != E_PENDING && FAILED(m_ErrorState)) { return HandleError(m_ErrorState, 0, NULL); } CHECK_MEMORY(); return m_ErrorState; } // ******************************************************************************** // // // HRESULT TSevenixProtocol::CheckFreshness() { USES_CONVERSION; HRESULT lResult; FILETIME lFileDate; SYSTEMTIME lSysTime; DWORD lSize = sizeof(lSysTime); if (m_StubInfo) { lResult = m_StubInfo->QueryOption(QUERY_TIME_OF_LAST_CHANGE, &lSysTime, &lSize); } else { lResult = CoInternetQueryInfo(m_RealUrl, QUERY_TIME_OF_LAST_CHANGE, 0, &lSysTime, sizeof(lSysTime), &lSize, 0); } if (SUCCEEDED(lResult)) { SystemTimeToFileTime(&lSysTime, &lFileDate); } else { CComPtr lMoniker; CComPtr lBindCtx; lResult = CreateBindCtx(0, &lBindCtx); ATLASSERT(SUCCEEDED(lResult)); if (SUCCEEDED(lResult)) { lResult = CreateURLMoniker(NULL, m_RealUrl, &lMoniker); if (SUCCEEDED(lResult)) lResult = lMoniker->GetTimeOfLastChange(lBindCtx, NULL, &lFileDate); TUrl lFileUrl(m_RealUrl); if (FAILED(lResult) && (lFileUrl.getScheme() == "file")) { CString lPath; lPath = lFileUrl.getHost() + lFileUrl.getFile(); lMoniker.Release(); lResult = CreateFileMoniker(T2CW(lPath), &lMoniker); if (SUCCEEDED(lResult)) lResult = lMoniker->GetTimeOfLastChange(lBindCtx, NULL, &lFileDate); } } } CString lFileString; CComBSTR lDate; if (lResult == S_OK) { InternetTimeFromFileTime(&lFileDate, lFileString.GetBuffer(INTERNET_RFC1123_BUFSIZE)); lFileString.ReleaseBuffer(); lResult = m_CurrentCacheEntry->getHeader(T_HEADER_LOCAL_DATE, 0, &lDate); ATLASSERT(lResult == S_OK); } return lResult; } // ******************************************************************************** // // // HRESULT TSevenixProtocol::LoadFromProtocol() { USES_CONVERSION; HRESULT lResult = S_FALSE; P_TRACE(_T("¤¤ [0x%x]::LoadFromProtocol: %s\n"), this, W2CT(m_RealUrl)); // We can use the underlying protocol lResult = CreateStubProtocol(); if (FAILED(lResult)) return HandleError(lResult, 0, NULL); SetQueryFlags(); // m_WriteToCache = TRUE; // we've got to proxy the callback, to catch interresting // cache info, like "mime" an cache file name CComQIPtr lIBindInfo(this); CComQIPtr lProxySink(this); TUrl lUrl(m_RealUrl); if (lUrl.getScheme() == "http") { lUrl.canonicalize(ICU_BROWSER_MODE|ICU_DECODE|ICU_NO_ENCODE); lUrl.canonicalize(ICU_BROWSER_MODE|ICU_ENCODE_PERCENT); } CComBSTR lStrUrl = lUrl.simpleUrlString(FALSE); m_ErrorState = m_StubProtocol->Start(lStrUrl, lProxySink, lIBindInfo, m_GrfPI, NULL); if (m_ErrorState == E_PENDING) { m_Pending = TRUE; } else if ((m_ErrorState != S_OK) && (m_StatusCode != HTTP_STATUS_OK) && (m_CurrentCacheEntry != NULL) && !m_HaveReportResult) { // if the cached file is up to date m_WriteToCache = FALSE; m_ErrorState = LoadFromCache(); } return m_ErrorState; } // ******************************************************************************** // // // HRESULT TSevenixProtocol::LoadFromCache() { USES_CONVERSION; CComPtr lCacheEntry; HRESULT lResult = S_OK; CComBSTR lFileName; CComBSTR lMime; CComBSTR lEncoding; CComBSTR lStrSize; long lSize = -1; BOOL lHaveFileName; BOOL lHaveMime; BOOL lHaveEncoding; BOOL lHaveSize; P_TRACE(_T("¤¤ [0x%x]::LoadFromCache: %s\n"), this, W2CT(m_RealUrl)); ATLASSERT(m_StubProtocol == NULL); // We are Offline or we need to use the cached file if ((m_CurrentCacheEntry == NULL) || (m_SupSink == NULL)) { // Warn the user m_ErrorState = INET_E_DOWNLOAD_FAILURE; // lResult = ReportResult(m_ErrorState, 0, L"Switch Online !!!"); return m_ErrorState; } lCacheEntry = m_CurrentCacheEntry; m_CacheEntryAvailable = TRUE; m_ReadFromCache = TRUE; lHaveFileName = (lCacheEntry->getFileName(&lFileName) == S_OK); lHaveMime = (lCacheEntry->getHeader(T_HEADER_MIME_TYPE, 0, &lMime) == S_OK); lHaveSize = ((lCacheEntry->getHeader(T_HEADER_SIZE, 0, &lStrSize) == S_OK) && lStrSize); lHaveEncoding = (lCacheEntry->getHeader(L"Content-Encoding", 0, &lEncoding) == S_OK); // Report the mime if (!lHaveMime && lHaveFileName) { CString lFileNameExtension; CString lName(lFileName); BOOL resFindExt = TPath::FindExtension(lName, lFileNameExtension); if (resFindExt && (!lFileNameExtension.IsEmpty())) { TString lFoundMime; TSystemMimeHelper* lMimeHelper = new TSystemMimeHelper(); HRESULT resFindMime = lMimeHelper->getFirstMimeTypeFromFileExtension(lFileNameExtension, lFoundMime); if ( (resFindMime == S_OK) && (!lFoundMime.IsEmpty()) ) { // // Special case for ASP files: // ASP cached file are HTML files // if (lFoundMime == "text/asp") lFoundMime = "text/html"; lMime = lFoundMime; lHaveMime = TRUE; } delete lMimeHelper; } if (!lHaveMime) { CFileStatus lStatus; if (!CFile::GetStatus(lName, lStatus)) return INET_E_DOWNLOAD_FAILURE; // Default values !!! lMime = "text/html"; } } // we report the mime to the sink if (lHaveMime) { lResult = FilterMime(lMime); if (m_HandleError || m_Redirecting) return lResult; if (lHaveEncoding) lMime = lEncoding; lResult = SupReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, lMime); ATLASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) return lResult; } if (lHaveSize) { LPWSTR lStop; lSize = wcstol(lStrSize, &lStop, 10); } // report the name of the cached file. if (lHaveFileName) { BOOL lGetStatus; CFileStatus lStatus; lGetStatus = CFile::GetStatus(W2CT(lFileName), lStatus); ATLASSERT(lGetStatus == TRUE); if (lGetStatus) { lResult = SupReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE, lFileName); ATLASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) return lResult; if (!lHaveSize) { ATLASSERT(lSize == -1); lSize = lStatus.m_size; } } } m_TotalSize = lSize; return AllDataAvailable(); } // ******************************************************************************** // // // HRESULT TSevenixProtocol::ReadFromCache(void *pv, ULONG cb, ULONG *pcbRead) { USES_CONVERSION; HRESULT lResult = S_OK; // If we've got a cache entry // we're supposed to have one ATLASSERT(m_CurrentCacheEntry); if (m_CurrentCacheEntry == NULL) return INET_E_DATA_NOT_AVAILABLE; *pcbRead = 0; // If the local file is not already open // Get the file name if ((m_LocalFile == NULL) && (m_CurrentRead == 0)) { CComBSTR lFileName; m_CurrentCacheEntry->getFileName(&lFileName); m_LocalFile = new CStdioFile(); if (!m_LocalFile->Open(CString(lFileName), CFile::modeRead | CFile::typeBinary | CFile::shareDenyNone)) return INET_E_DATA_NOT_AVAILABLE; } if (m_LocalFile) { TRY { // Read from file *pcbRead = m_LocalFile->Read(pv, cb); } CATCH (CFileException, e) { CComBSTR lFileName; m_CurrentCacheEntry->getFileName(&lFileName); TErr::trace( TErr::D_LOG|TErr::D_OUT, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, _T("Cache %1 error: Url %2, Filename %3\nThe cache entry does not seems to be valid\nIt will be remove from the cache..."), _T("read"), W2CT(m_RealUrl), (LPCTSTR)CString(lFileName) ); lResult = INET_E_DATA_NOT_AVAILABLE; // Do we try the download version ??? // m_CacheEntryAvailable = false; } END_CATCH m_CurrentRead += *pcbRead; } if ((!*pcbRead) || (*pcbRead < cb)) lResult = S_FALSE; ATLASSERT(SUCCEEDED(lResult)); return lResult; } // ******************************************************************************** // // // HRESULT TSevenixProtocol::ReadFromProtocol(void *pv, ULONG cb, ULONG *pcbRead) { USES_CONVERSION; HRESULT lResult = S_OK; // If we've got a protocol interface // we're supposed to have one ATLASSERT(m_StubProtocol); if (m_StubProtocol == NULL) return E_FAIL; if (m_FirstRead && (m_NewCacheEntry == NULL)) CheckNewCacheEntry(m_RealUrl, m_MimeType); // Read data from stub protocol lResult = m_StubProtocol->Read(pv, cb, pcbRead); if (m_FirstRead && (m_MimeType.Length() == 0)) { LPWSTR lSugestion = NULL; lResult = FindMimeFromData(NULL, NULL, pv, *pcbRead, NULL, 0, &lSugestion, 0); m_MimeType = lSugestion; if ((lSugestion == NULL) || !wcscmp(lSugestion, L"text/plain") || !wcscmp(lSugestion, L"application/octet-stream")) { *pcbRead = 0; return HandleError(INET_E_TYPE_NOT_SUPPORTED, 0, L""); } } m_CurrentRead += *pcbRead; #ifdef DEBUG_PROTOCOL /* if (m_FirstRead) { m_LastRead = CString((char*)pv, *pcbRead); if (m_LastRead.Find("Socket Error") >= 0) ATLASSERT(m_StatusCode == 200); } */ #endif #ifdef DEBUG_PROTOCOL if (!SUCCEEDED(lResult) && (lResult != E_PENDING)) { TErr::trace( TErr::D_LOG|TErr::D_OUT, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, _T("Net read error: Url %1\n Result=#%2!x!"), W2CT(m_RealUrl), lResult ); } #endif // DEBUG_PROTOCOL #if defined(_DEBUG) && defined(WARN_NO_CACHE_ENTRY) if ((m_NewCacheEntry == NULL) && fFirstRead) { TErr::trace( TErr::D_LOG|TErr::D_OUT, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, _T("Cache %1 error: Url %2, Filename %3\nThe cache entry does not seems to be valid\nIt will be remove from the cache..."), _T("no entry"), W2CT(m_RealUrl), _T("none") ); } #endif // _DEBUG // PS: // Under IE 5.5, there's a strange behaviour // The ReportData is called twice, so there's two Read session // The second Read report nothing, so I've try to report the buffer twice // but with no success ( I think there's a bug in the navigation due to this ! ). #ifdef REPORT_LAST_BUFFER_TWICE if (m_LastBufferAddr == pv) { *pcbRead = m_LastReadSize; } if (lResult == S_FALSE && *pcbRead) { m_LastBufferAddr = pv; m_LastReadSize = *pcbRead; } #endif // REPORT_LAST_BUFFER_TWICE return lResult; } #define STUB_READ_BUFFER_SIZE 8192 HRESULT TSevenixProtocol::StubRead(DWORD pLength) { if (m_bStubReading) return E_FAIL; P_TRACE("-- Stub Reading\n"); m_bStubReading = TRUE; BYTE* lData = NULL; LONG lLength = STUB_READ_BUFFER_SIZE; DWORD lSize; DWORD lReaded = 0; HRESULT lResult = S_OK; lData = new BYTE[lLength]; while (lResult == S_OK) { lSize = 0; lResult = OnRead(lData, lLength, &lSize); lReaded += lSize; } delete lData; if (lResult == S_FALSE) { SupReportResult(S_OK, 0, NULL); m_bContinueRead = FALSE; } P_TRACE("-- End Stub Reading\n"); m_bStubReading = FALSE; return lResult; } // ******************************************************************************** // // // HRESULT TSevenixProtocol::WriteToCache(void *pData, ULONG pLength) { USES_CONVERSION; CComBSTR lFileName; TRY { // if everything was ok, // and we need to cache data // and we've got something to write if (pLength != 0) { // If it's the first time // We need to open the file in Write mode if (m_LocalFile == NULL) { USES_CONVERSION; m_NewCacheEntry->getFileName(&lFileName); m_LocalFile = new CFile(); m_LocalFile->Open(W2CT(lFileName), CFile::modeWrite | CFile::modeCreate | CFile::shareDenyWrite); } // Write data to cache file m_LocalFile->Write(pData, pLength); } } CATCH (CFileException, e) { lFileName.Empty(); m_NewCacheEntry->getFileName(&lFileName); TErr::trace( TErr::D_LOG|TErr::D_OUT, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, _T("Cache %1 error: Url %2, Filename %3\nThe cache entry does not seems to be valid\nIt will be remove from the cache..."), _T("write"), W2CT(m_RealUrl), (LPCTSTR)CString(lFileName) ); return E_FAIL; } END_CATCH return S_OK; } // ******************************************************************************** // // // HRESULT TSevenixProtocol::ReadFromErrorString(void *pv, ULONG cb, ULONG *pcbRead) { ATLASSERT(m_HandleError || m_Redirecting); // Read from error string LONG lStillToRead = m_ErrorHtmlString.GetLength() - m_CurrentRead; if (lStillToRead <= 0) return S_FALSE; // ATLASSERT(cb <= lStillToRead); LONG lGoingToRead = min(cb, lStillToRead); CString lSubString = m_ErrorHtmlString.Mid(m_CurrentRead, lGoingToRead); memcpy(pv, lSubString, lGoingToRead); *pcbRead = lGoingToRead; m_CurrentRead += lGoingToRead; // no more to read if (lGoingToRead < cb) return S_FALSE; return S_OK; } // ******************************************************************************** // // // void TSevenixProtocol::CloseAll() { if (!m_HaveAbort && m_TotalSize && (m_CurrentRead != m_TotalSize)) { // simulate an abortion to remove // the data from the cache m_HaveAbort = TRUE; } // If we've got a local file if (m_LocalFile != NULL) { #ifdef DEBUG_CACHE CComBSTR lCacheName; CString lFileName; lFileName = m_LocalFile->GetFilePath(); if (m_NewCacheEntry) { m_NewCacheEntry->getFileName(&lCacheName); ATLASSERT(lFileName == CString(lCacheName)); } C_TRACE(_T("Closing file %s\n"), CString(lFileName)); #endif // we've got to close it if (m_NewCacheEntry) // If new file, flush m_LocalFile->Flush(); #ifdef DEBUG_CACHE else { if (!m_HaveAbort) { CFileStatus lStatus; m_LocalFile->GetStatus(lStatus); ATLASSERT(lStatus.m_size == m_CurrentRead); ATLASSERT(m_TotalSize == m_CurrentRead); } } #endif // DEBUG_CACHE m_LocalFile->Close(); delete m_LocalFile; m_LocalFile = NULL; } if (m_NewCacheEntry != NULL) { if (!m_HaveAbort) { // saved Headers m_NewCacheEntry->commit(); } else { // clean up the cache so that an invalid entry // is not insert m_NewCacheEntry->remove(); } m_NewCacheEntry = NULL; // Save cache to disk so that a crash won't screw it } } void TSevenixProtocol::ReleaseAll() { m_SupBindInfo.Release(); if (!m_IsLocked) { m_SupSink.Release(); m_StubInfo.Release(); m_StubProtocol.Release(); if (m_bReleaseOnQuit) Release(); } else { P_TRACE(_T(" - Protocol is Locked, so do not Release SupSink and StubHttpInfo\n")); } } // URL Form for sevenix: protocol is as such: // sevenix:[(...)][//] // (ex) sevenix:(id:125)//http://www.microsoft.com // (ex) sevenix:(id:78)http://www.microsoft.com // (ex) sevenix://http://www.microsoft.com // (ex) sevenix:http://www.microsoft.com HRESULT TSevenixProtocol::DoParse(LPCWSTR wstrURLIn) { USES_CONVERSION; wchar_t* pPathStart; int len; int lCompare; HRESULT hr = S_OK; // default is success m_Url = wstrURLIn; // Remove everything preceding first ":" pPathStart = wcschr(wstrURLIn, ':'); if (NULL != pPathStart) { pPathStart++; len = pPathStart - wstrURLIn - 1; lCompare = wcsncmp(A2CW(KEEBOO_NETWORK_PROTOCOL), wstrURLIn, len); } else { pPathStart = (LPWSTR)wstrURLIn; // protocol = NULL; lCompare = -1; } // Dummy Check - shouldn't ever fail this if (lCompare != 0) { // _ASSERTE(FALSE); ATLTRACE(_T("IIP::Start - Protocol != sevenix\n")); hr = S_FALSE; return hr; } // Remove "//" from string if there, URL syntax allows for other stuff here (//// for instance) while (L'/' == *pPathStart) pPathStart++; // long lFlags = ICU_BROWSER_MODE; // m_RealUrl = m_Url.canonicalizedUrlString(false, lFlags); // m_Url.canonicalize(ICU_BROWSER_MODE|ICU_DECODE|ICU_NO_ENCODE); // m_Url.canonicalize(ICU_BROWSER_MODE|ICU_ENCODE_PERCENT); m_RealUrl = m_Url.simpleUrlString(FALSE); TSevenixUrlInfo* lInfo; lInfo = (TSevenixUrlInfo*)m_Url.getExtendedInfo(); if (lInfo && lInfo->haveProperty(T_ROOT_PROPERTY)) m_RootDocument = TRUE; return hr; } /*------------ TSP_IInternetProtocolInfo.cpp ------------*/ #include "StdAfx.h" #ifndef T_INTERNET_PROTOCOL #include "TSevenixProtocol.h" #endif #include "TNetDebug.h" #include "TNetGlobals.h" #include "TNetHelpers.h" #include "TSevenixUrl.h" #include "TSevenixUrlInfo.h" #include "TEmbedMimeHelper.h" ///////////////////////////////////////////////////////////////////////////// // TSevenixProtocol #define MATCH_MY_PROTOCOL(action) ( action == PARSE_CANONICALIZE \ || action == PARSE_ROOTDOCUMENT \ || action == PARSE_DOCUMENT \ || action == PARSE_ENCODE \ || action == PARSE_DECODE) #include "mshtmhst.h" #include "intshcut.h" //T IInternetProtocolInfo // -------------------------------------------------------------------------------- // // STDMETHODIMP TSevenixProtocol::ParseUrl(LPCWSTR pwzUrl, PARSEACTION pParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult, DWORD* pcchResult, DWORD dwReserved) { CHECK_MEMORY(); m_UsedForInfo = TRUE; USES_CONVERSION; HRESULT lResult = S_OK; TUrl lUrl(pwzUrl); BOOL lAddExtended = TRUE; PARSEACTION lParseAction = pParseAction; PSUACTION lSecurityAction = PSU_DEFAULT; BOOL lIsSecurityAction = FALSE; LPWSTR lSecurity; LPSTR ppszTranslatedURL = NULL; #ifdef _DEBUG CString lFlagsString; #endif // _DEBUG switch (pParseAction) { case PARSE_CANONICALIZE: #ifdef _DEBUG if (dwParseFlags & ICU_BROWSER_MODE) lFlagsString += "Browser Mode, "; if (dwParseFlags & ICU_ENCODE_PERCENT) lFlagsString += "Encode Percent, "; if (dwParseFlags & ICU_ENCODE_SPACES_ONLY) lFlagsString += "Encode Spaces Only, "; if (dwParseFlags & ICU_NO_ENCODE) lFlagsString += "No Encode, "; if (dwParseFlags & ICU_NO_META) lFlagsString += "No Meta, "; #endif // We must use the none Unicode version of this function lResult = KBTranslateURL(lUrl.simpleUrlString(FALSE), TRANSLATEURL_FL_USE_DEFAULT_PROTOCOL , &ppszTranslatedURL); // if Result == S_FALSE, we do not need translation if (lResult != S_FALSE) { #ifdef DEBUG_PROTOCOL_INFO P_TRACE(_T("> TranslateURL: %s\n"), lUrl.simpleUrlString(FALSE)); P_TRACE(_T("> => %d : %s\n"), lResult, A2T(ppszTranslatedURL)); #endif lUrl = ppszTranslatedURL; } break; case PARSE_FRIENDLY: case PARSE_ROOTDOCUMENT: case PARSE_DOCUMENT: case PARSE_ANCHOR: case PARSE_ENCODE: case PARSE_DECODE: case PARSE_PATH_FROM_URL: case PARSE_URL_FROM_PATH: case PARSE_MIME: case PARSE_SERVER: case PARSE_SCHEMA: case PARSE_SITE: case PARSE_LOCATION: case PARSE_DOMAIN: break; case PARSE_SECURITY_URL: lIsSecurityAction = TRUE; lSecurityAction = PSU_SECURITY_URL_ONLY; break; case PARSE_SECURITY_DOMAIN: lIsSecurityAction = TRUE; lSecurityAction = PSU_DEFAULT; break; } CString lSimpleUrl = lUrl.simpleUrlString(FALSE); // CoInitialize(NULL); if (lIsSecurityAction) { #ifdef DEBUG_PROTOCOL_INFO P_TRACE(_T("*> ParseUrl(%s, %s)\n"), lUrl.simpleUrlString(FALSE), GetParseActionString(pParseAction)); #endif lResult = CoInternetGetSecurityUrl(T2CW(lSimpleUrl), &lSecurity, lSecurityAction, 0); if (lResult == S_OK) { DWORD lSize = wcslen(lSecurity) + 1; *pcchResult = lSize; if (lSize <= cchResult) { wcscpy(pwzResult, lSecurity); } else { lResult = S_FALSE; } } } else { lResult = CoInternetParseUrl(T2CW(lSimpleUrl), lParseAction, dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved); } // CoUninitialize(); if (lResult != S_OK) { #ifdef DEBUG_PROTOCOL_INFO P_TRACE(_T("&& Error \"%s\" in ParseUrl(%s, %s) => %s \n"), GetInetError(lResult), lSimpleUrl, GetParseActionString(lParseAction), W2CT(pwzResult)); #endif // DEBUG_PROTOCOL pwzResult[0] = 0; // return lResult; } else if (*pcchResult != 0) { TUrl lResultUrl = pwzResult; CString lScheme; lScheme = lResultUrl.getScheme(); if ((lScheme.Find("script") < 0) && (lScheme != _T("mailto")) && (lScheme != _T("news")) && (lScheme != _T("nntp"))) { if (MATCH_MY_PROTOCOL(pParseAction)) { // copy the exact protocol lResultUrl.setExtendedInfo(lUrl.getExtendedInfo()); } else if (pParseAction == PARSE_URL_FROM_PATH) { // add the right protocol lResultUrl.setExtendedInfo(TSevenixUrl("").getExtendedInfo()); } else { lAddExtended = FALSE; } if (lAddExtended) { CString lExtendedUrl = lResultUrl.extendedUrlString(FALSE); DWORD lSize = lExtendedUrl.GetLength() + 1; *pcchResult = lSize; if (lSize <= cchResult) { wcscpy(pwzResult, T2CW(lExtendedUrl)); } else { lResult = S_FALSE; } } } } // pwzResult[*pcchResult] = 0; CHECK_MEMORY(); #ifdef DEBUG_PROTOCOL if (lResult != S_OK) return lResult; switch (pParseAction) { case PARSE_CANONICALIZE: case PARSE_FRIENDLY: case PARSE_DOCUMENT: case PARSE_ANCHOR: case PARSE_ENCODE: case PARSE_DECODE: case PARSE_PATH_FROM_URL: case PARSE_URL_FROM_PATH: case PARSE_MIME: case PARSE_SERVER: case PARSE_SCHEMA: case PARSE_SITE: case PARSE_LOCATION: case PARSE_ROOTDOCUMENT: break; case PARSE_SECURITY_URL: case PARSE_DOMAIN: case PARSE_SECURITY_DOMAIN: P_TRACE(_T("*> ParseUrl(%s, %s)\n"), W2CT(pwzUrl), GetParseActionString(pParseAction)); P_TRACE(_T(" => %s\n"), W2T(pwzResult)); } #endif // DEBUG_PROTOCOL return lResult; } // -------------------------------------------------------------------------------- // // STDMETHODIMP TSevenixProtocol::CombineUrl(LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD pFlags, LPWSTR pwzResult, DWORD pStrSize, DWORD* pSizeResult, DWORD dwReserved) { CHECK_MEMORY(); #ifdef _DEBUG CString lFlagsString; if (pFlags & ICU_BROWSER_MODE) lFlagsString += "Browser Mode, "; if (pFlags & ICU_ENCODE_PERCENT) lFlagsString += "Encode Percent, "; if (pFlags & ICU_ENCODE_SPACES_ONLY) lFlagsString += "Encode Spaces Only, "; if (pFlags & ICU_NO_ENCODE) lFlagsString += "No Encode, "; if (pFlags & ICU_NO_META) lFlagsString += "No Meta, "; #endif CComBSTR lProtocol(KEEBOO_NETWORK_PROTOCOL":"); // if is already sevenix protocol if (!wcsncmp(lProtocol, pwzRelativeUrl, lProtocol.Length())) { DWORD lSize; lSize = wcslen(pwzRelativeUrl); // buffer too small if (pStrSize < lSize) return S_FALSE; wcscpy(pwzResult, pwzRelativeUrl); *pSizeResult = lSize; return S_OK; } m_UsedForInfo = TRUE; USES_CONVERSION; HRESULT lResult = S_FALSE; DWORD lExtensionSize = 0; BOOL lAddExtension = TRUE; BOOL lEmbed = FALSE; TSevenixUrlInfo* lInfo = NULL; // make a TUrl class TUrl lBaseUrl(pwzBaseUrl); // extract a simple Url CComBSTR bstr_lBaseUrl(lBaseUrl.simpleUrlString(FALSE)); // get the extension size lInfo = (TSevenixUrlInfo*)lBaseUrl.getExtendedInfo(); if (lInfo) { lExtensionSize = lInfo->getSize(); lInfo->removeProperty(T_ROOT_PROPERTY); } if (pFlags & ICU_BROWSER_MODE) { // if is embed if (!wcsncmp(L"embed:", pwzRelativeUrl, 6)) { pwzRelativeUrl += 6; lEmbed = TRUE; #ifdef TEST_CAN_CACHE_EMBED TEmbedMimeHelper* lHelper; lHelper = new TEmbedMimeHelper(); if (!lHelper->canCacheFile(W2CT(pwzRelativeUrl))) lAddExtension = FALSE; delete lHelper; #else // TEST_CAN_CACHE_EMBED lAddExtension = FALSE; #endif // TEST_CAN_CACHE_EMBED } } // if the buffer is bigger then the extension size if ((pStrSize - lExtensionSize) > 0) { // CoInitialize(NULL); // --- call the underlying protocol Url combination lResult = CoInternetCombineUrl( bstr_lBaseUrl, pwzRelativeUrl, pFlags, pwzResult, pStrSize - lExtensionSize, pSizeResult, dwReserved); // CoUninitialize(); } // if we successed if (lResult == S_OK) { // if the result size > 0 // an if we have an extension if ((*pSizeResult > 0) && lExtensionSize) { pwzResult[*pSizeResult] = 0; TUrl lResultUrl(pwzResult); // PS: // Need to canonicalize URL here // because of a Bug with the "res:" protocol and the sticker images. // I don't know exactly why, but if you don't canonicalize // after the getScheme, the file extension ".DLL" became ".DLLLL" // This happen only on some platform, and some page. lResultUrl.canonicalize(pFlags); // Hack: // we add the extra info only if we're not in a scripting Url // This should be done on a higher level CString lScheme = lResultUrl.getScheme(); if ((lScheme.Find("script") >= 0) && (lScheme.Find("mailto") == 0)) lAddExtension = FALSE; if (lAddExtension) { // copy the extra info in this new Url lResultUrl.setExtendedInfo(lBaseUrl.getExtendedInfo()); CString lExtUrl = lResultUrl.extendedUrlString(FALSE); // Calc the new size DWORD lNewSize = lExtUrl.GetLength(); // add the size to the result *pSizeResult = lNewSize; if (pStrSize < lNewSize) return S_FALSE; wcscpy(pwzResult, T2CW(lExtUrl)); // Check the new size validity ASSERT(lNewSize == wcslen(pwzResult)); } } else { // Just so the buffer is a valid string *pSizeResult = 0; pwzResult[0] = 0; } } CHECK_MEMORY(); return lResult; } // -------------------------------------------------------------------------------- // // STDMETHODIMP TSevenixProtocol::CompareUrl(LPCWSTR pwzUrl1, LPCWSTR pwzUrl2, DWORD dwCompareFlags) { CHECK_MEMORY(); m_UsedForInfo = TRUE; // P_TRACE("TSevenixProtocolInfo::CompareUrl", NULL); TUrl lUrl1(pwzUrl1); TUrl lUrl2(pwzUrl2); CComBSTR bstr_lUrl1 = lUrl1.simpleUrlString(); CComBSTR bstr_lUrl2 = lUrl2.simpleUrlString(); // CoInitialize(NULL); HRESULT lResult = CoInternetCompareUrl(bstr_lUrl1, bstr_lUrl2, dwCompareFlags); // CoUninitialize(); return lResult; } enum { NEED_CACHE = 0x01, USE_MONIKER = 0x02 }; long gQueryFlags[] = { /* QUERY_EXPIRATION_DATE */ sizeof(SYSTEMTIME), NEED_CACHE, /* QUERY_TIME_OF_LAST_CHANGE */ sizeof(SYSTEMTIME), NEED_CACHE | USE_MONIKER, /* QUERY_CONTENT_ENCODING */ 0, NEED_CACHE, /* QUERY_CONTENT_TYPE */ 0, NEED_CACHE, /* QUERY_REFRESH */ 0, 0, /* QUERY_RECOMBINE */ 0, 0, /* QUERY_CAN_NAVIGATE */ sizeof(DWORD), NEED_CACHE, /* QUERY_USES_NETWORK */ sizeof(DWORD), 0, /* QUERY_IS_CACHED */ sizeof(DWORD), NEED_CACHE, /* QUERY_IS_INSTALLEDENTRY */ sizeof(DWORD), 0, /* QUERY_IS_CACHED_OR_MAPPED */ sizeof(DWORD), NEED_CACHE, /* QUERY_USES_CACHE */ sizeof(DWORD), NEED_CACHE, }; #define T_QUERY_FLAG(Option) gQueryFlags[((((long)Option) - 1) * 2) + 1] #define T_BUFFER_SIZE(Option) gQueryFlags[(((long)Option) - 1) * 2] // ------------------------------------------------------------------------------------ // // // STDMETHODIMP TSevenixProtocol::QueryInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf, DWORD dwReserved) { USES_CONVERSION; HRESULT lResult = S_FALSE; CHECK_MEMORY(); #ifdef DEBUG_PROTOCOL_INFO P_TRACE(_T(" Application(IInternetProtocolInfo)::QueryInfo(%s): %s\n"), CString(pwzUrl), GetInternetQueryOptionString(QueryOption)); #endif m_UsedForInfo = TRUE; // Url Data TUrl lUrl(pwzUrl); CComBSTR lwUrl(lUrl.simpleUrlString(FALSE)); // We do not know option over the uses cache // is this a new version of IE ? ASSERT(QueryOption <= QUERY_IS_SAFE); if (QueryOption > QUERY_IS_SAFE) return INET_E_QUERYOPTION_UNKNOWN; // Check if protocol use network DWORD lUseNetwork = 0; DWORD lSize; lResult = CoInternetQueryInfo(lwUrl, QUERY_USES_NETWORK, 0, &lUseNetwork, sizeof(lUseNetwork), &lSize, 0); if (FAILED(lResult)) lUseNetwork = 0; if (QueryOption == QUERY_USES_NETWORK) { ASSERT(sizeof(lUseNetwork) == cbBuffer); memcpy(pBuffer, &lUseNetwork, cbBuffer); if (pcbBuf) *pcbBuf = lSize; return S_OK; } if (lUseNetwork) { CComPtr lEntry; BOOL lHaveCacheEntry = FALSE; BSTR lHeader; // get cache data if (T_QUERY_FLAG(QueryOption) & NEED_CACHE) { lResult = CacheGetEntry(pwzUrl, T_NETWORK_CACHE_NAME, &lEntry); if (lResult == S_OK) lHaveCacheEntry = TRUE; } // Check buffer size DWORD lBufferMinSize = T_BUFFER_SIZE(QueryOption); if (lBufferMinSize && (cbBuffer < lBufferMinSize)) lResult = S_FALSE; else { switch (QueryOption) { case QUERY_IS_CACHED: case QUERY_IS_CACHED_OR_MAPPED: if (lHaveCacheEntry) *((DWORD*)pBuffer) = 1; else *((DWORD*)pBuffer) = 0; break; case QUERY_USES_CACHE: *((DWORD*)pBuffer) = 1; break; case QUERY_EXPIRATION_DATE: if (lHaveCacheEntry) { ASSERT(lEntry); lResult = lEntry->getHeader(T_HEADER_EXPIRES, 0, &lHeader); // TO DO: Fill the buffer ASSERT(NULL); break; } case QUERY_TIME_OF_LAST_CHANGE: case QUERY_CONTENT_ENCODING: case QUERY_CONTENT_TYPE: case QUERY_REFRESH: case QUERY_RECOMBINE: case QUERY_CAN_NAVIGATE: case QUERY_USES_NETWORK: case QUERY_IS_INSTALLEDENTRY: case QUERY_IS_SECURE: case QUERY_IS_SAFE: lResult = CoInternetQueryInfo(lwUrl, QueryOption, dwQueryFlags, pBuffer, cbBuffer, pcbBuf, dwReserved); break; } } } else { lResult = CoInternetQueryInfo(lwUrl, QueryOption, dwQueryFlags, pBuffer, cbBuffer, pcbBuf, dwReserved); if (FAILED(lResult)) { if (!wcsncmp(lwUrl, L"file:", 5)) { lResult = QueryFileInfo(lwUrl, QueryOption, dwQueryFlags, pBuffer, cbBuffer, pcbBuf); } } } CHECK_MEMORY(); return lResult; } // ========================================================================== // // Description: // It's a function Description comment // // Inputs: // szParam1 - It's a function first parameter comment // nParam2 - It's a function second parameter comment // // Return Value: // It's the function return value comment // // Remarks: // It's the Remarks comment // HRESULT TSevenixProtocol::QueryFileInfo(LPCWSTR pwzUrl, QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf) { // Special treatment for "file:" CComPtr lMoniker; CComPtr lBindCtx; HRESULT lResult = S_OK; TUrl lUrl(pwzUrl); if (T_QUERY_FLAG(QueryOption) & USE_MONIKER) { lResult = CreateBindCtx(0, &lBindCtx); ASSERT(SUCCEEDED(lResult)); if (SUCCEEDED(lResult)) { lResult = CreateFileMoniker(CComBSTR(lUrl.getFile()), &lMoniker); } } switch (QueryOption) { case QUERY_IS_CACHED: case QUERY_IS_CACHED_OR_MAPPED: case QUERY_USES_CACHE: case QUERY_EXPIRATION_DATE: ASSERT(NULL); break; case QUERY_TIME_OF_LAST_CHANGE: { FILETIME lFileDate; ASSERT(lBindCtx && lMoniker); if (lBindCtx && lMoniker) lResult = lMoniker->GetTimeOfLastChange(lBindCtx, NULL, &lFileDate); } break; case QUERY_CONTENT_ENCODING: case QUERY_CONTENT_TYPE: case QUERY_REFRESH: case QUERY_RECOMBINE: case QUERY_CAN_NAVIGATE: case QUERY_USES_NETWORK: case QUERY_IS_INSTALLEDENTRY: case QUERY_IS_SAFE: break; case QUERY_IS_SECURE: break; } return lResult; } /*------------ TSP_IInternetProtocolSink.cpp ------------*/ #include "StdAfx.h" #include "TNetDebug.h" #include "TSevenixProtocol.h" #include "TNetHelpers.h" #include "TSevenixUrl.h" #include "TSevenixUrlInfo.h" #include "TInternetProtocol.h" // - Mime types #include "TInternetExplorerMimeHelper.h" #include "TOfficeImportMimeHelper.h" #include "TEmbedMimeHelper.h" #include "TSystemMimeHelper.h" #include "TLanguage.h" #include "TErr.h" #include "IEVersion.h" extern HINSTANCE g_hDllMain; #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif LPCWSTR gDefaultMime = L"application/octet-stream"; // // // HRESULT TSevenixProtocol::ReportData(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) { #ifdef DEBUG_PROTOCOL P_TRACE(_T("¤¤ Protocol[0x%x]::ReportData(%s) %d/%d\n"), this, GetBindStatusCallBackString(grfBSCF), ulProgress, ulProgressMax); #endif // DEBUG_PROTOCOL return OnReportData(grfBSCF, ulProgress, ulProgressMax); } HRESULT TSevenixProtocol::SupReportData(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) { if (m_SupSink) { #ifdef DEBUG_PROTOCOL P_TRACE(_T("¤¤ Sink[0x%x]::ReportData(%s) %d/%d\n"), this, GetBindStatusCallBackString(grfBSCF), ulProgress, ulProgressMax); #endif // DEBUG_PROTOCOL return m_SupSink->ReportData(grfBSCF, ulProgress, ulProgressMax); } return S_OK; } HRESULT TSevenixProtocol::OnReportData(DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) { #ifdef DEBUG_PROTOCOL P_TRACE(_T("¤¤ OnReportData[0x%x](%s) %d/%d\n"), this, GetBindStatusCallBackString(grfBSCF), ulProgress, ulProgressMax); #endif // DEBUG_PROTOCOL #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif m_CurrentProgress = ulProgress; if (m_TotalSize != ulProgressMax) m_TotalSize = ulProgressMax; #ifdef DEBUG_PROTOCOL else ATLASSERT(m_TotalSize == ulProgressMax); #endif DEBUG_PROTOCOL HRESULT lResult = S_OK; m_grfBSCF = grfBSCF; if (m_bStorageState && !m_ReadFromCache) { #ifdef DEBUG_PROTOCOL P_TRACE(_T("¤¤ Storage[0x%x]::ReportData(%s) %d/%d\n"), this, GetBindStatusCallBackString(grfBSCF), ulProgress, ulProgressMax); #endif // DEBUG_PROTOCOL DWORD lErrorLength; lErrorLength = m_ErrorHtmlString.GetLength(); if (m_Redirecting && lErrorLength) lResult = SupReportData(BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE | BSCF_LASTDATANOTIFICATION, lErrorLength, lErrorLength); if (m_bContinueRead) lResult = StubRead(m_CurrentProgress - m_CurrentRead); return S_OK; } lResult = SupReportData(grfBSCF, ulProgress, ulProgressMax); ATLASSERT(SUCCEEDED(lResult)); return lResult; } // // // HRESULT TSevenixProtocol::ReportProgress(ULONG ulStatusCode, LPCWSTR szStatusText) { #ifdef DEBUG_PROTOCOL USES_CONVERSION; P_TRACE(_T("¤¤ Protocol[0x%x]::ReportProgress: %s, %s\n"), this, FindProtocolProgressCode(ulStatusCode), W2CT(szStatusText)); #endif // DEBUG_PROTOCOL return OnReportProgress(ulStatusCode, szStatusText); } HRESULT TSevenixProtocol::SupReportProgress(ULONG ulStatusCode, LPCWSTR szStatusText, BOOL pSkipStorage) { if (m_bStorageState && !pSkipStorage) { ATLASSERT(m_HandleError || m_Redirecting); return S_OK; } if (m_SupSink) { #ifdef DEBUG_PROTOCOL USES_CONVERSION; P_TRACE(_T("¤¤ Sink[0x%x]::ReportProgress: %s, %s\n"), this, FindProtocolProgressCode(ulStatusCode), W2CT(szStatusText)); #endif // DEBUG_PROTOCOL return m_SupSink->ReportProgress(ulStatusCode, szStatusText); } return S_OK; } HRESULT TSevenixProtocol::OnReportProgress(ULONG ulStatusCode, LPCWSTR szStatusText) { HRESULT lResult; #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif if (ulStatusCode == BINDSTATUS_REDIRECTING) { lResult = RedirectingTo(szStatusText); if (SUCCEEDED(lResult)) return lResult; } USES_CONVERSION; CComBSTR lStatusText = szStatusText; CString lDispStatusText = szStatusText; #ifdef DEBUG_PROTOCOL P_TRACE(_T("¤¤ OnReportProgress[0x%x] %s, %s\n"), this, FindProtocolProgressCode(ulStatusCode), W2CT(szStatusText)); #endif // DEBUG_PROTOCOL if ((ulStatusCode == BINDSTATUS_MIMETYPEAVAILABLE) || (ulStatusCode == BINDSTATUS_CACHEFILENAMEAVAILABLE) || (ulStatusCode == BINDSTATUS_DOWNLOADINGDATA)) { GetHTTPStatusCode(); } BEGIN_PROGRESS_STATUS_MAP(ulStatusCode, szStatusText, lResult) // PROGRESS_STATUS_ENTRY(BINDSTATUS_FINDINGRESOURCE, OnFindResource) // PROGRESS_STATUS_ENTRY(BINDSTATUS_CONNECTING, OnConnecting) // PROGRESS_STATUS_ENTRY(BINDSTATUS_REDIRECTING, OnRedirecting) // PROGRESS_STATUS_ENTRY(BINDSTATUS_BEGINDOWNLOADDATA, OnBeginDownload) // PROGRESS_STATUS_ENTRY(BINDSTATUS_DOWNLOADINGDATA, OnDownloading) // PROGRESS_STATUS_ENTRY(BINDSTATUS_ENDDOWNLOADDATA, OnEndDownload) // PROGRESS_STATUS_ENTRY(BINDSTATUS_BEGINDOWNLOADCOMPONENTS, OnBeginDownloadComponents) // PROGRESS_STATUS_ENTRY(BINDSTATUS_INSTALLINGCOMPONENTS, OnInstallingComponents) // PROGRESS_STATUS_ENTRY(BINDSTATUS_ENDDOWNLOADCOMPONENTS, OnEndDownloadComponents) // PROGRESS_STATUS_ENTRY(BINDSTATUS_USINGCACHEDCOPY, OnUsingCachedCopy) // PROGRESS_STATUS_ENTRY(BINDSTATUS_SENDINGREQUEST, OnSendingRequest) // PROGRESS_STATUS_ENTRY(BINDSTATUS_CLASSIDAVAILABLE, OnClsidAvailable) PROGRESS_STATUS_ENTRY(BINDSTATUS_MIMETYPEAVAILABLE, OnMimeTypeAvailable) PROGRESS_STATUS_ENTRY(BINDSTATUS_CACHEFILENAMEAVAILABLE, OnCacheFilenameAvailable) // PROGRESS_STATUS_ENTRY(BINDSTATUS_BEGINSYNCOPERATION, OnBeginSyncOp) // PROGRESS_STATUS_ENTRY(BINDSTATUS_ENDSYNCOPERATION, OnEndSyncOp) // PROGRESS_STATUS_ENTRY(BINDSTATUS_BEGINUPLOADDATA, OnBeginUpload) // PROGRESS_STATUS_ENTRY(BINDSTATUS_UPLOADINGDATA, OnUploading) // PROGRESS_STATUS_ENTRY(BINDSTATUS_ENDUPLOADDATA, OnEndUpload) // PROGRESS_STATUS_ENTRY(BINDSTATUS_PROTOCOLCLASSID, OnProtocolClsid) PROGRESS_STATUS_ENTRY(BINDSTATUS_ENCODING, OnEncoding) PROGRESS_STATUS_ENTRY(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, OnMimeTypeAvailable) // PROGRESS_STATUS_ENTRY(BINDSTATUS_CLASSINSTALLLOCATION, OnClassInstallLocation) PROGRESS_STATUS_ENTRY(BINDSTATUS_DECODING, OnDecoding) // PROGRESS_STATUS_ENTRY(BINDSTATUS_LOADINGMIMEHANDLER, OnLoadingMimeHandler) // PROGRESS_STATUS_ENTRY(BINDSTATUS_CONTENTDISPOSITIONATTACH, OnContentDispositionAttach) // PROGRESS_STATUS_ENTRY(BINDSTATUS_FILTERREPORTMIMETYPE, OnFilterReportMimeType) // PROGRESS_STATUS_ENTRY(BINDSTATUS_CLSIDCANINSTANTIATE, OnClsidCanInstantiate) // PROGRESS_STATUS_ENTRY(BINDSTATUS_IUNKNOWNAVAILABLE, OnIUnknownAvailable) // PROGRESS_STATUS_ENTRY(BINDSTATUS_DIRECTBIND, OnDirectBind) // PROGRESS_STATUS_ENTRY(BINDSTATUS_RAWMIMETYPE, OnRawMimeType) // PROGRESS_STATUS_ENTRY(BINDSTATUS_PROXYDETECTING, OnProxyDetecting) PROGRESS_STATUS_ENTRY(BINDSTATUS_ACCEPTRANGES, OnAcceptRanges) END_PROGRESS_STATUS_MAP(SupReportProgress) #ifdef _DEBUG if (m_SupSink != NULL) ATLASSERT((!m_IsTerminate || m_IsLocked) && !m_HaveAbort); else ATLASSERT(m_HaveAbort); #endif // _DEBUG return lResult; } HRESULT TSevenixProtocol::OnMimeTypeAvailable(LPCWSTR lStatusText, BSTR* pNewStatusText, BOOL& bProxy) { HRESULT lResult; m_MimeType = lStatusText; #ifdef Pierre USES_CONVERSION; KB_LOG_INFO2(_T("Mimetype %1 Available for %2"), W2CT(m_MimeType), W2CT(m_RealUrl)); #endif // Pierre if (!wcsicmp(m_MimeType, gDefaultMime)) { CComBSTR lMimeType; if (SUCCEEDED(GuessMimeType(m_RealUrl, &lMimeType))) { m_MimeType = lMimeType; lStatusText = m_MimeType; m_MimeType.CopyTo(pNewStatusText); } #ifdef Pierre KB_LOG_INFO2(_T("Guessed Mimetype %1 for %2"), W2CT(m_MimeType), W2CT(m_RealUrl)); #endif // Pierre } lResult = FilterMime(lStatusText); if (m_HandleError || m_Redirecting) { bProxy = FALSE; return lResult; } // Set the cache mime type. if (!m_ReadFromCache && CheckNewCacheEntry()) { m_NewCacheEntry->addHeader(T_HEADER_CONTENT_TYPE, lStatusText); } return S_OK; } HRESULT TSevenixProtocol::OnCacheFilenameAvailable(LPCWSTR swStatusText, BSTR* pNewStatusText, BOOL& bProxy) { HRESULT lResult; if (m_MimeType.Length() == 0) { GuessMimeType(swStatusText, &m_MimeType); if (m_MimeType.Length() != 0) { lResult = FilterMime(m_MimeType); if (m_HandleError || m_Redirecting) { bProxy = FALSE; return lResult; } if (m_SupSink != NULL) { ATLASSERT(!m_IsTerminate && !m_HaveAbort); lResult = SupReportProgress(BINDSTATUS_MIMETYPEAVAILABLE, m_MimeType); } } } // Change the cache file name. { ISevenixCacheEntry* lEntry; lEntry = m_CurrentCacheEntry; if (!m_ReadFromCache && CheckNewCacheEntry()) lEntry = m_NewCacheEntry; if (lEntry != NULL) lEntry->getFileName(pNewStatusText); } return S_OK; } HRESULT TSevenixProtocol::OnRedirecting(LPCWSTR, BSTR* , BOOL& bProxy) { return E_NOTIMPL; } HRESULT TSevenixProtocol::OnUsingCachedCopy(LPCWSTR, BSTR* , BOOL& bProxy) { return E_NOTIMPL; } HRESULT TSevenixProtocol::OnAcceptRanges(LPCWSTR, BSTR* , BOOL& bProxy) { bProxy = FALSE; return S_OK; } HRESULT TSevenixProtocol::OnEncoding(LPCWSTR, BSTR* , BOOL& bProxy) { return S_OK; } HRESULT TSevenixProtocol::OnDecoding(LPCWSTR pStatus, BSTR* , BOOL& bProxy) { return S_OK; } // // // HRESULT TSevenixProtocol::ReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { #ifdef DEBUG_PROTOCOL P_TRACE(_T("¤¤ Protocol[0x%x]::ReportResult: 0x%x, %d\n"), this, hrResult, dwError); #endif // DEBUG_PROTOCOL return OnReportResult(hrResult, dwError, szResult); } HRESULT TSevenixProtocol::SupReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { if (m_bStorageState && m_Redirecting) { #ifdef DEBUG_PROTOCOL P_TRACE(_T("¤¤ Storage[0x%x]::ReportResult: 0x%x, %d\n"), this, hrResult, dwError); #endif // DEBUG_PROTOCOL return S_OK; } m_HaveReportResult = TRUE; if (m_SupSink) { #ifdef DEBUG_PROTOCOL P_TRACE(_T("¤¤ Sink[0x%x]::ReportResult: 0x%x, %d\n"), this, hrResult, dwError); #endif // DEBUG_PROTOCOL return m_SupSink->ReportResult(hrResult, dwError, szResult); } return S_OK; } HRESULT TSevenixProtocol::OnReportResult(HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { HRESULT lResult; if (m_HandleError && m_ErrorHandled) return S_OK; #ifdef DEBUG_PROTOCOL P_TRACE(_T("¤¤ OnReportResult[0x%x]: 0x%x, %d\n"), this, hrResult, dwError); #endif // DEBUG_PROTOCOL #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif if (hrResult == INET_E_REDIRECTING) return RedirectingTo(szResult); if (m_Redirecting) return S_OK; if (hrResult != S_OK) { lResult = HandleError(hrResult, dwError, szResult); if (lResult == S_OK) return lResult; } if (!m_HandleError) return SupReportResult(hrResult, dwError, szResult); return S_FALSE; } // // // HRESULT TSevenixProtocol::Switch(PROTOCOLDATA *pPROTOCOLDATA) { #ifdef DEBUG_PROTOCOL P_TRACE(_T(" Protocol( Sink[0x%x] )::Switch\n"), this); #endif // DEBUG_PROTOCOL #ifdef DEBUG_PROTOCOL if (m_BlockingState) DebugBreak(); #endif return m_SupSink->Switch(pPROTOCOLDATA); } HRESULT TSevenixProtocol::SwitchSink( IInternetProtocolSink* pOIProtSink) { if (m_bSwitchDone) return E_FAIL; #ifdef DEBUG_PROTOCOL P_TRACE(" Register Sink to Switch [0x%x]\n", pOIProtSink); #endif m_SupSinkSwitch = pOIProtSink; return S_OK; } HRESULT TSevenixProtocol::CommitSwitch() { if (m_bSwitchDone) return E_FAIL; #ifdef DEBUG_PROTOCOL P_TRACE(" Do Switch Sink [0x%x] to Sink [0x%x]\n", m_SupSink, m_SupSinkSwitch); #endif CComPtr lSink(m_SupSinkSwitch); m_SupSinkSwitch = m_SupSink; m_SupSink = lSink; m_bSwitchDone = TRUE; return S_OK; } HRESULT TSevenixProtocol::RollbackSwitch() { if (!m_bSwitchDone) return E_FAIL; #ifdef DEBUG_PROTOCOL P_TRACE(" Rollback Switch Sink [0x%x] to Sink [0x%x]\n", m_SupSink, m_SupSinkSwitch); #endif CComPtr lSink(m_SupSinkSwitch); m_SupSinkSwitch = m_SupSink; m_SupSink = lSink; m_bSwitchDone = FALSE; return S_OK; } // // // void TSevenixProtocol::GetHTTPStatusCode() { if (m_StatusCode != 0) return ; CComQIPtr lHttpInfo(m_StubProtocol); if (lHttpInfo == NULL) { m_StatusCode = HTTP_STATUS_OK; // HTTP_STATUS_NOT_MODIFIED; return ; } DWORD lSize = 0; DWORD lFlags = 0; HRESULT lResult; // Get Http Result lSize = sizeof(m_StatusCode); lResult = lHttpInfo->QueryInfo(HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &m_StatusCode, &lSize, &lFlags, NULL); ATLASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) { // What can we do ? m_StatusCode = HTTP_STATUS_OK; } #ifdef Pierre // I want to see what append on errors // ATLASSERT(m_StatusCode == HTTP_STATUS_OK); #endif } // // // BOOL TSevenixProtocol::CheckNewCacheEntry(LPCWSTR pUrl, LPCWSTR pMime) { if (m_ReadFromCache) return FALSE; if (!m_WriteToCache) return FALSE; USES_CONVERSION; if (pUrl == NULL) pUrl = T2CW(m_Url.extendedUrlString()); if (pMime == NULL) pMime = m_MimeType; CComPtr lNetCache; TUrl lUrlClass(pUrl); CString lUrl(lUrlClass.simpleUrlString()); CString lMime(pMime); HRESULT lResult; if (m_NewEntryChecked) { // We allready check return ((m_NewCacheEntry != NULL) ? TRUE : FALSE); } m_NewEntryChecked = TRUE; // do not rely on scheme, // the crackUrl API do not always handle it correctly // no cache for resources url if ((lUrl.Find("res:") == 0) || (lUrl.Find("its:") == 0) || (lUrl.Find("mk:") == 0) || (lUrl.Find("internal:") == 0)) return FALSE; if (m_StatusCode != HTTP_STATUS_OK) { switch (m_StatusCode) { case HTTP_STATUS_NOT_MODIFIED: return FALSE; break; default: #ifdef Pierre // What do we do in case like this ? // ATLASSERT(m_StatusCode == 0); #endif return FALSE; } } CString lExt; if (lMime.GetLength() == 0) { lExt = PathFindExtension(lUrl); // if is not embed if (lExt.GetLength()) { TSystemMimeHelper* lSystemHelper; lSystemHelper = new TSystemMimeHelper(); lSystemHelper->getFirstMimeTypeFromFileExtension(lExt, lMime); delete lSystemHelper; } } if (lMime.GetLength()) { TInternetExplorerMimeHelper* lIEHelper; BOOL lIEMime; lIEHelper = new TInternetExplorerMimeHelper(); lIEMime = lIEHelper->isMimeTypeSupported(lMime); delete lIEHelper; if (!lIEMime) { TEmbedMimeHelper* lEmbedHelper; BOOL lEmbebMime; lEmbedHelper = new TEmbedMimeHelper(); lEmbebMime = lEmbedHelper->isMimeTypeSupported(lMime); delete lEmbedHelper; if (lEmbebMime) return FALSE; } } lResult = GetCache(T_NETWORK_CACHE_NAME, &lNetCache); ATLASSERT(SUCCEEDED(lResult)); if (lResult == S_OK) { lResult = lNetCache->createEntry(T2W(lUrlClass.extendedUrlString()), &m_NewCacheEntry); ATLASSERT(SUCCEEDED(lResult)); } return (lResult == S_OK) ? TRUE : FALSE; } HRESULT TSevenixProtocol::RedirectingTo(LPCWSTR szStatusText) { USES_CONVERSION; // HRESULT lResult; TSevenixUrl lNewUrl(szStatusText); if (lNewUrl.equals(m_Url)) return E_FAIL; if (!m_RootDocument) return E_FAIL; P_TRACE(_T(" => Redirecting(0x%X)...\n From: %s\n To: %s\n"), this, m_Url.extendedUrlString(), W2CT(szStatusText)); m_StatusCode = HTTP_STATUS_OK; CheckNewCacheEntry(); TCHAR theString[512]; UINT nLen = ::LoadString(g_hDllMain, IDS_NET_PROTOCOL_REDIRECT, theString, 512); ATLASSERT(nLen < 511); TSevenixUrlInfo* lInfo; lInfo = (TSevenixUrlInfo*)lNewUrl.getExtendedInfo(); if (lInfo) { lInfo->addProperty(T_ROOT_PROPERTY); } else { TSevenixUrlInfo* lMainUrlInfo; lMainUrlInfo = (TSevenixUrlInfo*)m_Url.getExtendedInfo(); if (lMainUrlInfo) { lNewUrl.setExtendedInfo(lMainUrlInfo); TSevenixUrlInfo* lNewUrlInfo; lNewUrlInfo = (TSevenixUrlInfo*)lNewUrl.getExtendedInfo(); lNewUrlInfo->addProperty(T_ROOT_PROPERTY); } } // We need to put the EXTENDED url in the HTML code because of the following problem: // 1/ Navigate on url (for instance http://www.altavista.com/r?nd01) // -> It seems like we loose at some point the root property for the document. This // is why a banner redirection inside a redirected page replace the page instead // of being embedded in the page. // -> It seemd like putting the EXTENDED url in the REFRESH HTML code fix the problem, because // the root property is made more persistent through redirections... m_ErrorHtmlString.FormatMessage(theString, lNewUrl.extendedUrlString()); //m_ErrorHtmlString.FormatMessage(theString, lNewUrl.simpleUrlString()); m_Redirecting = TRUE; m_WriteToCache = TRUE; m_ErrorHandled = TRUE; m_ErrorState = E_FAIL; SetStorageState(); return AllDataAvailable(); } HRESULT TSevenixProtocol::FilterMime(LPCWSTR pMime) { HRESULT lResult; CString lMime(pMime); if (!m_RootDocument) return S_OK; long lPos; // Content-type can be: "mimetype; charset" // so remove charset !!!! lPos = lMime.Find(';'); if (lPos >= 0) { lMime = lMime.Mid(0, lPos); } lMime.TrimLeft(); lMime.TrimRight(); lMime.MakeLower(); // We always support 'text/html' if (lMime == "text/html") return S_OK; // Check that this is a supported mime type TInternetExplorerMimeHelper* lMimeHelper; lMimeHelper = new TInternetExplorerMimeHelper(); BOOL lIEMime = lMimeHelper->isMimeTypeSupported(lMime); delete lMimeHelper; lMimeHelper = NULL; if (lIEMime) { if ((lMime.Find("image/") == 0) && m_RootDocument) { CString lDll; // Use the picture system page TLanguage::GetNeutralLanguageDllPath(lDll); lResult = LoadDllData(CComBSTR(lDll), L"picture.htm"); m_Redirecting =TRUE; m_WriteToCache = FALSE; SetStorageState(); return AllDataAvailable(); } return S_OK; } TOfficeImportMimeHelper* lMimeHelper2; lMimeHelper2 = new TOfficeImportMimeHelper(); BOOL lFilterMime = lMimeHelper2->isMimeTypeSupported(lMime); delete lMimeHelper2; lMimeHelper2 = NULL; if (lFilterMime) return S_OK; TEmbedMimeHelper* lMimeHelper3; BOOL lEmbebMime; lMimeHelper3 = new TEmbedMimeHelper(); lEmbebMime = lMimeHelper3->isMimeTypeSupported(lMime); if (lEmbebMime) return EmbedData(pMime); if (m_LoadFromNetwork) return HandleError(INET_E_TYPE_NOT_SUPPORTED, 0, pMime); return HandleError(INET_E_TYPE_NOT_SUPPORTED, 1, pMime); } HRESULT TSevenixProtocol::EmbedData(LPCWSTR pMime) { HRESULT lResult; CString lEmbedUrl; if (m_ReadFromCache) { CComBSTR lFileName; m_CurrentCacheEntry->getFileName(&lFileName); lEmbedUrl = CString("file://") + (LPCWSTR)lFileName; } else { TUrl lUrl(m_Url); TSevenixUrlInfo* lInfo; lInfo = (TSevenixUrlInfo*)lUrl.getExtendedInfo(); if (lInfo) { lInfo->setUniqueID(); lInfo->removeProperty(T_ROOT_PROPERTY); } lEmbedUrl = lUrl.simpleUrlString(); } CString lDll; CString lEmbedSrc; // Use the picture system page TLanguage::GetNeutralLanguageDllPath(lDll); lResult = LoadDllData(CComBSTR(lDll), L"embed.htm"); lEmbedSrc = m_ErrorHtmlString; m_ErrorHtmlString.Empty(); m_ErrorHtmlString.FormatMessage( lEmbedSrc, pMime, lEmbedUrl); m_HandleError = FALSE; m_Redirecting = TRUE; m_WriteToCache = FALSE; m_ErrorHandled = TRUE; m_ErrorState = E_FAIL; SetStorageState(); return AllDataAvailable(); } LPCSTR gKnownMimetype[] = { ".pdf", "%PDF", "application/pdf", ".ai", "%!PS", "application/postscript", ".ps", "%!PS", "application/postscript", ".eps", NULL, "application/postscript", NULL, NULL, NULL }; HRESULT TSevenixProtocol::GuessMimeType(LPCWSTR pFileName, BSTR* pMime) { USES_CONVERSION; HRESULT lResult = E_FAIL; LPWSTR lMime = NULL; LPCSTR lFileName = W2CA(pFileName); LPCSTR lExtension = ::PathFindExtension(lFileName); LONG lIndex = 0; while (gKnownMimetype[lIndex]) { if (!strnicmp(gKnownMimetype[lIndex], lExtension, strlen(gKnownMimetype[lIndex]))) { *pMime = ::SysAllocString(A2CW(gKnownMimetype[lIndex + 2])); return S_OK; } lIndex += 3; } CString lMimeString; TSystemMimeHelper* lHelper; lHelper = new TSystemMimeHelper(); lResult = lHelper->getFirstMimeTypeFromFileExtension(A2CT(lExtension), lMimeString); delete lHelper; if (SUCCEEDED(lResult)) { *pMime = ::SysAllocString(T2CW(lMimeString)); return S_OK; } BYTE lData[2048]; LONG lSize = 0; CFile lFile; if (lFile.Open(lFileName, CFile::modeRead)) { lSize = lFile.Read(lData, 2048); lFile.Close(); if (lSize > 0) { lIndex = 1; while (gKnownMimetype[lIndex]) { if (!strnicmp(gKnownMimetype[lIndex], (char*)lData, strlen(gKnownMimetype[lIndex]))) { *pMime = ::SysAllocString(A2CW(gKnownMimetype[lIndex + 1])); return S_OK; } lIndex += 3; } lResult = ::FindMimeFromData(NULL, pFileName, lData, lSize, gDefaultMime, 0, &lMime, 0); *pMime = ::SysAllocString(lMime); } else { *pMime = ::SysAllocString(gDefaultMime); } } return lResult; }/*------------ PropertyChangeSupport.cpp ------------*/ #include "StdAfx.h" #ifndef T_PROPERTY_CHANGE_SUPPORT #include "PropertyChangeSupport.h" #endif #ifndef T_PROPERTY_CHANGE_LISTENER #include "PropertyChangeListener.h" #endif #ifndef T_PROPERTY_CHANGE_EVENT #include "PropertyChangeEvent.h" #endif #ifndef T_PTR_TO_PTR_HASHTABLE #include "TPtrToPtrHashTable.h" #endif #ifndef T_PTR_ARRAY #include "TPtrArray.h" #endif #ifndef T_PTR_ITERATOR #include "TPtrIterator.h" #endif #ifndef T_STRING_ARRAY #include "TStringArray.h" #endif //#define DEBUG_ACTIVE_EVENTS //#define _DEBUG_LISTENERS class TPCSInfo { public: long m_Count; TStringArray *m_PropList; TPCSInfo() : m_Count(0), m_PropList(NULL) {} }; // ----------------------------------------------------------------------------- // PropertyChangeSupport // TPropertyChangeSupport::TPropertyChangeSupport() { fSource = NULL; fListeners = NULL; #ifdef _DEBUG fActiveEventsArray = NULL; #endif } // ----------------------------------------------------------------------------- // // void TPropertyChangeSupport::setSource(CObject* pSource) { fSource = pSource; } // ----------------------------------------------------------------------------- // // TPropertyChangeSupport::~TPropertyChangeSupport() { #if defined(_DEBUG) && defined(DEBUG_LISTENER_REGISTRATION) if (fListeners) ASSERT(fListeners->isEmpty()); if (fActiveEventsArray) ASSERT(fActiveEventsArray->isEmpty()); #endif // _DEBUG_LISTENERS TPtrIterator *lIterator = fListeners->elements(); while (lIterator && lIterator->hasMoreElements()) { TPCSInfo* lListenedPropsInfo = (TPCSInfo*)lIterator->nextElement(); if (lListenedPropsInfo) { TStringArray* lList = lListenedPropsInfo->m_PropList; if (lList) { lListenedPropsInfo->m_PropList = NULL; lList->removeAllElements(); delete lList; } delete lListenedPropsInfo; } } delete lIterator; #ifdef _DEBUG if (fActiveEventsArray) { TPtrIterator* activeEventsIter = fActiveEventsArray->elements(); while (activeEventsIter && activeEventsIter->hasMoreElements()) { TPropertyChangeEvent* curEvent = (TPropertyChangeEvent *)activeEventsIter->nextElement(); if (curEvent) delete curEvent; } delete activeEventsIter; fActiveEventsArray->removeAllElements(); delete fActiveEventsArray; fActiveEventsArray = NULL; } #endif delete fListeners; } // ----------------------------------------------------------------------------- // // HRESULT TPropertyChangeSupport::addPropertyChangeListener( TPropertyChangeListener* pListener, LPCTSTR pPropertyToListenTo) { ASSERT(pListener); // as there's no ASSERT in RELEASE, // we keep the test: (pListener == NULL) // just in case !!!! if ((pListener == NULL) || !fLocker.lock()) return E_FAIL; // Do we have the a listener list if (fListeners == NULL) fListeners = new TPtrToPtrHashTable(); #ifdef _DEBUG if (fActiveEventsArray == NULL) fActiveEventsArray = new TPtrArray(); #endif // Get the list of properties we're listening at TPCSInfo* lListenedPropsInfo; if (fListeners->get(pListener, (void**)&lListenedPropsInfo)) { ASSERT(lListenedPropsInfo != NULL); if (lListenedPropsInfo != NULL) return E_FAIL; } else { lListenedPropsInfo = new TPCSInfo; fListeners->put(pListener, lListenedPropsInfo); } lListenedPropsInfo->m_Count++; // Either the listener isn't in the list // or it is and the Listened Props Array is NULL if (pPropertyToListenTo) { if (lListenedPropsInfo->m_PropList == NULL) { // We can't have the same listener for all and a specific property ASSERT(lListenedPropsInfo->m_Count == 1); lListenedPropsInfo->m_PropList = new TStringArray(); } if (!lListenedPropsInfo->m_PropList->contains(pPropertyToListenTo)) lListenedPropsInfo->m_PropList->addElement(pPropertyToListenTo); } else if (lListenedPropsInfo->m_PropList != NULL) { // We want to listen everything, so let's remove the // Listened Props Array TStringArray* lList = lListenedPropsInfo->m_PropList; lListenedPropsInfo->m_PropList = NULL; lList->removeAllElements(); delete lList; } pListener->AddRef(); fLocker.unlock(); return S_OK; } // ----------------------------------------------------------------------------- // // HRESULT TPropertyChangeSupport::removePropertyChangeListener( TPropertyChangeListener *pListener, LPCTSTR pPropertyNotToListenToAnymore) { ASSERT(pListener); ASSERT(fListeners); // as there's no ASSERT in RELEASE, // we keep the test: (pListener == NULL) // just in case !!!! if ((pListener == NULL) || (fListeners == NULL) || !fLocker.lock()) return E_FAIL; boolean lFound = false; TPCSInfo* lListenedPropsInfo = NULL; lFound = fListeners->get(pListener, (void**)&lListenedPropsInfo); if (!lFound || (lListenedPropsInfo == NULL)) return E_FAIL; // The listener is in the list and the Listened // Props Array isn't NULL ASSERT(lListenedPropsInfo->m_Count > 0); lListenedPropsInfo->m_Count--; if (lListenedPropsInfo->m_Count == 0) { TStringArray* lList = lListenedPropsInfo->m_PropList; if (lList) { lListenedPropsInfo->m_PropList = NULL; lList->removeAllElements(); delete lList; } delete lListenedPropsInfo; fListeners->remove(pListener); } else { if (pPropertyNotToListenToAnymore) { // We'll see if this property is listened to VERIFY(lListenedPropsInfo->m_PropList->contains(pPropertyNotToListenToAnymore)); lListenedPropsInfo->m_PropList->removeElement(pPropertyNotToListenToAnymore); } } // We shouldn't be the last to keep a reference to a listener // setInvalid should be done after the removeProp... VERIFY(pListener->Release() != 0); fLocker.unlock(); return S_OK; } // ----------------------------------------------------------------------------- // // HRESULT TPropertyChangeSupport::firePropertyChange(LPCTSTR pPropertyName, void* pOldValue, void* pNewValue, CObject* pSource, bool pIsForced) { if ( !pIsForced && pOldValue != NULL && (pOldValue == pNewValue)) return S_FALSE; if (pSource == NULL) pSource = fSource; // synchronized if (!fLocker.lock()) return E_FAIL; TPropertyChangeEvent *lEvent = new TPropertyChangeEvent(pSource, pPropertyName, pOldValue, pNewValue); #ifdef _DEBUG // LOOP WARNING on event [%s]\n"), *(evt->getPropertyName())); if (eventAlreadyIsInActiveEventsArray(lEvent)) return E_FAIL; // ******************** // I put the event we'll handle in the active events array fActiveEventsArray->addElement(lEvent); // ******************** #ifdef DEBUG_ACTIVE_EVENTS TRACE(_T("TPropertyChangeSupport::firePropertyChange(void*) - Currently handled events' count : %d\n"), fActiveEventsArray->size()); #endif #endif CHECK_MEMORY(); TPtrIterator *lIterator = fListeners->keys(); CHECK_MEMORY(); while (lIterator->hasMoreElements()) { TPropertyChangeListener* lTarget = (TPropertyChangeListener*)lIterator->nextElement(); #ifdef _DEBUG ASSERT((int)lTarget != 0xcdcdcdcd); if ((int)lTarget == 0xcdcdcdcd) continue ; #endif #ifdef Pierre ASSERT(lTarget->getValidState()); #endif if (!lTarget->getValidState()) { TRACE(_T("TPropertyChangeSupport::firePropertyChange(void*) - Listener [0x%x] is INVALID\n"), (void*)lTarget); continue; } TPCSInfo* lListenedPropsInfo = (TPCSInfo*)fListeners->get(lTarget); // ASSERT(lListenedPropsInfo); if (lListenedPropsInfo == NULL) continue; if ((lListenedPropsInfo->m_PropList != NULL) && !lListenedPropsInfo->m_PropList->contains(pPropertyName)) { continue ; } lTarget->propertyChange(lEvent); } CHECK_MEMORY(); delete lIterator; CHECK_MEMORY(); #ifdef _DEBUG // ******************** // The handling of the event being over, I remove the event from the active events array fActiveEventsArray->removeElement(lEvent); // ******************** #endif // end synchronized fLocker.unlock(); delete lEvent; return S_OK; } // ----------------------------------------------------------------------------- // // HRESULT TPropertyChangeSupport::firePropertyChange(LPCTSTR pPropertyName, LPCTSTR pOldValue, LPCTSTR pNewValue, CObject* pSource, bool pIsForced) { if (!pIsForced && pOldValue && pNewValue && (!_tcscmp(pOldValue, pNewValue))) return S_FALSE; if (pSource == NULL) pSource = fSource; // synchronized if (!fLocker.lock()) return E_FAIL; TPropertyChangeEvent *evt = new TPropertyChangeEvent(pSource, pPropertyName, pOldValue, pNewValue); #ifdef _DEBUG // LOOP WARNING on event [%s]\n"), *(evt->getPropertyName())); if (eventAlreadyIsInActiveEventsArray(evt)) return E_FAIL; // ******************** // I put the event we'll handle in the active events array fActiveEventsArray->addElement(evt); // ******************** #ifdef DEBUG_ACTIVE_EVENTS TRACE("TPropertyChangeSupport::firePropertyChange(CString*) - Currently handled events' count : %d\n",fActiveEventsArray->size()); #endif #endif TPtrIterator *lIterator = fListeners->keys(); while (lIterator->hasMoreElements()) { TPropertyChangeListener* lTarget = (TPropertyChangeListener*)lIterator->nextElement(); #ifdef _DEBUG ASSERT((int)lTarget != 0xcdcdcdcd); if ((int)lTarget == 0xcdcdcdcd) continue ; #endif if (!lTarget->getValidState()) { TRACE(_T("TPropertyChangeSupport::firePropertyChange(CString*) - Listener [0x%x] is INVALID\n"), (void*)lTarget); continue; } TPCSInfo* lListenedPropsInfo = (TPCSInfo*)fListeners->get(lTarget); // ASSERT(lListenedPropsInfo); if (lListenedPropsInfo == NULL) continue; if (lListenedPropsInfo->m_PropList && !lListenedPropsInfo->m_PropList->contains(pPropertyName)) { continue ; } lTarget->propertyChange(evt); } delete lIterator; #ifdef _DEBUG // ******************** // The handling of the event being over, I remove the event from the active events array fActiveEventsArray->removeElement(evt); // ******************** #endif // end synchronized fLocker.unlock(); delete evt; return S_OK; } // ----------------------------------------------------------------------------- // // #ifdef _DEBUG boolean TPropertyChangeSupport::eventAlreadyIsInActiveEventsArray(TPropertyChangeEvent* pEvent) { if (fActiveEventsArray) { boolean found = false; TPtrIterator* iter = fActiveEventsArray->elements(); while (iter && iter->hasMoreElements()) { TPropertyChangeEvent* curEvent = (TPropertyChangeEvent *)iter->nextElement(); if (arePropertyChangeEventsIdentical(pEvent,curEvent)) { found = true; // We're in a loop here !!!! #ifdef Pierre ASSERT(!found); #endif break; } } delete iter; return found; } else { return false; } } // ----------------------------------------------------------------------------- // // boolean TPropertyChangeSupport::arePropertyChangeEventsIdentical(TPropertyChangeEvent* pEvt1,TPropertyChangeEvent* pEvt2) { if (pEvt1->getSource() != pEvt2->getSource()) return false; if ((*pEvt1->getPropertyName()) != (*pEvt2->getPropertyName())) return false; void* lEvt1_CObject_newValue = pEvt1->getNewValue(); void* lEvt1_CObject_oldValue = pEvt1->getOldValue(); void* lEvt2_CObject_newValue = pEvt2->getNewValue(); void* lEvt2_CObject_oldValue = pEvt2->getOldValue(); LPCTSTR lEvt1_CString_newValue = pEvt1->getNewStringValue(); LPCTSTR lEvt1_CString_oldValue = pEvt1->getOldStringValue(); LPCTSTR lEvt2_CString_newValue = pEvt2->getNewStringValue(); LPCTSTR lEvt2_CString_oldValue = pEvt2->getOldStringValue(); if ((lEvt1_CObject_newValue != NULL) || (lEvt1_CObject_oldValue != NULL)) { // Evt1 is an event of type CObject* if ((lEvt2_CObject_newValue != NULL) || (lEvt2_CObject_oldValue != NULL)) { // Evt1 is an event of type CObject* // Let's compare respectively the old and new values if (lEvt1_CObject_oldValue != lEvt2_CObject_oldValue) return false; if (lEvt1_CObject_newValue != lEvt2_CObject_newValue) return false; return true; } else { return false; } } else if ((lEvt1_CString_newValue != NULL) || (lEvt1_CString_oldValue != NULL)) { // Evt1 is an event of type CString* if ((lEvt2_CString_newValue != NULL) || (lEvt2_CString_oldValue != NULL)) { // Evt2 is an event of type CString* // Let's compare respectively the old and new values if (_tcscmp(lEvt1_CString_oldValue, lEvt2_CString_oldValue)) return false; if (_tcscmp(lEvt1_CString_newValue, lEvt2_CString_newValue)) return false; return true; } else { return false; } } else { // !!!! Evt1 is not recognize as either CObject* or CString* type !!!! // lEvt1_???_newValue and lEvt1_???_oldValue are all NULL if (lEvt2_CString_newValue != NULL) return false; if (lEvt2_CString_oldValue != NULL) return false; if (lEvt2_CObject_newValue != NULL) return false; if (lEvt2_CObject_oldValue != NULL) return false; return true; } } #endif long TPropertyChangeSupport::listenerCount() { if (fListeners) return fListeners->GetCount(); return 0; }/*------------ TDispatchExImpl2.h ------------*/ #ifndef T_DISPATCH_EX_IMPL #define T_DISPATCH_EX_IMPL #include "TMetaManager.h" #include "TManager.h" #include "TPropertyObjectModel.h" #include "TStringToPtrHashTable.h" //#include "TGenericIterator.h" //#include "TGenericHashTable.h" #include "dispex.h" #include "TTypeInfoHolderEx.h" #include "TExtendDispatch.h" ///////////////////////////////////////////////////////////////////////////// // IDispatchImpl template , WORD wMajor = 1, WORD wMinor = 0> class ATL_NO_VTABLE IDispatchExImpl2 : public T { public: typedef ctih t_tih; typedef cext t_ext; // IDispatch STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) { *pctinfo = 1; return S_OK; } STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { return m_tih.GetTypeInfo(itinfo, lcid, pptinfo); } STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) { return m_tih.GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); } STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { return m_tih.Invoke((IDispatch*)this, dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); } // IDispatchEx STDMETHOD(GetDispID)(BSTR bstrName, DWORD grfdex, DISPID *pid) { if (m_ext.GetDispID(&m_tih, bstrName, grfdex, pid) == S_OK) return S_OK; return m_tih.GetDispID(bstrName, grfdex, pid); } STDMETHOD(InvokeEx)(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { if (m_ext.InvokeEx(&m_tih, (IDispatch*)this, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller) == S_OK) return S_OK; return m_tih.InvokeEx((IDispatch*)this, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); } STDMETHOD(DeleteMemberByName)(BSTR bstr, DWORD grfdex) { if (m_ext.DeleteMemberByName(&m_tih, bstr, grfdex) == S_OK) return S_OK; return m_tih.DeleteMemberByName(bstr, grfdex); } STDMETHOD(DeleteMemberByDispID)(DISPID id) { if (m_ext.DeleteMemberByDispID(&m_tih, id) == S_OK) return S_OK; return m_tih.DeleteMemberByDispID(id); } STDMETHOD(GetMemberProperties)(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) { return m_tih.GetMemberProperties(id, grfdexFetch, pgrfdex); } STDMETHOD(GetMemberName)(DISPID id, BSTR *pbstrName) { return m_tih.GetMemberName(id, pbstrName); } STDMETHOD(GetNextDispID)(DWORD grfdex, DISPID id, DISPID* pid) { return m_tih.GetNextDispID(grfdex, id, pid); } STDMETHOD(GetNameSpaceParent)(IUnknown** ppunk) { return m_tih.GetNameSpaceParent(ppunk); } HRESULT IsExtendedMember(DISPID pID, BOOL* pResult) { return m_tih.IsExtendedMember(pID, pResult); } protected: static t_tih m_tih; t_ext m_ext; static HRESULT GetTI(LCID lcid, ITypeInfo** ppInfo) { return m_tih.GetTI(lcid, ppInfo); } }; template IDispatchExImpl2::t_tih IDispatchExImpl2::m_tih = {piid, plibid, wMajor, wMinor, NULL, 0, NULL, 0, 0}; #endif // T_DISPATCH_EX_IMPL /*------------ TErr.cpp ------------*/ // TErr.cpp: implementation of the TErr class. // ////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include #include "ProductName.h" #include "TPreferences.h" #include "TErr.h" #include "TErrDlg.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Constante initialization ////////////////////////////////////////////////////////////////////// // --- static methods LPCTSTR getGravityString( int nGravity); CString getTimeStamp(); CString getIdString( int nId); LPCTSTR getLineString( int nLine); CString getShortFilename( LPCTSTR szFilename); int getErrorId( int nLine, int nId); LPCTSTR getLogFilename(); void setLogFilename( LPCTSTR szFullName); DWORD getLogMaxMessage(); void setLogMaxMessage( DWORD dwMaxMessage); // --- static parameters LPTSTR g_szFullName = NULL; LPCTSTR m_szDefaultFullName = NULL; LPCTSTR m_szFullName = NULL; DWORD m_dwMaxMessage = 2000L; DWORD m_dwNbMessage = 0L; DWORD m_dwPosition = 0L; DWORD m_dwBeginInfo = 0L; bool m_bIsNewStart = true; bool m_bIsToLog; bool m_bIsToOpen = true; CStdioFile m_file; BOOL g_bIsNewFile = TRUE; class TErrCleaner { public: ~TErrCleaner() { if (g_szFullName) { free(g_szFullName); g_szFullName = NULL; } if (m_file.m_pStream) m_file.Close(); } }; TErrCleaner g_theErrCleaner; /* ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// TErr::TErr( int nDest, // --- Destination flag, compose with OUT, LOG, BOX int nGravity, // --- Fravity flag, may be INFO, WARN or FATL int nId, // --- Message Identify, may be NO_ID, or a valid resource string LPCSTR szFilename, // --- source filename int nLine, // --- line number, ... ) { // --- initialize the variable argument list va_list vaList; va_start( vaList, nLine); // --- store the destination m_nDest = nDest; m_nGravity = nGravity; m_nId = nId; // --- build lines buildStrings( m_stgHeader1, m_stgHeader2, m_stgArrayLine, // --- output value nDest, nGravity, nId, szFilename, nLine, vaList // --- input value ); // --- finalize the variable argument list va_end( vaList); } */ TErr::TErr( int nDest, int nGravity, int nId, CString& stgHeader1, CString& stgHeader2, CString stgArrayLine[]) { // --- store parameters m_nDest = nDest; m_nGravity = nGravity; m_nId = nId; m_stgHeader1 = stgHeader1; m_stgHeader2 = stgHeader2; for (int n=0; n < IDS_ERR_NB_LINE; n++) m_stgArrayLine[n] = stgArrayLine[n]; } /* TErr::~TErr() { // --- nothing to do } */ ////////////////////////////////////////////////////////////////////// // buildStrings ////////////////////////////////////////////////////////////////////// void TErr::formatMessage( CString& stgMessage, int nId, ...) { AFX_MANAGE_STATE(AfxGetAppModuleState()); // --- initialize variable arguments va_list vaList; va_start( vaList, nId); // --- build lines CString stgDummy1, stgDummy2, stgArrayLine[IDS_ERR_NB_LINE]; buildStrings( stgDummy1, stgDummy2, stgArrayLine, // --- output value D_BOX, G_INF, nId, NULL, 0, vaList // --- input value ); // --- concat the message stgMessage.Empty(); for( int n=0; n m_dwMaxMessage) { m_dwPosition = m_dwBeginInfo; m_dwNbMessage = 0L; m_file.Seek(m_dwPosition, CFile::begin); } else { m_dwPosition = m_file.GetPosition(); } // --- write the end of the log file m_file.WriteString( _T("****** End of Log File\n")); } CATCH( CFileException, e) { ::OutputDebugString( _T("Can't write in Log file\n")); } END_CATCH // --- flush and close the file TRY { m_file.Flush(); } CATCH( CFileException, e) { ::OutputDebugString( _T("Can't flush the Log file\n")); } END_CATCH } } } if (m_nDest & D_BOX) { TPreferences lPref("Interface\\Dialogs"); CString lId; int lValue = 0; lId.Format(_T("%d"), m_nId); if ((lPref.GetInt(lId, &lValue) == S_OK) && lValue) return ; // --- the user message box has been selected int nResult = IDOK; // --- if complete resource message if( m_nId != NO_ID) { TErrDlg dlg( m_nGravity, m_nId, m_stgArrayLine[0], m_stgArrayLine[1], m_stgArrayLine[2]); nResult = dlg.DoModal(); } // --- if short message or dialog failure if( m_nId == NO_ID || nResult != IDOK) { // --- the dialog can't be displayed, may be his resource DLL is not loaded CString stg( _T("")); // --- concat the 2 headers into a single string if( m_nId != NO_ID ) { // We have some text but no dialog // typically err with Languages DLLs stg = m_stgArrayLine[1]; stg += _T("\n"); stg += m_stgArrayLine[2]; } else { stg = m_stgHeader1; stg += _T("\n"); stg += m_stgHeader2; } // --- select the box style gravity UINT uStyle = 0; switch (m_nGravity & 0x7) { case G_FAT: uStyle = MB_ICONSTOP; break; case G_WAR: uStyle = MB_ICONEXCLAMATION; break; case G_INF: uStyle = MB_ICONINFORMATION; break; default:ATLASSERT( false); } uStyle |= MB_OK; // --- display message in an AfxBox if (AfxMessageBox( stg, uStyle) == 0) { // --- Can't display it, there is not enought memory AfxThrowMemoryException(); } } } } ////////////////////////////////////////////////////////////////////// // trace ////////////////////////////////////////////////////////////////////// void TErr::trace( int nDest, // --- Destination flag, compose with OUT, LOG, BOX int nGravity, // --- Fravity flag, may be INFO, WARN or FATL int nId, // --- Message Identify, may be NO_ID, or a valid resource string LPCSTR szFilename, // --- source filename int nLine, // --- line number, ... ) { #ifndef _DEBUG if (nDest == D_OUT) return ; #endif AFX_MANAGE_STATE(AfxGetAppModuleState()); // --- initialize variable arguments va_list vaList; va_start( vaList, nLine); // --- build lines CString stgHeader1, stgHeader2, stgArrayLine[IDS_ERR_NB_LINE]; buildStrings( stgHeader1, stgHeader2, stgArrayLine, // --- output value nDest, nGravity, nId, szFilename, nLine, vaList // --- input value ); // --- finalize variable arguments va_end( vaList); // --- instanciate a private TErr TErr error( nDest, nGravity, nId, stgHeader1, stgHeader2, stgArrayLine); error.output(); } ////////////////////////////////////////////////////////////////////// // getGravityString ////////////////////////////////////////////////////////////////////// LPCTSTR TErr::getGravityString( int nGravity) { // --- verify parameters ASSERT( nGravity == G_INF || nGravity == G_WAR || nGravity == G_FAT); // --- definition of the 0 Based array of the label static const LPCTSTR tabSzGravityLabel[] = { _T(""), _T(""), _T("")}; return tabSzGravityLabel[nGravity-1]; } ////////////////////////////////////////////////////////////////////// // getTimeStamp ////////////////////////////////////////////////////////////////////// CString TErr::getTimeStamp() { // --- get the current time for the time stamp CTime timeStamp = CTime::GetCurrentTime(); // --- return time stamp or an empty string if Destination is output window return timeStamp.Format( _T("%X")); // was "%d %b %y %X" } ////////////////////////////////////////////////////////////////////// // getIdString ////////////////////////////////////////////////////////////////////// CString TErr::getIdString( int nId) { CString stgId; // --- id not defined, return NO_ID, else return formated number if( nId == NO_ID) stgId = _T("No ID"); else stgId.Format( _T("ID:%03d"), nId); return stgId; } ////////////////////////////////////////////////////////////////////// // getLineString ////////////////////////////////////////////////////////////////////// LPCTSTR TErr::getLineString( int nLine) { // --- verify parameters ASSERT( nLine == L_TIT || nLine == L_DES || nLine == L_COR); // --- definition of the 0 Based array of the label static const LPCTSTR tabSzLineLabel[] = { _T("TIT:"), _T("DES:"), _T("COR:")}; return tabSzLineLabel[nLine]; } ////////////////////////////////////////////////////////////////////// // getShortFilename ////////////////////////////////////////////////////////////////////// CString TErr::getShortFilename( LPCSTR szFilename) { CString stgDrive; CString stgDir; CString stgFname; CString stgExt; if( szFilename) { USES_CONVERSION; // --- split the full file name _tsplitpath( A2CT(szFilename), stgDrive.GetBuffer( _MAX_DRIVE), stgDir.GetBuffer( _MAX_DIR), stgFname.GetBuffer( _MAX_FNAME), stgExt.GetBuffer( _MAX_EXT) ); // --- reconcat filename and extension stgFname.ReleaseBuffer(); stgExt.ReleaseBuffer(); // stgFname += stgExt; } else { stgFname = _T(""); } return stgFname; } LPCTSTR TErr::getLogFilename() { return g_szFullName; } void TErr::setLogFilename( LPCTSTR szFullName) { if (g_szFullName) { free(g_szFullName); g_szFullName = NULL; } if (szFullName && _tcslen(szFullName)) g_szFullName = _tcsdup(szFullName); else { TCHAR lFileName[MAX_PATH]; ::GetModuleFileName(NULL, lFileName, MAX_PATH); ::PathRemoveFileSpec(lFileName); ::PathAppend(lFileName, KEEBOO_PRODUCT_NAME _T(".log")); g_szFullName = _tcsdup(lFileName); } m_bIsNewStart = true; g_bIsNewFile = FALSE; } DWORD TErr::getLogMaxMessage() { return m_dwMaxMessage; } void TErr::setLogMaxMessage( DWORD dwMaxMessage) { m_dwMaxMessage = dwMaxMessage; } /*------------ TErr.h ------------*/ // TErr.h: interface for the TErr class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_TERR_H__018EC621_F55C_11D1_8A77_00A0244E2DEF__INCLUDED_) #define AFX_TERR_H__018EC621_F55C_11D1_8A77_00A0244E2DEF__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #include "SharedResource.h" class TErr { // --- methods public: // _7X_OS_EXT_CLASS TErr( int nDest, int nGravity, int nId, LPCSTR szFilename, int nLine, ...); // _7X_OS_EXT_CLASS virtual ~TErr(); _7X_OS_EXT_CLASS static void trace( int nDest, int nGravity, int nId, LPCSTR szFilename, int nLine, ...); _7X_OS_EXT_CLASS static void formatMessage( CString& stgMessage, int nId, ...); _7X_OS_EXT_CLASS void output(); _7X_OS_EXT_CLASS static LPCTSTR getLogFilename(); _7X_OS_EXT_CLASS static void setLogFilename( LPCTSTR szFullName); _7X_OS_EXT_CLASS static DWORD getLogMaxMessage(); _7X_OS_EXT_CLASS static void setLogMaxMessage( DWORD dwMaxMessage); private: TErr( int nDest, int nGravity, int nId, CString& stgHeader1, CString& stgHeader2, CString stgArrayLine[]); static void TErr::buildStrings( CString& stgHeader1, CString& stgHeader2, CString stgArrayLine[], int nDest, int nGravity, int nId, LPCSTR szFilename, int nLine, va_list vaList ); // --- helper methods static LPCTSTR getGravityString( int nGravity); static CString getTimeStamp(); static CString getIdString( int nId); static LPCTSTR getLineString( int nLine); static CString getShortFilename( LPCSTR szFilename); static int getErrorId( int nLine, int nId); // --- attributs private: int m_nDest; int m_nGravity; int m_nId; CString m_stgHeader1, m_stgHeader2; CString m_stgArrayLine[IDS_ERR_NB_LINE]; // --- constants public: // --- gravity constants enum { G_INF = 0x01, // --- information G_WAR, // --- warning G_FAT, // --- error fatal G_REMOVE = 0x08 }; // --- destination constants enum { D_OUT = 0x01, // --- output debug window D_LOG = 0x02, // --- log file D_BOX = 0x04 // --- message box }; // --- message ID constants enum { NO_ID = -1 // --- undefined ID }; // --- line constants enum { L_TIT = 0x00, // --- index of the title L_DES, // --- index of the description L_COR // --- index of the correction }; // --- friend friend class TErrDlg; }; ////////////////////////////////////////////////////////////////////// // getErrorIds ////////////////////////////////////////////////////////////////////// inline int TErr::getErrorId( int nLine, int nId) { // --- verify parameters ATLASSERT( nLine == L_TIT || nLine == L_DES || nLine == L_COR); ATLASSERT( nId != NO_ID); return( nId + nLine); } #define KB_LOG_WARN0(msg) TErr::trace(TErr::D_OUT | TErr::D_LOG, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, msg); #define KB_LOG_WARN1(msg, arg1) TErr::trace(TErr::D_OUT | TErr::D_LOG, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, msg, arg1); #define KB_LOG_WARN2(msg, arg1, arg2) TErr::trace(TErr::D_OUT | TErr::D_LOG, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, msg, arg1, arg2); #define KB_LOG_INFO0(msg) TErr::trace(TErr::D_OUT | TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, msg); #define KB_LOG_INFO1(msg, arg1) TErr::trace(TErr::D_OUT | TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, msg, arg1); #define KB_LOG_INFO2(msg, arg1, arg2) TErr::trace(TErr::D_OUT | TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, msg, arg1, arg2); #define KB_BOX_WARN0(msg) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, msg); #define KB_BOX_WARN1(msg, arg1) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, msg, arg1); #define KB_BOX_WARN2(msg, arg1, arg2) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_WAR, TErr::NO_ID, __FILE__, __LINE__, msg, arg1, arg2); #define KB_BOX_INFO0(msg) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, msg); #define KB_BOX_INFO1(msg, arg1) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, msg, arg1); #define KB_BOX_INFO2(msg, arg1, arg2) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, msg, arg1, arg2); #define KB_BOX_IDWARN0(id) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_WAR, id, __FILE__, __LINE__); #define KB_BOX_IDWARN1(id, arg1) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_WAR, id, __FILE__, __LINE__, arg1); #define KB_BOX_IDWARN2(id, arg1, arg2) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_WAR, id, __FILE__, __LINE__, arg1, arg2); #define KB_BOX_IDINFO0(id) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_INF, id, __FILE__, __LINE__); #define KB_BOX_IDINFO1(id, arg1) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_INF, id, __FILE__, __LINE__, arg1); #define KB_BOX_IDINFO2(id, arg1, arg2) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_INF, id, __FILE__, __LINE__, arg1, arg2); #define KB_BOX_IDFATAL0(id) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_FAT, id, __FILE__, __LINE__); #define KB_BOX_IDFATAL1(id, arg1) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_FAT, id, __FILE__, __LINE__, arg1); #define KB_BOX_IDFATAL2(id, arg1, arg2) TErr::trace(TErr::D_OUT | TErr::D_BOX, TErr::G_FAT, id, __FILE__, __LINE__, arg1, arg2); #endif // !defined(AFX_TERR_H__018EC621_F55C_11D1_8A77_00A0244E2DEF__INCLUDED_) /*------------ THTMLString.cpp ------------*/ #include "StdAfx.h" #include "THTMLString.h" #include "TAppInfo.h" #include "TAppVersionInfo.h" #include "TAppBrandingInfo.h" #include "TLanguagesInfo.h" #include "TLooksInfo.h" #include "SharedResource.h" #include "TPath.h" #include "TPreferences.h" #include "TGlobalResource.h" #ifdef _DEBUG static bool _useAfterClean = false; #endif class THTMLStringCleaner { public: ~THTMLStringCleaner() { THTMLString::PurgeInternal(); #ifdef _DEBUG _useAfterClean = true; #endif } }; static LPTSTR lpCurrentLookFullPath = NULL; static LPTSTR lpCurrentLanguageFullPath = NULL; static LPTSTR lpNeutralFullPath = NULL; //static LPTSTR lpFullStyle = NULL; //static LPTSTR lpFullStyleHandler = NULL; static LPTSTR lpAppPath = NULL; static LPTSTR lpWebSite = NULL; static THTMLStringCleaner _THTMLStringCleaner; void THTMLString::PurgeInternal( void ) { #ifdef _DEBUG if( _useAfterClean ) { TRACE( "THTMLString::PurgeInternal deja fait\n" ); } _useAfterClean = true; #endif if( lpCurrentLookFullPath ) { delete [] lpCurrentLookFullPath; lpCurrentLookFullPath = NULL; } if( lpCurrentLanguageFullPath ) { delete [] lpCurrentLanguageFullPath; lpCurrentLanguageFullPath = NULL; } if( lpNeutralFullPath ) { delete [] lpNeutralFullPath; lpNeutralFullPath = NULL; } /* if ( lpFullStyle ) { delete [] lpFullStyle; lpFullStyle = NULL; } if ( lpFullStyleHandler ) { delete [] lpFullStyleHandler; lpFullStyleHandler = NULL; } */ if( lpAppPath ) { delete [] lpAppPath; lpAppPath = NULL; } if( lpWebSite ) { delete [] lpWebSite; lpWebSite = NULL; } } void THTMLString::InitInternal( void ) { #ifdef _DEBUG _ASSERT( _useAfterClean != true ); // If it happens it means that // someone want to use THTMLSTring // AFTER the internal buffer purge #endif if( !lpCurrentLookFullPath ) { TLooksInfo lLooks; CString lCurrentLookFullPath; ASSERT( lLooks.GetCurrentLook() ); lCurrentLookFullPath = lLooks.GetCurrentLook()->GetFullPath(); lpCurrentLookFullPath = new TCHAR[ lCurrentLookFullPath.GetLength() + 6 + 1 ]; strcpy( lpCurrentLookFullPath, "res://"); strcat( lpCurrentLookFullPath,(LPCTSTR)lCurrentLookFullPath ); } if( !lpCurrentLanguageFullPath ) { TLanguagesInfo lLangs1; CString lCurrentLanguageFullPath; ASSERT( lLangs1.GetCurrentLanguage() ); lCurrentLanguageFullPath = lLangs1.GetCurrentLanguage()->GetFullPath(); lpCurrentLanguageFullPath = new TCHAR[ lCurrentLanguageFullPath.GetLength() + 6 + 1 ]; strcpy( lpCurrentLanguageFullPath, "res://"); strcat( lpCurrentLanguageFullPath,(LPCTSTR)lCurrentLanguageFullPath ); } if( !lpNeutralFullPath ) { TLanguagesInfo lLangs2; CString lNeutralFullPath; ASSERT( lLangs2.GetNeutralLanguage() ); lNeutralFullPath = lLangs2.GetNeutralLanguage()->GetFullPath(); // WARNING: CString::Replace is a MFC42 ( 6.0 ) call // If we use it, we will add a dependency // // lNeutralFullPath.Replace( _T( "\\" ),_T( "\\\\" ) ); lpNeutralFullPath = new TCHAR[ lNeutralFullPath.GetLength() + 6 + 1 ]; strcpy( lpNeutralFullPath, "res://"); strcat( lpNeutralFullPath,(LPCTSTR)lNeutralFullPath ); } if( !lpAppPath ) { TAppInfo lAppInfo; CString lAppPath; lAppPath = lAppInfo.GetPath(); lpAppPath = new TCHAR[ lAppPath.GetLength() + 1 ]; strcpy( lpAppPath,(LPCTSTR)lAppPath ); } /* if( !lpFullStyle ) { CString lStyleName; CString lStyleFile; CString lFullStyle; KBLoadString(IDS_HTML_HELP_KEEBOO_CHM_FILE_NAME, lStyleFile); ASSERT(lStyleFile.GetLength()); CString lStyleFileFullPath(lpAppPath); TPath lPath(lStyleFileFullPath); lPath.AddPath(lStyleFile); KBLoadString(IDS_HTML_HELP_KEEBOO_CSS_FILE_NAME, lStyleName); ASSERT(lStyleName.GetLength()); lFullStyle.Format( _T("its:%s::/%s"), lStyleFileFullPath, lStyleName); lpFullStyle = new TCHAR[ lFullStyle.GetLength() + 1 ]; strcpy( lpFullStyle,(LPCTSTR)lFullStyle ); } if( !lpFullStyleHandler ) { CString lStyleFile; CString lStyleFileBaseUrl; CString lCssHandlerFile; KBLoadString(IDS_HTML_HELP_KEEBOO_CHM_FILE_NAME, lStyleFile); CString lStyleFileFullPath(lpAppPath); TPath lPath(lStyleFileFullPath); lPath.AddPath(lStyleFile); KBLoadString(IDS_HTML_HELP_KEEBOO_CSS_HANDLER_FILE_NAME, lCssHandlerFile); lStyleFileBaseUrl.Format( _T("its:%s::/%s"), lStyleFileFullPath, lCssHandlerFile); lpFullStyleHandler = new TCHAR[ lStyleFileBaseUrl.GetLength() + 1 ]; strcpy( lpFullStyleHandler,(LPCTSTR)lStyleFileBaseUrl ); } */ if( !lpWebSite ) { TAppInfo lAppInfo; CString lWebSite; lWebSite = lAppInfo.BuildKeeBooWebUrl(""); lpWebSite = new TCHAR[ lWebSite.GetLength() + 1 ]; strcpy( lpWebSite, (LPCTSTR)lWebSite ); } } TCHAR* THTMLString::FormatInternal( LPCTSTR pFormat,...) { va_list vaList; LPTSTR szTemp; va_start( vaList,pFormat ); if( (::FormatMessage( FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,pFormat,0,0,(LPTSTR)&szTemp,0,&vaList ) == 0) || (szTemp == NULL) ) { AfxThrowMemoryException(); } va_end( vaList); return szTemp; } BOOL THTMLString::Format( unsigned long pResID,... ) { CString lFormat; HINSTANCE hInst = KBFindResourceHandle(MAKEINTRESOURCE(pResID), RT_HTML); VERIFY(hInst); HRSRC hResource = ::FindResource(hInst, MAKEINTRESOURCE(pResID), RT_HTML); VERIFY(hResource); if( hResource == NULL ) { return FALSE; } HGLOBAL lGlobal = ::LoadResource(hInst, hResource); LPVOID lpBuff = ::LockResource(lGlobal); DWORD dwSize = ::SizeofResource(hInst, hResource); LPTSTR lFormatBuffer = new TCHAR[ dwSize + 1 ]; memcpy(lFormatBuffer, lpBuff, dwSize); lFormatBuffer[ dwSize ] = 0; ::UnlockResource(hResource); ::FreeResource(hResource); va_list vaList; va_start( vaList,pResID); LPTSTR szTemp; if( (::FormatMessage( FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,lFormatBuffer,0,0,(LPTSTR)&szTemp,0,&vaList ) == 0) || (szTemp == NULL)) { delete [] lFormatBuffer; AfxThrowMemoryException(); } delete [] lFormatBuffer; TCHAR *ls = GetBuffer( strlen( szTemp ) + 1 ); strcpy( ls,szTemp ); ReleaseBuffer(); LocalFree( szTemp ); va_end( vaList); return TRUE; } BOOL THTMLString::StdFormat( unsigned long pResID,... ) { HINSTANCE hInst = KBFindResourceHandle(MAKEINTRESOURCE(pResID), RT_HTML); VERIFY(hInst); HRSRC hResource = ::FindResource(hInst, MAKEINTRESOURCE(pResID), RT_HTML); VERIFY(hResource); if( hResource == NULL ) { return FALSE; } HGLOBAL lGlobal = ::LoadResource(hInst, hResource); LPVOID lpBuff = ::LockResource(lGlobal); DWORD dwSize = ::SizeofResource(hInst, hResource); LPTSTR lFormatBuffer = new TCHAR[ dwSize + 1 ]; memcpy(lFormatBuffer, lpBuff, dwSize); lFormatBuffer[ dwSize ] = 0; ::UnlockResource(hResource); ::FreeResource(hResource); va_list vaList; BOOL lResult; va_start( vaList,pResID ); lResult = StdFormat( lFormatBuffer, vaList); delete [] lFormatBuffer; va_end( vaList); return lResult; } BOOL THTMLString::StdFormat( LPCTSTR pFormat,... ) { va_list vaList; BOOL lResult; va_start( vaList,pFormat ); lResult = StdFormat(pFormat, vaList); va_end( vaList); return lResult; } BOOL THTMLString::StdFormat( LPCTSTR pFormat, va_list vaList) { LPTSTR szTemp,szFormat; InitInternal(); TAppBrandingInfo lBrandingInfo; TAppVersionInfo lAppInfo; CString stgVersionPartner; stgVersionPartner = lAppInfo.GetProductID() + CString(" - ") + lBrandingInfo.GetPartnerID(); szFormat = FormatInternal( pFormat, "", // 1 "", // 2 "", // 3 "", // 4 lAppInfo.GetProductName(), // 5 lAppInfo.GetProductPostName(), // 6 lpWebSite, // 7 stgVersionPartner // 8 ); if( (::FormatMessage( FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER,szFormat,0,0,(LPTSTR)&szTemp,0,&vaList ) == 0) || (szTemp == NULL) ) { AfxThrowMemoryException(); } TCHAR *ls = GetBuffer( strlen( szTemp ) + 1 ); strcpy( ls,szTemp ); ReleaseBuffer(); LocalFree( szTemp ); LocalFree( szFormat ); return TRUE; } BOOL THTMLString::LoadString( unsigned long pResID ) { HINSTANCE hInst = KBFindResourceHandle(MAKEINTRESOURCE(pResID), RT_HTML); VERIFY(hInst); HRSRC hResource = ::FindResource(hInst, MAKEINTRESOURCE(pResID), RT_HTML); VERIFY(hResource); if( hResource == NULL ) { return FALSE; } HGLOBAL lGlobal = ::LoadResource(hInst, hResource); LPVOID lpBuff = ::LockResource(lGlobal); DWORD dwSize = ::SizeofResource(hInst, hResource); LPTSTR lStrBuffer = new TCHAR[ dwSize + 1 ]; memcpy(lStrBuffer, lpBuff, dwSize); lStrBuffer[ dwSize ] = 0; ::UnlockResource(hResource); ::FreeResource(hResource); TCHAR *ls = GetBuffer( strlen( lStrBuffer ) + 1 ); strcpy( ls,lStrBuffer ); ReleaseBuffer(); delete [] lStrBuffer; return TRUE; }/*------------ TModuleVersion.h ------------*/ #ifndef _TModuleVersion_ #define _TModuleVersion_ #include #pragma comment(linker, "/defaultlib:version.lib") // TModuleVersion version info about a module. // To use://// TModuleVersion ver // if (ver.GetFileVersionInfo("_T("mymodule))) { // // info is in ver, you can call GetValue to get variable info like // CString s = ver.GetValue(_T("CompanyName"));// }// class TModuleVersion : public VS_FIXEDFILEINFO { public: TModuleVersion() { fVersionInfo = NULL; } virtual ~TModuleVersion() { delete [] fVersionInfo; } BOOL GetFileVersionInfo( LPCTSTR pFileName) { fTranslation.fCharset = 1252; // default = ANSI code page memset((VS_FIXEDFILEINFO*)this, 0, sizeof(VS_FIXEDFILEINFO)); unsigned long lLen,lLost; lLen = ::GetFileVersionInfoSize( (LPTSTR)pFileName,&lLost ); if( lLen <= 0 ) return FALSE; fVersionInfo = new BYTE[ lLen ]; if (!::GetFileVersionInfo( (LPTSTR)pFileName,0,lLen,fVersionInfo) ) return FALSE; LPVOID lpvi; UINT iLen; if( !VerQueryValue( fVersionInfo, _T("\\"), &lpvi, &iLen) ) return FALSE; *(VS_FIXEDFILEINFO*)this = *(VS_FIXEDFILEINFO*)lpvi; if (VerQueryValue( fVersionInfo,"\\VarFileInfo\\Translation",&lpvi,&iLen ) && (iLen >= 4) ) { fTranslation = *(TRANSLATION*)lpvi; } return TRUE; } DWORD GetLocaleId( void ) { return MAKELONG( fTranslation.fLangID,fTranslation.fCharset ); } BOOL GetValue( LPCTSTR pKeyName, CString& sVal) { if (fVersionInfo) { // To get a string value must pass query in the form // // "\StringFileInfo\\keyname" // // where is the languageID concatenated with the // code page, in hex. Glurk // CString query; query.Format( _T("\\StringFileInfo\\%04x%04x\\%s" ),fTranslation.fLangID,fTranslation.fCharset, pKeyName); LPCTSTR pVal; UINT iLenVal; if( VerQueryValue( fVersionInfo,(LPTSTR)(LPCTSTR)query,(LPVOID*)&pVal,&iLenVal) ) { sVal = pVal; return TRUE; } } return FALSE; } CString GetFullLanguageName( void ) { CString lName; TCHAR *s = lName.GetBuffer( 128 ); int l; l = ::GetLocaleInfo( fTranslation.fLangID,LOCALE_SLANGUAGE,s,128 ); if( l > 0 ) { s[ l ] = 0; } lName.ReleaseBuffer(); return lName; } CString GetLanguageName( void ) { CString lName; TCHAR *s = lName.GetBuffer( 20 ); int l; l = ::GetLocaleInfo( fTranslation.fLangID,LOCALE_SABBREVLANGNAME ,s,20 ); if( l > 0 ) { s[ l ] = 0; } lName.ReleaseBuffer(); return lName; } protected: BYTE* fVersionInfo; // all version info struct TRANSLATION { WORD fLangID; // language ID WORD fCharset; // character set (code page) } fTranslation; }; #endif // _TModuleVersion_ /*------------ TTypeInfoHolderEx.h ------------*/ #ifndef T_TYPE_INFO_HOLDER_EX #define T_TYPE_INFO_HOLDER_EX #define _INLINE_FCT inline class TTypeInfoHolderEx { // Should be 'protected' but can cause compiler to generate fat code. public: const GUID* m_pguid; const GUID* m_plibid; WORD m_wMajor; WORD m_wMinor; ITypeInfo* m_pInfo; long m_dwRef; struct stringdispid { CComBSTR bstr; int nLen; DISPID id; BOOL hardcoded; }; stringdispid* m_pMap; int m_nCount; DISPID m_MaxID; public: // IDispatch HRESULT GetTypeInfo(UINT /* itinfo */, LCID lcid, ITypeInfo** pptinfo); HRESULT GetIDsOfNames(REFIID /* riid */, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid); HRESULT Invoke(IDispatch* p, DISPID dispidMember, REFIID /* riid */, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr); // IDispatchEx HRESULT GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid); HRESULT InvokeEx(IDispatch* pDisp, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller); HRESULT DeleteMemberByName(BSTR bstr, DWORD grfdex); HRESULT DeleteMemberByDispID( DISPID id); HRESULT GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex); HRESULT GetMemberName(DISPID id, BSTR *pbstrName); HRESULT GetNextDispID(DWORD /* grfdex */, DISPID id, DISPID* pid); HRESULT GetNameSpaceParent(IUnknown** /* ppunk */); // Other HRESULT GetTI(LCID lcid, ITypeInfo** ppInfo); HRESULT GetTI(LCID lcid); HRESULT EnsureTI(LCID lcid); HRESULT IsExtendedMember(DISPID pID, BOOL* pResult); // This function is called by the module on exit // It is registered through _Module.AddTermFunc() static void __stdcall Cleanup(DWORD dw); HRESULT LoadNameCache(ITypeInfo* pTypeInfo); DWORD translateProperty(DWORD invkind, DWORD grfdexFetch); void AddName(DISPID pId, BSTR pName); }; #include "TTypeInfoHolderEx.inl" #endif // T_TYPE_INFO_HOLDER_EX /*------------ TTypeInfoHolderEx.inl ------------*/ // // Legal comments /* *

Copyright (C) 1997 - 1998 Sevenix Corporation

*/ // Info comments /** * @author Pierre De SACY */ _INLINE_FCT HRESULT TTypeInfoHolderEx::GetTI(LCID lcid, ITypeInfo** ppInfo) { HRESULT hr = S_OK; if (m_pInfo == NULL) hr = GetTI(lcid); *ppInfo = m_pInfo; if (m_pInfo != NULL) { m_pInfo->AddRef(); hr = S_OK; } return hr; } _INLINE_FCT HRESULT TTypeInfoHolderEx::EnsureTI(LCID lcid) { HRESULT hr = S_OK; if (m_pInfo == NULL) hr = GetTI(lcid); return hr; } // This function is called by the module on exit // It is registered through _Module.AddTermFunc() _INLINE_FCT void TTypeInfoHolderEx::Cleanup(DWORD dw) { TTypeInfoHolderEx* p = (TTypeInfoHolderEx*) dw; if (p->m_pInfo != NULL) p->m_pInfo->Release(); p->m_pInfo = NULL; delete [] p->m_pMap; p->m_pMap = NULL; } _INLINE_FCT HRESULT TTypeInfoHolderEx::GetTypeInfo(UINT /* itinfo */, LCID lcid, ITypeInfo** pptinfo) { HRESULT hRes = E_POINTER; if (pptinfo != NULL) hRes = GetTI(lcid, pptinfo); return hRes; } _INLINE_FCT HRESULT TTypeInfoHolderEx::GetIDsOfNames(REFIID /* riid */, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) { HRESULT hRes = EnsureTI(lcid); if (m_pInfo != NULL) { for (int lIndex = 0; lIndex < (int)cNames; lIndex++) { int lCount; int n; n = ocslen(rgszNames[lIndex]); for (lCount = m_nCount - 1; lCount >= 0; lCount--) { stringdispid& lEntry = m_pMap[lCount]; if ((n == lEntry.nLen) && (memcmp(lEntry.bstr, rgszNames[lIndex], lEntry.nLen * sizeof(OLECHAR)) == 0)) { rgdispid[lIndex] = lEntry.id; break; } } if (lCount < 0) { // Try to find a default name hRes = m_pInfo->GetIDsOfNames(rgszNames + lIndex, 1, &rgdispid[lIndex]); if (FAILED(hRes)) break; #ifdef _DEBUG CComBSTR lName; ASSERT(GetMemberName(rgdispid[lIndex], &lName) == S_OK); // If we've got this assert // it might be a Case sensitive problem // check all Javascript code for the following name ASSERT(memcmp(lName, rgszNames[lIndex], lName.Length()) == 0); #endif } } } return hRes; } _INLINE_FCT HRESULT TTypeInfoHolderEx::Invoke(IDispatch* p, DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarResult, EXCEPINFO* pei, UINT* puArgErr) { HRESULT hRes = EnsureTI(lcid); if (m_pInfo != NULL) hRes = m_pInfo->Invoke(p, id, wFlags, pdp, pvarResult, pei, puArgErr); return hRes; } _INLINE_FCT HRESULT TTypeInfoHolderEx::LoadNameCache(ITypeInfo* pTypeInfo) { TYPEATTR* pta; HRESULT hr = pTypeInfo->GetTypeAttr(&pta); if (SUCCEEDED(hr)) { m_nCount = pta->cFuncs; m_pMap = m_nCount == 0 ? 0 : new stringdispid[m_nCount]; for (int lIndex = 0; lIndex < m_nCount; lIndex++) { stringdispid& lEntry = m_pMap[lIndex]; FUNCDESC* pfd; if (SUCCEEDED(pTypeInfo->GetFuncDesc(lIndex, &pfd))) { CComBSTR bstrName; if (SUCCEEDED(pTypeInfo->GetDocumentation(pfd->memid, &bstrName, NULL, NULL, NULL))) { lEntry.bstr.Attach(bstrName.Detach()); lEntry.nLen = SysStringLen(lEntry.bstr); lEntry.id = pfd->memid; lEntry.hardcoded = TRUE; if ((pfd->memid > 0) && !(pfd->memid & 0xF0000000) && (pfd->memid > m_MaxID)) m_MaxID = pfd->memid; } pTypeInfo->ReleaseFuncDesc(pfd); } } pTypeInfo->ReleaseTypeAttr(pta); } return S_OK; } _INLINE_FCT HRESULT TTypeInfoHolderEx::GetTI(LCID lcid) { //If this assert occurs then most likely didn't initialize properly ATLASSERT(m_plibid != NULL && m_pguid != NULL); ATLASSERT(!InlineIsEqualGUID(*m_plibid, GUID_NULL) && "Did you forget to pass the LIBID to CComModule::Init?"); if (m_pInfo != NULL) return S_OK; HRESULT hRes = E_FAIL; EnterCriticalSection(&_Module.m_csTypeInfoHolder); if (m_pInfo == NULL) { ITypeLib* pTypeLib; hRes = LoadRegTypeLib(*m_plibid, m_wMajor, m_wMinor, lcid, &pTypeLib); if (SUCCEEDED(hRes)) { CComPtr spTypeInfo; hRes = pTypeLib->GetTypeInfoOfGuid(*m_pguid, &spTypeInfo); if (SUCCEEDED(hRes)) { CComPtr spInfo(spTypeInfo); CComPtr spTypeInfo2; if (SUCCEEDED(spTypeInfo->QueryInterface(&spTypeInfo2))) spInfo = spTypeInfo2; LoadNameCache(spInfo); m_pInfo = spInfo.Detach(); } pTypeLib->Release(); } } LeaveCriticalSection(&_Module.m_csTypeInfoHolder); _Module.AddTermFunc(Cleanup, (DWORD)this); return hRes; } // ------------------------------------------------------------------- // GetDispID _INLINE_FCT HRESULT TTypeInfoHolderEx::GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid) { ASSERT(pid); HRESULT lResult = GetIDsOfNames(IID_NULL, &bstrName, 1, LOCALE_SYSTEM_DEFAULT, pid); if ((lResult != S_OK) && (grfdex & fdexNameEnsure)) { DISPID lNextFreeID = m_MaxID + 1; #ifdef DEBUG_DISPATCH_EX TRACE(_T("\n -*-*- Create a new DispID %d for %s\n\n"), lNextFreeID, CString(bstrName)); #endif // DEBUG_DISPATCH_EX AddName(lNextFreeID, bstrName); *pid = lNextFreeID; return S_OK; } #ifdef DEBUG_DISPATCH_EX if (lResult != S_OK) TRACE(_T("GetDispID(%s): Not Found\n"), CString(bstrName)); #endif // DEBUG_DISPATCH_EX return lResult; } // ------------------------------------------------------------------- // InvokeEx _INLINE_FCT HRESULT TTypeInfoHolderEx::InvokeEx(IDispatch* pDisp, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { #ifdef DEBUG_DISPATCH_EX CComBSTR lName; if (GetMemberName(id, &lName) == S_OK) TRACE(_T("InvokeEx(%s : %d)\n"), CString(lName), id); #endif UINT uArgErr; if (wFlags == 0) wFlags = DISPATCH_METHOD; return Invoke(pDisp, id, IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &uArgErr); } // ------------------------------------------------------------------- // DeleteMemberByName _INLINE_FCT HRESULT TTypeInfoHolderEx::DeleteMemberByName(BSTR bstr, DWORD grfdex) { #ifdef DEBUG_DISPATCH_EX TRACE(_T("DeleteMemberByName(%s)\n"), CString(bstr)); #endif // DEBUG_DISPATCH_EX for (long lIndex = 0; lIndex < m_nCount; lIndex++) { stringdispid& lEntry = m_pMap[lIndex]; int n = ocslen(bstr); if (n == lEntry.nLen) { if (((grfdex & fdexNameCaseSensitive) && (memcmp(lEntry.bstr, bstr, lEntry.nLen * sizeof(OLECHAR)) == 0)) || ((grfdex & fdexNameCaseInsensitive) && (_wcsicmp(lEntry.bstr, bstr) == 0))) { if (!lEntry.hardcoded) { //lEntry.nLen = 0; //::SysFreeString(lEntry.bstr); return S_OK; } return S_FALSE; } } } return DISP_E_MEMBERNOTFOUND; } // ------------------------------------------------------------------- // DeleteMemberByDispID _INLINE_FCT HRESULT TTypeInfoHolderEx::DeleteMemberByDispID( DISPID id) { CComBSTR lMemberName; HRESULT lResult; #ifdef DEBUG_DISPATCH_EX TRACE(_T("DeleteMemberByDispID(%d)\n"), id); #endif // DEBUG_DISPATCH_EX lResult = GetMemberName(id, &lMemberName); if (lResult == S_OK) lResult = DeleteMemberByName(lMemberName, fdexNameCaseSensitive); return lResult; } // ------------------------------------------------------------------- // GetMemberProperties _INLINE_FCT HRESULT TTypeInfoHolderEx::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) { #ifdef DEBUG_DISPATCH_EX TRACE(_T("GetMemberProperties(%d)\n"), id); #endif // DEBUG_DISPATCH_EX long lIndex; for (lIndex = 0; lIndex < m_nCount; lIndex++) { if (id == m_pMap[lIndex].id) break; } if (lIndex >= m_nCount) return DISP_E_MEMBERNOTFOUND; if (m_pMap[lIndex].hardcoded) { FUNCDESC* lFuncDesc; if (m_pInfo->GetFuncDesc(lIndex, &lFuncDesc) == S_OK) { *pgrfdex = translateProperty(lFuncDesc->invkind, grfdexFetch); m_pInfo->ReleaseFuncDesc(lFuncDesc); } } else { *pgrfdex = translateProperty(INVOKE_PROPERTYGET|INVOKE_PROPERTYPUT, grfdexFetch); } return S_OK; } // ------------------------------------------------------------------- // GetMemberName _INLINE_FCT HRESULT TTypeInfoHolderEx::GetMemberName(DISPID id, BSTR *pbstrName) { long lIndex; for (lIndex = 0; lIndex < m_nCount; lIndex++) { if (id == m_pMap[lIndex].id) break; } if (lIndex >= m_nCount) { #ifdef DEBUG_DISPATCH_EX TRACE(_T("GetMemberName(%d) - fail\n"), id); #endif // DEBUG_DISPATCH_EX return DISP_E_MEMBERNOTFOUND; } #ifdef DEBUG_DISPATCH_EX TRACE(_T("GetMemberName(%d) = %s\n"), id, CString(m_pMap[lIndex].bstr)); #endif // DEBUG_DISPATCH_EX *pbstrName = ::SysAllocString(m_pMap[lIndex].bstr); return S_OK; } // ------------------------------------------------------------------- // GetNextDispID _INLINE_FCT HRESULT TTypeInfoHolderEx::GetNextDispID(DWORD grfdex, DISPID id, DISPID* pid) { ASSERT(pid); if (pid == NULL) return E_INVALIDARG; DISPID lBestId; long lIndex; lBestId = 999999; *pid = 0; for (lIndex = 0; lIndex < m_nCount; lIndex++) { DISPID lNextId; lNextId = m_pMap[lIndex].id; if ((lNextId < lBestId) && (lNextId > id)) { lBestId = lNextId; break; } } if (lIndex >= m_nCount) { #ifdef DEBUG_DISPATCH_EX TRACE(_T("GetNextDispID(%d) = fail\n"), id); #endif // DEBUG_DISPATCH_EX return S_FALSE; } *pid = lBestId; #ifdef DEBUG_DISPATCH_EX TRACE(_T("GetNextDispID(%d) = %d\n"), id, *pid); #endif // DEBUG_DISPATCH_EX return S_OK; } // ------------------------------------------------------------------- // GetNameSpaceParent _INLINE_FCT HRESULT TTypeInfoHolderEx::GetNameSpaceParent(IUnknown** /* ppunk */) { // I don't know what to do here ???? #ifdef DEBUG_DISPATCH_EX TRACE(_T("GetNameSpaceParent\n")); #endif // DEBUG_DISPATCH_EX return S_FALSE; } // ------------------------------------------------------------------- // translateProperty _INLINE_FCT HRESULT TTypeInfoHolderEx::IsExtendedMember(DISPID pID, BOOL* pResult) { long lIndex; for (lIndex = 0; lIndex < m_nCount; lIndex++) { if (pID == m_pMap[lIndex].id) break; } if (lIndex >= m_nCount) return DISP_E_MEMBERNOTFOUND; *pResult = !m_pMap[lIndex].hardcoded; return S_OK; } _INLINE_FCT DWORD TTypeInfoHolderEx::translateProperty(DWORD invkind, DWORD grfdexFetch) { DWORD lResult = grfdexPropCannotAll; if (invkind & INVOKE_FUNC) lResult = (lResult & ~fdexPropCannotCall) | fdexPropCanCall; if (invkind & INVOKE_PROPERTYGET) lResult = (lResult & ~fdexPropCannotGet) | fdexPropCanGet; if (invkind & INVOKE_PROPERTYPUT) lResult = (lResult & ~fdexPropCannotPut) | fdexPropCanPut; if (invkind & INVOKE_PROPERTYPUTREF) lResult = (lResult & ~fdexPropCannotPutRef) | fdexPropCanPutRef; lResult = (grfdexFetch & lResult); return lResult; } _INLINE_FCT void TTypeInfoHolderEx::AddName(DISPID pId, BSTR pName) { stringdispid* lNewMap; m_nCount; lNewMap = new stringdispid[m_nCount + 1]; for (int lIndex = 0; lIndex < m_nCount; lIndex++) { stringdispid& lOldEntry = m_pMap[lIndex]; stringdispid& lNewEntry = lNewMap[lIndex]; lNewEntry.bstr.Attach(lOldEntry.bstr.Detach()); lNewEntry.nLen = lOldEntry.nLen; lNewEntry.id = lOldEntry.id; lNewEntry.hardcoded = lOldEntry.hardcoded; } lNewMap[m_nCount].bstr = pName; lNewMap[m_nCount].nLen = SysStringLen(lNewMap[m_nCount].bstr); lNewMap[m_nCount].id = pId; lNewMap[m_nCount].hardcoded = FALSE; if ((pId > 0) && !(pId & 0xF0000000) && (pId > m_MaxID)) { m_MaxID = pId; } // Lock ?? delete [] m_pMap; m_pMap = lNewMap; m_nCount++; // Unlock ?? } // History /* * $Log: /Books/C++/Source/Os/Component/TTypeInfoHolderEx.inl $ * * 4 30/12/99 16:44 Pierre * * 3 15/12/99 11:05 Pierre * * 2 5/05/99 19:10 Pierre * * 1 5/05/99 18:38 Pierre * */ /*------------ TUrl.cpp ------------*/ #include "StdAfx.h" #ifndef T_URL #include "TUrl.h" #endif #ifndef T_EXTENDED_URL_INFO #include "TExtendedUrlInfo.h" #endif #ifndef T_SEVENIX_URL_INFO #include "TSevenixUrlInfo.h" #endif //#include "atlbase.h" //#include "atlconv.cpp" #include "atlconv.h" #include "intshcut.h" typedef HRESULT (STDAPICALLTYPE *PFNTRANSLATEURL)(LPCSTR , DWORD , LPSTR *); PFNTRANSLATEURL gTranslateURL = NULL; BOOL gTryLoad = FALSE; HRESULT KBTranslateURL(LPCSTR pcszURL, DWORD dwInFlags, LPSTR *ppszTranslatedURL) { if (gTranslateURL != NULL) return gTranslateURL(pcszURL, dwInFlags, ppszTranslatedURL); if (gTryLoad) { // Our own implementation if (!*pcszURL) return S_FALSE; // If string already have a protocol LPCSTR lSearch = pcszURL; while (isalpha(*lSearch)) lSearch++; if ((*lSearch == ':') && ((lSearch - pcszURL) > 1)) return S_FALSE; *ppszTranslatedURL = new char[strlen(pcszURL) + 9]; if ((*lSearch == ':') && ((lSearch - pcszURL) == 1)) { strcpy(*ppszTranslatedURL, "file:///"); } else { if ( (*(lSearch+1) == '\\') && (*(lSearch+2) == '\\') ) { // UNC file path strcpy(*ppszTranslatedURL, "file://"); } else { strcpy(*ppszTranslatedURL, "http://"); } } strcat(*ppszTranslatedURL, pcszURL); return S_OK; } HINSTANCE hInst = ::LoadLibrary("Url.dll"); if (hInst) { gTranslateURL = (PFNTRANSLATEURL)::GetProcAddress(hInst, "TranslateURLA"); if (gTranslateURL == NULL) ::FreeLibrary(hInst); } gTryLoad = TRUE; return KBTranslateURL(pcszURL, dwInFlags, ppszTranslatedURL); } // Copy Constructor. TUrl::TUrl(const TUrl& pUrl) { fExtendedInfo = NULL; (*this) = pUrl; if (fExtendedInfo) fExtendedInfo = fExtendedInfo->clone(); } TUrl& TUrl::operator=(const TUrl& pUrl) { fFull = pUrl.fFull; fState = pUrl.fState; fCanonicalizeFlags = pUrl.fCanonicalizeFlags; //memcpy(&fComponents, &pUrl.fComponents, sizeof(fComponents)); fComponents = pUrl.fComponents; fExtendedInfo = NULL; if (pUrl.fExtendedInfo) fExtendedInfo = pUrl.fExtendedInfo->clone(); return (*this); } TUrl& TUrl::operator=(LPCSTR pUrl) { USES_CONVERSION; LPSTR lResultStr; fState = T_URL_STATE_FULL; fCanonicalizeFlags = -1; clearExtendedInfo(); if ((pUrl == NULL) || (*pUrl == 0)) { fFull = pUrl; return (*this); } CString lUrl = pUrl; findExtendedInfo(lUrl); // --- handle the case where there's no protocol: "www.xxx.com" if (pUrl && (KBTranslateURL(T2CA(lUrl), TRANSLATEURL_FL_GUESS_PROTOCOL , &lResultStr) == S_OK)) { fFull = lResultStr; } else if (translateUrlOnErrorHack(lUrl, fFull) != S_OK) fFull = lUrl; return (*this); } TUrl& TUrl::operator=(LPCWSTR pUrl) { USES_CONVERSION; (*this) = W2CA(pUrl); return (*this); } // Creates a URL object from the String representation. TUrl::TUrl(LPCSTR pUrl) : fState(T_URL_STATE_FULL), fExtendedInfo(NULL) { (*this) = pUrl; } // Creates a URL object from the String representation. TUrl::TUrl(LPCWSTR pUrl) : fState(T_URL_STATE_FULL), fExtendedInfo(NULL) { (*this) = pUrl; } // Creates a URL object from the specified protocol, host, port number, and file. TUrl::TUrl(LPCTSTR pScheme, LPCTSTR pHost, int pPort, LPCTSTR pFile) : fState(T_URL_STATE_COMPONENTS), fExtendedInfo(NULL) { fExtendedInfo = NULL; fCanonicalizeFlags = -1; set(pScheme, pHost, pPort, pFile, TString()); } // Creates a URL object from the specified protocol, host, port number, file and extra. TUrl::TUrl(LPCTSTR pScheme, LPCTSTR pHost, int pPort, LPCTSTR pFile, LPCTSTR pExtra) : fState(T_URL_STATE_COMPONENTS), fExtendedInfo(NULL) { fExtendedInfo = NULL; fCanonicalizeFlags = -1; set(pScheme, pHost, pPort, pFile, pExtra); } //Creates an absolute URL from the specified protocol name, host name, and file name. TUrl::TUrl(LPCTSTR pScheme, LPCTSTR pHost, LPCTSTR pFile) : fState(T_URL_STATE_COMPONENTS), fExtendedInfo(NULL) { fExtendedInfo = NULL; fCanonicalizeFlags = -1; set(pScheme, pHost, 80, pFile, TString()); } // Creates a URL by parsing the specification spec within a specified context. TUrl::TUrl(const TUrl pContextUrl, LPCTSTR pUrl) : fState(T_URL_STATE_FULL), fExtendedInfo(NULL) { (*this) = pContextUrl; CombineUrl(pUrl); } // Destruct a URL object. TUrl::~TUrl() { clearExtendedInfo(); } HRESULT TUrl::CombineUrl(LPCTSTR pRelativeUrl) { USES_CONVERSION; DWORD lBufSize = 1024; WCHAR* lBuffer = new WCHAR[lBufSize]; HRESULT lResult = E_FAIL; CComBSTR lExtendedUrl; CComBSTR lRelativeUrl; lExtendedUrl = T2CW(extendedUrlString()); lRelativeUrl = T2CW(pRelativeUrl); do { DWORD lCurBufSize = lBufSize; DWORD lReturnedBufSize; lResult = CoInternetCombineUrl( lExtendedUrl, lRelativeUrl, ICU_ENCODE_SPACES_ONLY, lBuffer, lBufSize, &lReturnedBufSize, 0); if (lResult != S_OK) { if (lResult == S_FALSE) { lBufSize = 2*lCurBufSize; delete lBuffer; lBuffer = NULL; lBuffer = new WCHAR[lBufSize]; } else { delete lBuffer; lBuffer = NULL; break; } } } while (lResult != S_OK); fFull = lBuffer; clearExtendedInfo(); findExtendedInfo(fFull); delete lBuffer; fState &= ~T_URL_CANONICAZILED; return lResult; } BOOL TUrl::equals(LPCTSTR pUrl, BOOL bExtendedUrl) { TUrl lUrl(pUrl); return equals(lUrl, bExtendedUrl); } BOOL TUrl::equals(TUrl& pUrl, BOOL bExtendedUrl) { CString lThisUrl; CString lOtherUrl; long lThisLength; long lOtherLength; long lCompareLength; if (bExtendedUrl) { lThisUrl = extendedUrlString(); lOtherUrl = pUrl.extendedUrlString(); } else { lThisUrl = simpleUrlString(); lOtherUrl = pUrl.simpleUrlString(); } lThisLength = lThisUrl.GetLength(); lOtherLength = lOtherUrl.GetLength(); if (lThisLength != lOtherLength) { if (((lThisLength + 1 == lOtherLength) && (lOtherUrl.GetAt(lThisLength) == '/')) || ((lThisLength == lOtherLength + 1)) && (lThisUrl.GetAt(lOtherLength) == '/')) { //lCompareLength = min(lThisLength, lOtherLength); return FALSE; } else { return FALSE; } } else { lCompareLength = lThisLength; } return !_tcsncmp(lThisUrl, lOtherUrl, lCompareLength); } BOOL TUrl::isCanonical(LPCTSTR pUrl) { return canonicalizedUrlString(pUrl, TRUE) == pUrl; } CString TUrl::canonicalizedUrlString(LPCTSTR pUrl, BOOL bExtendedUrl, DWORD dwFlags) { ASSERT(pUrl); TUrl lUrl(pUrl); HRESULT lResult; lResult = lUrl.canonicalize(dwFlags); ASSERT(SUCCEEDED(lResult)); if (bExtendedUrl) return lUrl.extendedUrlString(); return lUrl.simpleUrlString(); } HRESULT TUrl::canonicalize(DWORD dwFlags) { if ((fState & T_URL_CANONICAZILED) && (fCanonicalizeFlags == dwFlags)) return S_FALSE; fState |= T_URL_CANONICAZILED; fCanonicalizeFlags = dwFlags; CString urlString = simpleUrlString(FALSE); USES_CONVERSION; // Let's canonicalize the 'this' simple URL BOOL bResult = FALSE; DWORD urlBufferLength = 4096; char* urlResultBuffer = NULL; do { delete urlResultBuffer; urlResultBuffer = new char[urlBufferLength]; memset(urlResultBuffer, 0, urlBufferLength); bResult = InternetCanonicalizeUrlA( T2CA(urlString), urlResultBuffer, &urlBufferLength, dwFlags); } while ((!bResult) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)); CString canonicalizedUrlString = urlResultBuffer; delete urlResultBuffer; urlResultBuffer = NULL; // Is this case is well handled up stairs ASSERT(bResult); if (bResult == FALSE) { fFull.Empty(); return E_FAIL; } if (!fExtendedInfo) findExtendedInfo(canonicalizedUrlString); fFull = canonicalizedUrlString; fState = fState & (~T_URL_STATE_COMPONENTS); return S_OK; } //Returns the file name of this URL. TString TUrl::getFile() { if (!(fState & T_URL_STATE_COMPONENTS)) crackUrl(); return fComponents.getUrlPath(); } //Returns the host name of this URL, if applicable. TString TUrl::getHost() { if (!(fState & T_URL_STATE_COMPONENTS)) crackUrl(); return fComponents.getHostName(); } //Returns the port number of this URL. int TUrl::getPort() { if (!(fState & T_URL_STATE_COMPONENTS)) crackUrl(); return fComponents.getPort(); } //Returns the protocol name this URL. TString TUrl::getScheme(BOOL pCheckValid) { USES_CONVERSION; if (!(fState & T_URL_STATE_COMPONENTS)) crackUrl(); return fComponents.getScheme(pCheckValid); } TString TUrl::getProtocol() { USES_CONVERSION; if (!(fState & T_URL_STATE_COMPONENTS)) crackUrl(); return fComponents.getScheme(false); } //Returns the anchor (also known as the "reference") of this URL. TString TUrl::getExtra() { if (!(fState & T_URL_STATE_COMPONENTS)) crackUrl(); return fComponents.getExtraInfo(); } //Compares two URLs, excluding the "ref" fields. BOOL TUrl::sameFile(TUrl pUrl) { return pUrl.simpleUrlString() == simpleUrlString(); } //Sets the fields of the URL. void TUrl::set(LPCTSTR pScheme, LPCTSTR pHost, int pPort, LPCTSTR pFile, LPCTSTR pExtra) { USES_CONVERSION; fState = T_URL_STATE_COMPONENTS; // fill the component struct fComponents.initFromComponents( pScheme, pHost, pPort, "", "", pFile, pExtra); // fFull.Empty(); } //Constructs a string representation of this URL. TString TUrl::simpleUrlString(BOOL pCanonicalize) { if (!(fState & T_URL_STATE_FULL)) { fComponents.getUrlString(&fFull); fState = fState | T_URL_STATE_FULL; } if (pCanonicalize) canonicalize(); return fFull; } //Constructs a string representation of this URL. TString TUrl::extendedUrlString(BOOL pCanonicalize) { CString lSimpleUrl = simpleUrlString(pCanonicalize); if (fExtendedInfo != NULL) { return fExtendedInfo->addExtendedInfo(lSimpleUrl); } return lSimpleUrl; } void TUrl::crackUrl() { findExtendedInfo(fFull); USES_CONVERSION; fState = fState | T_URL_STATE_COMPONENTS; HRESULT res = fComponents.initFromUrlString(fFull); if (res != S_OK) { fState = fState & (~T_URL_STATE_COMPONENTS); } } TExtendedUrlInfo* TUrl::getExtendedInfo() { if ((fExtendedInfo == NULL) && (fState & T_URL_STATE_FULL) && !(fState & T_URL_STATE_EXTENDED_PARSED)) { findExtendedInfo(fFull); fState |= T_URL_STATE_EXTENDED_PARSED; } return fExtendedInfo; } void TUrl::setExtendedInfo(TExtendedUrlInfo* pInfo) { if (pInfo) { clearExtendedInfo(); fExtendedInfo = pInfo->clone(); } } void TUrl::clearExtendedInfo() { if (fExtendedInfo) { delete fExtendedInfo; fExtendedInfo = NULL; } } void TUrl::findExtendedInfo(CString& pUrl) { if (!fExtendedInfo) { if (TSevenixUrlInfo::handleUrl(pUrl)) { fExtendedInfo = new TSevenixUrlInfo(); pUrl = fExtendedInfo->getExtendedInfo(pUrl); } } } TString TUrl::getExtendedScheme() { if (fExtendedInfo) return fExtendedInfo->getExtendedScheme(); return TString(); } TString TUrl::getExtension() { CString lExt; CString lFile = getFile(); int lExtPos = lFile.ReverseFind('/'); if (lExtPos > 0) lFile = lFile.Right(lFile.GetLength() - lExtPos + 1); lExtPos = lFile.ReverseFind('\\'); if (lExtPos > 0) lFile = lFile.Right(lFile.GetLength() - lExtPos + 1); lExtPos = lFile.ReverseFind('.'); if ((lExtPos > 0) && (lFile.GetLength() - lExtPos) < 7) lExt = lFile.Right(lFile.GetLength() - lExtPos); return lExt; } HRESULT TUrl::translateUrlOnErrorHack(CString pURL, CString& pTranslatedURL) { USES_CONVERSION; int lColumnPos = pURL.Find(":/"); if (lColumnPos > 0) { LONG lSlashCount; LONG lCurCharPos; LONG lLength; TCHAR lCurChar; lSlashCount = 1; lCurCharPos = lColumnPos + 2; lLength = pURL.GetLength(); lCurChar = pURL.GetAt(lCurCharPos); while ( lCurChar && (lCurChar == _T('/')) && (lCurCharPos < lLength - 1)) { lSlashCount++; lCurChar = pURL.GetAt(++lCurCharPos); } if (lSlashCount == 4) { // Workaround for UNC file paths given as 'file:////UNC_DRIVE\USER\...' pTranslatedURL = pURL; pTranslatedURL.SetAt(lColumnPos + 3, _T('\\')); pTranslatedURL.SetAt(lColumnPos + 4, _T('\\')); return S_OK; } else if (lSlashCount == 3) { // Workaround for the ie DOM error with the Netscape boorkmark file // when no protocol is specified pTranslatedURL = pURL.Left(lColumnPos + 3); pTranslatedURL += pURL.Mid(lColumnPos + 4, pURL.GetLength()); return S_OK; } } return S_FALSE; } void TUrl::setDefaultProtocol() { // a protocol must have a scheme if (fFull.Find(':') != -1) return ; if (fFull.Find("\\\\") == 0) { fFull = "file://" + fFull; return ; } USES_CONVERSION; LPSTR lResultStr; if (KBTranslateURL(T2CA(fFull), TRANSLATEURL_FL_USE_DEFAULT_PROTOCOL , &lResultStr) == S_OK) { fFull = lResultStr; } }/*------------ Script.idl ------------*/ // Script.idl : IDL source for KBScript.dll // // This file will be processed by the MIDL tool to // produce the type library (Script.tlb) and marshalling code. import "oaidl.idl"; import "ocidl.idl"; import "dispex.idl"; #include "ScriptId.h" #include "Control\ControlerId.h" cpp_quote("#include \"Control\\ControlerId.h\"") // ******************************************************************* // ***************************** Public ****************************** // ******************************************************************* /**********************************************************************/ /* Media */ /**********************************************************************/ // --------------------------------------------------------------------- // IScriptMedium [ object, uuid(632B3714-F3A9-11D1-8302-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptMedium : IDispatchEx { [propget, id(SID_MEDIUM_ID)] HRESULT Id([out, retval] BSTR* ); [propget, id(SID_MEDIUM_PARENT)] HRESULT parent([out, retval] LPDISPATCH* ); [propget, id(SID_MEDIUM_NAME)] HRESULT name([out, retval] BSTR* ); [propput, id(SID_MEDIUM_NAME)] HRESULT name([in] BSTR ); [propget, id(SID_MEDIUM_LOCATION)] HRESULT location([out, retval] float* ); [propput, id(SID_MEDIUM_LOCATION)] HRESULT location([in] float ); }; /**********************************************************************/ /* Media - Books */ /**********************************************************************/ // --------------------------------------------------------------------- // IScriptBook [ object, uuid(3B02F5B1-EFAC-11D1-82FD-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptBook : IDispatchEx // IMedium { [propget, id(SID_BOOK_WRITABLE)] HRESULT writable([out, retval] BOOL* ); [propput, id(SID_BOOK_WRITABLE)] HRESULT writable([in] BOOL ); [propget, id(SID_BOOK_STYLE)] HRESULT style([out, retval] long* ); [propput, id(SID_BOOK_STYLE)] HRESULT style([in] long ); [propget, id(SID_BOOK_PRIMARY)] HRESULT primary([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_SECONDARY)] HRESULT secondary([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_SELECTED)] HRESULT selected([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_AUTHOR)] HRESULT author([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_PAGES)] HRESULT pages([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_FLIPMODE)] HRESULT flipMode([out, retval] BSTR* ); [propput, id(SID_BOOK_FLIPMODE)] HRESULT flipMode([in] BSTR ); [propget, id(SID_BOOK_FLIPANIM)] HRESULT flipAnimation([out, retval] VARIANT* ); [propput, id(SID_BOOK_FLIPANIM)] HRESULT flipAnimation([in] VARIANT ); [id(SID_BOOK_CHANGE_PAGE_TO)] HRESULT goTo([in, optional] VARIANT* , [in, optional] VARIANT* , [in, optional] VARIANT* ); [id(SID_BOOK_ADD_PAGE)] HRESULT add([in] VARIANT, [in, defaultvalue(T_POS_CURRENT)] long, [out, retval] LPDISPATCH* ); [id(SID_BOOK_COPY_PAGE)] HRESULT copy([in] VARIANT, [in, defaultvalue(T_POS_CURRENT)] long, [out, retval] LPDISPATCH* ); [id(SID_BOOK_MOVE_PAGE)] HRESULT move([in] VARIANT, [in, defaultvalue(T_POS_CURRENT)] long); [id(SID_BOOK_REMOVE_PAGE)] HRESULT remove([in] VARIANT); [id(SID_BOOK_CREATE)] HRESULT create([in] BSTR , [out, retval] LPDISPATCH* ); [propget, id(10)] HRESULT branding([out, retval] LPDISPATCH* ); }; [ hidden, uuid(3B0105B1-EFAC-11D1-82FD-0060979B3BF2) ] dispinterface DispScriptBook { properties: methods: [propget, id(SID_MEDIUM_ID)] BSTR Id(); [propget, id(SID_MEDIUM_PARENT)] LPDISPATCH parent(); [propget, id(SID_MEDIUM_NAME)] BSTR name(); [propput, id(SID_MEDIUM_NAME)] void name([in] BSTR ); [propget, id(SID_MEDIUM_LOCATION)] float location(); [propput, id(SID_MEDIUM_LOCATION)] void location([in] float ); [propget, id(SID_BOOK_WRITABLE)] HRESULT writable([out, retval] BOOL* ); [propput, id(SID_BOOK_WRITABLE)] HRESULT writable([in] BOOL ); [propget, id(SID_BOOK_STYLE)] HRESULT style([out, retval] long* ); [propput, id(SID_BOOK_STYLE)] HRESULT style([in] long ); [propget, id(SID_BOOK_AUTHOR)] HRESULT author([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_PRIMARY)] HRESULT primary([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_SECONDARY)] HRESULT secondary([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_SELECTED)] HRESULT selected([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_PAGES)] HRESULT pages([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_FLIPMODE)] HRESULT flipMode([out, retval] BSTR* ); [propput, id(SID_BOOK_FLIPMODE)] HRESULT flipMode([in] BSTR ); [propget, id(SID_BOOK_FLIPANIM)] HRESULT flipAnimation([out, retval] VARIANT* ); [propput, id(SID_BOOK_FLIPANIM)] HRESULT flipAnimation([in] VARIANT ); [id(SID_BOOK_CHANGE_PAGE_TO)] HRESULT goTo([in, optional] VARIANT* , [in, optional] VARIANT* , [in, optional] VARIANT* ); [id(SID_BOOK_ADD_PAGE)] HRESULT add([in] VARIANT, [in, defaultvalue(T_POS_CURRENT)] long, [out, retval] LPDISPATCH* ); [id(SID_BOOK_COPY_PAGE)] HRESULT copy([in] VARIANT, [in, defaultvalue(T_POS_CURRENT)] long, [out, retval] LPDISPATCH* ); [id(SID_BOOK_MOVE_PAGE)] HRESULT move([in] VARIANT, [in, defaultvalue(T_POS_CURRENT)] long); [id(SID_BOOK_REMOVE_PAGE)] HRESULT remove([in] VARIANT); [id(SID_BOOK_CREATE)] HRESULT create([in] BSTR , [out, retval] LPDISPATCH* ); [propget, id(10)] HRESULT branding([out, retval] LPDISPATCH* ); }; // --------------------------------------------------------------------- // IBookPagesArray [ object, uuid(7B456352-EFAC-11D1-82FD-0060979B3BF2), dual, pointer_default(unique) ] interface IBookPagesArray : IDispatchEx { [propget, id(SID_BOOK_INDEX)] HRESULT index([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_SUMMARY)] HRESULT summary([out, retval] LPDISPATCH* ); [propget, id(SID_BOOK_PROPERTY_PAGE)] HRESULT author([out, retval] LPDISPATCH* ); } // --------------------------------------------------------------------- // IScriptBookAuthor [ object, uuid(7B456353-EFAC-11D1-82FD-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptBookAuthor : IDispatch { [propget, id(SID_BOOK_AUTHOR_NAME)] HRESULT name([out, retval] BSTR* ); [propput, id(SID_BOOK_AUTHOR_NAME)] HRESULT name([in] BSTR ); [propget, id(SID_BOOK_AUTHOR_EMAIL)] HRESULT email([out, retval] BSTR* ); [propput, id(SID_BOOK_AUTHOR_EMAIL)] HRESULT email([in] BSTR ); [propget, id(SID_BOOK_AUTHOR_PHOTO)] HRESULT photo([out, retval] BSTR* ); [propput, id(SID_BOOK_AUTHOR_PHOTO)] HRESULT photo([in] BSTR ); } /**********************************************************************/ /* Media - Books - Contents */ /**********************************************************************/ /**********************************************************************/ /* Media - Books - Pages */ /**********************************************************************/ // --------------------------------------------------------------------- // IScriptPage [ object, uuid(3B02F5B3-EFAC-11D1-82FD-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptPage : IDispatchEx { [propget, id(SID_CONTENT_URL)] HRESULT url([out, retval] BSTR*); [propput, id(SID_CONTENT_URL)] HRESULT url([in] BSTR); [propget, id(SID_CONTENT_EXTENDED_URL)] HRESULT extendedUrl([out, retval] BSTR*); [propget, id(SID_CONTENT_MIME)] HRESULT mime([out, retval] BSTR*); [propget, id(SID_PAGE_BOOK)] HRESULT book([out, retval] LPDISPATCH* ); [propget, id(SID_PAGE_CHAPTER)] HRESULT chapter([out, retval] LPDISPATCH* ); [propget, id(SID_PAGE_TITLE)] HRESULT title([out, retval] BSTR* ); [propput, id(SID_PAGE_TITLE)] HRESULT title([in] BSTR ); [propget, id(SID_PAGE_NUMBER)] HRESULT number([out, retval] LPDISPATCH* ); [propget, id(SID_PAGE_POSITION)] HRESULT position([out, retval] long* ); [propget, id(SID_PAGE_SOURCE)] HRESULT Source([out, retval] BSTR* ); [propget, id(SID_PAGE_ANNOTATIONS)] HRESULT annotations([out, retval] LPDISPATCH* ); [propget, id(SID_PAGE_ANNOTATION)] HRESULT annotation([in] BSTR , [out, retval] LPDISPATCH* ); [id(SID_PAGE_REMOVE_ANNOTATION)] HRESULT removeAnnotation([in] BSTR ); [id(SID_PAGE_CONTAINS_ANNOTATION)] HRESULT containsAnnotation([in] BSTR , BOOL* ); [id(SID_PAGE_CREATE)] HRESULT create([in] BSTR , [out, retval] LPDISPATCH* ); [propget, id(SID_PAGE_ID)] HRESULT Id([out, retval] BSTR*); [id(SID_PAGE_SET_ID)] HRESULT SetId([in] BSTR, [out, retval] BOOL* ); [id(SID_PAGE_LOAD)] HRESULT load(); }; // --------------------------------------------------------------------- // IScriptChapter [ object, uuid(3B02F5B7-EFAC-11D1-82FD-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptChapter : IScriptPage { [propget, id(SID_CHAPTER_PAGES)] HRESULT pages([out, retval] LPDISPATCH* ); [id(SID_CHAPTER_ADD_PAGE)] HRESULT add([in] VARIANT, [in, defaultvalue(T_POS_LAST)] long, [out, retval] LPDISPATCH* ); [id(SID_CHAPTER_COPY_PAGE)] HRESULT copy([in] VARIANT, [in, defaultvalue(T_POS_LAST)] long, [out, retval] LPDISPATCH* ); [id(SID_CHAPTER_MOVE_PAGE)] HRESULT move([in] VARIANT, [in, defaultvalue(T_POS_LAST)] long); [id(SID_CHAPTER_REMOVE_PAGE)] HRESULT remove([in] VARIANT); }; /**********************************************************************/ /* Media - Books - Annotations */ /**********************************************************************/ // --------------------------------------------------------------------- // IScriptAnnotation [ odl, oleautomation, dual, uuid(3B02F5BF-EFAC-11D1-82FD-0060979B3BF2) ] interface IScriptAnnotation : IDispatch { // id 17xx [propget, id(1701)] HRESULT page([out, retval] LPDISPATCH* ); [propput, id(1701)] HRESULT page([in] LPDISPATCH ); [propget, id(1702)] HRESULT color([out, retval] VARIANT* ); [propput, id(1702)] HRESULT color([in] VARIANT ); [propget, id(1703)] HRESULT text([out, retval] BSTR* ); [propput, id(1703)] HRESULT text([in] BSTR ); [propget, id(1704)] HRESULT url([out, retval] BSTR* ); [propput, id(1704)] HRESULT url([in] BSTR ); [propget, id(1705)] HRESULT Id([out, retval] BSTR* ); }; [ hidden, uuid(3B02F5BF-EFAD-11D1-82FD-0060979B3BF2) ] dispinterface DispScriptAnnotation { properties: methods: [propget, id(1701)] LPDISPATCH page(); [propput, id(1701)] void page([in] LPDISPATCH ); [propget, id(1702)] VARIANT* color(); [propput, id(1702)] void color([in] VARIANT ); [propget, id(1703)] BSTR text(); [propput, id(1703)] void text([in] BSTR ); [propget, id(1704)] BSTR url(); [propput, id(1704)] void url([in] BSTR ); [propget, id(1705)] BSTR Id(); }; // --------------------------------------------------------------------- // IScriptHighlighter [ odl, oleautomation, dual, uuid(24B12620-F489-11D1-8303-0060979B3BF2) ] interface IScriptHighlighter : IDispatch { // id 19xx [propget, id(1901)] HRESULT sentence([out, retval] long* ); [propput, id(1901)] HRESULT sentence([in] long ); [propget, id(1902)] HRESULT word([out, retval] long* ); [propput, id(1902)] HRESULT word([in] long ); [propget, id(1903)] HRESULT character([out, retval] long* ); [propput, id(1903)] HRESULT character([in] long ); [propget, id(1904)] HRESULT count([out, retval] long* ); [propput, id(1904)] HRESULT count([in] long ); }; [ hidden, uuid(24B12620-F48A-11D1-8303-0060979B3BF2) ] dispinterface DispScriptHighlighter { properties: methods: [propget, id(1701)] LPDISPATCH page(); [propput, id(1701)] void page([in] LPDISPATCH ); [propget, id(1702)] VARIANT* color(); [propput, id(1702)] void color([in] VARIANT ); [propget, id(1703)] BSTR text(); [propput, id(1703)] void text([in] BSTR ); [propget, id(1704)] BSTR url(); [propput, id(1704)] void url([in] BSTR ); [propget, id(1705)] BSTR Id(); [propget, id(1901)] long sentence(); [propput, id(1901)] void sentence(long ); [propget, id(1902)] long word(); [propput, id(1902)] void word(long ); [propget, id(1903)] long character(); [propput, id(1903)] void character(long ); [propget, id(1904)] long count(); [propput, id(1904)] void count(long ); }; // --------------------------------------------------------------------- // IScriptSticker [ odl, oleautomation, dual, uuid(C61A8BB0-F489-11D1-8303-0060979B3BF2) ] interface IScriptSticker : IDispatch { // id 21xx [propget, id(2101)] HRESULT x([out, retval] long* ); [propput, id(2101)] HRESULT x([in] long ); [propget, id(2102)] HRESULT y([out, retval] long* ); [propput, id(2102)] HRESULT y([in] long ); [propget, id(2103)] HRESULT width([out, retval] long* ); [propput, id(2103)] HRESULT width([in] long ); [propget, id(2104)] HRESULT height([out, retval] long* ); [propput, id(2104)] HRESULT height([in] long ); }; [ hidden, uuid(C61A8BB0-F48A-11D1-8303-0060979B3BF2) ] dispinterface DispScriptSticker { properties: methods: [propget, id(1701)] LPDISPATCH page(); [propput, id(1701)] void page([in] LPDISPATCH ); [propget, id(1702)] VARIANT* color(); [propput, id(1702)] void color([in] VARIANT ); [propget, id(1703)] BSTR text(); [propput, id(1703)] void text([in] BSTR ); [propget, id(1704)] BSTR url(); [propput, id(1704)] void url([in] BSTR ); [propget, id(1705)] BSTR Id(); [propget, id(2101)] long x(); [propput, id(2101)] void x([in] long ); [propget, id(2102)] long y(); [propput, id(2102)] void y([in] long ); [propget, id(2103)] long width(); [propput, id(2103)] void width([in] long ); [propget, id(2104)] long height(); [propput, id(2104)] void height([in] long ); }; /**********************************************************************/ /* Media - Managers */ /**********************************************************************/ // --------------------------------------------------------------------- // IScriptGenericContainer [ object, uuid(632B3716-F3A9-11D1-8302-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptGenericContainer : IDispatch { // id 23xx [propget, id(2301)] HRESULT name([out, retval] BSTR* ); [propput, id(2301)] HRESULT name([in] BSTR ); [propget, id(2302)] HRESULT location([out, retval] long* ); [propput, id(2302)] HRESULT location([in] long ); [propget, id(2303)] HRESULT parent([out, retval] LPDISPATCH* ); [propget, id(2304)] HRESULT medias([out, retval] LPDISPATCH* ); [id(2305)] HRESULT getContainer([in] long pIndex, [out, retval] LPDISPATCH* ); }; // --------------------------------------------------------------------- // IScriptMediaContainer [ object, uuid(C61A8BB2-F489-11D1-8303-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptMediaContainer : IScriptGenericContainer { // id 24xx [propget, id(2401)] HRESULT mediums([out, retval] LPDISPATCH* ); // [id(2402)] HRESULT addMedium([in] long pPosition, [in] LPDISPATCH* ); [id(2402)] HRESULT create([in] BSTR pName, [out, retval] LPDISPATCH* ); [id(2403)] HRESULT removeMediumAt([in] long pPosition); [id(2404)] HRESULT removeMedium([in] LPDISPATCH ); [id(2405)] HRESULT getMedium([in] float pLocation, [out, retval] LPDISPATCH* ); }; // --------------------------------------------------------------------- // IScriptMediaShelf [ object, uuid(C61A8BB4-F489-11D1-8303-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptMediaShelf : IScriptMediaContainer { // id 25xx [propget, id(2501)] HRESULT color([out, retval] VARIANT* ); [propput, id(2501)] HRESULT color([in] VARIANT ); }; // --------------------------------------------------------------------- // IScriptMediaCase [ object, uuid(C61A8BB6-F489-11D1-8303-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptMediaCase : IScriptGenericContainer { // id 26xx [propget, id(2601)] HRESULT shelves([out, retval] LPDISPATCH* ); }; // --------------------------------------------------------------------- // IScriptMediaLibrary [ object, uuid(C61A8BB8-F489-11D1-8303-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptMediaLibrary : IScriptGenericContainer { // id 27xx [propget, id(2701)] HRESULT cases([out, retval] LPDISPATCH* ); [propget, id(2702)] HRESULT system([out, retval] LPDISPATCH* ); [propget, id(2703)] HRESULT favorite([out, retval] LPDISPATCH* ); [id(2710)] HRESULT create([in] BSTR, [in, optional] VARIANT, [in, optional] VARIANT, [in, optional] VARIANT, [in, optional] VARIANT, [out, retval] LPDISPATCH* ); [id(SID_LIBRARY_FIND)] HRESULT find([in] BSTR , [out, retval] LPDISPATCH* ); }; /**********************************************************************/ /* Context */ /**********************************************************************/ // --------------------------------------------------------------------- // IScriptContext [ object, uuid(C61A77BD-F488-11D1-8303-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptContext : IDispatchEx { [propget, id(10)] HRESULT page([out, retval] LPDISPATCH* ); [propget, id(20)] HRESULT book([out, retval] LPDISPATCH* ); [propput, id(20)] HRESULT book([in] LPDISPATCH ); [propget, id(40)] HRESULT Library([out, retval] LPDISPATCH* ); [propget, id(50)] HRESULT mode([out, retval] BSTR* ); [propget, id(60)] HRESULT online([out, retval] BOOL* ); [propput, id(60), hidden, nonbrowsable, restricted] HRESULT online([in] BOOL ); [propget, id(61)] HRESULT wizard([out, retval] BOOL* ); }; [ object, uuid(DD81A3E4-F556-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface IWebBrowserExternal : IDispatchEx { [propget, id(101)] HRESULT provider([out, retval] LPDISPATCH* ); [propget, id(102)] HRESULT context([out, retval] LPDISPATCH* ); [propget, id(104)] HRESULT skins([out, retval] LPDISPATCH* ); [propget, id(106)] HRESULT languages([out, retval] LPDISPATCH* ); [propget, id(96)] HRESULT branding([out, retval] LPDISPATCH* ); [propget, id(97)] HRESULT preferences([out, retval] LPDISPATCH* ); [propget, id(98)] HRESULT tools([out, retval] LPDISPATCH* ); [propget, id(99)] HRESULT share([out, retval] LPDISPATCH* ); [propget, id(100)] HRESULT network([out, retval] LPDISPATCH* ); [propget, id(107)] HRESULT helps([out, retval] LPDISPATCH* ); #ifdef _DEBUG [id(300)] HRESULT trace(BSTR ); #endif // _DEBUG } [ object, uuid(DD81A3E8-F556-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptGlobals : IDispatchEx { [propget, id(101)] HRESULT provider([out, retval] LPDISPATCH* ); [propget, id(102)] HRESULT context([out, retval] LPDISPATCH* ); [propget, id(104)] HRESULT skins([out, retval] LPDISPATCH* ); [propget, id(106)] HRESULT languages([out, retval] LPDISPATCH* ); [propget, id(96)] HRESULT branding([out, retval] LPDISPATCH* ); [propget, id(97)] HRESULT preferences([out, retval] LPDISPATCH* ); [propget, id(98)] HRESULT tools([out, retval] LPDISPATCH* ); [propget, id(99)] HRESULT share([out, retval] LPDISPATCH* ); [propget, id(100)] HRESULT network([out, retval] LPDISPATCH* ); [propget, id(107)] HRESULT helps([out, retval] LPDISPATCH* ); [id(201)] HRESULT alert([in] VARIANT , [optional, in] VARIANT , [optional, in] VARIANT ); [id(202)] HRESULT showDialog([in] BSTR , [optional, in] VARIANT , [optional, in] VARIANT ); [id(210)] HRESULT newClass([in, optional] VARIANT ,[out, retval] LPDISPATCH* ); #ifdef _DEBUG [id(300)] HRESULT trace(BSTR ); #endif // _DEBUG }; [ object, uuid(DD81A3E5-F556-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface IScriptProvider : IDispatch { [propget, id(201)] HRESULT name([out, retval] BSTR* ); [propget, id(202)] HRESULT release([out, retval] BSTR* ); [propget, id(203)] HRESULT appName([out, retval] BSTR* ); [propget, id(204)] HRESULT company([out, retval] BSTR* ); }; [ object, uuid(DD82A3E6-F556-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] // UITools is a bad name // OSTools would be best interface IScriptTools : IDispatch { [id(10)] HRESULT info([in] BSTR pMes ); [id(11)] HRESULT dirPicker([in] BSTR pDirInit,[in] BSTR infoText,[out,retval] BSTR* pRes ); [id(12)] HRESULT openWindow([in] BSTR pURL ); [id(13)] HRESULT alert([in] VARIANT pMes); [id(14)] HRESULT fileChooser([in] BSTR Title,[in] BSTR FileTypes,[in, optional] VARIANT* CurFile,[out,retval] BSTR* pRes ); [id(16)] HRESULT buildUrl([in] BSTR pShortURL,[out,retval] BSTR* pFullUrl ); [id(17)] HRESULT EncodeToHTML([in] BSTR pFrom,[out,retval] BSTR* pTo); [id(18)] HRESULT startRegister(); [propget, id(20)] HRESULT LocalTime([out,retval] BSTR *pMes ); // To get the local Time in our format [propget, id(21)] HRESULT LocalZone([out,retval] BSTR *pMes ); // To get the Time Zone useful to distinguish in a big country (like US Californie/New York) [propget, id(22)] HRESULT DataPath([out,retval] BSTR* pKeeBooDataPath ); [propget, id(23)] HRESULT UrlParams([out,retval] BSTR* pUrlParams ); [propget, id(24)] HRESULT PhotoPath([out,retval] BSTR* pPhotoPath ); }; [ object, uuid(5D5F19DA-CD15-11d4-9C34-00105AD739BD), dual, pointer_default(unique) ] interface IScriptHelps : IDispatch { [id(10)] HRESULT gettingStartHelp([in, optional] VARIANT Page, [in, optional] VARIANT WinMode); [id(11)] HRESULT mainHelp([in, optional] VARIANT Page, [in, optional] VARIANT WinMode); }; [ object, uuid(DD82A3E8-F456-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface IGlobalBranding : IDispatch { [propget,id(10)] HRESULT SKU([out,retval] BSTR* ); [propget,id(11)] HRESULT partner([out,retval] BSTR* ); [propget,id(12)] HRESULT userID([out,retval] BSTR* ); }; [ object, uuid(DD82A3E7-F456-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface IBookBranding : IGlobalBranding { [propget,id(13)] HRESULT logoimg([out,retval] BSTR* ); [propget,id(14)] HRESULT logourl([out,retval] BSTR* ); [propget,id(15)] HRESULT bannerimg([out,retval] BSTR* ); [propget,id(16)] HRESULT bannerurl([out,retval] BSTR* ); [id(1)] HRESULT SetLogo([in] BSTR pPath, [in] BSTR pUrl); [id(2)] HRESULT SetIndex([in] BSTR pPath, [in] BSTR pUrl); [id(3)] HRESULT SetToc([in] BSTR pPath, [in] BSTR pUrl); [id(4)] HRESULT SetAuthorID([in] BSTR, [in] BSTR); }; [ object, uuid(DD82A3E8-F457-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface IGlobalBranding1 : IGlobalBranding { [propget, id(17)] HRESULT license([out, retval] BSTR *); }; [ object, uuid(DD81A3E6-F556-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface IPreferencesArray : IDispatchEx { [id(10)] HRESULT create([in] BSTR pName, [out, retval] LPDISPATCH* ); [id(11)] HRESULT exists([in] BSTR pName, [out, retval] BOOL* ); [id(12)] HRESULT getkey([in] BSTR pName, [out, retval] VARIANT* ); [id(13)] HRESULT setkey([in] BSTR pName, [in] VARIANT ); }; [ object, uuid(DD81A3E9-F556-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface ILooksArray : IDispatchEx { [propget, id(12)] HRESULT current([out, retval] LPDISPATCH* ); [propput, id(12)] HRESULT current([in] LPDISPATCH ); }; [ object, uuid(DD81A3EA-F556-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface IValLook : IDispatch { [propget, id(10)] HRESULT name([out, retval] BSTR* ); [propget, id(11)] HRESULT path([out, retval] BSTR* ); [propget, id(12)] HRESULT language([out, retval] BSTR* ); [propget, id(13)] HRESULT previewpath([out, retval] BSTR* ); }; [ object, uuid(DD81A3EB-F556-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface ILanguagesArray : IDispatchEx { [propget, id(12)] HRESULT current([out, retval] LPDISPATCH* ); [propput, id(12)] HRESULT current([in] LPDISPATCH ); }; [ object, uuid(DD81A3EC-F556-11D1-8304-0060979B3BF2), dual, pointer_default(unique) ] interface IValLanguage : IDispatch { [propget, id(10)] HRESULT shortname([out, retval] BSTR* ); [propget, id(11)] HRESULT path([out, retval] BSTR* ); [propget, id(12)] HRESULT fullname([out, retval] BSTR* ); }; [ object, uuid(343224C0-9B71-11d3-9E0F-00105ADB9C00), dual, pointer_default(unique) ] interface IScriptShare : IDispatch { [propput, id(1)] HRESULT progressCount([in] long); [propget, id(1)] HRESULT progressCount([out, retval] long*); [propget, id(2)] HRESULT progressCurrent([out, retval] long*); [id(10)] HRESULT Import([in] VARIANT, [in, optional] VARIANT, [out, retval] LPDISPATCH*); [id(11)] HRESULT ExportToWebBook([in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT); [id(12)] HRESULT ExportToNativeBook([in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT); [id(13)] HRESULT ExportToMyKeeBoo([in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT, [in] VARIANT); [id(14)] HRESULT AddProgressEventListener([in] LPDISPATCH); [id(15)] HRESULT RemoveProgressEventListener([in] LPDISPATCH); }; // ******************************************************************* // **************************** TypeLib ****************************** // ******************************************************************* // --------------------------------------------------------------------- // ScriptLib [ uuid(0122FF01-EFAC-11D1-82FD-0060979B3BF2), version(1.0), helpstring("KeeBoo Script 1.0 Type Library") ] library ScriptLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); // Utils // interface IScriptDispatchNode; // interface IScriptPageNumbering; // Media interface IScriptMedium; // Books interface IScriptBook; dispinterface DispScriptBook; interface IBookPagesArray; interface IScriptBookAuthor; // Pages interface IScriptPage; interface IScriptDivider; interface IScriptChapter; // Annotations interface IScriptAnnotation; interface IScriptHighlighter; interface IScriptSticker; // interface IScriptBookmark; // interface IScriptKeyword; // interface IScriptKeywordsSticker; dispinterface DispScriptAnnotation; dispinterface DispScriptHighlighter; dispinterface DispScriptSticker; // dispinterface DispScriptBookmark; // dispinterface DispScriptKeywordsSticker; // Managers interface IScriptGenericContainer; interface IScriptMediaContainer; interface IScriptMediaShelf; interface IScriptMediaCase; interface IScriptMediaLibrary; // Context interface IScriptContext; interface IScriptGlobals; // Browser interface IWebBrowserExternal; interface IScriptProvider; // Preferences interface IPreferencesArray; // Looks interface ILooksArray; interface IValLook; // Languages interface ILanguagesArray; interface IValLanguage; interface IScriptTools; interface IBranding; interface IBookBranding; interface IGlobalBranding; interface IGlobalBranding1; // Helps interface IScriptHelps; // Share interface IScriptShare; [uuid(C61A8CB0-7777-11D1-8303-0060979B3BF2)] coclass TScriptContext { [default] interface IScriptContext; }; [uuid(C61A8CB1-7777-11D1-8303-0060979B3BF2)] coclass TWebBrowserExternal { [default] interface IWebBrowserExternal; }; };/*------------ TScriptArray.h ------------*/ #ifndef T_SCRIPT_ARRAY #define T_SCRIPT_ARRAY #include "TDispatchExImpl2.h" // ========================================================================== // // Description: // It's a class Description comment // // Remarks: // It's a class Remarks comment // template class TScriptArray : public IDispatchExImpl2 { public: #ifdef _DEBUG TScriptArray() { m_IsInExtended = FALSE; } #endif // _DEBUG STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid); STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr); STDMETHOD(GetDispID)(BSTR bstrName, DWORD grfdex, DISPID *pid) { return GetIDsOfNames(IID_NULL, &bstrName, 1, 0, pid); } STDMETHOD(InvokeEx)(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) { UINT lErr; return Invoke(id, IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &lErr); } protected: virtual HRESULT ArrayPut(int nIndex, VARIANTARG varValue) = 0; virtual HRESULT ArrayGet(int nIndex, VARIANTARG* pvarValue) = 0; virtual HRESULT get_length(long* plLength) = 0; virtual HRESULT put_length(long lLength) = 0; virtual DISPID ExtendDispid(LPOLESTR, DISPID*) { return DISP_E_MEMBERNOTFOUND; } virtual BOOL IsExtended(DISPID dispid) { return FALSE; } virtual HRESULT ExtendedInvoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { return E_FAIL; } // All array accesses will be given dispatch IDs of at least // DISPID_ARRAY - all non array members should have dispatch IDs of // less than this value. enum { DISPID_UNDEFINED = 9999, DISPID_LENGTH = 10000, DISPID_ARRAY = 10001 }; BOOL IsArrayAccess(DISPID dispid) { return dispid >= DISPID_ARRAY; } DISPID IndexToDispid(int nIndex) { _ASSERTE(nIndex >= 0); return nIndex + DISPID_ARRAY; } int DispidToIndex(DISPID dispid) { _ASSERTE(dispid >= DISPID_ARRAY); return dispid - DISPID_ARRAY; } #ifdef _DEBUG BOOL m_IsInExtended; #endif }; // ========================================================================== // // Description: // It's a function Description comment // // Inputs: // szParam1 - It's a function first parameter comment // nParam2 - It's a function second parameter comment // // Return Value: // It's the function return value comment // // Remarks: // It's the Remarks comment // template STDMETHODIMP TScriptArray::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) { ATLASSERT(m_IsInExtended == FALSE); // First, see if the base class can handle this name HRESULT lResult; lResult = IDispatchExImpl2::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); if(SUCCEEDED(lResult)) return lResult; // We can only handle a single name if(cNames != 1) { return DISP_E_NONAMEDARGS; } // See if this is the "length" property if(wcscmp(L"length", rgszNames[0]) == 0) { rgdispid[0] = DISPID_LENGTH; return S_OK; } // See if the name is a number by checking if all its characters are digits for (unsigned int i = 0; i < wcslen(rgszNames[0]); i++) { if(!iswdigit(rgszNames[0][i])) { #ifdef _DEBUG m_IsInExtended = TRUE; #endif // _DEBUG lResult = ExtendDispid(rgszNames[0], rgdispid); #ifdef _DEBUG m_IsInExtended = FALSE; #endif // _DEBUG return lResult; } } if (*rgszNames[0] == 0) { rgdispid[0] = DISPID_UNDEFINED; return S_OK; } // The name is a number, which means that this is an array access. // Return a dispatch ID representing the index rgdispid[0] = IndexToDispid(_wtoi(rgszNames[0])); return S_OK; } template STDMETHODIMP TScriptArray::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { // See if this is the "length" property if(dispidMember == DISPID_LENGTH) { if(wFlags & DISPATCH_PROPERTYPUT) { // Set the length of the array VARIANTARG vaTemp; HRESULT hr = VariantChangeType(&vaTemp, &(pdispparams->rgvarg[0]), 0, VT_I4); if(FAILED(hr)) { return hr; } return put_length(vaTemp.lVal); } if(wFlags & DISPATCH_PROPERTYGET) { // Get the length of the array long lLength; HRESULT hr = get_length(&lLength); if(FAILED(hr)) { return hr; } pvarResult->vt = VT_I4; pvarResult->lVal = lLength; return hr; } // We can only handle reads and writes return DISP_E_MEMBERNOTFOUND; } // See if this is an array access if(IsArrayAccess(dispidMember)) { // Convert the dispatch ID into an array index int nIndex = DispidToIndex(dispidMember); if(wFlags & DISPATCH_PROPERTYPUT) { // This is an attempt to write to an element of the array. // Check that we have exactly one argument if(pdispparams->cArgs != 1) { DISP_E_BADPARAMCOUNT; } return ArrayPut(nIndex, pdispparams->rgvarg[0]); } if(wFlags & DISPATCH_PROPERTYGET) { // This is an attempt to read from the array. // Check that we have no arguments if(pdispparams->cArgs != 0) { return DISP_E_BADPARAMCOUNT; } return ArrayGet(nIndex, pvarResult); } // We can only handle reads and writes return DISP_E_MEMBERNOTFOUND; } if (dispidMember == DISPID_UNDEFINED) { pvarResult->vt = VT_EMPTY; pvarResult->lVal = NULL; return S_OK; } if (IsExtended(dispidMember)) return ExtendedInvoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); return IDispatchExImpl2::Invoke( dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); } #endif // !T_SCRIPT_ARRAY/*------------ TScriptClass.h ------------*/ #ifndef T_SCRIPT_CLASS #define T_SCRIPT_CLASS #include "dispex.h" #include "TScriptFunction.h" // --- STL #include "xstddef" #pragma warning(disable: 4663) #pragma warning(disable: 4244) #pragma warning(disable: 4018) #pragma warning(disable: 4530) #include "vector" #include "map" //#include "defalloc.h" #pragma warning(default: 4663) #pragma warning(default: 4244) #pragma warning(default: 4018) #pragma warning(default: 4530) using namespace std; // --- End STL #define VAR_MIN_ID 10000 #define HARD_MIN_ID 9000 ///////////////////////////////////////////////////////////////////////////// // TScriptClass template class ATL_NO_VTABLE TScriptClass : public IDispatchImpl { private: typedef IDispatchImpl parent; public: TScriptClass() { m_CurrentId = 0; m_AllowUnimplemented = TRUE; } ~TScriptClass() { m_NameToIdMap.RemoveAll(); m_IdToVarMap.RemoveAll(); } // IDispatch STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) { return parent::GetTypeInfoCount(pctinfo); } STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) { return parent::GetTypeInfo(itinfo, lcid, pptinfo); } virtual BOOL AllowName(LPOLESTR pName) { return TRUE; } STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid) { HRESULT lResult; // We can only handle a single name ATLASSERT(cNames == 1); lResult = parent::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); if (FAILED(lResult)) { if (!AllowName(rgszNames[0])) return DISP_E_MEMBERNOTFOUND; lResult = FindMember(rgszNames[0], rgdispid); if (SUCCEEDED(lResult)) return lResult; m_CurrentId++; *rgdispid = VAR_MIN_ID + m_CurrentId; m_NameToIdMap.Add(rgszNames[0], *rgdispid); lResult = S_OK; } return lResult; } STDMETHOD(Invoke)(DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { if (id < HARD_MIN_ID) { return parent::Invoke(id, riid, lcid, wFlags, pdp, pvarResult, pexcepinfo, puArgErr); } if (wFlags & DISPATCH_METHOD) return InvokeMethod(id, riid, lcid, wFlags, pdp, pvarResult, pexcepinfo, puArgErr); if (wFlags & DISPATCH_PROPERTYGET) return InvokeGet(id, pvarResult); if (wFlags & DISPATCH_PROPERTYPUT) return InvokePut(id, pdp, pvarResult); return E_NOTIMPL; } STDMETHOD(InvokeMethod)(DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { LONG lIndex; CComVariant lVariable; lIndex = m_IdToVarMap.FindKey(id); if (lIndex != -1) lVariable = m_IdToVarMap.GetValueAt(lIndex); else { if (id == DISPID_THIS) lVariable = CComVariant((LPDISPATCH)this); if (!m_AllowUnimplemented) return DISP_E_MEMBERNOTFOUND; } if (lVariable.vt != VT_DISPATCH) { if (!m_AllowUnimplemented) return DISP_E_BADVARTYPE; if (pvarResult == NULL) return S_OK; return ::VariantClear(pvarResult); } CComQIPtr lDispEx(lVariable.pdispVal); if (lDispEx) { DISPPARAMS lOldParams; HRESULT lResult; memcpy(&lOldParams, pdp, sizeof(DISPPARAMS)); DISPID* lNewDispIDs; pdp->cNamedArgs++; lNewDispIDs = new DISPID[pdp->cNamedArgs]; if (pdp->rgdispidNamedArgs) memcpy(&lNewDispIDs[1], pdp->rgdispidNamedArgs, (pdp->cNamedArgs - 1) * sizeof(DISPID)); lNewDispIDs[0] = DISPID_THIS; pdp->rgdispidNamedArgs = lNewDispIDs; VARIANTARG* lNewVars; pdp->cArgs++; lNewVars = new VARIANTARG[pdp->cArgs]; if (pdp->rgvarg) memcpy(&lNewVars[1], pdp->rgvarg, (pdp->cArgs - 1) * sizeof(VARIANTARG)); lNewVars[0].vt = VT_DISPATCH; lNewVars[0].pdispVal = this; lNewVars[0].pdispVal->AddRef(); pdp->rgvarg = lNewVars; lResult = lDispEx->InvokeEx(0, lcid, wFlags, pdp, pvarResult, pexcepinfo, NULL); memcpy(pdp, &lOldParams, sizeof(DISPPARAMS)); delete lNewDispIDs; lNewVars[0].pdispVal->Release(); delete [] lNewVars; return lResult; } return lVariable.pdispVal->Invoke(0, riid, lcid, wFlags, pdp, pvarResult, pexcepinfo, puArgErr); } STDMETHOD(InvokeGet)(DISPID id, VARIANT* pvarResult) { LONG lIndex; CComVariant lVariable; lIndex = m_IdToVarMap.FindKey(id); if (lIndex != -1) lVariable = m_IdToVarMap.GetValueAt(lIndex); else { if (id == DISPID_THIS) lVariable = CComVariant((LPDISPATCH)this); if (!m_AllowUnimplemented) return DISP_E_MEMBERNOTFOUND; } return ::VariantCopy(pvarResult, &lVariable); } STDMETHOD(InvokePut)(DISPID id, DISPPARAMS* pdp, VARIANT* pvarResult) { LONG lIndex; CComVariant lVariable; // Remain Flags value // DISPATCH_PROPERTYPUT // DISPATCH_PROPERTYPUTREF // ATLASSERT(pdp->cArgs == 1); if (pdp->cArgs != 1) return DISP_E_BADPARAMCOUNT; if (id < VAR_MIN_ID) return DISP_E_BADVARTYPE; lVariable = pdp->rgvarg[0]; lIndex = m_IdToVarMap.FindKey(id); if (lIndex != -1) { m_IdToVarMap.SetAtIndex(lIndex, id, lVariable); return S_OK; } m_IdToVarMap.Add(id, lVariable); return S_OK; } HRESULT FindMember(BSTR pName, DISPID* pID) { LONG lIndex; CComBSTR lName(pName); lIndex = m_NameToIdMap.FindKey(lName); if (lIndex != -1) { *pID = m_NameToIdMap.GetValueAt(lIndex); return S_OK; } return E_FAIL; } HRESULT FindName(DISPID pID, BSTR* pName) { DWORD lSize; DWORD lIndex = 0; lSize = m_NameToIdMap.GetSize(); while (lIndex < lSize) { if (pID == m_NameToIdMap.GetValueAt(lIndex)) { return m_NameToIdMap.GetKeyAt(lIndex).CopyTo(pName); } lIndex++; } return E_FAIL; } HRESULT AddVariableMember(BSTR pName, VARIANT pValue) { return AddMember(pName, pValue, VAR_MIN_ID); } HRESULT AddMember(BSTR pName, VARIANT pValue, LONG pType = HARD_MIN_ID) { DISPID lID; if (SUCCEEDED(FindMember(pName, &lID))) return E_FAIL; m_CurrentId++; lID = pType + m_CurrentId; m_NameToIdMap.Add(pName, lID); m_IdToVarMap.Add(lID, pValue); return S_OK; } HRESULT GetMember(BSTR pName, VARIANT* pValue) { DISPID lID = 0; HRESULT lResult; lResult = FindMember(pName, &lID); if (FAILED(lResult)) return lResult; return InvokeGet(lID, pValue); } HRESULT SetMember(BSTR pName, VARIANT pValue, LONG pType = HARD_MIN_ID) { DISPID lID; LONG lIndex; if (FAILED(FindMember(pName, &lID))) return AddMember(pName, pValue, pType); lIndex = m_IdToVarMap.FindKey(lID); if (lIndex == -1) return E_FAIL; CComVariant lValue(pValue); m_IdToVarMap.SetAtIndex(lIndex, lID, lValue); return S_OK; } HRESULT AddFunction(BSTR pName, PFNINVOKE pFunction, LPVOID pData = NULL) { HRESULT lResult; CComObject* lFunction; CComPtr lDisp; lResult = CComObject::CreateInstance(&lFunction); ATLASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) return lResult; lFunction->SetData(pData); lFunction->SetFunction(pFunction); lResult = lFunction->QueryInterface(&lDisp); ATLASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) return lResult; return AddMember(pName, CComVariant(lDisp)); } HRESULT RemoveMember(BSTR pName) { DISPID lID; if (FAILED(FindMember(pName, &lID))) return E_FAIL; m_NameToIdMap.Remove(pName); m_IdToVarMap.Remove(lID); return S_OK; } void SetAllowUnimplemented(BOOL pVal) { m_AllowUnimplemented = pVal; } protected: typedef CSimpleMap< CComBSTR, long> tNameToIdMap; // typedef tNameToIdMap::value_type tNameToIdMapPair; typedef CSimpleMap< long, CComVariant > tIdToVarMap; // typedef tIdToVarMap::value_type tIdToVarMapPair; tNameToIdMap m_NameToIdMap; tIdToVarMap m_IdToVarMap; long m_CurrentId; BOOL m_AllowUnimplemented; }; class ATL_NO_VTABLE TScriptDefaultClass : public CComObjectRootEx, public TScriptClass { public: BEGIN_COM_MAP(TScriptDefaultClass) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() }; class ATL_NO_VTABLE TScriptMethodClass : public CComObjectRootEx, public TScriptClass { public: BEGIN_COM_MAP(TScriptDefaultClass) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() STDMETHOD(Invoke)(DISPID id, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) { if (id < HARD_MIN_ID) return parent::Invoke(id, riid, lcid, wFlags, pdp, pvarResult, pexcepinfo, puArgErr); return InvokeMethod(id, riid, lcid, wFlags, pdp, pvarResult, pexcepinfo, puArgErr); } }; #endif // T_SCRIPT_CLASS /*------------ TScriptEngine.cpp ------------*/ #include "StdAfx.h" #include "msscript.h" #include "ScriptPrivate.h" #include "TScriptEngine.h" #include "TScriptDlg.h" #include "TGlobalsDB.h" #include "TDBManager.h" #include "TErr.h" TScriptSite::TScriptSite() : m_pActiveScript(NULL), m_pActiveScriptParse(NULL), m_dwAppCookie(0), m_ErrorLine(0), m_Silent(FALSE), m_CalledDebugger(FALSE) { } TScriptSite::~TScriptSite() { // If this ATLASSERT fails, you've probably not remembered to call Close _ASSERTE((m_pActiveScript == NULL) && (m_pActiveScriptParse == NULL)); if((m_pActiveScript != NULL) || (m_pActiveScriptParse != NULL)) { // Should never get here, but just in case... Close(); } } HRESULT TScriptSite::Create(EngineType type) { if (!m_Silent) GetApplication(NULL); // If this ATLASSERT fails, you've probably called Create twice _ASSERTE((m_pActiveScript == NULL) && (m_pActiveScriptParse == NULL)); const CLSID* pCLSID; switch(type) { case TScriptSite::EngineType_JScript: pCLSID = &CLSID_JScript; break; case TScriptSite::EngineType_VBScript: pCLSID = &CLSID_VBScript; break; default: // Unknown script engine type _ASSERT(false); return E_FAIL; break; } HRESULT hr = CoCreateInstance(*pCLSID, NULL, CLSCTX_INPROC_SERVER, IID_IActiveScript, reinterpret_cast(&m_pActiveScript)); if(!SUCCEEDED(hr)) return hr; hr = m_pActiveScript->SetScriptSite(this); if(!SUCCEEDED(hr)) return hr; hr = m_pActiveScript->QueryInterface(IID_IActiveScriptParse, reinterpret_cast(&m_pActiveScriptParse)); if(!SUCCEEDED(hr)) return hr; hr = m_pActiveScriptParse->InitNew(); if (!m_Silent && m_pdm) { HRESULT lResult; ATLASSERT(m_pDebugDocHelper == NULL); lResult = m_pdm->CreateDebugDocumentHelper(NULL, &m_pDebugDocHelper); if (FAILED(lResult)) return hr; if (m_pDebugDocHelper == NULL) return E_FAIL; ATLASSERT(m_pDebugDocHelper); lResult = m_pDebugDocHelper->Init(m_pDebugApp, L"KBScript", L"KeeBoo Script", TEXT_DOC_ATTR_READONLY); if (FAILED(lResult)) return hr; lResult = m_pDebugDocHelper->Attach(NULL); if (FAILED(lResult)) return hr; lResult = m_pDebugDocHelper->SetDocumentAttr(TEXT_DOC_ATTR_READONLY); if (FAILED(lResult)) return hr; } return hr; } void TScriptSite::FinalRelease() { // Close(); } HRESULT TScriptSite::Close() { // If this ATLASSERT fails, you've probably called Close without calling Create // _ASSERTE((m_pActiveScript != NULL) && (m_pActiveScriptParse != NULL)); HRESULT lResult = S_FALSE; if(m_pActiveScriptParse != NULL) { m_pActiveScriptParse->Release(); m_pActiveScriptParse = NULL; } if(m_pActiveScript != NULL) { lResult = m_pActiveScript->Close(); m_pActiveScript->Release(); m_pActiveScript = NULL; } if (m_pDebugApp != NULL) m_pDebugApp = NULL; if (m_pDebugDocHelper) { m_pDebugDocHelper->Detach(); m_pDebugDocHelper = NULL; } if (m_pdm && m_dwAppCookie) { lResult = m_pdm->RemoveApplication(m_dwAppCookie); ATLASSERT(SUCCEEDED(lResult)); m_dwAppCookie = 0; m_pdm = NULL; } return lResult; } HRESULT TScriptSite::ParseScript(const OLECHAR* pszScriptText) { _ASSERTE(m_pActiveScriptParse != NULL); if (m_pActiveScriptParse == NULL) return E_FAIL; TSmartTransaction lSmart; EXCEPINFO ei; HRESULT hr; SCRIPTSTATE lState; m_CalledDebugger = FALSE; lSmart.beginTransaction(TGlobalsDB::getLibraryDBManager(), t_transaction_types::TRANSACTION_READONLY); hr = m_pActiveScript->GetScriptState(&lState); if(FAILED(hr)) return hr; if (lState == SCRIPTSTATE_CONNECTED) { hr = m_pActiveScript->SetScriptState(SCRIPTSTATE_DISCONNECTED); if(FAILED(hr)) return hr; } hr = m_pActiveScriptParse->ParseScriptText(pszScriptText, NULL, NULL, NULL, 0, 0, 0, NULL, &ei); if(FAILED(hr)) { //! TODO handle ei; if (!m_Silent) { CComPtr lScript; HWND lDebugHwnd = NULL; lScript.CoCreateInstance(CLSID_TScriptEngine); ATLASSERT(lScript); if (lScript) { lScript->ShowScriptWindow(&lDebugHwnd); if (lDebugHwnd) { ::SendMessage(lDebugHwnd, WM_USER_SET_DEBUG_TEXT, (WPARAM)pszScriptText, m_ErrorLine); } } } return hr; } hr = m_pActiveScript->SetScriptState(SCRIPTSTATE_CONNECTED); if(FAILED(hr)) return hr; return hr; } HRESULT TScriptSite::AddGlobals(LPCOLESTR pName, IDispatch* pDispatch) { _ASSERTE(m_pActiveScript != NULL); m_pGlobalsDispatch.insert(tGlobalsMapPair(pName, pDispatch)); pDispatch->AddRef(); HRESULT hr = m_pActiveScript->AddNamedItem(pName, SCRIPTITEM_GLOBALMEMBERS); return hr; } ///////////////////////////////////////////////////////////////////////////// // TScriptSite IActiveScriptSite methods HRESULT STDMETHODCALLTYPE TScriptSite::GetLCID(LCID* plcid) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE TScriptSite::GetItemInfo(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown** ppiunkItem, ITypeInfo** ppti) { // Validate our arguments if(dwReturnMask & SCRIPTINFO_IUNKNOWN) { if(ppiunkItem == NULL) { return E_INVALIDARG; } *ppiunkItem = NULL; } if(dwReturnMask & SCRIPTINFO_ITYPEINFO) { // We don't support type info (and shouldn't have to, unless we choose // to support sending ActiveX events to scripts). _ASSERT(false); return E_NOTIMPL; } // See if this is the special case Globals name tGlobalsIterator iter; iter = m_pGlobalsDispatch.find(pstrName); if (iter != m_pGlobalsDispatch.end()) { *ppiunkItem = (*iter).second; return S_OK; } // That's the only name we support! return TYPE_E_ELEMENTNOTFOUND; } HRESULT STDMETHODCALLTYPE TScriptSite::GetDocVersionString(BSTR* pbstrVersion) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE TScriptSite::OnScriptTerminate(const VARIANT* pvarResult, const EXCEPINFO* pexcepinfo) { return S_OK; } HRESULT STDMETHODCALLTYPE TScriptSite::OnStateChange(SCRIPTSTATE ssScriptState) { return S_OK; } HRESULT STDMETHODCALLTYPE TScriptSite::OnScriptError(IActiveScriptError * pscripterror) { HRESULT lResult = S_OK; // Get an EXCEPINFO which describes the error EXCEPINFO ei; if (FAILED(pscripterror->GetExceptionInfo(&ei))) return E_FAIL; // Call the deferred fill in function if necessary if(ei.pfnDeferredFillIn != NULL) { ei.pfnDeferredFillIn(&ei); } CComBSTR lLine; pscripterror->GetSourceLineText(&lLine); DWORD dwSourceContext; LONG ichCharPosition; pscripterror->GetSourcePosition(&dwSourceContext, &m_ErrorLine, &ichCharPosition); // Display a message box describing the error CString lMsg; CString lTemp; lMsg.Format(" -- JScript Error (#%X) --", (ei.wCode == 0) ? ei.scode : ei.wCode); if (ei.bstrDescription != NULL) lMsg += "\n - " + CString(ei.bstrDescription); if (ei.bstrSource != NULL) lMsg += "\n - Source: \"" + CString(ei.bstrSource) + "\""; if (lLine) lMsg += "\n - Text: \"" + CString(lLine) + "\""; if (dwSourceContext) { lTemp.Format("\n - Context: %d", dwSourceContext); lMsg += lTemp; } if (m_ErrorLine) { lTemp.Format("\n - Line: %d", m_ErrorLine + 1); lMsg += lTemp; } if (ichCharPosition) { lTemp.Format("\n - Char: %d", ichCharPosition); lMsg += lTemp; } if (!m_Silent) { LONG lReturn; lReturn = ::MessageBox(NULL, lMsg, "JScript Engine Error", MB_RETRYCANCEL | MB_ICONEXCLAMATION); if (lReturn == IDRETRY) { // Try to launch the Debugger lResult = E_FAIL; } } else { TErr::trace(TErr::D_LOG, TErr::G_FAT, TErr::NO_ID, __FILE__, __LINE__, lMsg); TRACE(lMsg); } // It is our responsibility to free the BSTR members of ei SysFreeString(ei.bstrSource); SysFreeString(ei.bstrDescription); SysFreeString(ei.bstrHelpFile); return lResult; } HRESULT STDMETHODCALLTYPE TScriptSite::OnEnterScript(void) { return S_OK; } HRESULT STDMETHODCALLTYPE TScriptSite::OnLeaveScript(void) { return S_OK; } /* // IDebugDocumentHost STDMETHODIMP TScriptSite::GetDeferredText(DWORD dwTextStartCookie, WCHAR *pcharText, SOURCE_TEXT_ATTR *pstaTextAttr, ULONG *pcNumChars, ULONG cMaxChars) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::GetScriptTextAttributes(LPCOLESTR pstrCode, ULONG uNumCodeChars, LPCOLESTR pstrDelimiter, DWORD dwFlags, SOURCE_TEXT_ATTR* pattr) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::OnCreateDocumentContext(IUnknown** ppunkOuter) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::GetPathName(BSTR *pbstrLongName, BOOL *pfIsOriginalFile) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::GetFileName(BSTR *pbstrShortName) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::NotifyChanged() { return E_NOTIMPL; } // IDebugDocumentHelper STDMETHODIMP TScriptSite::Init(IDebugApplication *pda, LPCOLESTR pszShortName, LPCOLESTR pszLongName, TEXT_DOC_ATTR docAttr) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::Attach(IDebugDocumentHelper *pddhParent) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::Detach() { return E_NOTIMPL; } STDMETHODIMP TScriptSite::AddUnicodeText(LPCOLESTR pszText) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::AddDBCSText(LPCSTR pszText) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::SetDebugDocumentHost(IDebugDocumentHost* pddh) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::AddDeferredText(ULONG cChars, DWORD dwTextStartCookie) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::DefineScriptBlock(ULONG ulCharOffset, ULONG cChars, IActiveScript* pas, BOOL fScriptlet, DWORD* pdwSourceContext) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::SetDefaultTextAttr(SOURCE_TEXT_ATTR staTextAttr) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::SetTextAttributes(ULONG ulCharOffset, ULONG cChars, SOURCE_TEXT_ATTR* pstaTextAttr) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::SetLongName(LPCOLESTR pszLongName) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::SetShortName(LPCOLESTR pszShortName) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::SetDocumentAttr(TEXT_DOC_ATTR pszAttributes) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::GetDebugApplicationNode(IDebugApplicationNode **ppdan) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::GetScriptBlockInfo(DWORD dwSourceContext, IActiveScript** ppasd, ULONG *piCharPos, ULONG *pcChars) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::CreateDebugDocumentContext(ULONG iCharPos, ULONG cChars, IDebugDocumentContext** ppddc) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::BringDocumentToTop() { return E_NOTIMPL; } STDMETHODIMP TScriptSite::BringDocumentContextToTop(IDebugDocumentContext *pddc) { return E_NOTIMPL; } */ // IActiveScriptSiteDebug STDMETHODIMP TScriptSite::GetDocumentContextFromPosition(DWORD dwSourceContext, ULONG uCharacterOffset, ULONG uNumChars, IDebugDocumentContext** ppsc) { return E_NOTIMPL; } STDMETHODIMP TScriptSite::GetApplication(IDebugApplication** ppda) { HRESULT lResult = S_OK; if (m_pDebugApp == NULL) { if (m_pdm == NULL) { lResult = m_pdm.CoCreateInstance(CLSID_ProcessDebugManager); ATLASSERT(SUCCEEDED(lResult) && m_pdm); } if (m_pdm != NULL) { lResult = m_pdm->CreateApplication(&m_pDebugApp); if (SUCCEEDED(lResult) && m_pDebugApp) { m_pDebugApp->SetName(L"KeeBoo Script Engine"); lResult = m_pdm->AddApplication(m_pDebugApp, &m_dwAppCookie); ATLASSERT(SUCCEEDED(lResult) && m_dwAppCookie); } } } if (ppda && m_pDebugApp) { *ppda = m_pDebugApp; (*ppda)->AddRef(); } return lResult; } STDMETHODIMP TScriptSite::GetRootApplicationNode(IDebugApplicationNode** ppdanRoot) { if (m_pDebugApp) return m_pDebugApp->GetRootNode(ppdanRoot); return E_FAIL; } STDMETHODIMP TScriptSite::OnScriptErrorDebug(IActiveScriptErrorDebug* pErrorDebug, BOOL* pfEnterDebugger, BOOL* pfCallOnScriptErrorWhenContinuing) { // Do not call debugger if in silent mode if (!m_Silent) { if (pfEnterDebugger) { *pfEnterDebugger = !m_CalledDebugger; // Only call debugger once by script !!! if (!m_CalledDebugger) m_CalledDebugger = TRUE; } } else if (pfEnterDebugger) *pfEnterDebugger = FALSE; if (pfCallOnScriptErrorWhenContinuing) *pfCallOnScriptErrorWhenContinuing = TRUE; return S_OK; } /// // // Don't know where to find those ..... // #ifndef __IID_DEFINED__ #define __IID_DEFINED__ typedef struct _IID { unsigned long x; unsigned short s1; unsigned short s2; unsigned char c[8]; } IID; #endif // __IID_DEFINED__ #ifndef CLSID_DEFINED #define CLSID_DEFINED typedef IID CLSID; #endif // CLSID_DEFINED const CLSID CLSID_VBScript = {0xb54f3741, 0x5b07, 0x11cf, {0xa4, 0xb0, 0x0, 0xaa, 0x0, 0x4a, 0x55, 0xe8}}; const CLSID CLSID_JScript = {0xf414c260, 0x6ac0, 0x11cf, {0xb6, 0xd1, 0x00, 0xaa, 0x00, 0xbb, 0xbb, 0x58}};/*------------ TScriptEngine.h ------------*/ #ifndef T_SCRIPT_ENGINE #define T_SCRIPT_ENGINE #include #include // --- STL #include "xstddef" #pragma warning(disable: 4663) #pragma warning(disable: 4244) #pragma warning(disable: 4018) #include "map" //#include "defalloc.h" using namespace std; // --- End STL template struct less : binary_function { bool operator()(const z& _X, const z& _Y) const { return wcscmp(_X, _Y) == -1; } }; class TScriptGlobals; class TScriptSite : public CComObjectRootEx, public IActiveScriptSite, // public IDebugDocumentHelper, // public IDebugDocumentHost, public IActiveScriptSiteDebug { public: TScriptSite(); virtual ~TScriptSite(); enum EngineType { EngineType_JScript, EngineType_VBScript }; void FinalRelease(); HRESULT Create(EngineType type); HRESULT Close(); HRESULT ParseScript(const OLECHAR* pszScriptText); HRESULT AddGlobals(LPCOLESTR pName, IDispatch* pDispatch); void SetSilent(BOOL pFlag) { m_Silent = pFlag; } BOOL GetSilent() { return m_Silent; } BEGIN_COM_MAP(TScriptSite) COM_INTERFACE_ENTRY(IActiveScriptSite) // COM_INTERFACE_ENTRY(IDebugDocumentHost) // COM_INTERFACE_ENTRY(IDebugDocumentHelper) COM_INTERFACE_ENTRY(IActiveScriptSiteDebug) END_COM_MAP() // IActiveScriptSite methods STDMETHOD(GetLCID)(LCID *plcid); STDMETHOD(GetItemInfo)(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown * *ppiunkItem, ITypeInfo * *ppti); STDMETHOD(GetDocVersionString)(BSTR *pbstrVersion); STDMETHOD(OnScriptTerminate)(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo); STDMETHOD(OnStateChange)(SCRIPTSTATE ssScriptState); STDMETHOD(OnScriptError)(IActiveScriptError *pscripterror); STDMETHOD(OnEnterScript)(void); STDMETHOD(OnLeaveScript)(void); /* // IDebugDocumentHost STDMETHOD(GetDeferredText)(DWORD dwTextStartCookie, WCHAR *pcharText, SOURCE_TEXT_ATTR *pstaTextAttr, ULONG *pcNumChars, ULONG cMaxChars); STDMETHOD(GetScriptTextAttributes)(LPCOLESTR pstrCode, ULONG uNumCodeChars, LPCOLESTR pstrDelimiter, DWORD dwFlags, SOURCE_TEXT_ATTR* pattr); STDMETHOD(OnCreateDocumentContext)(IUnknown** ppunkOuter); STDMETHOD(GetPathName)(BSTR *pbstrLongName, BOOL *pfIsOriginalFile); STDMETHOD(GetFileName)(BSTR *pbstrShortName); STDMETHOD(NotifyChanged)(); // IDebugDocumentHelper STDMETHOD(Init)(IDebugApplication *pda, LPCOLESTR pszShortName, LPCOLESTR pszLongName, TEXT_DOC_ATTR docAttr); STDMETHOD(Attach)(IDebugDocumentHelper *pddhParent); STDMETHOD(Detach)(); STDMETHOD(AddUnicodeText)(LPCOLESTR pszText); STDMETHOD(AddDBCSText)(LPCSTR pszText); STDMETHOD(SetDebugDocumentHost)(IDebugDocumentHost* pddh); STDMETHOD(AddDeferredText)(ULONG cChars, DWORD dwTextStartCookie); STDMETHOD(DefineScriptBlock)(ULONG ulCharOffset, ULONG cChars, IActiveScript* pas, BOOL fScriptlet, DWORD* pdwSourceContext); STDMETHOD(SetDefaultTextAttr)(SOURCE_TEXT_ATTR staTextAttr); STDMETHOD(SetTextAttributes)(ULONG ulCharOffset, ULONG cChars, SOURCE_TEXT_ATTR* pstaTextAttr); STDMETHOD(SetLongName)(LPCOLESTR pszLongName); STDMETHOD(SetShortName)(LPCOLESTR pszShortName); STDMETHOD(SetDocumentAttr)(TEXT_DOC_ATTR pszAttributes); STDMETHOD(GetDebugApplicationNode)(IDebugApplicationNode **ppdan); STDMETHOD(GetScriptBlockInfo)(DWORD dwSourceContext, IActiveScript** ppasd, ULONG *piCharPos, ULONG *pcChars); STDMETHOD(CreateDebugDocumentContext)(ULONG iCharPos, ULONG cChars, IDebugDocumentContext** ppddc); STDMETHOD(BringDocumentToTop)(); STDMETHOD(BringDocumentContextToTop)(IDebugDocumentContext *pddc); */ // IActiveScriptSiteDebug STDMETHOD(GetDocumentContextFromPosition)(DWORD dwSourceContext, ULONG uCharacterOffset, ULONG uNumChars, IDebugDocumentContext** ppsc); STDMETHOD(GetApplication)(IDebugApplication** ppda); STDMETHOD(GetRootApplicationNode)(IDebugApplicationNode** ppdanRoot); STDMETHOD(OnScriptErrorDebug)(IActiveScriptErrorDebug* pErrorDebug, BOOL* pfEnterDebugger, BOOL* pfCallOnScriptErrorWhenContinuing); private: typedef map< LPCOLESTR, IDispatch* , less > tGlobalsMap; typedef tGlobalsMap::value_type tGlobalsMapPair; typedef tGlobalsMap::iterator tGlobalsIterator; IActiveScriptParse* m_pActiveScriptParse; IActiveScript* m_pActiveScript; tGlobalsMap m_pGlobalsDispatch; CComPtr m_pdm; CComPtr m_pDebugApp; CComPtr m_pDebugDocHelper; // CString m_strCurrentFilePath; BOOL m_Silent:2; BOOL m_CalledDebugger:2; ULONG m_ErrorLine; DWORD m_dwAppCookie; }; #endif // !T_SCRIPT_ENGINE/*------------ TScriptFunction.h ------------*/ #ifndef T_SCRIPT_FUNCTION #define T_SCRIPT_FUNCTION typedef HRESULT (PFNINVOKE)(LPVOID , WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarResult); #define SFUNCTION_DATA_TYPE_IMPL(theClass, theData) \ theClass* pThis; \ pThis = (theClass*) theData; ///////////////////////////////////////////////////////////////////////////// // TScriptFunction class ATL_NO_VTABLE TScriptFunction : public CComObjectRootEx, public IDispatchImpl { public: HRESULT FinalConstruct() { m_pFunction = NULL; m_pData = NULL; m_bDestroyOnRelease = FALSE; return S_OK; } void FinalRelease() { if (m_bDestroyOnRelease) delete m_pData; } BEGIN_COM_MAP(TScriptFunction) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() STDMETHOD(Invoke)(DISPID id, REFIID , LCID , WORD wFlags, DISPPARAMS* pdp, VARIANT* pvarResult, EXCEPINFO* , UINT* ) { if ((id != 0) || (m_pFunction == NULL)) return DISP_E_MEMBERNOTFOUND; return (*m_pFunction)(m_pData, wFlags, pdp, pvarResult); } void SetFunction(PFNINVOKE* pFunction) { m_pFunction = pFunction; } void SetData(LPVOID pData, BOOL pDestroyOnRelease = FALSE) { m_pData = pData; m_bDestroyOnRelease = pDestroyOnRelease; } protected: PFNINVOKE* m_pFunction; LPVOID m_pData; BOOL m_bDestroyOnRelease :2; }; class CDispatchParams { public: CDispatchParams(DISPPARAMS* pParams = NULL) { m_Params = pParams; } DWORD GetArgsSize() { ATLASSERT(m_Params); return m_Params->cArgs; } DWORD GetNamedArgsSize() { ATLASSERT(m_Params); return m_Params->cNamedArgs; } HRESULT GetArgs(DWORD pIndex, VARIANT* pVariant) { ATLASSERT(m_Params); if (pIndex < m_Params->cArgs) return ::VariantCopy(pVariant, &m_Params->rgvarg[pIndex]); return E_FAIL; } HRESULT GetNamedArgs(DWORD pIndex, DISPID* pID) { ATLASSERT(m_Params); if (pIndex < m_Params->cNamedArgs) { *pID = m_Params->rgdispidNamedArgs[pIndex]; return S_OK; } return E_FAIL; } VARIANT* operator[](DWORD pIndex) { ATLASSERT(m_Params); if (pIndex < m_Params->cArgs) return &m_Params->rgvarg[pIndex]; return NULL; } protected: DISPPARAMS* m_Params; }; #endif // T_SCRIPT_FUNCTION /*------------ TScriptGlobals.cpp ------------*/ #include "StdAfx.h" #include "Script.h" #include "TExternal.h" #include "TScriptGlobals.h" #include "TScriptNewClass.h" #include "TScriptClass.h" #include "TScriptHtmlDialog.h" #include "TModelNames.h" #include "TBookModel.h" #include "TScriptContext.h" #include "TScriptPreferences.h" #include "TScriptLanguages.h" #include "TScriptLooks.h" #include "TScriptValLook.h" #include "TLooksInfo.h" #include "TLookAndfeel.h" #include "TScriptValLanguage.h" #include "TLanguagesInfo.h" #include "TScriptUITools.h" #include "TScriptHelps.h" #include "TScriptBranding.h" #include "TScriptClass.h" #include "TLanguage.h" #include "TErr.h" #include "TScriptShare.h" ///////////////////////////////////////////////////////////////////////////// // TScriptGlobals HRESULT TScriptGlobals::FinalConstruct() { return S_OK; } void TScriptGlobals::FinalRelease() { } STDMETHODIMP TScriptGlobals::get_provider(LPDISPATCH * pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lProvider; CComObject::CreateInstance(&lProvider); return lProvider->QueryInterface(pVal); } STDMETHODIMP TScriptGlobals::get_context(LPDISPATCH* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lContext; CComObject::CreateInstance(&lContext); return lContext->QueryInterface(pVal); } STDMETHODIMP TScriptGlobals::get_preferences(LPDISPATCH* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lPreferences; CComObject::CreateInstance(&lPreferences); return lPreferences->QueryInterface(pVal); } STDMETHODIMP TScriptGlobals::get_skins(LPDISPATCH* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lLooks; CComObject::CreateInstance(&lLooks); return lLooks->QueryInterface(pVal); } STDMETHODIMP TScriptGlobals::get_languages(LPDISPATCH* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lLanguages; CComObject::CreateInstance(&lLanguages); return lLanguages->QueryInterface(pVal); } STDMETHODIMP TScriptGlobals::get_tools(LPDISPATCH* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lTools; CComObject::CreateInstance(&lTools); if( lTools ) return lTools->QueryInterface(pVal); *pVal = NULL; return S_FALSE; } STDMETHODIMP TScriptGlobals::get_helps(LPDISPATCH* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lHelps; CComObject::CreateInstance(&lHelps); if( lHelps ) return lHelps->QueryInterface(pVal); *pVal = NULL; return S_FALSE; } STDMETHODIMP TScriptGlobals::get_branding(LPDISPATCH* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lBranding; CComObject::CreateInstance(&lBranding); if (lBranding) return lBranding->QueryInterface(pVal); *pVal = NULL; return S_FALSE; } STDMETHODIMP TScriptGlobals::get_share(LPDISPATCH* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lShare; CComObject::CreateInstance(&lShare); if (lShare) return lShare->QueryInterface(pVal); *pVal = NULL; return S_FALSE; } STDMETHODIMP TScriptGlobals::get_network(LPDISPATCH* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; return CreateNetworkObject(pVal); } STDMETHODIMP TScriptGlobals::alert(VARIANT pMessage, VARIANT pTitle, VARIANT pType) { USES_CONVERSION; BSTR lTitle; if (pTitle.vt != VT_BSTR) lTitle = L"alert"; else lTitle = pTitle.bstrVal; long lType = 0; BSTR lMsg; CComVariant lVariant; if (::VariantChangeType(&lVariant, &pMessage, 0, VT_BSTR) == S_OK) lMsg = lVariant.bstrVal; else { if (pMessage.vt == VT_DISPATCH) lMsg = L"Object"; else lMsg = L"undefined"; } if (pType.vt == VT_BSTR) { CString lStringType(pType.bstrVal); if (lStringType == "warning") lType = MB_ICONWARNING; if (lStringType == "info") lType = MB_ICONINFORMATION; if (lStringType == "question") lType = MB_ICONQUESTION; if (lStringType == "stop") lType = MB_ICONSTOP; if (lStringType == "error") { long lId = TErr::NO_ID; CComVariant lVariantID; if (::VariantChangeType(&lVariantID, &pTitle, 0, VT_I4) == S_OK) lId = lVariantID.lVal; TErr::trace(TErr::D_BOX, TErr::G_INF, (IDS_ERR + (lId * IDS_ERR_NB_LINE)), __FILE__, __LINE__, W2CT(lMsg), _T("%2"), _T("%3")); return S_OK; } } lType |= MB_OK; MessageBoxW(NULL, lMsg, lTitle, lType); return S_OK; } BOOL NextWord(CString& pLine, CString& pWord) { long lSpace = pLine.Find(' '); long lDotDot = pLine.Find(':'); long lDotComa = pLine.Find(';'); long lSub = 0; if (lSpace == -1) lSub = lDotDot; else if (lDotDot == -1) lSub = lSpace; else lSub = min(lSpace, lDotDot); if (lSub == -1) lSub = lDotComa; else if (lDotComa != -1) lSub = min(lSub, lDotComa); if (lSub == -1) { if (pLine.GetLength() == 0) return FALSE; pWord = pLine; pLine.Empty(); return TRUE; } pWord = pLine.Mid(0, lSub); pLine = pLine.Mid(lSub + 1); pWord.TrimLeft(); pWord.TrimRight(); return TRUE; } bool BooleanValue(CString& pVal) { if ((pVal == "yes") || (pVal == "1")) return true; if ((pVal == "no") || (pVal == "0")) return false; return false; } inline BOOL IsPercent(LPCTSTR pValue) { while (*pValue && isdigit(*pValue)) pValue++; if (*pValue == '%') return TRUE; return FALSE; } // dialogHeight: // dialogLeft: // dialogTop: // dialogWidth: // center:{ yes | no | 1 | 0 } // help:{ yes | no | 1 | 0 } // resizable:{ yes | no | 1 | 0 } // modal:{ yes | no | 1 | 0 } void ParseFeatures(VARIANT pFeatures, TScriptDefaultClass* pArgs) { if (pFeatures.vt != VT_BSTR) return ; CString lFeatures = pFeatures.bstrVal; CString lWord; while (NextWord(lFeatures, lWord)) { if (lWord == "dialogHeight") { CString lHeight; long lHeightValue; NextWord(lFeatures, lHeight); lHeightValue = atoi(lHeight); if (IsPercent(lHeight) && lHeightValue <= 100) { lHeightValue *= ::GetSystemMetrics(SM_CYSCREEN); lHeightValue /= 100; } pArgs->SetMember(L"height", CComVariant(lHeightValue)); } else if (lWord == "dialogTop") { CString lTop; NextWord(lFeatures, lTop); pArgs->SetMember(L"top", CComVariant(atoi(lTop))); } else if (lWord == "dialogLeft") { CString lLeft; NextWord(lFeatures, lLeft); pArgs->SetMember(L"left", CComVariant(atoi(lLeft))); } else if (lWord == "dialogWidth") { CString lWidth; long lWidthValue; NextWord(lFeatures, lWidth); lWidthValue = atoi(lWidth); if (IsPercent(lWidth) && lWidthValue <= 100) { lWidthValue *= ::GetSystemMetrics(SM_CXSCREEN); lWidthValue /= 100; } pArgs->SetMember(L"width", CComVariant(lWidthValue)); } else if (lWord == "minWidth") { CString lWidth; long lWidthValue; NextWord(lFeatures, lWidth); lWidthValue = atoi(lWidth); if (IsPercent(lWidth) && lWidthValue <= 100) { lWidthValue *= ::GetSystemMetrics(SM_CXSCREEN); lWidthValue /= 100; } pArgs->SetMember(L"minWidth", CComVariant(lWidthValue)); } else if (lWord == "minHeight") { CString lHeight; long lHeightValue; NextWord(lFeatures, lHeight); lHeightValue = atoi(lHeight); if (IsPercent(lHeight) && lHeightValue <= 100) { lHeightValue *= ::GetSystemMetrics(SM_CYSCREEN); lHeightValue /= 100; } pArgs->SetMember(L"minHeight", CComVariant(lHeightValue)); } else { CString lValue; if (NextWord(lFeatures, lValue)) pArgs->SetMember(CComBSTR(lWord), CComVariant(BooleanValue(lValue))); } } } STDMETHODIMP TScriptGlobals::showDialog(BSTR pUrl, VARIANT pArgs, VARIANT pFeatures) { USES_CONVERSION; TErr::trace(TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, "Script : showDialog('%1', '%2')", W2CT(pUrl), pFeatures.vt == VT_BSTR ? W2CT(pFeatures.bstrVal) : ""); CComPtr lFeatures; if (pFeatures.vt == VT_DISPATCH) lFeatures = pFeatures.pdispVal; else { CComObject* lFeaturesClass; CComObject::CreateInstance(&lFeaturesClass); lFeaturesClass->AddMember(L"id", CComVariant(CComBSTR("dialog"))); lFeaturesClass->AddMember(L"height", CComVariant(300)); lFeaturesClass->AddMember(L"width", CComVariant(400)); lFeaturesClass->AddMember(L"top", CComVariant(50)); lFeaturesClass->AddMember(L"left", CComVariant(50)); lFeaturesClass->AddMember(L"center", CComVariant(true)); lFeaturesClass->AddMember(L"modal", CComVariant(true)); lFeaturesClass->AddMember(L"sysMenu", CComVariant(true)); lFeaturesClass->AddMember(L"toolWindow", CComVariant(true)); lFeaturesClass->AddMember(L"dialogArgs", CComVariant(pArgs)); lFeaturesClass->AddMember(L"docFlags", CComVariant(DOCHOSTUIFLAG_NO3DBORDER)); if (pFeatures.vt == VT_BSTR) ParseFeatures(pFeatures, lFeaturesClass); lFeaturesClass->QueryInterface(&lFeatures); } HRESULT lResult = S_OK; TScriptHtmlDialog* lDlg = new TScriptHtmlDialog(); // lDlg->SetUrl(pUrl); lDlg->SetArguments(pArgs); lDlg->SetScriptObject(lFeatures); CComDispatchDriver lDriver(lFeatures); CComVariant lModalValue; CComVariant lUrl(pUrl); lResult = lDriver.PutPropertyByName(L"url", &lUrl); ATLASSERT(SUCCEEDED(lResult)); lResult = lDriver.GetPropertyByName(L"modal", &lModalValue); ATLASSERT(SUCCEEDED(lResult)); if (lModalValue.boolVal) { lDlg->DoModal(); delete lDlg; } else { CComVariant lWindowID; lResult = lDriver.GetPropertyByName(L"id", &lWindowID); ATLASSERT(SUCCEEDED(lResult)); TScriptHtmlDialog* lWin; lWin = TScriptHtmlDialog::FindWindow(lWindowID); if (lWin != NULL) { lWin->BringWindowToTop(); return S_FALSE; } TScriptHtmlDialog::AddWindow(lWindowID, lDlg); lDlg->Create(NULL); // lDlg->ShowWindow(SW_SHOW); } return lResult; } /* CComPtr lDocument; HRESULT lResult = E_FAIL; if (SUCCEEDED(lDocument.CoCreateInstance(CLSID_HTMLDocument))) { CComPtr lMoniker; CComPtr lBindContex; // LPMONIKER lMoniker = NULL; // LPBINDCTX lBindContex = NULL; CComQIPtr lPersistMoniker(lDocument); if (lPersistMoniker) { lResult = CreateURLMoniker(NULL, L"about:blank", &lMoniker); if (SUCCEEDED(lResult)) { lResult = CreateBindCtx(0, &lBindContex); if (SUCCEEDED(lResult)) { lResult = lPersistMoniker->Load(FALSE, lMoniker, lBindContex, STGM_READ); CComPtr lWindow; lResult = lDocument->get_parentWindow(&lWindow); CComBSTR lState; lResult = lDocument->get_readyState(&lState); if (lWindow) { CComVariant lFeaturesVariant(pFeatures); CComVariant lResultVariant; // lResult = lWindow->navigate(CComBSTR("about:blank")); lResult = lWindow->showModalDialog(CComBSTR(pUrl), &pArgs, &lFeaturesVariant, &lResultVariant); } } } } } */ #ifdef _DEBUG STDMETHODIMP TScriptGlobals::trace(BSTR pVal) { USES_CONVERSION; TRACE("#JScript> %s\n", W2CT(pVal)); return S_OK; } #endif STDMETHODIMP TScriptGlobals::get_globalPath(BSTR* pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; *pVal = m_Path; return S_OK; } void TScriptGlobals::SetPath(BSTR pPath) { m_Path = pPath; } STDMETHODIMP TScriptGlobals::newClass(VARIANT pFlag, LPDISPATCH *pVal) { ASSERT(pVal); if (pVal == NULL) return E_INVALIDARG; CComObject* lClass; CComObject::CreateInstance(&lClass); if (pFlag.vt == VT_BOOL) lClass->SetAllowUnimplemented(pFlag.boolVal); return lClass->QueryInterface(pVal); } /*------------ SimplePublisher.cpp ------------*/ // SimplePublisher.cpp : Implementation of CSimplePublisher #include "stdafxWebBookPublisher.h" #include "WebBookPublisher.h" #include "SimplePublisher.h" CWebPostDLL::CWebPostDLL( void ) : fDLLInstance( NULL ), fWpCreateSiteEx( NULL ), fWpCreateSite( NULL ), fWpDeleteSite( NULL ), fWpListSites( NULL ), fWpGetErrorString( NULL ), fWpDoesSiteExist( NULL ), fWpPost( NULL ), fWpPostEx( NULL ), fWpEnumProviders( NULL ) { fDLLInstance = ::LoadLibrary( _T( "WebPost.dll" )); if( fDLLInstance ) { fWpCreateSiteEx = (PFN_WPCREATESITEEX)GetWebPostFunction( "WpCreateSiteExA" ); fWpCreateSite = (PFN_WPCREATESITE)GetWebPostFunction( "WpCreateSiteA" ); fWpDeleteSite = (PFN_WPDELETESITE)GetWebPostFunction( "WpDeleteSiteA" ); fWpListSites = (PFN_WPLISTSITES)GetWebPostFunction( "WpListSitesA" ); fWpGetErrorString = (PFN_WPGETERRORSTRING)GetWebPostFunction( "WpGetErrorStringA" ); fWpDoesSiteExist = (PFN_WPDOESSITEEXIST)GetWebPostFunction( "WpDoesSiteExistA" ); fWpPost = (PFN_WPPOST)GetWebPostFunction( "WpPostA" ); fWpPostEx = (PFN_WPPOSTEXA)GetWebPostFunction( "WpPostExA" ); fWpEnumProviders = (PFN_WPENUMPROVIDERS)GetWebPostFunction( "WpEnumProvidersA" ); } } CWebPostDLL::~CWebPostDLL( void ) { if( fDLLInstance ) { ::FreeLibrary( fDLLInstance ); } } FARPROC CWebPostDLL::GetWebPostFunction( LPCTSTR FunctionName ) { FARPROC lpFunction = NULL; if( fDLLInstance ) { lpFunction = GetProcAddress( fDLLInstance,FunctionName ); } return lpFunction; } long CWebPostDLL::Check( void ) { if( !fDLLInstance ) return WebBookPublisher_ErrorCode_No_WebPost_dll; if( !fWpCreateSiteEx ) return WebBookPublisher_ErrorCode_No_WpCreateSiteExA; if( !fWpPostEx ) return WebBookPublisher_ErrorCode_No_WpPostExA; if( !fWpCreateSite ) return WebBookPublisher_ErrorCode_Function_Missing; if( !fWpDeleteSite ) return WebBookPublisher_ErrorCode_Function_Missing; if( !fWpListSites ) return WebBookPublisher_ErrorCode_Function_Missing; if( !fWpGetErrorString ) return WebBookPublisher_ErrorCode_Function_Missing; if( !fWpDoesSiteExist ) return WebBookPublisher_ErrorCode_Function_Missing; if( !fWpPost ) return WebBookPublisher_ErrorCode_Function_Missing; if( !fWpEnumProviders ) return WebBookPublisher_ErrorCode_Function_Missing; return NO_ERROR; } ///////////////////////////////////////////////////////////////////////////// // CSimplePublisher CSimplePublisher::CSimplePublisher( void ) : fNbProviders( 0 ), fProviders (NULL ), m_LastErrorCode( NO_ERROR ), fWebPostDLL(), #ifdef PROGRESSCONTROL fProvider( NULL ), #endif fIsPostErrorCode( false ) { InitProviders(); } CSimplePublisher::~CSimplePublisher( void ) { if( fSite ) { DisconnectSite( &m_LastErrorCode ); } if( fProviders ) { delete [] fProviders; } } // This is the strange code of post annulation #define E_CANCEL_POST 3221496086 void CSimplePublisher::WpStatus( TCHAR * Mess ) { USES_CONVERSION; CComBSTR lErrorString; get_LastErrorString( &lErrorString ); ATLTRACE( "\n%s -> %ld : %s",Mess,m_LastErrorCode, W2T( lErrorString ) ); } long CSimplePublisher::StoreWebPostCode( DWORD WebPostCode,bool IsPostErrorCode,char *Mess ) { BOOL lIsKeeBoo; m_LastErrorCode = WebPostCode; get_IsKeeBooCode( &lIsKeeBoo ); if( IS_ERROR( WebPostCode ) || lIsKeeBoo ) { switch (WebPostCode) { case E_CANCEL_POST: { m_LastErrorCode = WebBookPublisher_ErrorCode_Cancel_Post; fIsPostErrorCode = false; break; } #define E_SITE_DECONNECTED_1 -2147012865 #define E_SITE_DECONNECTED_2 -2147012866 case E_SITE_DECONNECTED_1: case E_SITE_DECONNECTED_2: { m_LastErrorCode = WebBookPublisher_ErrorCode_Site_Deconnected; fIsPostErrorCode = false; break; } default: { m_LastErrorCode = WebPostCode; fIsPostErrorCode = IsPostErrorCode; } } } else { m_LastErrorCode = S_OK; fIsPostErrorCode = false; } #ifdef _DEBUG WpStatus( Mess ); #endif return m_LastErrorCode; } STDMETHODIMP CSimplePublisher::InterfaceSupportsErrorInfo( REFIID riid ) { static const IID* arr[] = { &IID_ISimplePublisher }; for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++) { if (InlineIsEqualGUID(*arr[i],riid)) return S_OK; } return S_FALSE; } STDMETHODIMP CSimplePublisher::get_CheckSystem( BOOL *pVal ) { ATLASSERT( pVal ); if( !pVal ) return E_INVALIDARG; m_LastErrorCode = fWebPostDLL.Check(); *pVal = m_LastErrorCode == NO_ERROR ? TRUE : FALSE; return S_OK; } STDMETHODIMP CSimplePublisher::get_Version( BSTR *pVal ) { ATLASSERT( pVal ); if( !pVal ) return E_INVALIDARG; CComBSTR lVersionValue( _T( "Simple Publisher : 1.0" ) ); *pVal = lVersionValue.Copy(); return S_OK; } STDMETHODIMP CSimplePublisher::CreateSite( BSTR SiteName,BSTR URL ) { USES_CONVERSION; StoreWebPostCode( fWebPostDLL.fWpCreateSite( W2T(SiteName),NULL, W2T(URL),NULL,0 ),false,"WpCreateSite" ); return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } STDMETHODIMP CSimplePublisher::DeleteSite( BSTR SiteName ) { USES_CONVERSION; StoreWebPostCode( fWebPostDLL.fWpDeleteSite( W2T(SiteName)),false,"WpDeleteSite" ); return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } STDMETHODIMP CSimplePublisher::get_SiteNames( long NumSite,BSTR* SiteName ) { long lNbSites; DWORD lBufLen; WPSITEINFO* lSites; // Verify All parameters ATLASSERT( NumSite >=0 ); ATLASSERT( SiteName ); if( get_NbSites( &lNbSites ) != S_OK ) return m_LastErrorCode; if( (NumSite < 0 ) || (NumSite >= lNbSites ) ) return E_INVALIDARG; if( !SiteName ) return E_INVALIDARG; // Do the job : Get Buffer Length for list if( StoreWebPostCode( fWebPostDLL.fWpListSites( &lBufLen,NULL,(unsigned long*)&lNbSites ),false,"WpListSite for get_SiteNames 1" ) == S_OK ) { // Alloc the Buffer lSites = (WPSITEINFO*)new unsigned char [ lBufLen + 1 ]; // Get the list if( StoreWebPostCode( fWebPostDLL.fWpListSites( &lBufLen,lSites,(unsigned long*)&lNbSites ),false,"WpListSite for get_SiteNames 2" ) == S_OK ) { // Extract the info for the right site CComBSTR lSiteName( lSites[ NumSite ].lpszSiteName ); *SiteName = lSiteName.Copy(); } delete [] lSites; } return m_LastErrorCode == NO_ERROR ? S_OK : E_FAIL; } STDMETHODIMP CSimplePublisher::get_SiteURLs( long NumSite, BSTR *SiteURL ) { long lNbSites; DWORD lBufLen; WPSITEINFO* lSites = NULL; // Verify All parameters ATLASSERT( NumSite >=0 ); ATLASSERT( SiteURL ); if( get_NbSites( &lNbSites ) != S_OK ) return m_LastErrorCode; if( (NumSite < 0 ) || (NumSite >= lNbSites ) ) return E_INVALIDARG; if( !SiteURL ) return E_INVALIDARG; // Do the job : Get Buffer Length for list if( StoreWebPostCode( fWebPostDLL.fWpListSites( &lBufLen,NULL,(unsigned long*)&lNbSites ),false,"WpListSite for get_SitesURL 1" ) == S_OK ) { // Alloc the Buffer lSites = (WPSITEINFO*)new unsigned char [ lBufLen + 1 ]; // Get the list if( StoreWebPostCode( fWebPostDLL.fWpListSites( &lBufLen,lSites,(unsigned long*)&lNbSites ),false,"WpListSite for get_SitesURL 2" ) == S_OK ) { // Extract the info for the right site CComBSTR lSiteURL( lSites[ NumSite ].lpszSiteURL ); *SiteURL = lSiteURL.Copy(); } } delete [] lSites; return m_LastErrorCode == NO_ERROR ? S_OK : E_FAIL; } STDMETHODIMP CSimplePublisher::get_NbSites( long *pVal ) { DWORD lBufLen; ATLASSERT( pVal ); if( !pVal ) return E_INVALIDARG; StoreWebPostCode( fWebPostDLL.fWpListSites( &lBufLen,NULL,(unsigned long*)pVal ),false,"WpListSite for get_NbSites" ); return m_LastErrorCode == NO_ERROR ? S_OK : E_FAIL; } STDMETHODIMP CSimplePublisher::get_LastErrorString( BSTR *pVal ) { CComBSTR lMess; ATLASSERT( pVal ); if( !pVal ) return E_INVALIDARG; switch( m_LastErrorCode ) { case WebBookPublisher_ErrorCode_Cancel_Post: lMess = _T( "Publish canceled by user" ); break; case WebBookPublisher_ErrorCode_Empty_DirPath: lMess = _T( "Empty Dir Path" ); break; case WebBookPublisher_ErrorCode_No_WpPostExA: lMess = _T( "No WpPostExtA function" ); break; case WebBookPublisher_ErrorCode_No_WpCreateSiteExA: lMess = _T( "No pCreateSiteExA" ); break; case WebBookPublisher_ErrorCode_No_WebPost_dll: lMess = _T( "Cannot found WebPost DLL" ); break; case WebBookPublisher_ErrorCode_Function_Missing: lMess = _T( "Missing function in WebPost.dll" ); break; case WebBookPublisher_ErrorCode_Unknown_Provider: lMess = _T( "The site uses an unknown provider" ); break; case WebBookPublisher_ErrorCode_Cannot_Read_Site_Key: lMess = _T( "The site exists but not his keys" ); break; case WebBookPublisher_ErrorCode_Cannot_Get_Interface: lMess = _T( "Cannot get interface for this provider" ); break; case WebBookPublisher_ErrorCode_Site_Deconnected: lMess = _T( "Site deconnected" ); break; case WebBookPublisher_ErrorCode_No_Site_Connected: lMess = _T( "No Site connected" ); break; default: if( fIsPostErrorCode ) { PostErrorString( m_LastErrorCode,pVal ); return S_OK; } else { DWORD lBufLen = 0; TCHAR* lBuff; LONG lRes; fWebPostDLL.fWpGetErrorString( m_LastErrorCode,NULL,&lBufLen ); lBufLen++; lBuff = new TCHAR[ lBufLen + 1 ]; *lBuff = 0; lRes = fWebPostDLL.fWpGetErrorString( m_LastErrorCode,lBuff,&lBufLen ); if(lRes == NO_ERROR ) { lBuff[ lBufLen-1 ] = 0; CComBSTR lErrorString( lBuff ); lMess = lErrorString; //Memory Leak lErrorString.Copy(); delete [] lBuff; } else { lMess = "?"; } } break; } *pVal = lMess.Copy(); return S_OK; } STDMETHODIMP CSimplePublisher::get_IsKeeBooCode( BOOL* pVal ) { ATLASSERT( pVal ); if( !pVal ) return E_INVALIDARG; switch( m_LastErrorCode ) { case WebBookPublisher_ErrorCode_Cancel_Post: case WebBookPublisher_ErrorCode_Empty_DirPath: case WebBookPublisher_ErrorCode_No_WpPostExA: case WebBookPublisher_ErrorCode_No_WpCreateSiteExA: case WebBookPublisher_ErrorCode_No_WebPost_dll: case WebBookPublisher_ErrorCode_Function_Missing: case WebBookPublisher_ErrorCode_Unknown_Provider: case WebBookPublisher_ErrorCode_Cannot_Read_Site_Key: case WebBookPublisher_ErrorCode_Cannot_Get_Interface: case WebBookPublisher_ErrorCode_No_Site_Connected: case WebBookPublisher_ErrorCode_Site_Deconnected: *pVal = TRUE; break; default: *pVal = FALSE; } return S_OK; } STDMETHODIMP CSimplePublisher::get_LastErrorCode( long *pVal ) { ATLASSERT( pVal ); if( !pVal ) return E_INVALIDARG; *pVal = m_LastErrorCode; return S_OK; } STDMETHODIMP CSimplePublisher::SiteExists( BSTR SiteName,BOOL* Exists ) { USES_CONVERSION; BOOL lExists; ATLASSERT( Exists ); if( !Exists ) { return E_INVALIDARG; } StoreWebPostCode( fWebPostDLL.fWpDoesSiteExist( W2T(SiteName), &lExists ),false,"WpDoesSiteExists" ); *Exists = lExists; return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } STDMETHODIMP CSimplePublisher::PostDir( BSTR SiteName,BSTR DirPath ) { USES_CONVERSION; CComBSTR lSiteName(SiteName); TCHAR* lDirPath = NULL; DWORD lSiteNameLen = lSiteName.Length() + 1; DWORD lDirPathLen = 0; DWORD lURLLen = 0; TCHAR * lTmp; lTmp = W2T( DirPath ); lDirPathLen = _tcslen( lTmp ) + 1; ATLASSERT( lDirPathLen > 0 ); if( lDirPathLen > 0 ) { lDirPath = new TCHAR [ lDirPathLen ]; _tcscpy( lDirPath,lTmp ); StoreWebPostCode( fWebPostDLL.fWpPost( NULL,1,&lDirPath,&lSiteNameLen,W2T(SiteName),&lURLLen,NULL,WPF_NO_WIZARD ),false,"WpPost" ); } else { m_LastErrorCode = WebBookPublisher_ErrorCode_Empty_DirPath; } if( lDirPath ) delete [] lDirPath; return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } STDMETHODIMP CSimplePublisher::CreateFullSite( BSTR SiteName,BSTR URL,BSTR UserName,BSTR Password ) { USES_CONVERSION; CComBSTR lURL( URL ); CComBSTR lUserName( UserName ); CComBSTR lPassword( Password ); StoreWebPostCode( fWebPostDLL.fWpCreateSiteEx( W2T(SiteName),NULL,W2T(lURL),NULL,W2T(lUserName),W2T(lPassword),0,NULL,NULL ),false,"WpCreateSiteEx" ); return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } STDMETHODIMP CSimplePublisher::FullPostDir( BSTR SiteName,BSTR DirPath,BSTR URL ) { CComBSTR lSiteName(SiteName); TCHAR* lDirPath = NULL; TCHAR* lURL = NULL; if( DirPath != NULL ) { USES_CONVERSION; DWORD lSiteNameLen = lSiteName.Length() + 1; DWORD lDirPathLen = 0; DWORD lURLLen = 0; TCHAR* lTmp; lTmp = W2T( DirPath ); lDirPathLen = _tcslen( lTmp ) + 1; ATLASSERT( lDirPathLen ); if( lDirPathLen >0 ) { lDirPath = new TCHAR [ lDirPathLen ]; _tcscpy( lDirPath, lTmp ); lTmp = W2T( URL ); lURLLen = _tcslen( lTmp ) ; if( lURLLen >0 ) { lURLLen += 1001; lURL = new TCHAR [ lURLLen ]; _tcscpy( lURL,lTmp ); } StoreWebPostCode( fWebPostDLL.fWpPostEx( NULL,1,&lDirPath,&lSiteNameLen, W2T(SiteName),&lURLLen,(LPTSTR)lURL,NULL,NULL,WPF_NO_WIZARD ),false,"WpPostEx" ); } else { m_LastErrorCode = WebBookPublisher_ErrorCode_Empty_DirPath; } } else { m_LastErrorCode = WebBookPublisher_ErrorCode_Empty_DirPath; } if( lDirPath ) delete [] lDirPath; if( lURL ) delete [] lURL; return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } HINSTANCE GetFTPFunction( LPCTSTR DllName,LPCTSTR FunctionName,FARPROC* pFunction ) { *pFunction = NULL; HINSTANCE lDllInst = LoadLibrary( _T( DllName )); if( lDllInst == NULL ) { } else { *pFunction = GetProcAddress(lDllInst, FunctionName ); if( !*pFunction ) { } } return lDllInst; } const IID IID_IWPSiteW = {0x5261F720,0x6C4C,0x11CF,{0x86,0xB1,0x00,0xAA,0x00,0x60,0xF8,0x6C}}; STDMETHODIMP CSimplePublisher::ConnectSite(/*[in]*/ BSTR SiteName,/* [out,retval] */ long* ErrCode) { USES_CONVERSION; BOOL lSiteExist = FALSE; if( fSite ) { DisconnectSite( &m_LastErrorCode ); } SiteExists( SiteName,&lSiteExist ); if( !lSiteExist ) { return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } TCHAR lRegKeyName[ 1000 ]; TCHAR* lProviderName = lRegKeyName; ULONG lProviderLen; _tcscpy( lRegKeyName,_T( "Software\\MicroSoft\\WebPost\\Sites\\" ) ); _tcscat( lRegKeyName, W2CT(SiteName) ); HKEY lKey = NULL; RegOpenKeyEx( HKEY_CURRENT_USER,lRegKeyName,0,KEY_READ,&lKey ); if( !lKey ) { StoreWebPostCode( WebBookPublisher_ErrorCode_Cannot_Read_Site_Key,false,"ConnectSite Clef" ); return S_FALSE; } lProviderLen = 999, *lProviderName = 0; RegQueryValueEx( lKey,_T( "Provider" ),NULL,NULL,(unsigned char*)lProviderName,&lProviderLen ); RegCloseKey( lKey ); if( (!lProviderName) || (_tcslen(lProviderName) == 0) ) { // No provider : I suppose FTP is best _tcscpy( lProviderName,_T( "{02b5e1d1-8b7c-11d0-ad45-00aa00a219aa}" ) ); } CComBSTR lProvider( lProviderName ); lProvider.ToLower(); unsigned i,j = -1; for( i = 0;i < fNbProviders;i++ ) { CComBSTR curProvider_Lower(CComBSTR(fProviders[ i ]->GetCLSID())); curProvider_Lower.ToLower(); if ( curProvider_Lower == lProvider ) { j = i; break; } } if ( j != -1) { PFN_WPPBINDTOSITEW fWppBindToSite; GetFTPFunction( W2CT(CComBSTR(fProviders[ j ]->GetDLL())),_T( "WppBindToSiteW" ),(FARPROC*)&fWppBindToSite ); if( !fWppBindToSite ) { StoreWebPostCode( WebBookPublisher_ErrorCode_Cannot_Read_Site_Key,false,"ConnectSite Clef" ); return S_FALSE; } StoreWebPostCode( fWppBindToSite(NULL, SiteName ,NULL,IID_IWPSiteW,-1,0,(PVOID *)&fSite ),false,"WppbindtoSite IWPSite" ); #ifdef PROGRESSCONTROL fWppBindToSite( NULL, SiteName ) ),NULL,IID_IWPProvider,-1,0,(PVOID *)&fProvider ); #endif if( !fSite ) { return S_FALSE; } StoreWebPostCode( fSite->NetworkConnect( NULL,NULL ),true,"NetWorkConnect" ); if( m_LastErrorCode != NO_ERROR ) { return S_FALSE; } StoreWebPostCode( fSite->ServerLogin( NULL,NULL ),true,"ServerLogin" ); if( m_LastErrorCode != NO_ERROR ) { return S_FALSE; } } else { StoreWebPostCode( WebBookPublisher_ErrorCode_Unknown_Provider,false,"Searching provider" ); return S_FALSE; } if( ErrCode ) { *ErrCode = m_LastErrorCode ; } return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } STDMETHODIMP CSimplePublisher::DisconnectSite( /* [out,retval] */ long* ErrCode ) { if( !fSite ) { StoreWebPostCode( WebBookPublisher_ErrorCode_No_Site_Connected,false,"DisconnectSite" ); if( ErrCode ) *ErrCode = m_LastErrorCode; return S_FALSE; } StoreWebPostCode( fSite->Commit(),true,"Commit" ); StoreWebPostCode( fSite->ServerLogout(),true,"ServerLgout" ); StoreWebPostCode( fSite->NetworkDisconnect(),true,"NetworkDisconnect" ); #ifdef PROGRESSCONTROL if( fProvider ) { fProvider = NULL; } #endif fSite = NULL; if( ErrCode ) { *ErrCode = m_LastErrorCode ; } return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } HRESULT CALLBACK Track( LPCWSTR wsFileName, DWORD dwNumBytes ) { return 0; } STDMETHODIMP CSimplePublisher::PostFile(/*[in]*/ BSTR FullFileName,/*[in]*/ BSTR FullUrlDest,/* [out,retval] */ long* ErrCode) { if( !fSite ) { StoreWebPostCode( WebBookPublisher_ErrorCode_No_Site_Connected,false,"DisconnectSite" ); if( ErrCode ) *ErrCode = m_LastErrorCode; return S_FALSE; } CComBSTR lFullFileName( FullFileName ); CComBSTR lFullUrlDest( FullUrlDest ); WCHAR lwFullFileName[ MAX_PATH ],lwFullUrlDest[ MAX_PATH ],*lpwFullFileName; DWORD lFullUrlDestLen; wcscpy( lwFullFileName,(WCHAR*) lFullFileName ); wcscpy( lwFullUrlDest,(WCHAR*) lFullUrlDest ); lpwFullFileName = lwFullFileName; lFullUrlDestLen = lFullUrlDest.Length(); #ifdef PROGRESSCONTROL if( fProvider ) { fProvider->SetProgressUpdateProc( (long *)Track ); } #endif StoreWebPostCode( fSite->PostFiles( 1,&lpwFullFileName,&lFullUrlDestLen,lFullUrlDest,WPF_NO_RECURSIVE_POST ),true,"PostFiles" ); if( ErrCode ) { *ErrCode = m_LastErrorCode ; } if( m_LastErrorCode ) { *ErrCode = m_LastErrorCode ; } return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } #define MAXBUF 4096 STDMETHODIMP CSimplePublisher::PostErrorString(/*[in] */LONG ErrCode,/*[out,retval]*/ BSTR* pMes) { ATLASSERT( pMes ); if( !pMes ) return E_INVALIDARG; CComBSTR lMes; if( fSite ) { ULONG lErrType; ULONG lErr = ErrCode; ULONG lErrBufLen; WCHAR rgwchError[ MAXBUF + 1]; USES_CONVERSION; lErrType = 0; *rgwchError = 0; lErrBufLen = MAXBUF; fSite->GetError( &lErrType,&lErr,&lErrBufLen,rgwchError ); lMes = W2T( rgwchError ); } *pMes = lMes.Copy(); return S_OK; } #include static long gNbFiles = 0; static TCHAR* gOrPath[ 1000 ]; static TCHAR* gDestPath[ 1000 ]; static void PrepPostFile( LPCTSTR pOrPath,LPCTSTR pDestPath ) { gOrPath[ gNbFiles ] = (TCHAR*)malloc( (_tcslen( pOrPath ) + 1)*sizeof( TCHAR ) ); _tcscpy( gOrPath[ gNbFiles ],pOrPath ); gDestPath[ gNbFiles ] = (TCHAR*)malloc( (_tcslen( pDestPath ) + 1)*sizeof( TCHAR ) ); _tcscpy( gDestPath[ gNbFiles ],pDestPath ); gNbFiles++; // printf( "\n%s",pOrPath ); // printf( " -> %s",pDestPath ); } #ifdef _DEBUG long BuildDir( LPCTSTR pDir,LPCTSTR pDestpath ); static void AddFile( LPCTSTR pDir, struct _finddata_t * pFoundFile, LPCTSTR pDestPath ) { if( (!strcmp( pFoundFile->name,_T( "." ) )) || (!strcmp( pFoundFile->name,_T( ".." ) )) ) { return; } long lLen = _tcslen( pFoundFile->name ) + 1 + _tcslen( pDir ); TCHAR lFileName[ MAX_PATH ]; TCHAR lNewDestPath[ MAX_PATH ]; if( pFoundFile->attrib & _A_SUBDIR ) { _tcscpy( lFileName,pDir ); _tcscat( lFileName,"\\" ); _tcscat( lFileName,pFoundFile->name ); _tcscat( lFileName,"\\" ); TCHAR lNewDir[ MAX_PATH ]; _tcscpy( lNewDir,pDir ); _tcscat( lNewDir,_T( "\\" ) ); _tcscat( lNewDir,pFoundFile->name ); _tcscpy( lNewDestPath,pDestPath ); // _tcscat( lNewDestPath,_T( "/" ) ); _tcscat( lNewDestPath,pFoundFile->name ); _tcscat( lNewDestPath,_T( "/" ) ); PrepPostFile( lFileName,pDestPath ); BuildDir( lNewDir,lNewDestPath ); return; } _tcscpy( lFileName,pDir ); _tcscat( lFileName,"\\" ); _tcscat( lFileName,pFoundFile->name ); _tcscpy( lNewDestPath,pDestPath ); // _tcscat( lNewDestPath,_T( "/" ) ); _tcscat( lNewDestPath,pFoundFile->name ); PrepPostFile( lFileName,lNewDestPath ); } long BuildDir( LPCTSTR pDir,LPCTSTR pDestPath ) { TCHAR lCurSpec[ MAX_PATH ]; struct _finddata_t lFoundInfo; long lFinder; _tcscpy( lCurSpec,pDir ); _tcscat( lCurSpec,_T( "\\*.*" ) ); lFinder = _findfirst( lCurSpec,&lFoundInfo ); if( lFinder != -1 ) { AddFile( pDir,&lFoundInfo,pDestPath ); while( _findnext( lFinder,&lFoundInfo ) == 0 ) { AddFile( pDir,&lFoundInfo,pDestPath ); } _findclose( lFinder ); } return gNbFiles; } #endif // _DEBUG STDMETHODIMP CSimplePublisher::NewPostDir(/*[in] */BSTR DirPath,/* [in] */BSTR URL,/*[out,retval]*/ LONG* pRes ) { if( !fSite ) { StoreWebPostCode( WebBookPublisher_ErrorCode_No_Site_Connected,false,"DisconnectSite" ); if( pRes ) *pRes = m_LastErrorCode; return S_FALSE; } USES_CONVERSION; CComBSTR lDirPath = DirPath; CComBSTR lURL = URL; #ifdef _DEBUG BuildDir( W2CT(lDirPath), W2CT(lURL) ); #endif // _DEBUG int i; for( i = 0;i < gNbFiles;i++ ) { lDirPath = gOrPath[ i ]; lURL = gDestPath[ i ]; ATLTRACE( "\n%s -> %s", W2CT(lDirPath), W2CT(lURL) ); PostFile( lDirPath,lURL,pRes ); if( *pRes != NO_ERROR ) { BSTR lErrMess; PostErrorString( *pRes,&lErrMess ); CComBSTR lbErrMess( lErrMess ); ATLTRACE( "\nError %lx %s",*pRes,W2CT(lbErrMess) ); } } if( pRes ) { *pRes= m_LastErrorCode ; } return m_LastErrorCode == NO_ERROR ? S_OK : S_FALSE; } void CSimplePublisher::InitProviders( void ) { DWORD lBufferLen = 0; WPPROVINFO* lProviderInfos = NULL; DWORD i; m_LastErrorCode = fWebPostDLL.Check(); if (m_LastErrorCode != NO_ERROR) { return; } m_LastErrorCode = fWebPostDLL.fWpEnumProviders( &lBufferLen,NULL,&fNbProviders ); if( m_LastErrorCode == NO_ERROR ) { lProviderInfos = (WPPROVINFO*)new unsigned char [ lBufferLen ]; m_LastErrorCode = fWebPostDLL.fWpEnumProviders( &lBufferLen,lProviderInfos,&fNbProviders ); if( m_LastErrorCode == NO_ERROR ) { fProviders = new CProvider*[ fNbProviders ]; for( i = 0;(i < fNbProviders);i++ ) { fProviders[ i ] = new CProvider( lProviderInfos[ i ].lpszProviderName,lProviderInfos[ i ].lpszProviderCLSID,lProviderInfos[ i ].lpszDllPath ); } } delete [] lProviderInfos; } } /*------------ SimplePublisher.h ------------*/ // SimplePublisher.h : Declaration of the CSimplePublisher #ifndef __SIMPLEPUBLISHER_H_ #define __SIMPLEPUBLISHER_H_ #include #include "WebBookPublisherResource.h" // main symbols ///////////////////////////////////////////////////////////////////////////// // CWebPostDLL typedef DWORD (WINAPI *PFN_WPCREATESITEEX)( LPTSTR szSiteName,LPTSTR szSiteLocalBaseDir,LPTSTR szSiteURL,LPTSTR szProviderCLSID,PTSTR szUsername,LPSTR szPassword,DWORD dwFlags,void** ppSPI,DWORD *pdwCharSet ); typedef DWORD (WINAPI *PFN_WPCREATESITE)( LPTSTR szSiteName,LPTSTR szSiteLocalBaseDir,LPTSTR szSiteURL,LPTSTR szProviderCLSID,DWORD dwFlags ); typedef DWORD (WINAPI *PFN_WPDELETESITE)( LPTSTR szSiteName ); typedef DWORD (WINAPI *PFN_WPLISTSITES)( LPDWORD pdwSitesBufLen,LPWPSITEINFO pSitesBuffer,LPDWORD pdwNumSites ); typedef DWORD (WINAPI *PFN_WPGETERRORSTRING)( UINT uErrCode,LPTSTR szOutputBuf,DWORD *pdwBuflen ); typedef DWORD (WINAPI *PFN_WPDOESSITEEXIST)( LPTSTR szSiteName,BOOL* pbSiteExists ); typedef DWORD (WINAPI *PFN_WPPOST)( HWND hWnd,DWORD dwNumLocalPaths,LPTSTR *pszLocalPaths,LPDWORD pdwSiteNameBufLen,LPTSTR szSiteName,LPDWORD pdwDestURLBufLen,LPTSTR szDestURL,DWORD dwFlags ); typedef DWORD (WINAPI *PFN_WPPOSTEXA)( HWND hWnd,DWORD dwNumLocalPaths,LPTSTR *pszLocalPaths,LPDWORD pdwSiteNameBufLen,LPTSTR szSiteName,LPDWORD pdwDestURLBufLen,LPTSTR szDestURL,LPSTR szUsername,LPSTR szPassword,DWORD dwFlags ); typedef DWORD (WINAPI *PFN_WPENUMPROVIDERS)( LPDWORD pdWProvidersBufLen,LPWPPROVINFO pProvidersBuffer,LPDWORD pdwNumProviders ); class CWebPostDLL { private: HINSTANCE fDLLInstance; FARPROC GetWebPostFunction( LPCTSTR FunctionName ); protected: public: PFN_WPCREATESITEEX fWpCreateSiteEx; PFN_WPCREATESITE fWpCreateSite; PFN_WPDELETESITE fWpDeleteSite; PFN_WPLISTSITES fWpListSites; PFN_WPGETERRORSTRING fWpGetErrorString; PFN_WPDOESSITEEXIST fWpDoesSiteExist; PFN_WPPOST fWpPost; PFN_WPPOSTEXA fWpPostEx; PFN_WPENUMPROVIDERS fWpEnumProviders; CWebPostDLL( void ); ~CWebPostDLL( void ); long Check( void ); }; ///////////////////////////////////////////////////////////////////////////// // CProvider class CProvider { private: CComBSTR fName; CComBSTR fCLSID; CComBSTR fDLL; protected: public: CProvider( LPTSTR pName,LPTSTR pCLSID,LPTSTR pDLL ) : fName( pName ),fCLSID( pCLSID ),fDLL( pDLL ) { fCLSID.ToLower(); // to make comparisons easier later on }; BSTR GetName( void ) { return fName; } BSTR GetCLSID( void ) { return fCLSID; } BSTR GetDLL( void ) { return fDLL; } }; ///////////////////////////////////////////////////////////////////////////// // CSimplePublisher class ATL_NO_VTABLE CSimplePublisher : public CComObjectRootEx, public CComCoClass, public ISupportErrorInfo, public IDispatchImpl { private: public: CSimplePublisher(); ~CSimplePublisher(); DECLARE_REGISTRY_RESOURCEID(IDR_SIMPLEPUBLISHER) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CSimplePublisher) COM_INTERFACE_ENTRY(ISimplePublisher) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(ISupportErrorInfo) END_COM_MAP() BEGIN_CONNECTION_POINT_MAP(CSimplePublisher) END_CONNECTION_POINT_MAP() // ISupportsErrorInfo STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid); // ISimplePublisher public: STDMETHOD(get_CheckSystem)(/*[out,retval]*/ BOOL* IsOk); STDMETHOD(get_LastErrorCode)(/*[out, retval]*/ long *pVal); STDMETHOD(get_LastErrorString)(/*[out, retval]*/ BSTR *pVal); STDMETHOD(get_Version)(/*[out, retval]*/ BSTR *pVal); STDMETHOD(get_IsKeeBooCode)(/*[out, retval]*/ BOOL *pVal); STDMETHOD(CreateSite)(/*[in]*/ BSTR SiteName,/*[in]*/ BSTR URL); STDMETHOD(DeleteSite)(/*[in]*/ BSTR SiteName); STDMETHOD(SiteExists)(/*[in]*/ BSTR SiteName,/*[out,retval]*/ BOOL* Exist); STDMETHOD(get_NbSites)(/*[out, retval]*/ long *pVal); STDMETHOD(get_SiteURLs)(/*[in]*/ long NumSite, /*[out, retval]*/ BSTR *pVal); STDMETHOD(get_SiteNames)(/*[in]*/ long NumSite,/* [out,retval] */ BSTR *SiteName); STDMETHOD(PostDir)(/*[in]*/ BSTR SiteName,/*[in]*/ BSTR DirPath); STDMETHOD(CreateFullSite)(/*[in]*/ BSTR SiteName,/*[in]*/ BSTR URL,/*[in]*/ BSTR UserName,/*[in]*/ BSTR Password); STDMETHOD(FullPostDir)(/*[in]*/ BSTR SiteName,/*[in]*/ BSTR DirPath,/*[in]*/ BSTR URL); STDMETHOD(ConnectSite)(/*[in]*/ BSTR SiteName,/* [out,retval] */ long* ErrCode); STDMETHOD(DisconnectSite)( /*[out,retval] */ long* ErrCode ); STDMETHOD(PostFile)(/*[in]*/ BSTR FullFileName,/*[in]*/ BSTR FullUrlDest,/* [out,retval] */ long* ErrCode); STDMETHOD(PostErrorString)(/*[in] */LONG ErrCode,/*[out,retval]*/ BSTR* pMes); STDMETHOD(NewPostDir)(/*[in] */BSTR DirPath,/* [in] */BSTR URL,/*[out,retval]*/ LONG* pRes ); private: bool fIsPostErrorCode; CWebPostDLL fWebPostDLL; long m_LastErrorCode; DWORD fNbProviders; CProvider **fProviders; CComPtr fSite; #ifdef PROGRESSCONTROL CComPtr fProvider; #endif long StoreWebPostCode( DWORD WebPostCode,bool IsPostErrorCode,char *Mess ); void WpStatus( TCHAR * Mess ); void InitProviders( void ); }; #endif //__SIMPLEPUBLISHER_H_ /*------------ TDHTMLExportManager.cpp ------------*/ #include "StdAfx.h" // MAIN INCLUDE #ifndef T_DHTML_EXPORT_MANAGER #include "TDHTMLExportManager.h" #endif // OTHER INCLUDES #include "TDHTMLWebKeeBookExportEngine.h" #include "TDHTMLDynamicKeeBookExportEngine.h" #include "TProgressHelper.h" #include "TGlobalResource.h" #include "SharedResource.h" #include "TPtrIterator.h" #include "TErr.h" #include "TObjectModel.h" #include "TModelNames.h" // DEFINES #ifndef _DHTML_EXPORT_TRACE #define _DHTML_EXPORT_TRACE #endif /* #ifdef _DHTML_EXPORT_TRACE #undef _DHTML_EXPORT_TRACE #endif */ /*************************************/ /***** class TDHTMLExportManager *****/ /*************************************/ // CONSTRUCTORS TDHTMLExportManager::TDHTMLExportManager() { fProgressHelper = new TProgressHelper(); } // DESTRUCTORS TDHTMLExportManager::~TDHTMLExportManager() { if (fProgressHelper) { delete fProgressHelper; fProgressHelper = NULL; } } // METHODS boolean TDHTMLExportManager::export(TExportData* pExportData, LPCTSTR pOutputFileName) { TString statusStr; boolean res = true; fExportData = pExportData; // PROGRESS NOTIFICATION if (fExportData && (fExportData->fMessageCallback != NULL)) { KBLoadString(IDS_PROGRESS_EXPORT_BEGIN,statusStr); int resVal = (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); UNUSED_ALWAYS(resVal); } if (!canExport(pExportData, pOutputFileName)) { return false; } fOutputFileName = pOutputFileName; /****************/ /***** INIT *****/ /****************/ // ------------------------------ // Progress Helper Initialization // ------------------------------ fLastReportedPercentage = 0; if (pExportData->fExportOutputFileFormat == TExportData::EXE_FILE_FORMAT) { // Phase 1 -> All the handlePage processing // Phase 2 -> handleBundledFiles // Phase 3 -> createAutoextractableFile float lPhase1TotalPercentage = 70; float lPhase2TotalPercentage = 10; float lPhase3TotalPercentage = 20; fProgressHelper->setPhaseCount(3); fProgressHelper->setTotalPercentageForPhase(1,lPhase1TotalPercentage); fProgressHelper->setTotalPercentageForPhase(2,lPhase2TotalPercentage); fProgressHelper->setTotalPercentageForPhase(3,lPhase3TotalPercentage); } else if (pExportData->fExportOutputFileFormat == TExportData::ZIP_FILE_FORMAT) { // Phase 1 -> All the handlePage processing // Phase 2 -> handleBundledFiles float lPhase1TotalPercentage = 75; float lPhase2TotalPercentage = 25; fProgressHelper->setPhaseCount(2); fProgressHelper->setTotalPercentageForPhase(1,lPhase1TotalPercentage); fProgressHelper->setTotalPercentageForPhase(2,lPhase2TotalPercentage); } else if (pExportData->fExportOutputFileFormat == TExportData::HTML_FILE_FORMAT) { // Phase 1 -> All the handlePage processing float lPhase1TotalPercentage = 100; fProgressHelper->setPhaseCount(1); fProgressHelper->setTotalPercentageForPhase(1,lPhase1TotalPercentage); } else { ASSERT(NULL); } // ------------------------------ // PROGRESS NOTIFICATION { // We use the Progress Bar Control if (fExportData->fMessageCallback != NULL) { (void) (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_INIT_USE_PROGRESS_BAR,0,0,NULL,NULL,(fExportData->fMessageCallbackData)); } reportCurrentGlobalPercentage(1,0.0f); } TPtrIterator* modelsToExportIter = getModelsToExport(); // PROGRESS NOTIFICATION if ((modelsToExportIter->hasMoreElements()) && (fExportData->fMessageCallback != NULL)) { KBLoadString(IDS_PROGRESS_EXPORT_DOCUMENTS_EXPORT,statusStr); int resVal = (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); UNUSED_ALWAYS(resVal); } // At the moment, we will only export the first model... // Later on, we could iterate on the models and generate several // autoextractable with incremental names... if /*while*/ (modelsToExportIter->hasMoreElements()) { TObjectModel* objToExport = (TObjectModel *)modelsToExportIter->nextElement(); res &= exportObject(objToExport); } // // If this Assert occured, // We should warn the user (before the export process) // that only the first book will be exported // ASSERT(modelsToExportIter->hasMoreElements() == false); delete modelsToExportIter; // PROGRESS NOTIFICATION { reportCurrentGlobalPercentage(fProgressHelper->getPhaseCount(),1.0f); // We don't use the Progress Bar Control anymore if (fExportData->fMessageCallback != NULL) { (void) (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_EXIT_USE_PROGRESS_BAR,0,0,NULL,NULL,(fExportData->fMessageCallbackData)); } } // PROGRESS NOTIFICATION : The End if (fExportData && (fExportData->fMessageCallback != NULL)) { KBLoadString(IDS_PROGRESS_EXPORT_END,statusStr); int resVal = (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); UNUSED_ALWAYS(resVal); } return res; } boolean TDHTMLExportManager::exportObject(TObjectModel* pObj) { ASSERT(pObj->isInstanceOf(T_BOOK_MODEL_NAME)); if ( fExportData->fExportOutputFormat == TExportData::WEB_KEEBOOK_FORMAT ) { TDHTMLWebKeeBookExportEngine lKeeBookExportEngine; return lKeeBookExportEngine.exportBook(fExportData, (TBookModel *)pObj, fOutputFileName); } #ifdef ALLOW_DYNAMIC_KEEBOOK else if ( fExportData->fExportOutputFormat == TExportData::DYNAMIC_KEEBOOK_FORMAT ) { TDHTMLDynamicKeeBookExportEngine lKeeBookExportEngine; return lKeeBookExportEngine.exportBook(fExportData, (TBookModel *)pObj, fOutputFileName); } #endif // ALLOW_DYNAMIC_KEEBOOK else { ASSERT(FALSE); return false; } } boolean TDHTMLExportManager::canExport(TExportData* pExportData, LPCTSTR pOutputFileName) { if (pExportData == null) return false; // Let's check if the output format is compatible if ( (pExportData->fExportOutputFormat != TExportData::WEB_KEEBOOK_FORMAT) #ifdef ALLOW_DYNAMIC_KEEBOOK && (pExportData->fExportOutputFormat != TExportData::DYNAMIC_KEEBOOK_FORMAT) #endif // ALLOW_DYNAMIC_KEEBOOK ) { TErr::trace( TErr::D_LOG | TErr::D_BOX, TErr::G_FAT, TErr::NO_ID, __FILE__, __LINE__, "DHtml Export Output Format not supported : (%1!d!)", pExportData->fExportOutputFormat); return false; } // Let's check if the output file format is compatible if ( (pExportData->fExportOutputFileFormat != TExportData::EXE_FILE_FORMAT) && (pExportData->fExportOutputFileFormat != TExportData::ZIP_FILE_FORMAT) && (pExportData->fExportOutputFileFormat != TExportData::HTML_FILE_FORMAT) ) { TErr::trace( TErr::D_LOG | TErr::D_BOX, TErr::G_FAT, TErr::NO_ID, __FILE__, __LINE__, "DHtml Export Output File Format not supported : (%1!d!)", pExportData->fExportOutputFileFormat); return false; } if (pExportData->fExportType == TExportData::BOOK_EXPORT) return TExportManager::canExport(pExportData, pOutputFileName); TErr::trace( TErr::D_LOG | TErr::D_BOX, TErr::G_FAT, TErr::NO_ID, __FILE__, __LINE__, "DHtml Export Type not supported : (%1!d!)", pExportData->fExportType); return false; } boolean TDHTMLExportManager::exportZipToExe(TExportData* pExportData, LPCTSTR pInFileName, LPCTSTR pOutputFileName) { TString statusStr; boolean res = true; fExportData = pExportData; // PROGRESS NOTIFICATION if (fExportData && (fExportData->fMessageCallback != NULL)) { KBLoadString(IDS_PROGRESS_EXPORT_BEGIN,statusStr); int resVal = (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); UNUSED_ALWAYS(resVal); } if (!canExport(fExportData, pOutputFileName)) return false; fOutputFileName = pOutputFileName; if ( fExportData->fExportOutputFormat == TExportData::WEB_KEEBOOK_FORMAT ) { TDHTMLWebKeeBookExportEngine lKeeBookExportEngine; res = lKeeBookExportEngine.exportZipToExe(fExportData, pInFileName, fOutputFileName); } #ifdef ALLOW_DYNAMIC_KEEBOOK else if ( fExportData->fExportOutputFormat == TExportData::DYNAMIC_KEEBOOK_FORMAT ) { TDHTMLDynamicKeeBookExportEngine lKeeBookExportEngine; res = lKeeBookExportEngine.exportZipToExe(fExportData, pInFileName, fOutputFileName); } #endif else { ASSERT(FALSE); return false; } // PROGRESS NOTIFICATION : The End if (fExportData && (fExportData->fMessageCallback != NULL)) { KBLoadString(IDS_PROGRESS_EXPORT_END,statusStr); int resVal = (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); UNUSED_ALWAYS(resVal); } return res; } // PROGRESS STUFF void TDHTMLExportManager::reportCurrentGlobalPercentage(LONG pVal, float pFull) { if ( fProgressHelper && (fExportData->fMessageCallback != NULL) ) { fProgressHelper->setCurrentPercentageForPhase(pVal, pFull); int percentage = (int)( fProgressHelper->getCurrentGlobalPercentage() ); if (percentage != fLastReportedPercentage) { fLastReportedPercentage = percentage; (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_PROGRESS_BAR_SET_POS,percentage,0,NULL,NULL,fExportData->fMessageCallbackData); } } } /*------------ TDHTMLKeeBookExportEngine.cpp ------------*/ #include "StdAfx.h" #include "TModelPtr.h" #ifndef T_DHTML_KEEBOOK_EXPORT_ENGINE #include "TDHTMLKeeBookExportEngine.h" #endif #define ZIP_WRITE #include "KBZip.h" #ifndef RES_HTML_TYPE #define RES_HTML_TYPE 23 #endif // OTHER INCLUDES #include "TDHTMLArchiveNamesManager.h" #include "THTMLProcessingEngine.h" #include "TErr.h" #include "TPath.h" #include "TBookModel.h" #include "TPageModel.h" #include "TContentModel.h" #include "TSystemInfo.h" #include "TLanguagesInfo.h" #include "TLooksInfo.h" #include "TSystemMimeHelper.h" #include "TEmbedMimeHelper.h" #include "TSevenixUrl.h" #include "TSevenixUrlInfo.h" #include "TStringToStringHashTable.h" #include "TAnnotationModel.h" #include "TMediaCaseModel.h" #include "TMediaShelfModel.h" #include "TStickerModel.h" #include "TDomAnnotationManager.h" #include "TModelIterator.h" #include "TModelHelpers.h" #include "TContentPropertiesConstants.h" #include "TZipManager.h" #include "TUnZipManager.h" #include "TRegKey.h" #include "TProgressHelper.h" #include "TExportData.h" #include "TExportBuffer.h" #include "SharedLookAndFeelRes.h" #include "TAnonymousGUID.h" #include "TGlobalResource.h" #include "TPoint.h" #include "THTMLString.h" #include "TPtrArray.h" #include "ProductVersion.h" #include "TAppInfo.h" #include "TAppBrandingInfo.h" #include "TUserInfo.h" #include "TAppVersionInfo.h" // Cache stuff #include "TNetHelpers.h" #include "Net.h" // BRANDING #include "TAutoRunBrandingGenerator.h" #include "TDynamicExportBrandingGenerator.h" #include "Branding.h" // Active Delivery stuff #include "adx.h" #include "SharedResource.h" // DEFINES #ifndef _DHTML_EXPORT_TRACE #define _DHTML_EXPORT_TRACE #endif /* #ifdef _DHTML_EXPORT_TRACE #undef _DHTML_EXPORT_TRACE #endif */ /***********************************/ /***** Private Classes - Begin *****/ /******************************************************************/ /***** class TDHTMLKeeBookExportEngine::TExportProcessingData *****/ /******************************************************************/ TDHTMLKeeBookExportEngine::TExportProcessingData::TExportProcessingData() { fCurrentPageNumber = 0; // 0-based fCurrentTabNumber = 0; fPageListBuffer = new TExportBuffer(); } TDHTMLKeeBookExportEngine::TExportProcessingData::~TExportProcessingData() { if (fPageListBuffer) { delete fPageListBuffer; fPageListBuffer = null; } } /**************************************************************************/ /***** class TDHTMLKeeBookExportEngine::TFinalizeExportProcessingData *****/ /**************************************************************************/ TDHTMLKeeBookExportEngine::TFinalizeExportProcessingData::TFinalizeExportProcessingData() { } TDHTMLKeeBookExportEngine::TFinalizeExportProcessingData::~TFinalizeExportProcessingData() { } /***********************************************************************/ /***** class TDHTMLKeeBookExportEngine::TCompressionProcessingData *****/ /***********************************************************************/ TDHTMLKeeBookExportEngine::TCompressionProcessingData::TCompressionProcessingData() { } TDHTMLKeeBookExportEngine::TCompressionProcessingData::~TCompressionProcessingData() { } /*************************************************************************/ /***** class TDHTMLKeeBookExportEngine::TAutoExtractableCreationData *****/ /*************************************************************************/ TDHTMLKeeBookExportEngine::TAutoExtractableCreationData::TAutoExtractableCreationData() { } TDHTMLKeeBookExportEngine::TAutoExtractableCreationData::~TAutoExtractableCreationData() { } /********************************************************************/ /***** class TDHTMLKeeBookExportEngine::TBrandingGenerationData *****/ /********************************************************************/ TDHTMLKeeBookExportEngine::TBrandingGenerationData::TBrandingGenerationData() { fBrandingType = 0; fExportProcessingData = NULL; fBrandingImagePathInArchive = _T(""); fBrandingImageRedirectUrl = _T(""); fBrandingImageSize = CSize(0,0); } TDHTMLKeeBookExportEngine::TBrandingGenerationData::~TBrandingGenerationData() { } /***** Private Classes - End *****/ /*********************************/ /*******************************************/ /***** class TDHTMLKeeBookExportEngine *****/ /*******************************************/ // CONSTRUCTORS TDHTMLKeeBookExportEngine::TDHTMLKeeBookExportEngine() { fFilterCache = NULL; fInternetCache = NULL; HRESULT hr; hr = GetCache(T_FILTER_CACHE_NAME, &fFilterCache); if (hr != S_OK) fFilterCache = null; hr = GetCache(T_NETWORK_CACHE_NAME, &fInternetCache); if (hr != S_OK) fInternetCache = null; fAutorunBookID = CLSID_NULL; fBookModel = NULL; fProgressHelper = new TProgressHelper(); fArchiveNamesMgr = new TDHTMLArchiveNamesManager(this->getWorkingDirectory()); m_bFatImage = TRUE; } // DESTRUCTORS TDHTMLKeeBookExportEngine::~TDHTMLKeeBookExportEngine() { if (fFilterCache) { fFilterCache->Release(); fFilterCache = NULL; } if (fInternetCache) { fInternetCache->Release(); fInternetCache = NULL; } if (fProgressHelper) { delete fProgressHelper; fProgressHelper = NULL; } if (fArchiveNamesMgr) { delete fArchiveNamesMgr; fArchiveNamesMgr = null; } } // METHODS boolean TDHTMLKeeBookExportEngine::exportBook(TExportData* pExportData, TBookModel* pObj, LPCTSTR pOutputFileName) { fExportData = pExportData; fOutputFileName = pOutputFileName; ASSERT(pObj->isInstanceOf(T_BOOK_MODEL_NAME)); return exportBookProcessing((TBookModel *)pObj); } boolean TDHTMLKeeBookExportEngine::exportZipToExe(TExportData* pExportData, LPCTSTR pInFileName, LPCTSTR pOutputFileName) { fExportData = pExportData; fOutputFileName = pOutputFileName; return exportZipToExeProcessing(pInFileName); } boolean TDHTMLKeeBookExportEngine::exportBookProcessing(TBookModel* pObj) { boolean bResult = true; // let's be sure the temporary directory is created CString lWorkingDirectory = getWorkingDirectory(); ASSERT(!lWorkingDirectory.IsEmpty()); if (lWorkingDirectory.IsEmpty()) return false; /****************/ /***** INIT *****/ /****************/ fBookModel = pObj; // ------------------------------ // Progress Helper Initialization // ------------------------------ exportBook_initProgressHelper(); // ------------------------------ CString lDynamicKeeBookMainHTMLOutputFile; CString lPreBundledZipFilePath; CString lBookTitle; CString lMainHTMLFileName; CString lDataFolderRelativePath; CString lShortcutIconFileName; // TCompressionProcessingData* lExportCompressionProcessingData = NULL; // TAutoExtractableCreationData* lAutoExtractableCreationData = NULL; TExportProcessingData* lExportProcessingData = newExportProcessingData(); bResult = true; // First, let's pre-fill the TExportProcessingData structure with useful values if (bResult) bResult &= exportBook_preFillExportProcessingData(pObj,lExportProcessingData); if ( (getExportData()->fExportOutputFileFormat == TExportData::ZIP_FILE_FORMAT) || (getExportData()->fExportOutputFileFormat == TExportData::EXE_FILE_FORMAT) ) { // Then, let's handle the Shortcut Icon file if (bResult) bResult &= exportBook_handleShortcutIconFileGeneration(); // Then, let's handle the Import To KeeBoo file if (bResult) bResult &= exportBook_handleImportToKeeBooFileGeneration(); } // Then, let's handle the branding items generation if (bResult) bResult &= exportBook_handleBranding(pObj,lExportProcessingData); // Then, let's handle the pages we will put before the content pages of the book if (bResult) bResult &= exportBook_handlePagesBeforeSummary(pObj,lExportProcessingData); // Then, let's handle the regular pages, ie. the summary and all its children if (bResult) bResult &= exportBook_handleRegularPages(pObj,lExportProcessingData); // Then, let's handle the pages we will put after the pages appearing in the book's summary if (bResult) bResult &= exportBook_handlePagesAfterSummaryPages(pObj,lExportProcessingData); // Then, let's handle the config.js file generation // This must be done as late as possible since it uses // exportProcessingData values if (bResult) bResult &= exportBook_handleParamsJSFileGeneration(pObj,lExportProcessingData); // Then, as all the exportProcessingData should be filled, let's generate // the Main KeeBook Scripting File if (bResult) bResult &= exportBook_finalizeExportProcessingData(pObj, lExportProcessingData); if (fExportData->fExportOutputFileFormat != TExportData::HTML_FILE_FORMAT) { // Now, we have everything needed to compose the keebook, so let's // take the files, compress them and then change it to self-extractable // when needed. if (bResult) bResult &= exportBook_finalizeBundleFiles(pObj, lExportProcessingData); CString lWorkingDirectoryToCleanUp = getWorkingDirectory(); if (!lWorkingDirectoryToCleanUp.IsEmpty()) { TPath lPath(lWorkingDirectoryToCleanUp); lPath.RemoveDirectory(); } } if (lExportProcessingData) { delete lExportProcessingData; lExportProcessingData = NULL; } fBookModel = NULL; return bResult; } boolean TDHTMLKeeBookExportEngine::exportZipToExeProcessing(LPCTSTR pInFileName) { CString statusStr; boolean res = true; // PROGRESS NOTIFICATION if (fExportData && (fExportData->fMessageCallback != NULL)) { KBLoadString(IDS_PROGRESS_EXPORT_BEGIN,statusStr); /* int resVal = */(fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); } /****************/ /***** INIT *****/ /****************/ // ------------------------------ // Progress Helper Initialization // ------------------------------ exportZipToExe_initProgressHelper(); // ------------------------------ // PROGRESS NOTIFICATION { // We use the Progress Bar Control if (fExportData->fMessageCallback != NULL) { (void) (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_INIT_USE_PROGRESS_BAR,0,0,NULL,NULL,(fExportData->fMessageCallbackData)); } reportCurrentGlobalPercentage(1,0.0f); } TPtrIterator* modelsToExportIter = NULL; if ((fExportData != null) && (fExportData->fModelsToExport != null)) modelsToExportIter = (fExportData->fModelsToExport)->elements(); // PROGRESS NOTIFICATION if (modelsToExportIter && (modelsToExportIter->hasMoreElements()) && (fExportData->fMessageCallback != NULL)) { KBLoadString(IDS_PROGRESS_EXPORT_DOCUMENTS_EXPORT,statusStr); /* int resVal = */(fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); } if (modelsToExportIter && modelsToExportIter->hasMoreElements()) { TObjectModel* objToExport = (TObjectModel *)modelsToExportIter->nextElement(); ASSERT(objToExport->isInstanceOf(T_BOOK_MODEL_NAME)); TBookModel* bookToExport = (TBookModel *)objToExport; // PROGRESS NOTIFICATION reportCurrentGlobalPercentage(1,0.0f); if (fExportData->fExportOutputFileFormat == TExportData::EXE_FILE_FORMAT) { // PROGRESS NOTIFICATION if (fExportData->fMessageCallback != NULL) { KBLoadString(IDS_PROGRESS_EXPORT_AUTOEXTRACTABLE_CREATION,statusStr); /* int resVal = */(fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); } CString lPreBundledZipFilePath = pInFileName; CString lBookTitle; CString lMainHTMLFileName; CString lDataFolderRelativePath; CString lShortcutIconFileName; lBookTitle = bookToExport->getName(); TPath::ReplaceForbiddenCharsInFileName(lBookTitle, CString(_T('_'))); KBLoadString(IDS_APB_MAIN_HTML_FILE_NAME_INDEX_HTML,lMainHTMLFileName); KBLoadString(IDS_APB_HTML_DATA_RELATIVE_PATH,lDataFolderRelativePath); KBLoadString(IDS_APB_SHORTCUT_ICON_FILE_NAME,lShortcutIconFileName); #ifndef ALLOW_WEB_EXE TAutoExtractableCreationData pData; pData.fZipFilePath = lPreBundledZipFilePath; pData.fExeFilePath = fOutputFileName; pData.fPathCompliantBookTitle = lBookTitle; pData.fMainHTMLFileName = lMainHTMLFileName; pData.fDataFolderRelativePath = lDataFolderRelativePath; pData.fShortcutIconFileName = lShortcutIconFileName; res &= exportBook_createAutoextractableFile(&pData); #else res &= exportBook_createAutoextractableFile(lPreBundledZipFilePath, lMainHTMLFileName); #endif } else if (fExportData->fExportOutputFileFormat == TExportData::ZIP_FILE_FORMAT) { CString lPreBundledZipFilePath = pInFileName; TRY { CFile::Rename(lPreBundledZipFilePath,fOutputFileName); res = true; } CATCH (CFileException, e) { res = false; } END_CATCH // PROGRESS NOTIFICATION (just to be sure) reportCurrentGlobalPercentage(2,1.0f); } else { ASSERT(NULL); } } delete modelsToExportIter; // PROGRESS NOTIFICATION { reportCurrentGlobalPercentage(1,1.0f); // We don't use the Progress Bar Control anymore if (fExportData->fMessageCallback != NULL) { (void) (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_EXIT_USE_PROGRESS_BAR,0,0,NULL,NULL,(fExportData->fMessageCallbackData)); } } // PROGRESS NOTIFICATION : The End if (fExportData && (fExportData->fMessageCallback != NULL)) { KBLoadString(IDS_PROGRESS_EXPORT_END,statusStr); /* int resVal = */(fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); } return res; } void TDHTMLKeeBookExportEngine::exportBook_initProgressHelper() { fLastReportedPercentage = 0; if (fExportData->fExportOutputFileFormat == TExportData::EXE_FILE_FORMAT) { // Phase 1 -> All the handlePage processing // Phase 2 -> handleBundledFiles // Phase 3 -> createAutoextractableFile int lPhase1TotalPercentage = 70; int lPhase2TotalPercentage = 10; int lPhase3TotalPercentage = 20; fProgressHelper->setPhaseCount(3); fProgressHelper->setTotalPercentageForPhase(1,lPhase1TotalPercentage); fProgressHelper->setTotalPercentageForPhase(2,lPhase2TotalPercentage); fProgressHelper->setTotalPercentageForPhase(3,lPhase3TotalPercentage); } else if (fExportData->fExportOutputFileFormat == TExportData::ZIP_FILE_FORMAT) { // Phase 1 -> All the handlePage processing // Phase 2 -> handleBundledFiles int lPhase1TotalPercentage = 75; int lPhase2TotalPercentage = 25; fProgressHelper->setPhaseCount(2); fProgressHelper->setTotalPercentageForPhase(1,lPhase1TotalPercentage); fProgressHelper->setTotalPercentageForPhase(2,lPhase2TotalPercentage); } else if (fExportData->fExportOutputFileFormat == TExportData::HTML_FILE_FORMAT) { // Phase 1 -> All the handlePage processing int lPhase1TotalPercentage = 100; fProgressHelper->setPhaseCount(1); fProgressHelper->setTotalPercentageForPhase(1,lPhase1TotalPercentage); } else { ASSERT(NULL); } } void TDHTMLKeeBookExportEngine::exportZipToExe_initProgressHelper() { fLastReportedPercentage = 0; if (fExportData->fExportOutputFileFormat == TExportData::EXE_FILE_FORMAT) { // Phase 1 -> createAutoextractableFile int lPhase1TotalPercentage = 100; fProgressHelper->setPhaseCount(1); fProgressHelper->setTotalPercentageForPhase(1,lPhase1TotalPercentage); } else if (fExportData->fExportOutputFileFormat == TExportData::ZIP_FILE_FORMAT) { // Phase 1 -> "rename input file to output file" int lPhase1TotalPercentage = 100; fProgressHelper->setPhaseCount(1); fProgressHelper->setTotalPercentageForPhase(1,lPhase1TotalPercentage); } else { ASSERT(NULL); } } boolean TDHTMLKeeBookExportEngine::exportBook_preFillExportProcessingData(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; CString lAuthorName; CString lAuthorEmail; TModelPtr pBookAuthorProperty; pBookAuthorProperty = (TPropertyObjectModel *)pBookModel->getProperty(T_BOOK_AUTHOR_PROPERTY); if( pBookAuthorProperty != NULL) { pBookAuthorProperty->getStringField(T_BOOK_AUTHOR_PROPERTY_NAME, &lAuthorName); pBookAuthorProperty->getStringField(T_BOOK_AUTHOR_PROPERTY_EMAIL, &lAuthorEmail); } CString lBookTitle = pBookModel->getName(); long lBookCasePos = 0; long lBookShelfPos = 0; { TModelPtr lShelf; pBookModel->getParent((TMediaContainerModel**)&lShelf); if (lShelf) { TModelPtr lCase; lShelf->getParent((TGenericContainerModel**)&lCase); if (lCase) { lBookCasePos = lCase->getLocation(); } lBookShelfPos = lShelf->getLocation(); } } CString lBookId = getAutorunBookID(pBookModel); // might become later the BookModel Book ID... long lBookStyle = pBookModel->getBookStyle(); float lBookPos = pBookModel->getLocation(); pExportProcessingData->fBookTitle = lBookTitle; pExportProcessingData->fBookCasePos = lBookCasePos; pExportProcessingData->fBookShelfPos = lBookShelfPos; pExportProcessingData->fBookId = lBookId; pExportProcessingData->fBookStyle = lBookStyle; pExportProcessingData->fBookPos = lBookPos; pExportProcessingData->fAuthorName = lAuthorName; pExportProcessingData->fAuthorEmail = lAuthorEmail; return bResult; } CString TDHTMLKeeBookExportEngine::getDragJSFileSourceCode() { AFX_MANAGE_STATE(AfxGetAppModuleState()) THTMLString lDragJSFileString; lDragJSFileString.LoadString(IDR_HTML_WEBBOOK_CONTENTS_DRAG_JS_FILE); // Let's remove the Copyright comment part CString lCommentBeginPattern( _T("/*") ); CString lCommentEndPattern( _T("*/") ); CString lCommentCopyrightPattern( _T("copyright") ); CString lDragJSFileLowerCaseString = lDragJSFileString; lDragJSFileLowerCaseString.MakeLower(); int lCopyrightComment_BeginPos = lDragJSFileLowerCaseString.Find( lCommentBeginPattern ); if ( lCopyrightComment_BeginPos >= 0) { int lCopyrightComment_EndPos = lDragJSFileLowerCaseString.Find( lCommentEndPattern ); if ( (lCopyrightComment_EndPos >= 0) && (lCopyrightComment_EndPos > lCopyrightComment_BeginPos) ) { // Here we have found '/* ... */' // Let's just check it is the Copyright comment int lCopyrightComment_CopyrightPos = lDragJSFileLowerCaseString.Find( lCommentCopyrightPattern ); if ( (lCopyrightComment_CopyrightPos >= 0) && (lCopyrightComment_CopyrightPos > lCopyrightComment_BeginPos) && (lCopyrightComment_CopyrightPos < lCopyrightComment_EndPos) ) { // Yeah! Gotcha! CString lDragJSFileSourceCode = lDragJSFileString.Left( lCopyrightComment_BeginPos ); lDragJSFileSourceCode += lDragJSFileString.Mid( lCopyrightComment_EndPos + lCommentEndPattern.GetLength() ); return lDragJSFileSourceCode; } } } return lDragJSFileString; } CString TDHTMLKeeBookExportEngine::getDragCSSFileSourceCode() { AFX_MANAGE_STATE(AfxGetAppModuleState()) THTMLString lDragCSSFileString; lDragCSSFileString.LoadString(IDR_HTML_WEBBOOK_CONTENTS_DRAG_CSS_FILE); // Let's remove the Copyright comment part CString lCommentBeginPattern( _T("/*") ); CString lCommentEndPattern( _T("*/") ); CString lCommentCopyrightPattern( _T("copyright") ); CString lDragCSSFileLowerCaseString = lDragCSSFileString; lDragCSSFileLowerCaseString.MakeLower(); int lCopyrightComment_BeginPos = lDragCSSFileLowerCaseString.Find( lCommentBeginPattern ); if ( lCopyrightComment_BeginPos >= 0) { int lCopyrightComment_EndPos = lDragCSSFileLowerCaseString.Find( lCommentEndPattern ); if ( (lCopyrightComment_EndPos >= 0) && (lCopyrightComment_EndPos > lCopyrightComment_BeginPos) ) { // Here we have found '/* ... */' // Let's just check it is the Copyright comment int lCopyrightComment_CopyrightPos = lDragCSSFileLowerCaseString.Find( lCommentCopyrightPattern ); if ( (lCopyrightComment_CopyrightPos >= 0) && (lCopyrightComment_CopyrightPos > lCopyrightComment_BeginPos) && (lCopyrightComment_CopyrightPos < lCopyrightComment_EndPos) ) { // Yeah! Gotcha! CString lDragCSSFileSourceCode = lDragCSSFileString.Left( lCopyrightComment_BeginPos ); lDragCSSFileSourceCode += lDragCSSFileString.Mid( lCopyrightComment_EndPos + lCommentEndPattern.GetLength() ); return lDragCSSFileSourceCode; } } } return lDragCSSFileString; } boolean TDHTMLKeeBookExportEngine::exportBook_handleShortcutIconFileGeneration() { boolean bResult = true; if (getExportData()->fExportDestination != TExportData::WEB_DESTINATION) { AFX_MANAGE_STATE(AfxGetAppModuleState()) CString lShortcutIconRandomFileName; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".ico"),lShortcutIconRandomFileName); writeResourceToFile( MAKEINTRESOURCE(IDR_APB_SHORTCUT_ICON_ICON_DATA), _T("ICON_DATA"), lShortcutIconRandomFileName); CString lDataRelativePath; KBLoadString(IDS_APB_HTML_DATA_RELATIVE_PATH,lDataRelativePath); lDataRelativePath += _T('\\'); CString lShortcutIconFileName; KBLoadString(IDS_APB_SHORTCUT_ICON_FILE_NAME,lShortcutIconFileName); CString lShortcutIconFileRelativePath; lShortcutIconFileRelativePath += lDataRelativePath; lShortcutIconFileRelativePath += lShortcutIconFileName; fArchiveNamesMgr->addFileToBundle(lShortcutIconRandomFileName, lShortcutIconFileRelativePath); } return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleImportToKeeBooFileGeneration() { boolean bResult = true; if (getExportData()->fExportDestination != TExportData::WEB_DESTINATION) { CString lImportToKeeBooFileName; KBLoadString(IDS_WEBBOOK_REGISTRATOR_AFTER_SUCCESS_IMPORT_TO_KEEBOO_FILE,lImportToKeeBooFileName); CString randomFileName; TPath::CreateRandomFilePath(this->getWorkingDirectory(), _T(".7xe"),randomFileName); TRY { CFile importToKeeBooFile(randomFileName, CFile::modeCreate | CFile::modeWrite); // Let's get some parameters CString lParametersString = getImportToKeeBooFileParameters(); importToKeeBooFile.Write(lParametersString.GetBuffer(1), lParametersString.GetLength()); importToKeeBooFile.Flush(); importToKeeBooFile.Close(); } CATCH(CFileException, e) { } END_CATCH CString lImportToKeeBooRelativePath = lImportToKeeBooFileName; fArchiveNamesMgr->addFileToBundle(randomFileName, lImportToKeeBooRelativePath); } return bResult; } CString TDHTMLKeeBookExportEngine::getImportToKeeBooFileParameters() { CString lMainHTMLFileName; if ( (getExportData()->fExportOutputFileFormat == TExportData::ZIP_FILE_FORMAT) || (getExportData()->fExportOutputFileFormat == TExportData::EXE_FILE_FORMAT) ) KBLoadString(IDS_APB_MAIN_HTML_FILE_NAME_INDEX_HTML,lMainHTMLFileName); else if (getExportData()->fExportOutputFileFormat == TExportData::HTML_FILE_FORMAT) lMainHTMLFileName = fOutputFileName; else ASSERT(FALSE); CString lDataRelativePath; KBLoadString(IDS_APB_HTML_DATA_RELATIVE_PATH,lDataRelativePath); CString lParametersString; lParametersString += _T("type="); lParametersString += _T("dynamic"); lParametersString += _T("\r\n"); lParametersString += _T("mainfile="); lParametersString += lMainHTMLFileName; lParametersString += _T("\r\n"); lParametersString += _T("contentfolder="); lParametersString += lDataRelativePath; lParametersString += _T("\r\n"); return lParametersString; } boolean TDHTMLKeeBookExportEngine::exportBook_handleBranding(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; CString lDataRelativePath; KBLoadString(IDS_APB_HTML_DATA_RELATIVE_PATH,lDataRelativePath); lDataRelativePath += _T('\\'); /*******************/ /** LOGO BRANDING **/ /*******************/ TBrandingGenerationData lLogoBrandingGenerationData; lLogoBrandingGenerationData.fBrandingType = E_BRANDING_TYPE_LOGO; lLogoBrandingGenerationData.fExportProcessingData = pExportProcessingData; bResult &= exportBook_handleBrandingType(pBookModel, &lLogoBrandingGenerationData); // Let's update the fields we are able to update in the TExportProcessingData // struct pExportProcessingData->fLogoBrandingImageRelativePath = _T(""); if (!(lLogoBrandingGenerationData.fBrandingImagePathInArchive).IsEmpty()) { CString lResRelativePath; TPath::GetRelativeFilePath(lDataRelativePath, lLogoBrandingGenerationData.fBrandingImagePathInArchive, lResRelativePath); pExportProcessingData->fLogoBrandingImageRelativePath = lResRelativePath; pExportProcessingData->fLogoBrandingImageRedirectUrl = lLogoBrandingGenerationData.fBrandingImageRedirectUrl; pExportProcessingData->fLogoBrandingImageSize = lLogoBrandingGenerationData.fBrandingImageSize; } /*********************/ /** BANNER BRANDING **/ /*********************/ TBrandingGenerationData lBannerBrandingGenerationData; lBannerBrandingGenerationData.fBrandingType = E_BRANDING_TYPE_BANNER; lBannerBrandingGenerationData.fExportProcessingData = pExportProcessingData; bResult &= exportBook_handleBrandingType(pBookModel, &lBannerBrandingGenerationData); // Let's update the fields we are able to update in the TExportProcessingData // struct pExportProcessingData->fBannerBrandingImageRelativePath = _T(""); if (!(lBannerBrandingGenerationData.fBrandingImagePathInArchive).IsEmpty()) { CString lResRelativePath; TPath::GetRelativeFilePath(lDataRelativePath, lBannerBrandingGenerationData.fBrandingImagePathInArchive, lResRelativePath); pExportProcessingData->fBannerBrandingImageRelativePath = lResRelativePath; pExportProcessingData->fBannerBrandingImageRedirectUrl = lBannerBrandingGenerationData.fBrandingImageRedirectUrl; pExportProcessingData->fBannerBrandingImageSize = lBannerBrandingGenerationData.fBrandingImageSize; } /********************/ /** INDEX BRANDING **/ /********************/ TBrandingGenerationData lIndexBrandingGenerationData; lIndexBrandingGenerationData.fBrandingType = E_BRANDING_TYPE_INDEX; lIndexBrandingGenerationData.fExportProcessingData = pExportProcessingData; bResult &= exportBook_handleBrandingType(pBookModel, &lIndexBrandingGenerationData); // Let's update the fields we are able to update in the TExportProcessingData // struct pExportProcessingData->fIndexBrandingImageRelativePath = _T(""); if (!(lIndexBrandingGenerationData.fBrandingImagePathInArchive).IsEmpty()) { CString lResRelativePath; TPath::GetRelativeFilePath(lDataRelativePath, lIndexBrandingGenerationData.fBrandingImagePathInArchive, lResRelativePath); pExportProcessingData->fIndexBrandingImageRelativePath = lResRelativePath; pExportProcessingData->fIndexBrandingImageRedirectUrl = lIndexBrandingGenerationData.fBrandingImageRedirectUrl; pExportProcessingData->fIndexBrandingImageSize = lIndexBrandingGenerationData.fBrandingImageSize; } return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleBrandingType(TBookModel* pBookModel, TBrandingGenerationData* pBrandingGenerationData) { // This should be overriden by subclasses... ATLASSERT(FALSE); return false; } boolean TDHTMLKeeBookExportEngine::exportBook_handleBrandingType_DynamicBranding(TBookModel* pBookModel, TBrandingGenerationData* pBrandingGenerationData) { boolean bResult = true; CString lBrandingImageUrl; CString lBrandingImageRedirectUrl; CSize lBrandingImageSize; TDynamicExportBrandingGenerator lBrandingInfoGenerator(pBookModel); // I ask the branding control informations about the branding image it displays if (!lBrandingInfoGenerator.IsExportingLogo(pBrandingGenerationData->fBrandingType)) return true; { lBrandingImageSize = lBrandingInfoGenerator.GetImageSize(pBrandingGenerationData->fBrandingType); } { CString lBrandingImageUrlPath; boolean bRes = lBrandingInfoGenerator.GetFileImageSourceSpecs( pBrandingGenerationData->fBrandingType, &lBrandingImageUrlPath); if (bRes) { // Let's check that the lBrandingImageUrlPath source spec is an URL if (lBrandingImageUrlPath.Find( _T("://") ) > 0 ) { lBrandingImageUrl = lBrandingImageUrlPath; // Let's then add the missing parameters: // WebBookID // MediaID // ExpImgWidth: Needed to keep exported image size specs at import time (retrieved by parsing urls in KBSetBranding params...) // ExpImgHeight: Idem lBrandingImageUrl += _T("&WebBookID="); lBrandingImageUrl += getAutorunBookID(pBookModel); /* lBrandingImageUrl += _T("&MediaID="); lBrandingImageUrl += _T("KeeBook"); */ if ( (lBrandingImageSize.cx > 0) && (lBrandingImageSize.cy > 0) ) { CString lBrandingImage_ImageWidth; CString lBrandingImage_ImageHeight; { CString lIntToStrTemplate(_T("%1!d!")); lBrandingImage_ImageWidth.FormatMessage(lIntToStrTemplate,lBrandingImageSize.cx); lBrandingImage_ImageHeight.FormatMessage(lIntToStrTemplate,lBrandingImageSize.cy); } lBrandingImageUrl += _T("&ExpImgWidth="); lBrandingImageUrl += lBrandingImage_ImageWidth; lBrandingImageUrl += _T("&ExpImgHeight="); lBrandingImageUrl += lBrandingImage_ImageHeight; } } } } { lBrandingImageRedirectUrl = lBrandingInfoGenerator.GetRedirect(pBrandingGenerationData->fBrandingType); // Let's then add the missing parameters: // WebBookID // MediaID // ExpImgWidth: Needed to keep exported image size specs at import time (retrieved by parsing urls in KBSetBranding params...) // ExpImgHeight: Idem lBrandingImageRedirectUrl += _T("&WebBookID="); lBrandingImageRedirectUrl += getAutorunBookID(pBookModel); /* lBrandingImageRedirectUrl += _T("&MediaID="); lBrandingImageRedirectUrl += _T("KeeBook"); */ if ( (lBrandingImageSize.cx > 0) && (lBrandingImageSize.cy > 0) ) { CString lBrandingImage_ImageWidth; CString lBrandingImage_ImageHeight; { CString lIntToStrTemplate(_T("%1!d!")); lBrandingImage_ImageWidth.FormatMessage(lIntToStrTemplate,lBrandingImageSize.cx); lBrandingImage_ImageHeight.FormatMessage(lIntToStrTemplate,lBrandingImageSize.cy); } lBrandingImageRedirectUrl += _T("&ExpImgWidth="); lBrandingImageRedirectUrl += lBrandingImage_ImageWidth; lBrandingImageRedirectUrl += _T("&ExpImgHeight="); lBrandingImageRedirectUrl += lBrandingImage_ImageHeight; } } // Let's update the fields we are able to update in the TBrandingGenerationData // struct pBrandingGenerationData->fBrandingImagePathInArchive = _T(""); if (!lBrandingImageUrl.IsEmpty()) { pBrandingGenerationData->fBrandingImagePathInArchive = lBrandingImageUrl; } pBrandingGenerationData->fBrandingImageRedirectUrl = _T(""); if (!lBrandingImageRedirectUrl.IsEmpty()) { pBrandingGenerationData->fBrandingImageRedirectUrl = lBrandingImageRedirectUrl; } pBrandingGenerationData->fBrandingImageSize = lBrandingImageSize; return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleBrandingType_StaticBranding(TBookModel* pBookModel, TBrandingGenerationData* pBrandingGenerationData) { boolean bResult = true; CString lBrandingImagePathInArchive; CString lBrandingImageRedirectUrl; CSize lBrandingImageSize; TAutoRunBrandingGenerator lBrandingInfoGenerator(pBookModel); // I ask the branding control informations about the branding image it displays if (!lBrandingInfoGenerator.IsExportingLogo(pBrandingGenerationData->fBrandingType)) return true; { lBrandingImageSize = lBrandingInfoGenerator.GetImageSize(pBrandingGenerationData->fBrandingType); } { TSystemMimeHelper* lMimeHelper = new TSystemMimeHelper(); if (lBrandingInfoGenerator.IsResImageSource(pBrandingGenerationData->fBrandingType)) { long lBrandingImageResourceType = 0; CString lBrandingImageResourceID; CString lBrandingImageMimeType; boolean bRes = lBrandingInfoGenerator.GetResImageSourceSpecs( pBrandingGenerationData->fBrandingType, &lBrandingImageResourceID, &lBrandingImageResourceType, &lBrandingImageMimeType); if (bRes) { ASSERT(!lBrandingImageResourceID.IsEmpty()); ASSERT(lBrandingImageResourceType); ASSERT(!lBrandingImageMimeType.IsEmpty()); // First, let's compute the branding image file extension CString lBrandingImageExtension; if (lBrandingImageMimeType.IsEmpty()) { // Let's put a default extension (gif) and hope that the browser will be smart enough // to correct it if it isn't the right one !!! lBrandingImageMimeType = _T("image/gif"); } lMimeHelper->getFirstFileExtensionsFromMimeType(lBrandingImageMimeType, lBrandingImageExtension); // Then, let's load the branding image resource and save it to a file CString lBrandingImageLocalFilePath; TPath::CreateRandomFilePath(this->getWorkingDirectory(), lBrandingImageExtension,lBrandingImageLocalFilePath); BOOL lCopyResult; lCopyResult = lBrandingInfoGenerator.CopyResourceToFile(lBrandingImageResourceID, MAKEINTRESOURCE(lBrandingImageResourceType), lBrandingImageLocalFilePath); if (lCopyResult) { // The file is new, so we force a new archive name creation fArchiveNamesMgr->createNewArchivePath( lBrandingImageLocalFilePath, lBrandingImageMimeType, TDHTMLArchiveNamesManager::ARCHIVE_FILE_TYPE_UNKNOWN, lBrandingImagePathInArchive ); fArchiveNamesMgr->addFileToBundle(lBrandingImageLocalFilePath, lBrandingImagePathInArchive); } } } else { CString lBrandingImageFilePath; CString lBrandingImageMimeType; boolean bRes = lBrandingInfoGenerator.GetFileImageSourceSpecs( pBrandingGenerationData->fBrandingType, &lBrandingImageFilePath); if (bRes) { CString strLocalFileName; // {PS} the following line is needed for the cache check !!! CString lBrandingImageFilePathUrl = TSevenixUrl(lBrandingImageFilePath, 0).extendedUrlString(); boolean bFileInfoRes = getLocalFileInfoFromUrl(lBrandingImageFilePathUrl,strLocalFileName,lBrandingImageMimeType); if (bFileInfoRes && (!strLocalFileName.IsEmpty())) { if (lBrandingImageMimeType.IsEmpty()) { CString lBrandingImageFilePathExtension; TPath::FindExtension(strLocalFileName, lBrandingImageFilePathExtension); if (!lBrandingImageFilePathExtension.IsEmpty()) { lMimeHelper->getFirstMimeTypeFromFileExtension(lBrandingImageFilePathExtension,lBrandingImageMimeType); } else { // Let's put a default extension (gif) and hope that the browser will be smart enough // to correct it if it isn't the right one !!! lBrandingImageMimeType = _T("image/gif"); } } // The file might already be in our bundle, so let's take our chance fArchiveNamesMgr->getArchiveFilePath( lBrandingImageFilePath, lBrandingImageMimeType, TDHTMLArchiveNamesManager::ARCHIVE_FILE_TYPE_UNKNOWN, lBrandingImagePathInArchive ); fArchiveNamesMgr->addFileToBundle(strLocalFileName, lBrandingImagePathInArchive); } } } delete lMimeHelper; lMimeHelper = NULL; } { lBrandingImageRedirectUrl = lBrandingInfoGenerator.GetRedirect(pBrandingGenerationData->fBrandingType); // Let's then add the missing parameters: // ExpImgWidth: Needed to keep exported image size specs at import time (retrieved by parsing urls in KBSetBranding params...) // ExpImgHeight: Idem if ( (lBrandingImageSize.cx > 0) && (lBrandingImageSize.cy > 0) ) { CString lBrandingImage_ImageWidth; CString lBrandingImage_ImageHeight; { CString lIntToStrTemplate(_T("%1!d!")); lBrandingImage_ImageWidth.FormatMessage(lIntToStrTemplate,lBrandingImageSize.cx); lBrandingImage_ImageHeight.FormatMessage(lIntToStrTemplate,lBrandingImageSize.cy); } lBrandingImageRedirectUrl += _T("&ExpImgWidth="); lBrandingImageRedirectUrl += lBrandingImage_ImageWidth; lBrandingImageRedirectUrl += _T("&ExpImgHeight="); lBrandingImageRedirectUrl += lBrandingImage_ImageHeight; } } // Let's update the fields we are able to update in the TBrandingGenerationData // struct pBrandingGenerationData->fBrandingImagePathInArchive = _T(""); if (!lBrandingImagePathInArchive.IsEmpty()) { pBrandingGenerationData->fBrandingImagePathInArchive = lBrandingImagePathInArchive; } else { // We must export images unless the branding does not want to... // Therefore let's export current hosting KeeBoo branding characteristics by default. return exportBook_handleBrandingType(NULL, pBrandingGenerationData); } pBrandingGenerationData->fBrandingImageRedirectUrl = _T(""); if (!lBrandingImageRedirectUrl.IsEmpty()) { pBrandingGenerationData->fBrandingImageRedirectUrl = lBrandingImageRedirectUrl; } pBrandingGenerationData->fBrandingImageSize = lBrandingImageSize; return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handlePagesBeforeSummary(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; // The AUTHOR page bResult = exportBook_handleAuthorPage(pBookModel,pExportProcessingData); return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleAuthorPage(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; CString lLocalFileName; TSystemMimeHelper* lMimeHelper = new TSystemMimeHelper(); CString lDataRelativePath; KBLoadString(IDS_APB_HTML_DATA_RELATIVE_PATH,lDataRelativePath); lDataRelativePath += _T('\\'); CString lPhotoBaseName; KBLoadString(IDS_APB_AUTHOR_PAGE_AUTHOR_PHOTO_BASE_NAME,lPhotoBaseName); // Let's compute the author's image file extension CString lAuthorPhotoExtension; TModelPtr pBookAuthorProperty; pBookModel->getProperty(T_BOOK_AUTHOR_PROPERTY, &pBookAuthorProperty); if( pBookAuthorProperty != NULL) { CString lAuthorPhotoUrl; pBookAuthorProperty->getStringField(T_BOOK_AUTHOR_PROPERTY_PHOTO, &lAuthorPhotoUrl); if (!lAuthorPhotoUrl.IsEmpty()) { CString strLocalFileName; CString strLocalFileMime; // {PS} the following line is needed for the cache check !!! lAuthorPhotoUrl = TSevenixUrl(lAuthorPhotoUrl, 0).extendedUrlString(); boolean bFileInfoRes = getLocalFileInfoFromUrl(lAuthorPhotoUrl,strLocalFileName,strLocalFileMime); if (bFileInfoRes) { // BEB - 30/07/99 - I commented out the following test because if the MIME I get for a JPEG // file is 'image/jpg', I wouldn't export it. I could have added the specific test, but as I don't // know in advance the various possible MIMEs, I do prefer export any file format I get here since it // shouldn't be different from GIF or JPEG... /* if ( (strLocalFileMime.CompareNoCase(_T("image/gif")) == 0) || (strLocalFileMime.CompareNoCase(_T("image/jpeg")) == 0)) { */ lLocalFileName = strLocalFileName; lMimeHelper->getFirstFileExtensionsFromMimeType(strLocalFileMime,lAuthorPhotoExtension); /* } */ } } } boolean bPhotoFileExists = true; if (lLocalFileName.IsEmpty()) { CString lImageGifMime("image/gif"); // Let's put a default image (gif) lMimeHelper->getFirstFileExtensionsFromMimeType(lImageGifMime, lAuthorPhotoExtension); // Let's save the image in the fWorkingDirectory CString randomFileName; TPath::CreateRandomFilePath(this->getWorkingDirectory(), lAuthorPhotoExtension,randomFileName); if (FAILED(writeResourceToFile(MAKEINTRESOURCE(IDG_TRANSPARENT_LOGO), RT_HTML, randomFileName))) bPhotoFileExists = false; lLocalFileName = randomFileName; } CString lAuthorPhotoRelativePath; lAuthorPhotoRelativePath += lDataRelativePath; lAuthorPhotoRelativePath += lPhotoBaseName; lAuthorPhotoRelativePath += lAuthorPhotoExtension; if (bPhotoFileExists) { fArchiveNamesMgr->addFileToBundle(lLocalFileName, lAuthorPhotoRelativePath); } // Let's update the fields we are able to update in the TExportProcessingData // struct CString lAuthorPhotoFileName; lAuthorPhotoFileName += lPhotoBaseName; lAuthorPhotoFileName += lAuthorPhotoExtension; pExportProcessingData->fAuthorPhotoRelativePath = lAuthorPhotoFileName; delete lMimeHelper; lMimeHelper = NULL; return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleRegularPages(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; // PROGRESS STUFF fTotalPageCount = pBookModel->getPageCount(); fCurrentlyHandledPageCount = 0; TModelPtr pSummary; pSummary = pBookModel->getSummary(); if (pSummary) { bResult = exportBook_handlePage(pSummary,pExportProcessingData); } return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handlePage(TPageModel* pPageModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; // PROGRESS NOTIFICATION if (fExportData && (fExportData->fMessageCallback != NULL)) { CString statusStr; CString pageTitle = pPageModel->getTitle(); TModelPtr book; pPageModel->getBook(&book); if (book) { CString bookTitle = book->getName(); CString statusStrTemplate; KBLoadString(IDS_PROGRESS_EXPORT_PAGE_OF_TITLE_IN_BOOK,statusStrTemplate); statusStr.FormatMessage(statusStrTemplate, (LPCTSTR)bookTitle, (LPCTSTR)pageTitle); } else { CString statusStrTemplate; KBLoadString(IDS_PROGRESS_EXPORT_PAGE_OF_TITLE,statusStrTemplate); statusStr.FormatMessage(statusStrTemplate, (LPCTSTR)pageTitle); } /* int resVal = */(fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); } // PROGRESS NOTIFICATION reportCurrentGlobalPercentage(1,((float)fCurrentlyHandledPageCount)/((float)fTotalPageCount)); fCurrentlyHandledPageCount++; // WARNING : // The order of the following tests is VERY important. It has to be // from the most derived class to the class which is the closest // to the TObjectModel base class if (pPageModel->isInstanceOf(T_CHAPTER_MODEL_NAME)) { bResult = exportBook_handleChapterPage(pPageModel,pExportProcessingData); } else if (pPageModel->isInstanceOf(T_PAGE_MODEL_NAME)) { bResult = exportBook_handleContentPage(pPageModel,pExportProcessingData); } return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleChapterPage(TPageModel* pPageModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; if (!pPageModel->isInstanceOf(T_CHAPTER_MODEL_NAME)) return false; AFX_MANAGE_STATE(AfxGetAppModuleState()) TChapterModel* lChapterModel = (TChapterModel*)pPageModel; boolean bChapterIsSummary = lChapterModel->isInstanceOf(T_SUMMARY_MODEL_NAME); /******************/ /** PUSH CHAPTER **/ /******************/ if (!bChapterIsSummary) { CString lChapterMainPageTitle = lChapterModel->getTitle(); CString lKBScriptPushChapterTemplate; KBLoadString(IDS_WEBBOOK_KBSCRIPT_PUSH_CHAPTER_TEMPLATE,lKBScriptPushChapterTemplate); VERIFY(!lKBScriptPushChapterTemplate.IsEmpty()); // To suit javascript requirements, let's replace special characters this->formatDisplayStringForJavascript(lChapterMainPageTitle); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... CString lCompletedKBScriptPushChapter; lCompletedKBScriptPushChapter = lKBScriptPushChapterTemplate; lCompletedKBScriptPushChapter.Replace( _T("%kb_param_1%"), lChapterMainPageTitle); pExportProcessingData->fPageListBuffer->writeString(lCompletedKBScriptPushChapter); } // Then I put my children into the process TModelIterator* lPagesIter; lPagesIter = pPageModel->getPages(); while (lPagesIter && lPagesIter->hasMoreElements()) { TModelPtr lCurPage; lPagesIter->nextElement((TObjectModel**)&lCurPage); bResult &= exportBook_handlePage(lCurPage,pExportProcessingData); } delete lPagesIter; /*****************/ /** POP CHAPTER **/ /*****************/ if (!bChapterIsSummary) { CString lKBScriptPopChapterTemplate; KBLoadString(IDS_WEBBOOK_KBSCRIPT_POP_CHAPTER_TEMPLATE,lKBScriptPopChapterTemplate); VERIFY(!lKBScriptPopChapterTemplate.IsEmpty()); CString lCompletedKBScriptPopChapter = lKBScriptPopChapterTemplate; pExportProcessingData->fPageListBuffer->writeString(lCompletedKBScriptPopChapter); } return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleContentPage(TPageModel* pPageModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; // First I deal with myself BOOL bPageHasPostContent = hasPagePostContent(pPageModel); if (!bPageHasPostContent) { exportBook_handleHTMLPageProcessing( pPageModel, pExportProcessingData); // Then I put my children into the process TModelIterator* lPagesIter = pPageModel->getPages(); while (lPagesIter && lPagesIter->hasMoreElements()) { TModelPtr lCurPage; lPagesIter->nextElement((TObjectModel**)&lCurPage); bResult &= exportBook_handlePage(lCurPage,pExportProcessingData); } delete lPagesIter; } return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleHTMLPageProcessing(TPageModel* pPageModel, TExportProcessingData* pExportProcessingData) { // This should be overriden by subclasses... ATLASSERT(FALSE); return false; } boolean TDHTMLKeeBookExportEngine::exportBook_handleHTMLPageProcessing_PictureCase(TPageModel* pPageModel, TExportProcessingData* pExportProcessingData) { TModelPtr lContentModel; lContentModel = pPageModel->getContent(); if (!lContentModel) return false; CString sevenixUrl = lContentModel->getUrl(); boolean bIsExportLight = !getExportData()->fExportWithContent; if (bIsExportLight) { TUrl lUrl(sevenixUrl); CString lLocalPath; boolean bContentIsLocal = isUrlLocalFile(lUrl.simpleUrlString(), lLocalPath); if (bContentIsLocal) { // light + local => add local doc to bundle CString strLocalFileName; CString strLocalFileMime; boolean bFileInfoRes = this->getLocalFileInfoFromUrl(sevenixUrl,strLocalFileName,strLocalFileMime); if ( !bFileInfoRes || (strLocalFileName.IsEmpty()) ) { // Where is the doc??? Error... ASSERT(FALSE); return false; } else { if (strLocalFileMime.IsEmpty()) { CString lUrlFile = TUrl(sevenixUrl).getFile(); CString lImageFileExtension; TPath::FindExtension( lUrlFile , lImageFileExtension ); if (!lImageFileExtension.IsEmpty()) { TSystemMimeHelper* lSystemMimeHelper = new TSystemMimeHelper(); lSystemMimeHelper->getFirstMimeTypeFromFileExtension(lImageFileExtension,strLocalFileMime); } } CString lPathInArchiveRes; // The file is new, so we force a new archive name creation fArchiveNamesMgr->createNewArchivePath( sevenixUrl, strLocalFileMime, TDHTMLArchiveNamesManager::ARCHIVE_FILE_TYPE_IMAGE, lPathInArchiveRes ); fArchiveNamesMgr->addFileToBundle(strLocalFileName, lPathInArchiveRes, sevenixUrl); CFileStatus lStatus; if (m_bFatImage && CFile::GetStatus(strLocalFileName, lStatus)) { if (lStatus.m_size > (200 * 1024)) { TErr::trace(TErr::D_BOX, TErr::G_WAR|TErr::G_REMOVE, IDS_ERR_IMAGE_SIZE, __FILE__, __LINE__, lUrl.getFile()); m_bFatImage = FALSE; } } return exportBook_handleHTMLPageProcessing_PictureCase_HandleWriteScripts(pPageModel,pExportProcessingData,lPathInArchiveRes); } } else // !bContentIsLocal { return exportBook_handleHTMLPageProcessing_PictureCase_HandleWriteScripts(pPageModel,pExportProcessingData,_T("")); } } else // !bIsExportLight { CString strLocalFileName; CString strLocalFileMime; boolean bFileInfoRes = this->getLocalFileInfoFromUrl(sevenixUrl,strLocalFileName,strLocalFileMime); if ( !bFileInfoRes || (strLocalFileName.IsEmpty()) ) { // full + distant => just make it point on the distant image return exportBook_handleHTMLPageProcessing_PictureCase_HandleWriteScripts(pPageModel,pExportProcessingData,_T("")); } else { if (strLocalFileMime.IsEmpty()) { CString lUrlFile = TUrl(sevenixUrl).getFile(); CString lImageFileExtension; TPath::FindExtension( lUrlFile , lImageFileExtension ); if (!lImageFileExtension.IsEmpty()) { TSystemMimeHelper* lSystemMimeHelper = new TSystemMimeHelper(); lSystemMimeHelper->getFirstMimeTypeFromFileExtension(lImageFileExtension,strLocalFileMime); } } CString lPathInArchiveRes; // The file is new, so we force a new archive name creation fArchiveNamesMgr->createNewArchivePath( sevenixUrl, strLocalFileMime, TDHTMLArchiveNamesManager::ARCHIVE_FILE_TYPE_IMAGE, lPathInArchiveRes ); fArchiveNamesMgr->addFileToBundle(strLocalFileName, lPathInArchiveRes, sevenixUrl); return exportBook_handleHTMLPageProcessing_PictureCase_HandleWriteScripts(pPageModel,pExportProcessingData,lPathInArchiveRes); } } return false; } boolean TDHTMLKeeBookExportEngine::exportBook_handleHTMLPageProcessing_PictureCase_HandleWriteScripts(TPageModel* pPageModel, TExportProcessingData* pExportProcessingData, CString pGeneratedFilePathInArchive) { TModelPtr lContentModel; lContentModel = pPageModel->getContent(); if (!lContentModel) return false; CString lContentPageUrl = TUrl(lContentModel->getUrl()).simpleUrlString(); CString lLocalPath; boolean bContentIsLocal = isUrlLocalFile(lContentPageUrl, lLocalPath); if (bContentIsLocal) { // We won't put the URL in the insert_picture call because it makes no sense lContentPageUrl = _T(""); } CString lContentPageTitle = pPageModel->getTitle(); boolean bPageIsQualified = false; { // Picture are exported as image files, which means we cannot save an HTML DOM, // which means we won't export highlighers... boolean bDoExportAnnotations_Sticker = getExportData()->fExportAnnotationStickers; // boolean bDoExportAnnotations_Highlighter = false; TModelIterator* lAnnotationsIter = pPageModel->getAnnotations(); while (lAnnotationsIter && lAnnotationsIter->hasMoreElements()) { TModelPtr lCurAnnotation; lAnnotationsIter->nextElement((TObjectModel **)&lCurAnnotation); if (bDoExportAnnotations_Sticker && lCurAnnotation->isInstanceOf(T_STICKER_MODEL_NAME)) { bPageIsQualified = true; break; } /* else if (bDoExportAnnotations_Highlighter && lCurAnnotation->isInstanceOf(T_HIGHLIGHTER_MODEL_NAME)) { bPageIsQualified = true; break; } */ } delete lAnnotationsIter; } boolean bPictureShouldFitToPage = getExportData()->fExportPicturesFitToPage; CString lKBScriptInsertPictureTemplate; KBLoadString(IDS_WEBBOOK_KBSCRIPT_INSERT_PICTURE_TEMPLATE,lKBScriptInsertPictureTemplate); VERIFY(!lKBScriptInsertPictureTemplate.IsEmpty()); CString lKBInsertPicture_FileName; CString lKBInsertPicture_PictureUrl; getKBInsertPictureParameters(pGeneratedFilePathInArchive, lContentPageUrl, lKBInsertPicture_FileName, lKBInsertPicture_PictureUrl); // BG627 - BG642 // Browser may have problems navigating urls with decoded % because they think it // prefixes some encoded entity (%25, %27...) if ( TPath::IsURL( lKBInsertPicture_PictureUrl ) ) { TUrl lUrl(lKBInsertPicture_PictureUrl); if (lUrl.getScheme() == "http") { lUrl.canonicalize(ICU_BROWSER_MODE|ICU_DECODE|ICU_NO_ENCODE); lUrl.canonicalize(ICU_BROWSER_MODE|ICU_ENCODE_PERCENT); } lKBInsertPicture_PictureUrl = lUrl.simpleUrlString(FALSE); } // To suit javascript requirements, let's replace special characters this->formatPathStringForJavascript(lKBInsertPicture_FileName); this->formatPathStringForJavascript(lKBInsertPicture_PictureUrl); this->formatDisplayStringForJavascript(lContentPageTitle); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... CString lCompletedKBScriptInsertPicture; lCompletedKBScriptInsertPicture = lKBScriptInsertPictureTemplate; lCompletedKBScriptInsertPicture.Replace( _T("%kb_param_1%"), lContentPageTitle); lCompletedKBScriptInsertPicture.Replace( _T("%kb_param_2%"), lKBInsertPicture_FileName); lCompletedKBScriptInsertPicture.Replace( _T("%kb_param_3%"), lKBInsertPicture_PictureUrl); lCompletedKBScriptInsertPicture.Replace( _T("%kb_param_4%"), (bPageIsQualified ? T_JAVASCRIPT_TRUE : T_JAVASCRIPT_FALSE)); lCompletedKBScriptInsertPicture.Replace( _T("%kb_param_5%"), T_JAVASCRIPT_NULL); lCompletedKBScriptInsertPicture.Replace( _T("%kb_param_6%"), T_JAVASCRIPT_NULL); lCompletedKBScriptInsertPicture.Replace( _T("%kb_param_7%"), T_JAVASCRIPT_NULL); lCompletedKBScriptInsertPicture.Replace( _T("%kb_param_8%"), (bPictureShouldFitToPage ? T_JAVASCRIPT_TRUE : T_JAVASCRIPT_FALSE)); pExportProcessingData->fPageListBuffer->writeString(lCompletedKBScriptInsertPicture); // ***************************************** // And now, let's handle STICKER annotations // ***************************************** if (bPageIsQualified) { boolean bDoExportAnnotations_Sticker = getExportData()->fExportAnnotationStickers; TModelIterator* lAnnotationsIter = pPageModel->getAnnotations(); while (lAnnotationsIter && lAnnotationsIter->hasMoreElements()) { TModelPtr lCurAnnotation; lAnnotationsIter->nextElement((TObjectModel **)&lCurAnnotation); if (bDoExportAnnotations_Sticker && lCurAnnotation->isInstanceOf(T_STICKER_MODEL_NAME)) { TModelPtr lSticker; lSticker = (TStickerModel *)lCurAnnotation.p; CString lStickerText = lSticker->getTextContent(); // Let's format the TEXT for the Javascript... lStickerText.Replace(_T("\r\n\r\n"),_T(" ")); lStickerText.Replace(_T("\n\r\n\r"),_T(" ")); lStickerText.Replace(_T("\r\n"),_T(" ")); lStickerText.Replace(_T("\n\r"),_T(" ")); this->formatDisplayStringForJavascript(lStickerText); CPoint lPoint; lPoint = (CPoint)lSticker->getPosition(); CSize lSize; lSize = (CSize)lSticker->getSize(); CComBSTR lColorStringBSTR; TDomAnnotationManager::TranslateColor(lSticker->getColor(),&lColorStringBSTR); CString lColorString = CString(lColorStringBSTR); CString lKBScriptAddStickerTemplate; KBLoadString(IDS_WEBBOOK_KBSCRIPT_ADD_STICKER_TEMPLATE,lKBScriptAddStickerTemplate); VERIFY(!lKBScriptAddStickerTemplate.IsEmpty()); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... CString lIntToStrTemplate(_T("%1!d!")); CString lPointXStr; lPointXStr.FormatMessage(lIntToStrTemplate,lPoint.x); CString lPointYStr; lPointYStr.FormatMessage(lIntToStrTemplate,lPoint.y); CString lSizeCxStr; lSizeCxStr.FormatMessage(lIntToStrTemplate,lSize.cx); CString lSizeCyStr; lSizeCyStr.FormatMessage(lIntToStrTemplate,lSize.cy); CString lCompletedKBScriptAddSticker; lCompletedKBScriptAddSticker = lKBScriptAddStickerTemplate; lCompletedKBScriptAddSticker.Replace( _T("%kb_param_1%"), lStickerText); lCompletedKBScriptAddSticker.Replace( _T("%kb_param_2%"), lPointXStr); lCompletedKBScriptAddSticker.Replace( _T("%kb_param_3%"), lPointYStr); lCompletedKBScriptAddSticker.Replace( _T("%kb_param_4%"), lSizeCxStr); lCompletedKBScriptAddSticker.Replace( _T("%kb_param_5%"), lSizeCyStr); lCompletedKBScriptAddSticker.Replace( _T("%kb_param_6%"), lColorString); pExportProcessingData->fPageListBuffer->writeString(lCompletedKBScriptAddSticker); } } delete lAnnotationsIter; } return true; } void TDHTMLKeeBookExportEngine::getKBInsertPictureParameters(CString pGeneratedFilePathInArchive, CString pContentPageUrl, CString& pFileName, CString& pPictureUrl) { // This should be overriden by subclasses... ATLASSERT(FALSE); } boolean TDHTMLKeeBookExportEngine::exportBook_handleHTMLPageProcessing_RegularCase(TPageModel* pPageModel, TExportProcessingData* pExportProcessingData) { TModelPtr lContentModel; pPageModel->getContent(&lContentModel); if (!lContentModel) return false; boolean bDealWithRealDoc = false; CString sevenixUrl = lContentModel->getUrl(); boolean bIsExportLight = !getExportData()->fExportWithContent; TUrl lUrl(sevenixUrl); CString lLocalPath; boolean bContentIsLocal = isUrlLocalFile(lUrl.simpleUrlString(), lLocalPath); if (bContentIsLocal) { // light + local => add local doc to bundle CString strLocalFileName; CString strLocalFileMime; boolean bFileInfoRes = getLocalFileInfoFromUrl(sevenixUrl,strLocalFileName,strLocalFileMime); if (bFileInfoRes && !strLocalFileName.IsEmpty() ) bDealWithRealDoc = true; else { // Where is the doc??? Error... ASSERT(FALSE); return false; } } else // !bContentIsLocal { if (!bIsExportLight) { CString strLocalFileName; CString strLocalFileMime; boolean bFileInfoRes = getLocalFileInfoFromUrl(sevenixUrl,strLocalFileName,strLocalFileMime); if (bFileInfoRes && !strLocalFileName.IsEmpty() ) bDealWithRealDoc = true; } } CString lPathInArchiveRes; // This is here only for not repeating code several times... if (bDealWithRealDoc) { // Let's deal with real doc to have it and its sub-items put in our file bundle boolean bIsSpecialCase_EmbedFormatPage = isEmbedFormatFile(sevenixUrl); if (bIsSpecialCase_EmbedFormatPage) { // This file is an embedded multimedia format file, so let's generate a // special page CString lPathInArchiveRes; boolean bResEmbed = exportBook_handleEmbedFormatPage( pPageModel->getTitle(), sevenixUrl, lPathInArchiveRes ); if (!bResEmbed) { ASSERT(FALSE); return false; } // Write scripts return exportBook_handleHTMLPageProcessing_RegularCase_HandleWriteScripts(pPageModel,pExportProcessingData,lPathInArchiveRes); } // Now, we are in the nothing-could-be-more-regular case // Navigate on doc /* boolean bResNavigation = */ exportBook_handleHTMLPageProcessing_RegularCase_Navigate(pPageModel,pExportProcessingData,lPathInArchiveRes); // Write scripts } return exportBook_handleHTMLPageProcessing_RegularCase_HandleWriteScripts(pPageModel,pExportProcessingData,lPathInArchiveRes); } boolean TDHTMLKeeBookExportEngine::exportBook_handleEmbedFormatPage(CString pPageTitle, CString pPageUrl, CString& pPathInArchiveRes) { // This should be overriden by subclasses... ATLASSERT(FALSE); return false; } boolean TDHTMLKeeBookExportEngine::exportBook_handleHTMLPageProcessing_RegularCase_Navigate(TPageModel* pPageModel, TExportProcessingData* pExportProcessingData, CString& pGeneratedFilePathInArchive) { BOOL bResult = FALSE; TModelPtr lContentModel; pPageModel->getContent(&lContentModel); if (!lContentModel) return FALSE; CString sevenixUrl = lContentModel->getUrl(); // It may be a user preference, but currently we don't want the export // processing to try to connect itself to the internet for items not available // in the cache store. // Therefore, let's add an info to the URL in order to tell the protocol // not to connect itself to the internet : T_NO_RELOAD_PROPERTY TUrl lNoConnectSevenixUrl(sevenixUrl); TSevenixUrlInfo* lInfo = NULL; lInfo = (TSevenixUrlInfo*)lNoConnectSevenixUrl.getExtendedInfo(); ASSERT(lInfo); // lInfo->addProperty(T_NO_RELOAD_PROPERTY); // lInfo->addProperty(T_ROOT_PROPERTY); CString lNoConnectSevenixUrlString = lNoConnectSevenixUrl.extendedUrlString(); THTMLProcessingEngine *pHTMLProcessingEngine; pHTMLProcessingEngine = new THTMLProcessingEngine; if ( SUCCEEDED( pHTMLProcessingEngine->Init( lNoConnectSevenixUrlString/*sevenixUrl*/ ))) { TProcessDomCallbackData lProcessDomData; lProcessDomData.fThis = this; lProcessDomData.fPageModel = pPageModel; lProcessDomData.fExportProcessingData = pExportProcessingData; TStringToStringHashTable* lTable; lTable = new TStringToStringHashTable(); lProcessDomData.fChildrenUrlToRelativePathTable = lTable; pHTMLProcessingEngine->Run( &TDHTMLKeeBookExportEngine::ProcessDom, &TDHTMLKeeBookExportEngine::ProcessDom_handleHighlighters, (void* FAR)&lProcessDomData ); // Let's see what I have in my hashtable #if defined(_DEBUG) && defined(_DHTML_EXPORT_TRACE) TStringIterator* lKeysIter = lTable->keys(); while (lKeysIter && lKeysIter->hasMoreElements()) { CString curKey = lKeysIter->nextElement(); CString curValue = lTable->get(curKey); TRACE2("TDHTMLDynamicKeeBookExportEngine::handleHTMLPageProcessing_RegularCase_Navigate - key : [%s] - value : [%s]\n",curKey,curValue); } delete lKeysIter; #endif CString lNormalizedSevenixUrl; lNormalizedSevenixUrl = TUrl::canonicalizedUrlString(lNoConnectSevenixUrlString, true); CString lRelativeFilePathNormalSize = lTable->get(lNormalizedSevenixUrl); if (lRelativeFilePathNormalSize.IsEmpty()) { bResult = FALSE; } if (lTable) { delete lTable; lTable = null; } // Results pGeneratedFilePathInArchive = lRelativeFilePathNormalSize; bResult = TRUE; } else { bResult = FALSE; } if (pHTMLProcessingEngine) delete pHTMLProcessingEngine; return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleHTMLPageProcessing_RegularCase_HandleWriteScripts(TPageModel* pPageModel, TExportProcessingData* pExportProcessingData, CString pGeneratedFilePathInArchive) { TModelPtr lContentModel; lContentModel = pPageModel->getContent(); if (!lContentModel) return false; CString lRelativeFilePathNormalSize = pGeneratedFilePathInArchive; CString lContentPageUrl = TUrl(lContentModel->getUrl()).simpleUrlString(); CString lLocalPath; boolean bContentIsLocal = isUrlLocalFile(lContentPageUrl, lLocalPath); if (bContentIsLocal) { // We won't put the URL in the insert_page call because it makes no sense lContentPageUrl = _T(""); } CString lContentPageTitle = pPageModel->getTitle(); boolean bPageIsQualified = false; { boolean bDoExportAnnotations_Sticker = getExportData()->fExportAnnotationStickers; boolean bDoExportAnnotations_Highlighter = getExportData()->fExportAnnotationHighlighters; TModelIterator* lAnnotationsIter = pPageModel->getAnnotations(); while (lAnnotationsIter && lAnnotationsIter->hasMoreElements()) { TModelPtr lCurAnnotation; lAnnotationsIter->nextElement((TObjectModel **)&lCurAnnotation); if (bDoExportAnnotations_Sticker && lCurAnnotation->isInstanceOf(T_STICKER_MODEL_NAME)) { bPageIsQualified = true; break; } else if (bDoExportAnnotations_Highlighter && lCurAnnotation->isInstanceOf(T_HIGHLIGHTER_MODEL_NAME)) { bPageIsQualified = true; break; } } delete lAnnotationsIter; } CString lKBScriptInsertPageTemplate; KBLoadString(IDS_WEBBOOK_KBSCRIPT_INSERT_PAGE_TEMPLATE,lKBScriptInsertPageTemplate); VERIFY(!lKBScriptInsertPageTemplate.IsEmpty()); CString lCompletedKBScriptInsertPage; boolean bIsExportLight = !getExportData()->fExportWithContent; if (bIsExportLight) { if (!lRelativeFilePathNormalSize.IsEmpty()) { // The paths we put in the 'links' template are relative // to the 'IDS_APB_HTML_DATA_RELATIVE_PATH' folder, and // as the relative paths we got here are relative to the // root folder, we should normally recompute the relative paths... // BUT, in the Dynamic KeeBook with attached content files case, we // let the path relative to the root folder. lContentPageUrl = lRelativeFilePathNormalSize; lContentPageUrl.Replace(_T("\\"),_T("/")); } // BG627 - BG642 // Browser may have problems navigating urls with decoded % because they think it // prefixes some encoded entity (%25, %27...) if ( TPath::IsURL( lContentPageUrl ) ) { TUrl lUrl(lContentPageUrl); if (lUrl.getScheme() == "http") { lUrl.canonicalize(ICU_BROWSER_MODE|ICU_DECODE|ICU_NO_ENCODE); lUrl.canonicalize(ICU_BROWSER_MODE|ICU_ENCODE_PERCENT); } lContentPageUrl = lUrl.simpleUrlString(FALSE); } // To suit javascript requirements, let's replace special characters this->formatPathStringForJavascript(lContentPageUrl); this->formatDisplayStringForJavascript(lContentPageTitle); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptInsertPage = lKBScriptInsertPageTemplate; lCompletedKBScriptInsertPage.Replace( _T("%kb_param_1%"), lContentPageTitle); lCompletedKBScriptInsertPage.Replace( _T("%kb_param_2%"), _T("")); lCompletedKBScriptInsertPage.Replace( _T("%kb_param_3%"), lContentPageUrl); lCompletedKBScriptInsertPage.Replace( _T("%kb_param_4%"), ( ( bPageIsQualified && (!lRelativeFilePathNormalSize.IsEmpty()) ) ? T_JAVASCRIPT_TRUE:T_JAVASCRIPT_FALSE)); } else { // The paths we put in the 'links' template are relative // to the 'IDS_APB_HTML_DATA_RELATIVE_PATH' folder, and // as the relative paths we got here are relative to the // root folder, we have to recompute the relative paths... CString lDataRelativePath; KBLoadString(IDS_APB_HTML_DATA_RELATIVE_PATH,lDataRelativePath); lDataRelativePath += _T('\\'); CString lResRelativePath; TPath::GetRelativeFilePath(lDataRelativePath, lRelativeFilePathNormalSize, lResRelativePath); lRelativeFilePathNormalSize = lResRelativePath; lRelativeFilePathNormalSize.Replace(_T("\\"),_T("/")); // BG627 - BG642 // Browser may have problems navigating urls with decoded % because they think it // prefixes some encoded entity (%25, %27...) if ( TPath::IsURL( lContentPageUrl ) ) { TUrl lUrl(lContentPageUrl); if (lUrl.getScheme() == "http") { lUrl.canonicalize(ICU_BROWSER_MODE|ICU_DECODE|ICU_NO_ENCODE); lUrl.canonicalize(ICU_BROWSER_MODE|ICU_ENCODE_PERCENT); } lContentPageUrl = lUrl.simpleUrlString(FALSE); } // To suit javascript requirements, let's replace special characters this->formatPathStringForJavascript(lRelativeFilePathNormalSize); this->formatPathStringForJavascript(lContentPageUrl); this->formatDisplayStringForJavascript(lContentPageTitle); lCompletedKBScriptInsertPage = lKBScriptInsertPageTemplate; lCompletedKBScriptInsertPage.Replace( _T("%kb_param_1%"), lContentPageTitle); lCompletedKBScriptInsertPage.Replace( _T("%kb_param_2%"), lRelativeFilePathNormalSize); lCompletedKBScriptInsertPage.Replace( _T("%kb_param_3%"), lContentPageUrl); lCompletedKBScriptInsertPage.Replace( _T("%kb_param_4%"), ( ( bPageIsQualified && (!lRelativeFilePathNormalSize.IsEmpty()) ) ? T_JAVASCRIPT_TRUE:T_JAVASCRIPT_FALSE)); } pExportProcessingData->fPageListBuffer->writeString(lCompletedKBScriptInsertPage); return true; } boolean TDHTMLKeeBookExportEngine::exportBook_handlePagesAfterSummaryPages(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; // The INDEX page bResult = exportBook_handleIndexPage(pBookModel,pExportProcessingData); return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleIndexPage(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; // Nothing to do... return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_handleParamsJSFileGeneration(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { ATLASSERT(FALSE); return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { boolean bResult = true; TFinalizeExportProcessingData* lFinalizeExportProcessingData = new TFinalizeExportProcessingData(); lFinalizeExportProcessingData->fExportProcessingData = pExportProcessingData; // For the AUTHOR PAGE bResult &= exportBook_finalizeExportProcessingData_KBSetAuthor(pBookModel, lFinalizeExportProcessingData); // For the BOOK TITLE bResult &= exportBook_finalizeExportProcessingData_KBSetTitle(pBookModel, lFinalizeExportProcessingData); // For the BOOK ID bResult &= exportBook_finalizeExportProcessingData_KBSetBookId(pBookModel, lFinalizeExportProcessingData); // For the Default Skin bResult &= exportBook_finalizeExportProcessingData_KBSetSkin(pBookModel, lFinalizeExportProcessingData); // For the Default Language bResult &= exportBook_finalizeExportProcessingData_KBSetLanguage(pBookModel, lFinalizeExportProcessingData); // For the BRANDING bResult &= exportBook_finalizeExportProcessingData_KBSetBranding(pBookModel, lFinalizeExportProcessingData); // For the Audience // bResult &= exportBook_finalizeExportProcessingData_KBSetAudience(pBookModel, lFinalizeExportProcessingData); // For the Flip Page Mode bResult &= exportBook_finalizeExportProcessingData_KBSetFlipPageMode(pBookModel, lFinalizeExportProcessingData); // For the Flip Animation bResult &= exportBook_finalizeExportProcessingData_KBSetFlipAnimation(pBookModel, lFinalizeExportProcessingData); // For the Toobar disabled bResult &= exportBook_finalizeExportProcessingData_KBDisableToolbar(pBookModel, lFinalizeExportProcessingData); //**************** // Let's now handle B2B specific instructions //**************** // I search "b2b" in the lower-cased BrandingLicense string, just in case the BrandingLicense string // is not just "B2B"... CString lBrandingLicense = getBrandingLicense(); lBrandingLicense.MakeLower(); if (lBrandingLicense.Find( _T("b2b") ) != -1) { fExportData->fExportDisablePrivatePage = TRUE; fExportData->fExportDisableSourcePage = TRUE; // For Set System Pages Urls bResult &= exportBook_finalizeExportProcessingData_KBSetSystemPageUrl_B2B(pBookModel, lFinalizeExportProcessingData); } // For Disable System Pages bResult &= exportBook_finalizeExportProcessingData_KBDisableSystemPage_B2B(pBookModel, lFinalizeExportProcessingData); // Buffered links and tabs lists CString lPageListBuffer; lPageListBuffer = (lFinalizeExportProcessingData->fExportProcessingData->fPageListBuffer)->getBuffer(); // For the ... tag CString lHtmlPageTitleLocalized; KBLoadString(IDS_DYNAMIC_KEEBOOK_HTML_PAGE_TITLE_LOCALIZED, lHtmlPageTitleLocalized); // For the <META NAME="keywords"... tag CString lMetaKeywords; KBLoadString(IDS_META_KEYWORDS_LOCALIZED, lMetaKeywords); GetStringDefaultProperty<TBookModel>(pBookModel, T_BOOK_DEFAULT_PROPERTY_META_KEYWORDS, lMetaKeywords); // For the GeneratorXXX variables CString lGeneratorProductName; CString lGeneratorProductVersion; CString lGeneratorProductFullString; CString lGeneratorProductQualifier; { TAppVersionInfo lVersionInfo; lGeneratorProductName = lVersionInfo.GetProductName(); lGeneratorProductVersion = lVersionInfo.GetProductID(); lGeneratorProductQualifier = lVersionInfo.GetProductQualifier(); lGeneratorProductFullString = lGeneratorProductName; lGeneratorProductFullString += _T("® "); lGeneratorProductFullString += lGeneratorProductVersion; lGeneratorProductFullString += _T(" "); lGeneratorProductFullString += lGeneratorProductQualifier; } // For the User ID (AuthorUser) // (in case the book has no User ID, we take the one of the current user) CString lUserId; { lUserId = getBookUserID(pBookModel); if (lUserId.IsEmpty()) lUserId = getUserID(); } // For the Partner ID (AuthorPartner) // (in case the book has no Partner ID, we take the one of the application) CString lPartnerId; { lPartnerId = getBookPartnerID(pBookModel); if (lPartnerId.IsEmpty()) lPartnerId = getPartnerID(); } // For the Reader ID (ReaderUser) CString lReaderUser; { lReaderUser = _T("{00000000-0000-0000-0000-000000001784}"); } // For the Engine Site Url CString lKeeBookEnginePath; lKeeBookEnginePath = getKBScriptingEnginePathValue(); // For the Scripting Engine type CString lKeeBookScriptingEngine; lKeeBookScriptingEngine = getKBScriptingScriptingEngineValue(); // For the branding ASP with all parameters CString lGetBrandingDescrFileUrl; lGetBrandingDescrFileUrl = getKBScriptingBrandingDescrFileUrl(pBookModel); // For the <BODY><NOSCRIPT>... tag CString lHtmlPageBodyNoScriptContentLocalized; KBLoadString(IDS_DYNAMIC_KEEBOOK_BODY_NOSCRIPT_CONTENT_LOCALIZED, lHtmlPageBodyNoScriptContentLocalized); THTMLString lCompletedMainFileTemplate; lCompletedMainFileTemplate.LoadString(IDR_HTML_DYNAMIC_KEEBOOK_MAIN_FILE_TEMPLATE); lCompletedMainFileTemplate.Replace( _T("%KB_HEAD_TITLE_CONTENT_PARAM%"), lHtmlPageTitleLocalized); lCompletedMainFileTemplate.Replace( _T("%KB_META_KEYWORDS_PARAM%"), lMetaKeywords); lCompletedMainFileTemplate.Replace( _T("%KB_GENERATOR_PARAM%"), lGeneratorProductFullString); lCompletedMainFileTemplate.Replace( _T("%KB_ENGINE_PATH_PARAM%"), lKeeBookEnginePath); lCompletedMainFileTemplate.Replace( _T("%KB_SCRIPTING_ENGINE_PARAM%"), lKeeBookScriptingEngine); lCompletedMainFileTemplate.Replace( _T("%KB_AUTHOR_USER_PARAM%"), lUserId); lCompletedMainFileTemplate.Replace( _T("%KB_AUTHOR_PARTNER_PARAM%"), lPartnerId); lCompletedMainFileTemplate.Replace( _T("%KB_READER_USER_PARAM%"), lReaderUser); lCompletedMainFileTemplate.Replace( _T("%KB_WEBBOOK_ENGINE_VERSION_PARAM%"), WEBBOOK_ENGINE_VERSION); lCompletedMainFileTemplate.Replace( _T("%KB_WEBBOOK_KEEBOO_MINIMUM_VERSION_PARAM%"),WEBBOOK_KEEBOO_MINIMUM_VERSION); lCompletedMainFileTemplate.Replace( _T("%KB_GENERATOR_PRODUCT_PARAM%"), lGeneratorProductName); lCompletedMainFileTemplate.Replace( _T("%KB_GENERATOR_VERSION_PARAM%"), lGeneratorProductVersion); lCompletedMainFileTemplate.Replace( _T("%KB_GENERATOR_PRODUCT_QUALIFIER%"), lGeneratorProductQualifier); lCompletedMainFileTemplate.Replace( _T("%KB_WEBBOOK_TEMPLATE_VERSION_PARAM%"), WEBBOOK_TEMPLATE_VERSION); lCompletedMainFileTemplate.Replace( _T("%KB_SET_AUTHOR_PARAM%"), lFinalizeExportProcessingData->fKBSetAuthor); lCompletedMainFileTemplate.Replace( _T("%KB_SET_TITLE_PARAM%"), lFinalizeExportProcessingData->fKBSetTitle); lCompletedMainFileTemplate.Replace( _T("%KB_SET_BOOK_ID_PARAM%"), lFinalizeExportProcessingData->fKBSetBookId); lCompletedMainFileTemplate.Replace( _T("%KB_SET_SKIN_PARAM%"), lFinalizeExportProcessingData->fKBSetSkin); lCompletedMainFileTemplate.Replace( _T("%KB_SET_LANGUAGE_PARAM%"), lFinalizeExportProcessingData->fKBSetLanguage); lCompletedMainFileTemplate.Replace( _T("%KB_SET_BRANDING_PARAM%"), lFinalizeExportProcessingData->fKBSetBranding); // lCompletedMainFileTemplate.Replace( _T("%KB_SET_AUDIENCE_PARAM%"), lFinalizeExportProcessingData->fKBSetAudience); lCompletedMainFileTemplate.Replace( _T("%KB_SET_FLIP_PAGE_MODE_PARAM%"), lFinalizeExportProcessingData->fKBSetFlipPageMode); lCompletedMainFileTemplate.Replace( _T("%KB_SET_FLIP_ANIMATION_PARAM%"), lFinalizeExportProcessingData->fKBSetFlipAnimation); lCompletedMainFileTemplate.Replace( _T("%KB_SET_SYSTEM_PAGE_URL_PARAM%"), lFinalizeExportProcessingData->fKBSetSystemPageUrl); lCompletedMainFileTemplate.Replace( _T("%KB_DISABLE_SYSTEM_PAGE_PARAM%"), lFinalizeExportProcessingData->fKBDisableSystemPage); lCompletedMainFileTemplate.Replace( _T("%KB_DISABLE_TOOLBAR_PARAM%"), lFinalizeExportProcessingData->fKBDisableToolbar); lCompletedMainFileTemplate.Replace( _T("%KB_INSERT_PAGES_CHAPTERS_PARAM%"), lPageListBuffer); lCompletedMainFileTemplate.Replace( _T("%KB_GET_BRANDING_DESCR_FILE_URL_PARAM%"), lGetBrandingDescrFileUrl); lCompletedMainFileTemplate.Replace( _T("%KB_BODY_NOSCRIPT_CONTENT_PARAM%"), lHtmlPageBodyNoScriptContentLocalized); // *** // Let's write everything // *** CString randomFileName; TPath::CreateRandomFilePath(getWorkingDirectory(), _T(".htm"),randomFileName); TRY { CFile jsFile(randomFileName, CFile::modeCreate | CFile::modeWrite); jsFile.Write(lCompletedMainFileTemplate.GetBuffer(1), lCompletedMainFileTemplate.GetLength()); jsFile.Flush(); jsFile.Close(); } CATCH(CFileException, e) { bResult = false; } END_CATCH if ( (getExportData()->fExportOutputFileFormat == TExportData::ZIP_FILE_FORMAT) || (getExportData()->fExportOutputFileFormat == TExportData::EXE_FILE_FORMAT) ) { CString lMainHtmlFileRelativePath; KBLoadString(IDS_APB_MAIN_HTML_FILE_NAME_INDEX_HTML,lMainHtmlFileRelativePath); fArchiveNamesMgr->addFileToBundle(randomFileName, lMainHtmlFileRelativePath); if (getExportData()->fExportDestination == TExportData::WEB_DESTINATION) { CString lMainHtmlFileRelativePath_WebVariations; KBLoadString(IDS_APB_MAIN_HTML_FILE_NAME_INDEX_HTM,lMainHtmlFileRelativePath_WebVariations); fArchiveNamesMgr->addFileToBundle(randomFileName, lMainHtmlFileRelativePath_WebVariations); KBLoadString(IDS_APB_MAIN_HTML_FILE_NAME_DEFAULT_HTM,lMainHtmlFileRelativePath_WebVariations); fArchiveNamesMgr->addFileToBundle(randomFileName, lMainHtmlFileRelativePath_WebVariations); KBLoadString(IDS_APB_MAIN_HTML_FILE_NAME_DEFAULT_HTML,lMainHtmlFileRelativePath_WebVariations); fArchiveNamesMgr->addFileToBundle(randomFileName, lMainHtmlFileRelativePath_WebVariations); } } else if (getExportData()->fExportOutputFileFormat == TExportData::HTML_FILE_FORMAT) { // This is the single HTML file we want to export... this->setDynamicKeeBookMainHTMLOutputFilePath(pExportProcessingData, randomFileName); } else { ASSERT(FALSE); } if (lFinalizeExportProcessingData) { delete lFinalizeExportProcessingData; lFinalizeExportProcessingData = NULL; } return bResult; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetAuthor(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { // This should be overriden by subclasses... ATLASSERT(FALSE); return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetTitle(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lBookTitle((LPCTSTR)lExportProcessingData->fBookTitle); this->formatDisplayStringForJavascript(lBookTitle); CString lKBScriptSetTitleTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_SET_TITLE_TEMPLATE,lKBScriptSetTitleTemplate); VERIFY(!lKBScriptSetTitleTemplate.IsEmpty()); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... CString lCompletedKBScriptSetTitle; lCompletedKBScriptSetTitle = lKBScriptSetTitleTemplate; lCompletedKBScriptSetTitle.Replace( _T("%kb_param_1%"), lBookTitle); // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBSetTitle = lCompletedKBScriptSetTitle; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetBookId(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lKBScriptSetBookIdTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_SET_BOOKID_TEMPLATE,lKBScriptSetBookIdTemplate); VERIFY(!lKBScriptSetBookIdTemplate.IsEmpty()); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... CString lCompletedKBScriptSetBookId; lCompletedKBScriptSetBookId = lKBScriptSetBookIdTemplate; lCompletedKBScriptSetBookId.Replace( _T("%kb_param_1%"), lExportProcessingData->fBookId); // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBSetBookId = lCompletedKBScriptSetBookId; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetSkin(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { // TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lKBScriptSetSkinTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_SET_SKIN_TEMPLATE,lKBScriptSetSkinTemplate); VERIFY(!lKBScriptSetSkinTemplate.IsEmpty()); CString lCompletedKBScriptSetSkin; TLooksInfo lLooksInfo; CString lCurrentLook = (lLooksInfo.GetCurrentLook())->GetName(); lCurrentLook.MakeLower(); if (!lCurrentLook.IsEmpty()) { // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptSetSkin = lKBScriptSetSkinTemplate; lCompletedKBScriptSetSkin.Replace( _T("%kb_param_1%"), lCurrentLook); } // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBSetSkin = lCompletedKBScriptSetSkin; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetLanguage(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { // TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lKBScriptSetLanguageTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_SET_LANGUAGE_TEMPLATE,lKBScriptSetLanguageTemplate); VERIFY(!lKBScriptSetLanguageTemplate.IsEmpty()); CString lCompletedKBScriptSetLanguage; TLanguagesInfo lLanguagesInfo; CString lCurrentLanguage = (lLanguagesInfo.GetCurrentLanguage())->GetName(); lCurrentLanguage.MakeLower(); if (!lCurrentLanguage.IsEmpty()) { // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptSetLanguage = lKBScriptSetLanguageTemplate; lCompletedKBScriptSetLanguage.Replace( _T("%kb_param_1%"), lCurrentLanguage); } // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBSetLanguage = lCompletedKBScriptSetLanguage; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetBranding(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lBannerBrandingImageRelativePath((LPCTSTR)lExportProcessingData->fBannerBrandingImageRelativePath); this->formatPathStringForJavascript(lBannerBrandingImageRelativePath); CString lBannerBrandingImageRedirectUrl((LPCTSTR)lExportProcessingData->fBannerBrandingImageRedirectUrl); this->formatPathStringForJavascript(lBannerBrandingImageRedirectUrl); CString lLogoBrandingImageRelativePath((LPCTSTR)lExportProcessingData->fLogoBrandingImageRelativePath); this->formatPathStringForJavascript(lLogoBrandingImageRelativePath); CString lLogoBrandingImageRedirectUrl((LPCTSTR)lExportProcessingData->fLogoBrandingImageRedirectUrl); this->formatPathStringForJavascript(lLogoBrandingImageRedirectUrl); CString lIndexBrandingImageRelativePath((LPCTSTR)lExportProcessingData->fIndexBrandingImageRelativePath); this->formatPathStringForJavascript(lIndexBrandingImageRelativePath); CString lIndexBrandingImageRedirectUrl((LPCTSTR)lExportProcessingData->fIndexBrandingImageRedirectUrl); this->formatPathStringForJavascript(lIndexBrandingImageRedirectUrl); CString lKBScriptSetBrandingTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_SET_BRANDING_TEMPLATE,lKBScriptSetBrandingTemplate); VERIFY(!lKBScriptSetBrandingTemplate.IsEmpty()); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... CString lCompletedKBScriptSetBranding; lCompletedKBScriptSetBranding = lKBScriptSetBrandingTemplate; lCompletedKBScriptSetBranding.Replace( _T("%kb_param_1%"), lLogoBrandingImageRelativePath); lCompletedKBScriptSetBranding.Replace( _T("%kb_param_2%"), lLogoBrandingImageRedirectUrl); lCompletedKBScriptSetBranding.Replace( _T("%kb_param_3%"), lIndexBrandingImageRelativePath); lCompletedKBScriptSetBranding.Replace( _T("%kb_param_4%"), lIndexBrandingImageRedirectUrl); lCompletedKBScriptSetBranding.Replace( _T("%kb_param_5%"), lBannerBrandingImageRelativePath); lCompletedKBScriptSetBranding.Replace( _T("%kb_param_6%"), lBannerBrandingImageRedirectUrl); // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBSetBranding = lCompletedKBScriptSetBranding; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetAudience(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { // TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lKBScriptSetAudienceTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_SET_AUDIENCE_TEMPLATE,lKBScriptSetAudienceTemplate); VERIFY(!lKBScriptSetAudienceTemplate.IsEmpty()); CString lCompletedKBScriptSetAudience; { CString lActivateBookAudience; if ( getExportData()->fExportInsertAudienceWatchingCode ) { lActivateBookAudience = T_JAVASCRIPT_TRUE; } else { lActivateBookAudience = T_JAVASCRIPT_FALSE; } // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptSetAudience = lKBScriptSetAudienceTemplate; lCompletedKBScriptSetAudience.Replace( _T("%kb_param_1%"), lActivateBookAudience); } // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBSetAudience = lCompletedKBScriptSetAudience; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetFlipPageMode(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { // TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lKBScriptSetFlipPageModeTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_SET_FLIPPAGEMODE_TEMPLATE,lKBScriptSetFlipPageModeTemplate); VERIFY(!lKBScriptSetFlipPageModeTemplate.IsEmpty()); CString lCompletedKBScriptSetFlipPageMode; { CString lFlipPageMode; if ( getExportData()->fExportPageFlipMode == TExportData::TWO_BY_TWO_PAGE_FLIP_MODE ) { lFlipPageMode = _T("flipTwoPages"); } else { lFlipPageMode = _T("flipOnePage"); } // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptSetFlipPageMode = lKBScriptSetFlipPageModeTemplate; lCompletedKBScriptSetFlipPageMode.Replace( _T("%kb_param_1%"), lFlipPageMode); } // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBSetFlipPageMode = lCompletedKBScriptSetFlipPageMode; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetFlipAnimation(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { // TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lKBScriptSetFlipAnimationTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_SET_FLIPANIMATION_TEMPLATE,lKBScriptSetFlipAnimationTemplate); VERIFY(!lKBScriptSetFlipAnimationTemplate.IsEmpty()); CString lCompletedKBScriptSetFlipAnimation; { CString lFlipAnimation; if ( getExportData()->fExportFlipAnimation ) { lFlipAnimation = T_JAVASCRIPT_TRUE; } else { lFlipAnimation = T_JAVASCRIPT_FALSE; } // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptSetFlipAnimation = lKBScriptSetFlipAnimationTemplate; lCompletedKBScriptSetFlipAnimation.Replace( _T("%kb_param_1%"), lFlipAnimation); } // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBSetFlipAnimation = lCompletedKBScriptSetFlipAnimation; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBDisableToolbar(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { // TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lKBScriptDisableToolbarTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_DISABLE_TOOLBAR_TEMPLATE,lKBScriptDisableToolbarTemplate); VERIFY(!lKBScriptDisableToolbarTemplate.IsEmpty()); CString lCompletedKBScriptDisableToolbar; { CString lDisableToolbar; if ( getExportData()->fExportDisableToolbar) { lDisableToolbar = T_JAVASCRIPT_TRUE; } else { lDisableToolbar = T_JAVASCRIPT_FALSE; } // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptDisableToolbar = lKBScriptDisableToolbarTemplate; lCompletedKBScriptDisableToolbar.Replace( _T("%kb_param_1%"), lDisableToolbar); } // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBDisableToolbar = lCompletedKBScriptDisableToolbar; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBDisableSystemPage_B2B(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { // TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lKBScriptDisableSystemPageTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_DISABLE_SYSTEM_PAGE_TEMPLATE,lKBScriptDisableSystemPageTemplate); VERIFY(!lKBScriptDisableSystemPageTemplate.IsEmpty()); CString lCompletedKBScriptDisableSystemPage; if (fExportData->fExportDisablePrivatePage) { CString lCompletedKBScriptDisableSystemPage_private; CString lDisableSystemPage_private("private"); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptDisableSystemPage_private = lKBScriptDisableSystemPageTemplate; lCompletedKBScriptDisableSystemPage_private.Replace(_T("%kb_param_1%"), lDisableSystemPage_private); lCompletedKBScriptDisableSystemPage += lCompletedKBScriptDisableSystemPage_private; lCompletedKBScriptDisableSystemPage += _T("\r\n"); } if (fExportData->fExportDisableSourcePage) { CString lCompletedKBScriptDisableSystemPage_sources; CString lDisableSystemPage_sources("sources"); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptDisableSystemPage_sources = lKBScriptDisableSystemPageTemplate; lCompletedKBScriptDisableSystemPage_sources.Replace(_T("%kb_param_1%"), lDisableSystemPage_sources); lCompletedKBScriptDisableSystemPage += lCompletedKBScriptDisableSystemPage_sources; } // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBDisableSystemPage = lCompletedKBScriptDisableSystemPage; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeExportProcessingData_KBSetSystemPageUrl_B2B(TBookModel* pBookModel, TFinalizeExportProcessingData* pFinalizeExportProcessingData) { // TExportProcessingData* lExportProcessingData = pFinalizeExportProcessingData->fExportProcessingData; CString lKBScriptSetSystemPageUrlTemplate; KBLoadString(IDS_DYNAMIC_KEEBOOK_SET_SYSTEM_PAGE_URL_TEMPLATE,lKBScriptSetSystemPageUrlTemplate); VERIFY(!lKBScriptSetSystemPageUrlTemplate.IsEmpty()); CString lCompletedKBScriptSetSystemPageUrl; // BEB - We do not make it this way eventually. You may therefore remove this // code if you wish... /* { CString lSetSystemPageUrl_author("author"); CString lSetSystemPageUrl_url("EnginePath + \"systempages/author.htm?license=b2b\""); // Please do not use the win32 ::FormatMessage API because it does not handle parameters over 1024 characters on some platforms... lCompletedKBScriptSetSystemPageUrl = lKBScriptSetSystemPageUrlTemplate; lCompletedKBScriptSetSystemPageUrl.Replace( _T("%kb_param_1%"), lSetSystemPageUrl_author); lCompletedKBScriptSetSystemPageUrl.Replace( _T("%kb_param_2%"), lSetSystemPageUrl_url); } */ // Let's update the fields we are able to update in the TFinalizeExportProcessingData struct pFinalizeExportProcessingData->fKBSetSystemPageUrl = lCompletedKBScriptSetSystemPageUrl; return true; } boolean TDHTMLKeeBookExportEngine::exportBook_finalizeBundleFiles(TBookModel* pBookModel, TExportProcessingData* pExportProcessingData) { // This should be overriden by subclasses... ATLASSERT(FALSE); return false; } #ifdef ALLOW_WEB_EXE boolean TDHTMLKeeBookExportEngine::exportBook_createAutoextractableFile(LPCTSTR szZipFilePath, LPCTSTR szMainFile) { long lResult; // Let's create the exe file directory if not existing CString lExeFilePath = fOutputFileName ; if (PathRemoveFileSpec(lExeFilePath.GetBuffer(0)) ) { lExeFilePath.ReleaseBuffer(); TPath lPathHelper(lExeFilePath); BOOL lCreated = lPathHelper.CreateDirectory(); ASSERT(lCreated); } else { lExeFilePath.ReleaseBuffer(); } // Add main.conf and main.kbjs files CString lZipFilePath = szZipFilePath ; if (PathRemoveFileSpec(lZipFilePath.GetBuffer(0)) ) lZipFilePath.ReleaseBuffer(); CString lConfigFile(lZipFilePath); CString lScriptFile(lZipFilePath); ::PathAppend(lConfigFile.GetBufferSetLength(MAX_PATH), _T("main.kbconf")); ::PathAppend(lScriptFile.GetBufferSetLength(MAX_PATH), _T("main.kbjs")); boolean bResult = copyResourceData(IDR_EXE_MAIN_CONFIG, MAKEINTRESOURCE(RES_HTML_TYPE), lConfigFile); bResult = copyResourceData(IDR_EXE_MAIN_SCRIPT, MAKEINTRESOURCE(RES_HTML_TYPE), lScriptFile); KeeBoo::Zip lZip; KeeBoo::ZipFiles* lZipFiles = NULL; if (lZip.Open(CComBSTR(szZipFilePath), OPEN_EXISTING, GENERIC_READ|GENERIC_WRITE)) { if (lZip.GetFiles(&lZipFiles) == S_OK) { lZipFiles->put_Compatible(FALSE); lZipFiles->AddFileByName(CComBSTR(lConfigFile)); lZipFiles->AddFileByName(CComBSTR(lScriptFile)); lZipFiles = NULL; } lZip.Close(); } // Create exe bResult = copyResourceData(IDR_EXE_BINARY, _T("EXE_DATA"), fOutputFileName); bResult = appendToFile(fOutputFileName, szZipFilePath); return bResult; } #else boolean TDHTMLKeeBookExportEngine::exportBook_createAutoextractableFile(TAutoExtractableCreationData* pData) { long lResult; // Let's create the exe file directory if not existing CString lExeFilePath = pData->fExeFilePath; LPTSTR lExeFilePathBuffer = lExeFilePath.GetBuffer(1); if ( PathRemoveFileSpec(lExeFilePathBuffer) ) { lExeFilePath.ReleaseBuffer(); TPath lPathHelper(lExeFilePath); BOOL lCreated = lPathHelper.CreateDirectory(); ASSERT(lCreated); } else { lExeFilePath.ReleaseBuffer(); } // Let's create the autoextractable CString lTemplateFilePath_APB_main; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".adt"),lTemplateFilePath_APB_main); CString lTemplateFilePath_APB_main_def; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".add"),lTemplateFilePath_APB_main_def); writeResourceToFile( MAKEINTRESOURCE(IDR_ACTIVEDELIVERY_APB_MAIN_TEMPLATE), _T("ACTIVE_DELIVERY_DATA"), lTemplateFilePath_APB_main); writeResourceToFile( MAKEINTRESOURCE(IDR_ACTIVEDELIVERY_APB_MAIN_DEFINITION), _T("ACTIVE_DELIVERY_DATA"), lTemplateFilePath_APB_main_def); CString lTemplateFilePath_APB_events; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".adt"),lTemplateFilePath_APB_events); CString lTemplateFilePath_APB_events_def; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".add"),lTemplateFilePath_APB_events_def); writeResourceToFile( MAKEINTRESOURCE(IDR_ACTIVEDELIVERY_APB_EVENTS_TEMPLATE), _T("ACTIVE_DELIVERY_DATA"), lTemplateFilePath_APB_events); writeResourceToFile( MAKEINTRESOURCE(IDR_ACTIVEDELIVERY_APB_EVENTS_DEFINITION), _T("ACTIVE_DELIVERY_DATA"), lTemplateFilePath_APB_events_def); CString lTemplateFilePath_APB_btnText; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".adt"),lTemplateFilePath_APB_btnText); CString lTemplateFilePath_APB_btnText_def; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".add"),lTemplateFilePath_APB_btnText_def); writeResourceToFile( MAKEINTRESOURCE(IDR_ACTIVEDELIVERY_BUTTON_TEXT_TEMPLATE), _T("ACTIVE_DELIVERY_DATA"), lTemplateFilePath_APB_btnText); writeResourceToFile( MAKEINTRESOURCE(IDR_ACTIVEDELIVERY_BUTTON_TEXT_DEFINITION), _T("ACTIVE_DELIVERY_DATA"), lTemplateFilePath_APB_btnText_def); CString lADScriptFilePath; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".adx"),lADScriptFilePath); // First, let's create an empty script lResult = CreateADScript(lADScriptFilePath); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // Then, let's copy the predefined elements in it lResult = CopyElements( lTemplateFilePath_APB_main, lADScriptFilePath, lTemplateFilePath_APB_main_def ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } lResult = CopyElements( lTemplateFilePath_APB_events, lADScriptFilePath, lTemplateFilePath_APB_events_def ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } lResult = CopyElements( lTemplateFilePath_APB_btnText, lADScriptFilePath, lTemplateFilePath_APB_btnText_def ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // Now, let's set manually some elements /////////////////////// // the ZIP File Path // /////////////////////// lResult = SetADString( lADScriptFilePath, ADK_ZIPFILENAME, pData->fZipFilePath ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } /////////////////////// // the EXE File Path // /////////////////////// lResult = SetADString( lADScriptFilePath, ADK_EXEFILENAME, pData->fExeFilePath ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } /////////////////////// // the EXE File Icon // /////////////////////// // We use the APPLICATION ICON for the autoplayBooks' icon TAppInfo lAppInfo; CString stgPath = lAppInfo.GetFullPath(); /* CString stgPath; LPTSTR szPath = stgPath.GetBuffer( MAX_PATH); DWORD resModuleFile = ::GetModuleFileName( AfxGetApp()->m_hInstance, szPath, MAX_PATH); stgPath.ReleaseBuffer(); if ( (resModuleFile != 0) && (!stgPath.IsEmpty()) ) */ if (!stgPath.IsEmpty()) { CString lIconIndex(_T('2')); CString lActiveDeliveryIconString = stgPath + CString(";") + lIconIndex; lResult = SetADString( lADScriptFilePath, ADK_ICONFILENAME, lActiveDeliveryIconString ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } } //************************************************// // the Default Absolute Extraction Path: <custom> // //************************************************// CString lADRelativeExtractionPathTemplate("<exe>\\\"%1\""); // Let's remove the - and / from the values passed as command line, just // to be sure. // TO DO : put all the parameters in a text file interpreted by the autoextractable : // <FLAG>lflsf</FLAG> // <VALUE>lkshfklsdhfl<VALUE> // ... CString lPathCompliantExeFileName_tmp; TPath::FindFileName(pData->fExeFilePath, lPathCompliantExeFileName_tmp); TPath::RemoveExtension(lPathCompliantExeFileName_tmp); lPathCompliantExeFileName_tmp.Replace(_T('-'),_T(' ')); lPathCompliantExeFileName_tmp.Replace(_T('/'),_T(' ')); lPathCompliantExeFileName_tmp.TrimLeft(); lPathCompliantExeFileName_tmp.TrimRight(); CString lADRelativeExtractionPath; lADRelativeExtractionPath.FormatMessage( lADRelativeExtractionPathTemplate, lPathCompliantExeFileName_tmp ); lResult = SetADString( lADScriptFilePath, ADK_CUSTOMPATH, lADRelativeExtractionPath ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } //***************************************// // the unique REGISTRATOR Application // // to be ran before and after extraction // //***************************************// CString lRegistratorApplicationPath; { TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".exe"),lRegistratorApplicationPath); writeResourceToFile( MAKEINTRESOURCE(IDR_EXE_APB_REGISTRATOR), _T("EXE_DATA"), lRegistratorApplicationPath); } CString lAutorunBookId = getAutorunBookID(fBookModel); //*****************************// // the REGISTRATOR Application // // to run before extraction // //*****************************// { // Run programs before the extraction begins lResult = SetADInt( lADScriptFilePath, ADK_PROGBEFORE, 1 ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // We give the Registrator App's embedded flag and authoring path CString lValXString; lValXString += _T("1"); lValXString += _T(";"); lValXString += lRegistratorApplicationPath; lResult = SetADString( lADScriptFilePath, ADK_PROGBEFOREVALX, lValXString ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // We give the Object's Registrator App's embedded flag and object file's authoring path // Remark: // Although it does not seem to be documented, Active Delivery automatically // appends the path of this object file to the executable's command line during // extraction CString lRegistratorBeforeObjectLocalFilePath; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".ini"),lRegistratorBeforeObjectLocalFilePath); TRY { CStdioFile dataFile(lRegistratorBeforeObjectLocalFilePath, CFile::modeCreate | CFile::modeWrite); dataFile.Flush(); dataFile.Close(); } CATCH(CFileException, e) { } END_CATCH // Here we should get the parameters CString lUserId = getBookUserID(fBookModel); CString lKeeBooSKU = getBookKeeBooSKU(fBookModel); CString lPartnerID = getBookPartnerID(fBookModel); // And then write them to the data file TRY { CStdioFile dataFile(lRegistratorBeforeObjectLocalFilePath, CFile::modeWrite); dataFile.WriteString(_T("[parameters]\r\n")); dataFile.WriteString(_T("autorunbookid=")); dataFile.WriteString(lAutorunBookId); dataFile.WriteString(_T("\r\n")); dataFile.WriteString(_T("authoruserid=")); dataFile.WriteString(lUserId); dataFile.WriteString(_T("\r\n")); dataFile.WriteString(_T("authorkeeboosku=")); dataFile.WriteString(lKeeBooSKU); dataFile.WriteString(_T("\r\n")); dataFile.WriteString(_T("authorpartnerid=")); dataFile.WriteString(lPartnerID); dataFile.WriteString(_T("\r\n")); dataFile.Flush(); dataFile.Close(); } CATCH(CFileException, e) { } END_CATCH CString lObjXString; lObjXString += _T("1"); lObjXString += _T(";"); lObjXString += lRegistratorBeforeObjectLocalFilePath; lResult = SetADString( lADScriptFilePath, ADK_PROGBEFOREOBJX, lObjXString ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // We give the Registrator App's synchronous flag and command-line options CString lOptXString; lOptXString += _T("1"); lOptXString += _T(";"); CString lCommandLineTemplate; KBLoadString(IDS_APB_REGISTRATOR_BEFORE_CMD_LINE,lCommandLineTemplate); // Here we should get the parameters CString lRtpFileName("<ADRTP>"); // Let's remove the - and / from the values passed as data in the parameters data file, just // to be sure. CString lRtpFileName_tmp(lRtpFileName); lRtpFileName_tmp.Replace(_T('-'),_T(' ')); lRtpFileName_tmp.Replace(_T('/'),_T(' ')); lRtpFileName_tmp.TrimLeft(); lRtpFileName_tmp.TrimRight(); long lMode_Before = 1; CString lCommandLine; lCommandLine.FormatMessage( lCommandLineTemplate, lMode_Before, // -mode lRtpFileName_tmp // -rtpfilename ); lOptXString += lCommandLine; // command line lResult = SetADString( lADScriptFilePath, ADK_PROGBEFOREOPTX, lOptXString ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // We give the Registrator App's [Return Code/Action/Parameter] trios CString lRetXString; CString lADRetTrioTemplate(_T("%1!d!,%2!d!,%3")); // return value : ADRC_NOERROR -> CONTINUE CString lADRetTrio_0; lADRetTrio_0.FormatMessage( lADRetTrioTemplate, ADRC_NOERROR, ADACT_CONTINUE, _T("") ); lRetXString += lADRetTrio_0; lRetXString += _T(";"); // return value : ADRC_IDABORT -> EXIT CString lADRetTrio_1; lADRetTrio_1.FormatMessage( lADRetTrioTemplate, ADRC_IDABORT, ADACT_EXIT, _T("") ); lRetXString += lADRetTrio_1; lResult = SetADString( lADScriptFilePath, ADK_PROGBEFORERETX, lRetXString ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } } //*****************************// // the REGISTRATOR Application // // to run after successful // // extraction // //*****************************// { // Run programs after a successful extraction lResult = SetADInt( lADScriptFilePath, ADK_PROGOK, 1 ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // We give the Registrator App's embedded flag and authoring path CString lValXString; lValXString += _T("1"); lValXString += _T(";"); lValXString += lRegistratorApplicationPath; lResult = SetADString( lADScriptFilePath, ADK_PROGOKVALX, lValXString ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // We give the Object's Registrator App's embedded flag and object file's authoring path // // REMARK: // Although it does not seem to be documented, Active Delivery automatically // appends the path of this object file to the executable's command line during // extraction CString lRegistratorAfterSuccessObjectLocalFilePath; TPath::CreateRandomFilePath(this->getWorkingDirectory(),_T(".ini"),lRegistratorAfterSuccessObjectLocalFilePath); TRY { CFile dataFile(lRegistratorAfterSuccessObjectLocalFilePath, CFile::modeCreate | CFile::modeWrite); dataFile.Flush(); dataFile.Close(); } CATCH(CFileException, e) { } END_CATCH // Here we should get the parameters CString lTargetFilePath = pData->fMainHTMLFileName; CString lIconFileName; if ( !(pData->fShortcutIconFileName).IsEmpty() ) { lIconFileName = pData->fDataFolderRelativePath; lIconFileName += _T('\\'); lIconFileName += pData->fShortcutIconFileName; } CString lOpenShortcutName; KBLoadString(IDS_APB_REGISTRATOR_AFTER_SUCCESS_OPEN_SHORTCUT,lOpenShortcutName); CString lImportToKeeBooFileName; KBLoadString(IDS_WEBBOOK_REGISTRATOR_AFTER_SUCCESS_IMPORT_TO_KEEBOO_FILE,lImportToKeeBooFileName); CString lExeFileName; TPath::FindFileName(pData->fExeFilePath, lExeFileName); TPath::RemoveExtension(lExeFileName); // Let's remove the - and / from the values passed as data in the parameters data file, just // to be sure. CString lPathCompliantExeFileName_tmp(lExeFileName); lPathCompliantExeFileName_tmp.Replace(_T('-'),_T(' ')); lPathCompliantExeFileName_tmp.Replace(_T('/'),_T(' ')); lPathCompliantExeFileName_tmp.TrimLeft(); lPathCompliantExeFileName_tmp.TrimRight(); CString lTargetFilePath_tmp(lTargetFilePath); lTargetFilePath_tmp.Replace(_T('-'),_T(' ')); lTargetFilePath_tmp.Replace(_T('/'),_T(' ')); lTargetFilePath_tmp.TrimLeft(); lTargetFilePath_tmp.TrimRight(); CString lIconFileName_tmp(lIconFileName); lIconFileName_tmp.Replace(_T('-'),_T(' ')); lIconFileName_tmp.Replace(_T('/'),_T(' ')); lIconFileName_tmp.TrimLeft(); lIconFileName_tmp.TrimRight(); CString lOpenShortcutName_tmp(lOpenShortcutName); lOpenShortcutName_tmp.Replace(_T('-'),_T(' ')); lOpenShortcutName_tmp.Replace(_T('/'),_T(' ')); lOpenShortcutName_tmp.TrimLeft(); lOpenShortcutName_tmp.TrimRight(); CString lImportToKeeBooFileName_tmp(lImportToKeeBooFileName); lImportToKeeBooFileName_tmp.Replace(_T('-'),_T(' ')); lImportToKeeBooFileName_tmp.Replace(_T('/'),_T(' ')); lImportToKeeBooFileName_tmp.TrimLeft(); lImportToKeeBooFileName_tmp.TrimRight(); // And then write them to the data file TRY { CStdioFile dataFile(lRegistratorAfterSuccessObjectLocalFilePath, CFile::modeWrite); dataFile.WriteString(_T("[parameters]\r\n")); dataFile.WriteString(_T("desktopshortcutname=")); dataFile.WriteString(lPathCompliantExeFileName_tmp); dataFile.WriteString(_T("\r\n")); dataFile.WriteString(_T("targetfilepath=")); dataFile.WriteString(lTargetFilePath_tmp); dataFile.WriteString(_T("\r\n")); dataFile.WriteString(_T("shortcuticonpath=")); dataFile.WriteString(lIconFileName_tmp); dataFile.WriteString(_T("\r\n")); dataFile.WriteString(_T("autorunbookid=")); dataFile.WriteString(lAutorunBookId); dataFile.WriteString(_T("\r\n")); dataFile.WriteString(_T("openshortcutname=")); dataFile.WriteString(lOpenShortcutName_tmp); dataFile.WriteString(_T("\r\n")); dataFile.Flush(); dataFile.Close(); } CATCH(CFileException, e) { } END_CATCH CString lObjXString; lObjXString += _T("1"); lObjXString += _T(";"); lObjXString += lRegistratorAfterSuccessObjectLocalFilePath; lResult = SetADString( lADScriptFilePath, ADK_PROGOKOBJX, lObjXString ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // We give the Registrator App's synchronous flag and command-line options CString lOptXString; lOptXString += _T("1"); lOptXString += _T(";"); CString lCommandLineTemplate; KBLoadString(IDS_APB_REGISTRATOR_AFTER_SUCCESS_CMD_LINE,lCommandLineTemplate); // Here we should get the parameters CString lRtpFileName("<ADRTP>"); CString lInstallDirectory("<Custom>"); // Let's remove the - and / from the values passed as data in the parameters data file, just // to be sure. CString lInstallDirectory_tmp(lInstallDirectory); lInstallDirectory_tmp.Replace(_T('-'),_T(' ')); lInstallDirectory_tmp.Replace(_T('/'),_T(' ')); lInstallDirectory_tmp.TrimLeft(); lInstallDirectory_tmp.TrimRight(); CString lRtpFileName_tmp(lRtpFileName); lRtpFileName_tmp.Replace(_T('-'),_T(' ')); lRtpFileName_tmp.Replace(_T('/'),_T(' ')); lRtpFileName_tmp.TrimLeft(); lRtpFileName_tmp.TrimRight(); long lMode_AfterSuccess = 2; CString lCommandLine; lCommandLine.FormatMessage( lCommandLineTemplate, lMode_AfterSuccess, // -mode lRtpFileName_tmp, // -rtpfilename lInstallDirectory_tmp // -installdirectory ); lOptXString += lCommandLine; // command line lResult = SetADString( lADScriptFilePath, ADK_PROGOKOPTX, lOptXString ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } // We give the Registrator App's [Return Code/Action/Parameter] trios CString lRetXString; CString lADRetTrioTemplate(_T("%1!d!,%2!d!,%3")); // return value : ADRC_NOERROR -> CONTINUE CString lADRetTrio_0; lADRetTrio_0.FormatMessage( lADRetTrioTemplate, ADRC_NOERROR, ADACT_CONTINUE, _T("") ); lRetXString += lADRetTrio_0; lResult = SetADString( lADScriptFilePath, ADK_PROGOKRETX, lRetXString ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } } //*****************************// // the REGISTRATOR Application // // to run after failed // // extraction // //*****************************// { // DO NOT RUN programs after a failed extraction lResult = SetADInt( lADScriptFilePath, ADK_PROGFAIL, 0 ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } } // At last, let's create the package lResult = CreateADPackage( lADScriptFilePath, FALSE ); if ( lResult != ADFACTRY_NO_ERROR ) { exportBook_handleActiveDeliveryError(lResult); return false; } return true; } #endif void TDHTMLKeeBookExportEngine::exportBook_handleActiveDeliveryError(long lADError) { // Potentially, we should pop-up different error messages depending on the // Active Delivery error. For now, a generic message will be enough. TErr::trace( TErr::D_BOX, TErr::G_FAT, IDS_ERR_ACTIVE_DELIVERY, __FILE__, __LINE__ ); TErr::trace( TErr::D_LOG, TErr::G_FAT, TErr::NO_ID, __FILE__, __LINE__, "Active Delivery Error : %1!d!", lADError); } CString TDHTMLKeeBookExportEngine::getDynamicKeeBookMainHTMLOutputFilePath(TExportProcessingData* pExportProcessingData) { // Not Applicable ASSERT(FALSE); return _T(""); } void TDHTMLKeeBookExportEngine::setDynamicKeeBookMainHTMLOutputFilePath(TExportProcessingData* pExportProcessingData, CString pFilePath) { // Not Applicable ASSERT(FALSE); } TExportData* TDHTMLKeeBookExportEngine::getExportData() { return fExportData; } CString TDHTMLKeeBookExportEngine::getWorkingDirectory() { if (fWorkingDirectory.IsEmpty()) { TPath::CreateNewDirectoryPath(TSystemInfo::GetTempPath(),fWorkingDirectory); TPath lPathHelper(fWorkingDirectory); BOOL lCreated = lPathHelper.CreateDirectory(); ASSERT(lCreated); } return fWorkingDirectory; } CString TDHTMLKeeBookExportEngine::getLanguageName() { TLanguagesInfo lLanguagesInfo; CString lCurrentLanguage = (lLanguagesInfo.GetCurrentLanguage())->GetLanguage(); lCurrentLanguage.MakeLower(); return lCurrentLanguage; } CString TDHTMLKeeBookExportEngine::getLanguageFolderName() { TLanguagesInfo lLanguagesInfo; CString lCurrentLanguage = (lLanguagesInfo.GetCurrentLanguage())->GetLanguage(); lCurrentLanguage.MakeLower(); return lCurrentLanguage; } CString TDHTMLKeeBookExportEngine::getLookAndFeelFolderName() { TLooksInfo lLooksInfo; CString lCurrentLook = (lLooksInfo.GetCurrentLook())->GetName(); lCurrentLook.MakeLower(); return lCurrentLook; } CString TDHTMLKeeBookExportEngine::getLanguageFolderRelativePath() { CString lLanguageFolderRelativePath; lLanguageFolderRelativePath = getLanguageFolderName(); return lLanguageFolderRelativePath; } CString TDHTMLKeeBookExportEngine::getLookAndFeelFolderRelativePath() { CString lLookAndFeelFolderRelativePath; lLookAndFeelFolderRelativePath = getLookAndFeelFolderName(); return lLookAndFeelFolderRelativePath; } boolean TDHTMLKeeBookExportEngine::getLocalFileInfoFromUrl(LPCTSTR pUrl, CString& pLocalFileName, CString& pLocalFileMime) { boolean bResult = false; HRESULT hr; TSystemMimeHelper* lMimeHelper = new TSystemMimeHelper(); CComPtr<ISevenixCacheEntry> lIsce; TSevenixUrl sevenixUrl(pUrl); CComBSTR lUrl(sevenixUrl.extendedUrlString()); hr = CacheGetEntry(lUrl, T_FILTER_CACHE_NAME, &lIsce); if (hr != S_OK) { hr = CacheGetEntry(lUrl, T_NETWORK_CACHE_NAME, &lIsce); } if (hr == S_OK) { // The MIME CString lMime; CComBSTR bstr_mime; lIsce->getHeader(T_HEADER_MIME_TYPE, 0, &bstr_mime); lMime = CString(bstr_mime); if (lMime.IsEmpty()) { CString lUrlFile = sevenixUrl.getFile(); CString lUrlFileExtension; TPath::FindExtension( lUrlFile , lUrlFileExtension ); if(lUrlFileExtension.IsEmpty()) { lUrlFileExtension = _T(".htm"); } lMimeHelper->getFirstMimeTypeFromFileExtension(lUrlFileExtension,lMime); } pLocalFileMime = lMime; // RESULT // The Local File Name CString lLocalFileName; CComBSTR bstr_localFileName; lIsce->getFileName(&bstr_localFileName); lLocalFileName = bstr_localFileName; pLocalFileName = lLocalFileName; // RESULT bResult = true; } else { // The url is in no cache, so let's see if it is a local file CString lLocalFilePath; // First, let's see if it is a 'sevenixed' file path if ((sevenixUrl.getProtocol()).CompareNoCase(CString("file")) == 0) { // 'pUrl' has the following form : sevenix:????file://??? sevenixUrl.canonicalize(); lLocalFilePath = sevenixUrl.getFile(); } else { // 'pUrl' most certainly is a regular file path : driveLetter:\??? lLocalFilePath = pUrl; } if (!lLocalFilePath.IsEmpty()) { // We'll just check if the file exists CFileStatus status; if( !CFile::GetStatus( lLocalFilePath, status ) ) { // The file doesn't exist pLocalFileMime.Empty(); // RESULT pLocalFileName.Empty(); // RESULT bResult = false; } else { // The file exists pLocalFileName = lLocalFilePath; // RESULT CString lTempFileExtension; TPath::FindExtension(pLocalFileName,lTempFileExtension); CString lTempFileMimeType; lMimeHelper->getFirstMimeTypeFromFileExtension(lTempFileExtension,lTempFileMimeType); pLocalFileMime = lTempFileMimeType; // RESULT bResult = true; } } } delete lMimeHelper; lMimeHelper = NULL; return bResult; } boolean TDHTMLKeeBookExportEngine::isUrlLocalFile(LPCTSTR pUrl, CString& pResFilePath) { TUrl lUrl(pUrl); TUrl lSimpleUrl(lUrl.simpleUrlString()); boolean bIsLocalFile = false; CString lResFilePath; if ((lSimpleUrl.getProtocol()).CompareNoCase(_T("file")) == 0) { bIsLocalFile = true; lResFilePath = lSimpleUrl.getFile(); } if (!bIsLocalFile) { CFileStatus status; if( CFile::GetStatus( pUrl, status ) ) { // 'lUrlStr' is a local file path : driveLetter:\??? bIsLocalFile = true; lResFilePath = pUrl; } } // Results pResFilePath = lResFilePath; return bIsLocalFile; } boolean TDHTMLKeeBookExportEngine::isUrlImageFileForBrowser(LPCTSTR pUrl, CString& pImageFileMime) { CString strFileName; CString strFileMime; boolean bFileInfoRes = this->getLocalFileInfoFromUrl(pUrl,strFileName,strFileMime); if ( !bFileInfoRes || (strFileMime.IsEmpty()) ) { CString lUrlFile = TUrl(pUrl).getFile(); CString lUrlFileExtension; TPath::FindExtension( lUrlFile , lUrlFileExtension ); if (!lUrlFileExtension.IsEmpty()) { TSystemMimeHelper* lSystemMimeHelper = new TSystemMimeHelper(); lSystemMimeHelper->getFirstMimeTypeFromFileExtension(lUrlFileExtension,strFileMime); } else { return false; } } if (strFileMime.IsEmpty()) return false; // Here we have a MIME, so let's see if it is an image's one if ( (strFileMime.CompareNoCase(_T("image/gif")) == 0) || (strFileMime.CompareNoCase(_T("image/jpeg")) == 0) || (strFileMime.CompareNoCase(_T("image/png")) == 0) ) { pImageFileMime = strFileMime; return true; } return false; } boolean TDHTMLKeeBookExportEngine::isUrlImageFile(LPCTSTR pUrl, CString& pImageFileMime) { CString strFileName; CString strFileMime; boolean bFileInfoRes = this->getLocalFileInfoFromUrl(pUrl,strFileName,strFileMime); if ( !bFileInfoRes || (strFileMime.IsEmpty()) ) { CString lUrlFile = TUrl(pUrl).getFile(); CString lUrlFileExtension; TPath::FindExtension( lUrlFile , lUrlFileExtension ); if (!lUrlFileExtension.IsEmpty()) { TSystemMimeHelper* lSystemMimeHelper = new TSystemMimeHelper(); lSystemMimeHelper->getFirstMimeTypeFromFileExtension(lUrlFileExtension,strFileMime); } else { return false; } } if (strFileMime.IsEmpty()) return false; // Here we have a MIME, so let's see if it is an image's one strFileMime.MakeLower(); if (strFileMime.Find(_T("image/")) != -1) { pImageFileMime = strFileMime; return true; } // Special case for encapsulated postscript if (strFileMime.CompareNoCase(_T("application/postscript")) == 0) { CString lUrlFile = TUrl(pUrl).getFile(); CString lUrlFileExtension; TPath::FindExtension( lUrlFile , lUrlFileExtension ); if (!lUrlFileExtension.IsEmpty()) { if (lUrlFileExtension.CompareNoCase(_T(".eps")) == 0) { pImageFileMime = strFileMime; return true; } } } return false; } boolean TDHTMLKeeBookExportEngine::isEmbedFormatFile(LPCTSTR pUrl) { CString lUrlFile = TUrl(pUrl).getFile(); CString lUrlFileExtension; TPath::FindExtension( lUrlFile , lUrlFileExtension ); if (!lUrlFileExtension.IsEmpty()) { TSystemMimeHelper* lSystemMimeHelper = new TSystemMimeHelper(); CString lMime; lSystemMimeHelper->getFirstMimeTypeFromFileExtension(lUrlFileExtension,lMime); if (!lMime.IsEmpty()) { TEmbedMimeHelper* lEmbedMimeHelper = new TEmbedMimeHelper(); BOOL lEmbedMime = lEmbedMimeHelper->isMimeTypeSupported(lMime); if (lEmbedMime) { return true; } } } return false; } long TDHTMLKeeBookExportEngine::getPageDepth(TPageModel* pPageModel) { long resDepth = 0; TModelPtr<TPageModel> lChildPage; lChildPage = pPageModel; for (;;) { TModelPtr<TPageModel> lParentPage; lChildPage->getParentChapter(&lParentPage); if ( (!lParentPage) || (lParentPage == lChildPage) ) { break; } else { lChildPage = lParentPage; resDepth++; } } return resDepth; } boolean TDHTMLKeeBookExportEngine::hasPagePostContent(TPageModel* pPageModel) { TModelPtr<TContentModel> lPageMainContent; pPageModel->getContent(&lPageMainContent); if (lPageMainContent != null) { TModelPtr<TPropertyObjectModel> lProp; GetModelProperty<TContentModel>(lPageMainContent, T_CONTENT_NETWORK_PROPERTIES, &lProp); if (lProp != NULL) { CString lPostData; lProp->getStringField(T_CONTENT_NETWORK_POST_DATA, &lPostData); if (lPostData.GetLength()) { return true; } } } return false; } boolean TDHTMLKeeBookExportEngine::doCompression(LPCTSTR pSrcDirectory,LPCTSTR pOutputFileName) { boolean res = true; if (!TZipManager::initDynaZip32_ZIP()) { return false; } ZIPCMDSTRUCT zipCmdStruct; TZipManager::initZIPCmdStruct((ZIPCMDSTRUCT FAR *)&zipCmdStruct); // Strings allocation LPSTR lpstr_lpszTempPath = (LPSTR)NULL; LPSTR lpstr_lpszZIPFile = (LPSTR)NULL; LPSTR lpstr_lpszItemList = (LPSTR)NULL; CString quotedFileSpec = CString((LPCTSTR)pSrcDirectory); TPath lPath_quotedFileSpec(quotedFileSpec); lPath_quotedFileSpec.AddPath(_T("*.*")); quotedFileSpec = CString("\"") + quotedFileSpec + CString("\""); CString tmpDirPathBuffer; tmpDirPathBuffer = TSystemInfo::GetTempPath(); ASSERT(!tmpDirPathBuffer.IsEmpty()); if (!tmpDirPathBuffer.IsEmpty()) { lpstr_lpszTempPath = strdup(T2CA(tmpDirPathBuffer)); zipCmdStruct.pathForTempFlag = TRUE; zipCmdStruct.lpszTempPath = lpstr_lpszTempPath; } zipCmdStruct.function = ZIP_ADD; // Recurse traversing of directories zipCmdStruct.recurseFlag = TRUE; // Cause paths stored in the archive to be relative to the root compression directory zipCmdStruct.wZipSubOptions |= ZSO_RELATIVEPATHFLAG; // Max compression zipCmdStruct.compFactor = 9; lpstr_lpszZIPFile = strdup(T2CA(pOutputFileName)); zipCmdStruct.lpszZIPFile = lpstr_lpszZIPFile; lpstr_lpszItemList = strdup(T2CA(quotedFileSpec)); zipCmdStruct.lpszItemList = lpstr_lpszItemList; zipCmdStruct.lpRenameProc = (FARPROC)&TDHTMLKeeBookExportEngine::doCompression_RenameCallback; TZipRenameCallbackData_doCompression* renameCallbackData = new TZipRenameCallbackData_doCompression(); renameCallbackData->fThis = this; zipCmdStruct.lpRenameUserData = (void FAR *)renameCallbackData; zipCmdStruct.lpMajorStatus = (FARPROC)&TDHTMLKeeBookExportEngine::doCompression_MajorStatusCallback; TZipMajorStatusCallbackData_doCompression* majorStatusCallbackData = new TZipMajorStatusCallbackData_doCompression(); majorStatusCallbackData->fThis = this; zipCmdStruct.lpMajorUserData = (void FAR *)majorStatusCallbackData; zipCmdStruct.lpMinorStatus = (FARPROC)&TDHTMLKeeBookExportEngine::doCompression_MinorStatusCallback; TZipMinorStatusCallbackData_doCompression* minorStatusCallbackData = NULL; //new TZipMinorStatusCallbackData_doCompression(); //minorStatusCallbackData->fThis = this; zipCmdStruct.lpMinorUserData = (void FAR *)minorStatusCallbackData; // We need to have this callback because when the zip file doesn't exists, // the ZIP_UPDATE mode generates a warning we don't wan't to pop up... zipCmdStruct.lpMessageDisplay = (FARPROC)&TDHTMLKeeBookExportEngine::doCompression_MessageDisplayCallback; TZipMessageDisplayCallbackData_doCompression* messageDisplayCallbackData = new TZipMessageDisplayCallbackData_doCompression(); messageDisplayCallbackData->fThis = this; zipCmdStruct.lpMessageDisplayData = (void FAR *)messageDisplayCallbackData; int response = TZipManager::DZip_proc((ZIPCMDSTRUCT FAR *)&zipCmdStruct); delete majorStatusCallbackData; delete minorStatusCallbackData; delete messageDisplayCallbackData; // Strings deallocation free(lpstr_lpszTempPath); free(lpstr_lpszZIPFile); free(lpstr_lpszItemList); if (response != ZE_OK) { return false; } if (!res) { // We should delete the potentially created but incomplete zip file } return res; } boolean TDHTMLKeeBookExportEngine::doDecompression(LPCTSTR pInputFileName, LPCTSTR pDestDirectory) { boolean res = true; if (!TUnZipManager::initDynaZip32_UNZIP()) { return false; } int response; UNZIPCMDSTRUCT unzipCmdStruct; TUnZipManager::initUNZIPCmdStruct((UNZIPCMDSTRUCT FAR *)&unzipCmdStruct); // Strings allocation LPSTR lpstr_lpszZIPFile = (LPSTR)NULL; // Little zip archive validity test... lpstr_lpszZIPFile = strdup(T2CA(pInputFileName)); unzipCmdStruct.lpszZIPFile = lpstr_lpszZIPFile; unzipCmdStruct.function = UNZIP_COUNTALLZIPMEMBERS; response = TUnZipManager::DUnZip_proc((UNZIPCMDSTRUCT FAR *)&unzipCmdStruct); // Strings deallocation free(lpstr_lpszZIPFile); if (response != UE_OK) { return false; } // We pass the validity test, so let's do the real extracting TUnZipManager::initUNZIPCmdStruct((UNZIPCMDSTRUCT FAR *)&unzipCmdStruct); // Strings allocation lpstr_lpszZIPFile = (LPSTR)NULL; LPSTR lpstr_lpszDestination = (LPSTR)NULL; LPSTR lpstr_lpszFilespec = (LPSTR)NULL; CString quotedFileSpec = CString("\"") + CString("*.*") + CString("\""); lpstr_lpszZIPFile = strdup(T2CA(pInputFileName)); unzipCmdStruct.lpszZIPFile = lpstr_lpszZIPFile; unzipCmdStruct.function = UNZIP_EXTRACT; lpstr_lpszDestination = strdup(T2CA(pDestDirectory)); unzipCmdStruct.lpszDestination = lpstr_lpszDestination; lpstr_lpszFilespec = strdup(T2CA(quotedFileSpec)); unzipCmdStruct.lpszFilespec = lpstr_lpszFilespec; unzipCmdStruct.overWriteFlag = TRUE; unzipCmdStruct.noDirectoryNamesFlag = FALSE; unzipCmdStruct.recurseFlag = TRUE; unzipCmdStruct.wUnzipSubOptions |= USO_OVERWRITE_RO; unzipCmdStruct.lpMajorStatus = (FARPROC)&TDHTMLKeeBookExportEngine::doDecompression_MajorStatusCallback; TUnZipMajorStatusCallbackData_doDecompression* majorStatusCallbackData = new TUnZipMajorStatusCallbackData_doDecompression(); unzipCmdStruct.lpMajorUserData = (void FAR *)majorStatusCallbackData; unzipCmdStruct.lpMinorStatus = (FARPROC)&TDHTMLKeeBookExportEngine::doDecompression_MinorStatusCallback; TUnZipMinorStatusCallbackData_doDecompression* minorStatusCallbackData = new TUnZipMinorStatusCallbackData_doDecompression(); unzipCmdStruct.lpMinorUserData = (void FAR *)minorStatusCallbackData; unzipCmdStruct.lpMessageDisplay = (FARPROC)&TDHTMLKeeBookExportEngine::doDecompression_MessageDisplayCallback; TUnZipMessageDisplayCallbackData_doDecompression* messageDisplayCallbackData = new TUnZipMessageDisplayCallbackData_doDecompression(); unzipCmdStruct.lpMessageDisplayData = (void FAR *)messageDisplayCallbackData; response = TUnZipManager::DUnZip_proc((UNZIPCMDSTRUCT FAR *)&unzipCmdStruct); // Strings deallocation free(lpstr_lpszZIPFile); free(lpstr_lpszDestination); free(lpstr_lpszFilespec); if (response != UE_OK) { res = false; } if (!res) { // We should delete the potentially created temporary directory } return res; } void TDHTMLKeeBookExportEngine::formatPathStringForJavascript(CString& pString) { // The order is VERY IMPORTANT pString.Replace(_T("\\"),_T("\\\\")); pString.Replace(_T("\""),_T("\\\"")); pString.Replace(_T("\'"),_T("\\\'")); } void TDHTMLKeeBookExportEngine::unformatPathStringFromJavascript(CString& pString) { // The order is VERY IMPORTANT pString.Replace(_T("\\\'"),_T("\'")); pString.Replace(_T("\\\""),_T("\"")); pString.Replace(_T("\\\\"),_T("\\")); } void TDHTMLKeeBookExportEngine::formatDisplayStringForJavascript(CString& pString, boolean pEncodeEntities) { // The order is VERY IMPORTANT pString.Replace( _T("\\"), _T("\\\\")); pString.Replace( _T("\""), _T("\\\"")); pString.Replace( _T("\'"), _T("\\\'")); if (pEncodeEntities) { pString.Replace( _T("&"), _T("&")); pString.Replace( _T("<"), _T("<")); pString.Replace( _T(">"), _T(">")); // Then, let's replace the non-ascii characters of code c by &#c; // This is real BAD for multibyte chars, but we keep it for now... CString lWorkString; for (int ii=0; ii < pString.GetLength(); ii++) { TCHAR curChar = pString.GetAt(ii); if (!_istascii(curChar)) { int byteValue = (int)(BYTE)curChar; CString lStringToAdd; lStringToAdd.Format( _T("&#%u;"), byteValue ); lWorkString += lStringToAdd; } else { lWorkString += curChar; } } pString = lWorkString; } } HRESULT TDHTMLKeeBookExportEngine::writeResourceToFile(LPCTSTR pResName, LPCTSTR pResType, LPCTSTR pDestFilePath) { HINSTANCE hInst = KBFindResourceHandle(pResName, pResType); if (hInst == NULL) { return S_FALSE; } HRSRC hResource = ::FindResource(hInst, pResName, pResType); if (hResource == NULL) { return S_FALSE; } HGLOBAL lGlobal = ::LoadResource(hInst, hResource); LPVOID lpBuff = ::LockResource(lGlobal); DWORD dwSize = ::SizeofResource(hInst, hResource); BYTE* lData = (BYTE*)lpBuff; CFile destFile; HRESULT lResult = S_OK; if (destFile.Open(pDestFilePath, CFile::modeCreate | CFile::modeWrite)) { TRY { destFile.Write(lData, dwSize); destFile.Flush(); } CATCH(CFileException, e) { lResult = S_FALSE; } END_CATCH destFile.Close(); } ::UnlockResource(hResource); ::FreeResource(hResource); return S_OK; } // TRACKING HELPERS CString TDHTMLKeeBookExportEngine::getUserID() { TUserInfo lUserInfo; return lUserInfo.GetUserID(); } CString TDHTMLKeeBookExportEngine::getKeeBooSKU() { TAppVersionInfo lAppInfo; return lAppInfo.GetSKU(); } CString TDHTMLKeeBookExportEngine::getPartnerID() { CString lPartnerId; TAppBrandingInfo lAppInfo; lPartnerId = lAppInfo.GetPartnerID(); return lPartnerId; } CString TDHTMLKeeBookExportEngine::getBookUserID(TBookModel* pBookModel) { CString lBookUserId; if ( pBookModel ) { TModelPtr<TPropertyObjectModel> pBookAuthorProperty; pBookModel->getProperty(T_BOOK_AUTHOR_PROPERTY, &pBookAuthorProperty); if( pBookAuthorProperty != NULL) { pBookAuthorProperty->getStringField(T_BOOK_AUTHOR_PROPERTY_AUTHOR_USER, &lBookUserId); } } return lBookUserId; } CString TDHTMLKeeBookExportEngine::getBookKeeBooSKU(TBookModel* pBookModel) { CString lBookKeeBooSKU; if ( pBookModel ) { TModelPtr<TPropertyObjectModel> pBookAuthorProperty; pBookModel->getProperty(T_BOOK_AUTHOR_PROPERTY, &pBookAuthorProperty); if( pBookAuthorProperty != NULL) { pBookAuthorProperty->getStringField(T_BOOK_AUTHOR_PROPERTY_AUTHOR_SKU, &lBookKeeBooSKU); } } return lBookKeeBooSKU; } CString TDHTMLKeeBookExportEngine::getBookPartnerID(TBookModel* pBookModel) { CString lBookPartnerID; if ( pBookModel ) { TModelPtr<TPropertyObjectModel> pBookAuthorProperty; pBookModel->getProperty(T_BOOK_AUTHOR_PROPERTY, &pBookAuthorProperty); if( pBookAuthorProperty != NULL) { pBookAuthorProperty->getStringField(T_BOOK_AUTHOR_PROPERTY_AUTHOR_PARTNER, &lBookPartnerID); } } return lBookPartnerID; } CString TDHTMLKeeBookExportEngine::getAutorunBookID(TBookModel* pBookModel) { CString lAutorunBookIDStr; if (pBookModel != NULL) { TModelPtr<TPropertyObjectModel> lProp; pBookModel->getDefaultProperty(&lProp); if (lProp) { lProp->getStringField(T_BOOK_DEFAULT_PROPERTY_BOOK_ID, &lAutorunBookIDStr); if (lAutorunBookIDStr.GetLength()) return lAutorunBookIDStr; } } if (IsEqualCLSID(fAutorunBookID,CLSID_NULL) == TRUE) { TAnonymousGUID::CoCreateGuid(&fAutorunBookID); } CComBSTR ppsz(fAutorunBookID); lAutorunBookIDStr = ppsz; return lAutorunBookIDStr; } CString TDHTMLKeeBookExportEngine::getGetBrandingAspUrlWithParameters(TBookModel* pBookModel) { CString lResultUrl; CoInit lCoInit; CComPtr<IBrandingInfo2> lBrandingInfo; lBrandingInfo.CoCreateInstance( CLSID_TBrandingInfo ); if ( lBrandingInfo ) { CComBSTR bstr_lGetBrandingAspUrl; HRESULT lResult = lBrandingInfo->get_GetBrandingAsp( &bstr_lGetBrandingAspUrl ); if (lResult == S_OK) { CString lGetBrandingAspUrl = bstr_lGetBrandingAspUrl; if (!lGetBrandingAspUrl.IsEmpty()) { TAutoRunBrandingGenerator lBrandingInfoGenerator(pBookModel); CString lPartnerID = lBrandingInfoGenerator.GetBookAuthorPartner(); CString lUserId = lBrandingInfoGenerator.GetBookAuthorUser(); lGetBrandingAspUrl += _T("?AuthorPartner="); lGetBrandingAspUrl += lPartnerID; lGetBrandingAspUrl += _T("&AuthorUser="); lGetBrandingAspUrl += lUserId; lGetBrandingAspUrl += _T("&Lang="); lGetBrandingAspUrl += getLanguageName(); lResultUrl = lGetBrandingAspUrl; } } } lBrandingInfo = NULL; return lResultUrl; } CString TDHTMLKeeBookExportEngine::getBrandingLicense() { CString lResultLicense; CoInit lCoInit; CComPtr<IBrandingInfo3> lBrandingInfo; lBrandingInfo.CoCreateInstance( CLSID_TBrandingInfo ); if ( lBrandingInfo ) { CComBSTR bstr_lBrandingLicense; HRESULT lResult = lBrandingInfo->get_BrandingLicense( &bstr_lBrandingLicense ); if (lResult == S_OK) { lResultLicense = bstr_lBrandingLicense; } } lBrandingInfo = NULL; return lResultLicense; } // PROGRESS STUFF void TDHTMLKeeBookExportEngine::reportCurrentGlobalPercentage(LONG pVal, float pFull) { if ( fProgressHelper && (fExportData->fMessageCallback != NULL) ) { fProgressHelper->setCurrentPercentageForPhase(pVal, pFull); int percentage = (int)( fProgressHelper->getCurrentGlobalPercentage() ); if (percentage != fLastReportedPercentage) { fLastReportedPercentage = percentage; (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_PROGRESS_BAR_SET_POS,percentage,0,NULL,NULL,fExportData->fMessageCallbackData); } } } CString TDHTMLKeeBookExportEngine::findRenamedFilePathInFilesToAddToBundle(LPCTSTR pOldFilePath) { int lBundleLength = fArchiveNamesMgr->getBundleSize(); if ( lBundleLength > 0 ) { CString oldFileNameSlash(pOldFilePath); CString oldFileNameBackslash(pOldFilePath); StringReplace(oldFileNameSlash.GetBuffer(0), _T('\\'), _T('/')); oldFileNameSlash.ReleaseBuffer(); StringReplace(oldFileNameBackslash.GetBuffer(0), _T('/'), _T('\\')); oldFileNameBackslash.ReleaseBuffer(); for (int ii = 0; ii < lBundleLength; ii++) { CString curLocalFilePath; CString curPathInArchive; fArchiveNamesMgr->getBundleItemAt(ii,curLocalFilePath,curPathInArchive); if ( (curLocalFilePath.CompareNoCase(oldFileNameSlash) == 0) || (curLocalFilePath.CompareNoCase(oldFileNameBackslash) == 0) ) { // I remove it from the bundle fArchiveNamesMgr->removeBundleItemAt(ii); // Replacing all backslashes by slashes is NECESSARY for archives to // work on Macintosh... StringReplace(curPathInArchive.GetBuffer(0), _T('\\'), _T('/')); curPathInArchive.ReleaseBuffer(); return curPathInArchive; } } } return CString(""); // means not found } /*************************************/ /********** ZIP stuff **************/ /*************************************/ int FAR PASCAL TDHTMLKeeBookExportEngine::doCompression_RenameCallback(DZRENAME FAR * dzr, void FAR *lpUserData) { //TZipRenameCallbackData_doCompression* data = (TZipRenameCallbackData_doCompression *)lpUserData; // Let's just ensure that all files have read/write file permissions... long attr = dzr->Attr; attr &= ~0x01; dzr->Attr = attr; return 0; } BOOL FAR PASCAL TDHTMLKeeBookExportEngine::doCompression_MinorStatusCallback(LPSTR szItem,long percent,void FAR *lpMinorUserData) { // TZipMinorStatusCallbackData_doCompression* data = (TZipMinorStatusCallbackData_doCompression*)lpMinorUserData; return FALSE; } ///// BOOL FAR PASCAL TDHTMLKeeBookExportEngine::doCompression_MajorStatusCallback(LPSTR szItem,long percent,void FAR *lpMajorUserData) { // TZipMajorStatusCallbackData_doCompression* data = (TZipMajorStatusCallbackData_doCompression *)lpMajorUserData; // TDHTMLKeeBookExportEngine* lThis = data->fThis; return FALSE; } ///// BOOL FAR PASCAL TDHTMLKeeBookExportEngine::doCompression_MessageDisplayCallback(UINT MsgID,UINT mbType,int p1,int p2,LPSTR lpsz1,LPSTR lpsz2,VOID FAR * lpMessageDisplayData) { // TZipMessageDisplayCallbackData_doCompression* data = (TZipMessageDisplayCallbackData_doCompression *)lpMessageDisplayData; switch (MsgID) { case MSGID_WARN : case MSGID_ERROR : case MSGID_ZOPEN : case MSGID_ZREAD : case MSGID_ZWRITE : { return IDOK; } default : { return 0; } } return 0; } /***********************************/ /********** UNZIP stuff **********/ /***********************************/ ///// BOOL FAR PASCAL TDHTMLKeeBookExportEngine::doDecompression_MinorStatusCallback(LPSTR szItem,long percent,void FAR *lpMinorUserData) { TUnZipMinorStatusCallbackData_doDecompression* data = (TUnZipMinorStatusCallbackData_doDecompression *)lpMinorUserData; UNUSED_ALWAYS(data); return FALSE; } ///// BOOL FAR PASCAL TDHTMLKeeBookExportEngine::doDecompression_MajorStatusCallback(LPSTR szItem,long percent,void FAR *lpMajorUserData) { TUnZipMajorStatusCallbackData_doDecompression* data = (TUnZipMajorStatusCallbackData_doDecompression *)lpMajorUserData; UNUSED_ALWAYS(data); return FALSE; } ///// BOOL FAR PASCAL TDHTMLKeeBookExportEngine::doDecompression_MessageDisplayCallback(UINT MsgID,UINT mbType,int p1,int p2,LPSTR lpsz1,LPSTR lpsz2,VOID FAR * lpMessageDisplayData) { TUnZipMessageDisplayCallbackData_doDecompression* data = (TUnZipMessageDisplayCallbackData_doDecompression *)lpMessageDisplayData; UNUSED_ALWAYS(data); switch (MsgID) { case MSGID_WARN : case MSGID_ERROR : case MSGID_ZOPEN : case MSGID_ZREAD : case MSGID_ZWRITE : { return IDOK; } default : { return 0; } } return 0; } boolean TDHTMLKeeBookExportEngine::handlePreBundledZipFiles(TCompressionProcessingData* pData) { // ********** // First, let's copy all the pre-bundled ZIP files to our working directory // ********** CString lResultFilePath_Neutral; CString lResultFilePath_LookAndFeel; CString lResultFilePath_Language; // Let's copy the NEUTRAL zip file if ( getExportData()->fExportOutputFileFormat == TExportData::EXE_FILE_FORMAT ) { #ifdef ALLOW_WEB_EXE if (!copyPreBundledZipToDirectory(IDR_WEBEXE_FILES_NEUTRAL_ZIP,getWorkingDirectory(),lResultFilePath_Neutral)) return false; #else if (!copyPreBundledZipToDirectory(IDR_WEBBOOK_FILES_NEUTRAL_ZIP,getWorkingDirectory(),lResultFilePath_Neutral)) return false; #endif } else { if (!copyPreBundledZipToDirectory(IDR_WEBBOOK_FILES_NEUTRAL_ZIP,getWorkingDirectory(),lResultFilePath_Neutral)) return false; } // Let's copy the LOOK&FEEL zip file if (!copyPreBundledZipToDirectory(IDR_WEBBOOK_FILES_LOOKANDFEEL_ZIP,getWorkingDirectory(),lResultFilePath_LookAndFeel)) return false; // Let's copy the LANGUAGE zip file if (!copyPreBundledZipToDirectory(IDR_WEBBOOK_FILES_LANG_ZIP,getWorkingDirectory(),lResultFilePath_Language)) return false; // ********** // Then, let's decompress all the copied ZIP files to a temporary directory // ********** CString lZipDecompressionFolder; TPath::CreateRandomFilePath(getWorkingDirectory(), _T(""),lZipDecompressionFolder); TPath::CreateDirectory(lZipDecompressionFolder); // Let's decompress the NEUTRAL zip file CString lZipDecompressionFolder_Neutral = CString((LPCTSTR)lZipDecompressionFolder); if (!doDecompression(lResultFilePath_Neutral,lZipDecompressionFolder_Neutral)) return false; // Let's decompress the LOOK&FEEL zip file CString lLookAndFeelFolderRelativePath = getLookAndFeelFolderRelativePath(); CString lZipDecompressionFolder_LookAndFeel = CString((LPCTSTR)lZipDecompressionFolder); TPath lPath_LookAndFeel(lZipDecompressionFolder_LookAndFeel); lPath_LookAndFeel.AddPath(lLookAndFeelFolderRelativePath); TPath::CreateDirectory(lZipDecompressionFolder_LookAndFeel); if (!doDecompression(lResultFilePath_LookAndFeel,lZipDecompressionFolder_LookAndFeel)) return false; // Let's decompress the LANGUAGE zip file CString lLanguageFolderRelativePath = getLanguageFolderRelativePath(); CString lZipDecompressionFolder_Language = CString((LPCTSTR)lZipDecompressionFolder); TPath lPath_Language(lZipDecompressionFolder_Language); lPath_Language.AddPath(lLanguageFolderRelativePath); TPath::CreateDirectory(lZipDecompressionFolder_Language); if (!doDecompression(lResultFilePath_Language,lZipDecompressionFolder_Language)) return false; CString lReconstructedZipFilePath; TPath::CreateRandomFilePath(getWorkingDirectory(), _T(".zip"),lReconstructedZipFilePath); if (!doCompression(lZipDecompressionFolder,lReconstructedZipFilePath)) return false; // Let's update the fields we are able to update in the TCompressionProcessingData struct pData->fPreBundledZipFilePath = lReconstructedZipFilePath; return true; } boolean TDHTMLKeeBookExportEngine::copyPreBundledZipToDirectory(WORD pZipDataResID, LPCTSTR pDir, CString& pResultZipFilePath) { CString lBundleZipFilePath; TPath::CreateRandomFilePath(pDir, _T(".zip"), lBundleZipFilePath); boolean bResult = copyResourceData(pZipDataResID, _T("ZIP_DATA"), lBundleZipFilePath); if (bResult) pResultZipFilePath = lBundleZipFilePath; return bResult; } boolean TDHTMLKeeBookExportEngine::appendToFile(LPCTSTR pTargetFile, LPCTSTR pAppendFile) { boolean bResult = false; CFile targetFile; CFile fromFile; if (targetFile.Open(pTargetFile, CFile::modeWrite)) { targetFile.SeekToEnd(); if (fromFile.Open(pAppendFile, CFile::modeRead)) { BYTE lpBuff[4096]; DWORD dwSizeInBytes = fromFile.GetLength(); TRY { DWORD dwDone = 0; DWORD dwReaded = 1; while ((dwDone < dwSizeInBytes) && dwReaded) { dwReaded = fromFile.Read(lpBuff, 4096); targetFile.Write(lpBuff, dwReaded); dwDone += dwReaded; } fromFile.Close(); targetFile.Close(); bResult = true; } CATCH(CFileException, e) { TErr::trace( TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, "Problem encountered when appending data to (%1) file", (LPCTSTR)pTargetFile); bResult = false; } END_CATCH } } return bResult; } boolean TDHTMLKeeBookExportEngine::copyResourceData(DWORD pResID, LPCTSTR pType, LPCTSTR pFilePath) { HINSTANCE hInst = KBFindResourceHandle(MAKEINTRESOURCE(pResID), pType); if (hInst == NULL) return false; HRSRC hResource = ::FindResource(hInst, MAKEINTRESOURCE(pResID), pType); if (hResource == NULL) return false; HGLOBAL lGlobal = ::LoadResource(hInst, hResource); if (lGlobal == NULL) return false; LPVOID lpBuff = ::LockResource(lGlobal); boolean bResult = true; CFile tmpFile; if (tmpFile.Open(pFilePath, CFile::modeCreate | CFile::modeWrite)) { DWORD dwSizeInBytes = ::SizeofResource(hInst, hResource); TRY { tmpFile.Write(lpBuff, dwSizeInBytes); tmpFile.Close(); } CATCH(CFileException, e) { TErr::trace( TErr::D_LOG, TErr::G_INF, TErr::NO_ID, __FILE__, __LINE__, "Problem encountered when copying data to (%1) file", (LPCTSTR)pFilePath); bResult = false; } END_CATCH } ::UnlockResource(hResource); ::FreeResource(hResource); } boolean TDHTMLKeeBookExportEngine::handleBundledFiles(TCompressionProcessingData* pData) { boolean res = true; if (!TZipManager::initDynaZip32_ZIP()) { return false; } int lBundleLength = fArchiveNamesMgr->getBundleSize(); if (lBundleLength > 0) { USES_CONVERSION; CString lFilesToZip; for (int ii = 0; ii < lBundleLength; ii++) { CString curLocalPath; CString curArchivePath; if (fArchiveNamesMgr->getBundleItemAt(ii, curLocalPath, curArchivePath)) { #if defined(_DEBUG) && defined(_DHTML_EXPORT_TRACE) TRACE2("TDHTMLDynamicKeeBookExportEngine::handleBundledFiles - localPath:[%s] - archivePath:[%s]\n",curLocalPath,curArchivePath); #endif curLocalPath.Replace(_T("\\"),_T("/")); lFilesToZip += CString("\"") + curLocalPath + CString("\""); if ( (ii + 1) < lBundleLength ) // means we'll loop at least once more { lFilesToZip += _T(' '); } } } ZIPCMDSTRUCT zipCmdStruct; TZipManager::initZIPCmdStruct((ZIPCMDSTRUCT FAR *)&zipCmdStruct); // Strings allocation LPSTR lpstr_lpszTempPath = (LPSTR)NULL; LPSTR lpstr_lpszZIPFile = (LPSTR)NULL; LPSTR lpstr_lpszItemList = (LPSTR)NULL; CString tmpDirPathBuffer; tmpDirPathBuffer = TSystemInfo::GetTempPath(); ASSERT(!tmpDirPathBuffer.IsEmpty()); if (!tmpDirPathBuffer.IsEmpty()) { lpstr_lpszTempPath = strdup(T2CA(tmpDirPathBuffer)); zipCmdStruct.pathForTempFlag = TRUE; zipCmdStruct.lpszTempPath = lpstr_lpszTempPath; } zipCmdStruct.function = ZIP_UPDATE; // We chose not to store directory entries because we cannot change // or cancel such entries in the 'Rename Callback' feature zipCmdStruct.noDirectoryEntriesFlag = TRUE; // Max compression zipCmdStruct.compFactor = 9; lpstr_lpszZIPFile = strdup(T2CA(pData->fPreBundledZipFilePath)); zipCmdStruct.lpszZIPFile = lpstr_lpszZIPFile; lpstr_lpszItemList = strdup(T2CA(lFilesToZip)); zipCmdStruct.lpszItemList = lpstr_lpszItemList; #if defined(_DEBUG) && defined(_DHTML_EXPORT_TRACE) zipCmdStruct.bDiagnostic = TRUE; #endif zipCmdStruct.lpRenameUserData = NULL; zipCmdStruct.lpMajorUserData = NULL; zipCmdStruct.lpMinorUserData = NULL; zipCmdStruct.lpMessageDisplayData = NULL; setZipCmdStructCallbacks(zipCmdStruct); int response = TZipManager::DZip_proc((ZIPCMDSTRUCT FAR *)&zipCmdStruct); delete zipCmdStruct.lpRenameUserData; delete zipCmdStruct.lpMajorUserData; delete zipCmdStruct.lpMinorUserData; delete zipCmdStruct.lpMessageDisplayData; // Strings deallocation free(lpstr_lpszTempPath); free(lpstr_lpszZIPFile); free(lpstr_lpszItemList); if (response != ZE_OK) { return false; } } if (!res) { // We should delete the potentially created but incomplete zip file } return res; }/*------------ TMAPIHelpers.h ------------*/ #ifndef T_MAPI_HELPERS #define T_MAPI_HELPERS typedef ULONG (FAR PASCAL MAPIGetNetscapeVersion)(); typedef MAPIGetNetscapeVersion FAR *LPMAPIGetNetscapeVersion; typedef BOOL (FAR PASCAL IsEudoraMapiDLL)(); typedef IsEudoraMapiDLL FAR *LPIsEudoraMapiDLL; // !!!!! This prototype is wrong, but since we do not call the method currently it's ok !!!!! typedef HRESULT (FAR PASCAL GetOutlookVersion)(ULONG*); typedef GetOutlookVersion FAR *LPGetOutlookVersion; inline BOOL CheckMAPIAvailable() { // We first try to load the MAPI32 DLL HINSTANCE lMAPILibrary = ::LoadLibrary("MAPI32.DLL"); if (!lMAPILibrary) // The MAPI32 DLL is not here, so we are quite sure that SMAPI isn't available return FALSE; ::FreeLibrary(lMAPILibrary); return TRUE; } inline HRESULT IsMAPINetscapeImplementation(ULONG* pNetscapeVersion) { if (!CheckMAPIAvailable()) return E_FAIL; HINSTANCE lMAPILibrary = ::LoadLibrary("MAPI32.DLL"); ATLASSERT(lMAPILibrary); LPMAPIGetNetscapeVersion MAPI_GetNescapeVersion = (LPMAPIGetNetscapeVersion)GetProcAddress(lMAPILibrary, "MAPIGetNetscapeVersion"); ULONG ulNetscapeVersion = 0; if (MAPI_GetNescapeVersion) { // This is the Netscape implementation of SMAPI ulNetscapeVersion = MAPI_GetNescapeVersion(); } ::FreeLibrary(lMAPILibrary); if (ulNetscapeVersion) { *pNetscapeVersion = ulNetscapeVersion; return S_OK; } return S_FALSE; } inline HRESULT IsMAPIEudoraImplementation() { if (!CheckMAPIAvailable()) return E_FAIL; HINSTANCE lMAPILibrary = ::LoadLibrary("MAPI32.DLL"); ATLASSERT(lMAPILibrary); LPIsEudoraMapiDLL MAPI_IsEudoraMapiDLL = (LPIsEudoraMapiDLL)GetProcAddress(lMAPILibrary, "IsEudoraMapiDLL"); ::FreeLibrary(lMAPILibrary); return MAPI_IsEudoraMapiDLL ? S_OK : S_FALSE; } inline HRESULT IsMAPIMicrosoftImplementation() { if (!CheckMAPIAvailable()) return E_FAIL; HINSTANCE lMAPILibrary = ::LoadLibrary("MAPI32.DLL"); ATLASSERT(lMAPILibrary); DWORD res; BOOL MAPIStatus = FALSE; CRegKey lWindowsMessagingSubsystemKey; res = lWindowsMessagingSubsystemKey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows Messaging Subsystem", KEY_READ); if (ERROR_SUCCESS == res) { TCHAR lMAPIValue[128]; DWORD lSize = 128; res = lWindowsMessagingSubsystemKey.QueryValue(lMAPIValue, _T("MAPI"), &lSize); if (ERROR_SUCCESS == res) { if (!_tcscmp(lMAPIValue, _T("1"))) MAPIStatus = TRUE; } } // Then it may be a MICROSOFT OutLook (Express) 5.x one // We check a specific new entry point, but we won't try to use it... LPGetOutlookVersion MAPI_GetOutlookVersion; MAPI_GetOutlookVersion = (LPGetOutlookVersion)GetProcAddress(lMAPILibrary, "GetOutlookVersion"); ::FreeLibrary(lMAPILibrary); /*** Great are the chances that the underlying MAPI client is a MICROSOFT OutLook (Express) 4.x one ***/ // This is the MICROSOFT OutLook (Express) 5.x implementation of SMAPI return (MAPIStatus && MAPI_GetOutlookVersion) ? S_OK : S_FALSE; } #endif // T_MAPI_HELPERS /*------------ TMAPIMessage.h ------------*/ #ifndef T_MAPI_MESSAGE #define T_MAPI_MESSAGE #include "MAPI.H" enum E_MAPI_MESSAGE_RESULT { E_MAPI_MESSAGE_ERROR_SUCCESS, E_MAPI_MESSAGE_ATTACH_FAILED, E_MAPI_MESSAGE_TO_FAILED, E_MAPI_MESSAGE_CC_FAILED, E_MAPI_MESSAGE_UNKNOWN_ERROR, E_MAPI_MESSAGE_ADD_RECIPIENT_FAILED }; class TMAPIMessage { public: TMAPIMessage() { memset(&fMAPIMessage, 0, sizeof(MapiMessage)); } virtual ~TMAPIMessage() { // Free malloced subject if (fMAPIMessage.lpszSubject) free(fMAPIMessage.lpszSubject); // Free malloced recipients for (int ii = 0; ii < (int)fMAPIMessage.nRecipCount; ii++) { free(fMAPIMessage.lpRecips[ii].lpszName); } // Free malloced attachments for (int jj = 0; jj < (int)fMAPIMessage.nFileCount; jj++) { free(fMAPIMessage.lpFiles[jj].lpszPathName); free(fMAPIMessage.lpFiles[jj].lpszFileName); } } public: MapiMessage fMAPIMessage; CString fSubject; CString fText; public: E_MAPI_MESSAGE_RESULT Subject(LPCTSTR pSubject) { if (fMAPIMessage.lpszSubject) { free(fMAPIMessage.lpszSubject); fMAPIMessage.lpszSubject = NULL; } if (pSubject) { fSubject = pSubject; fMAPIMessage.lpszSubject = strdup(fSubject); } return E_MAPI_MESSAGE_ERROR_SUCCESS; } E_MAPI_MESSAGE_RESULT To(LPCTSTR pRecipient) { E_MAPI_MESSAGE_RESULT lResult; lResult = AddRecipient(pRecipient, MAPI_TO); if (lResult == E_MAPI_MESSAGE_ADD_RECIPIENT_FAILED) return E_MAPI_MESSAGE_TO_FAILED; return lResult; } E_MAPI_MESSAGE_RESULT Cc(LPCTSTR pRecipient) { E_MAPI_MESSAGE_RESULT lResult; lResult = AddRecipient(pRecipient, MAPI_CC); if (lResult == E_MAPI_MESSAGE_ADD_RECIPIENT_FAILED) return E_MAPI_MESSAGE_TO_FAILED; return lResult; } E_MAPI_MESSAGE_RESULT Attach(LPCTSTR pFilePath, LPCTSTR pName) { if (!pFilePath) return E_MAPI_MESSAGE_ERROR_SUCCESS; if (!pName) pName = ::PathFindFileName(pFilePath); // Add a new attachment record fMAPIMessage.lpFiles = (MapiFileDesc *) realloc(fMAPIMessage.lpFiles, (fMAPIMessage.nFileCount + 1) * sizeof(MapiFileDesc)); ATLASSERT(fMAPIMessage.lpFiles); if (fMAPIMessage.lpFiles == (MapiFileDesc *) NULL) return E_MAPI_MESSAGE_ATTACH_FAILED; memset(&fMAPIMessage.lpFiles[fMAPIMessage.nFileCount], 0, sizeof(MapiFileDesc)); fMAPIMessage.lpFiles[fMAPIMessage.nFileCount].lpszPathName = strdup(pFilePath); if (strlen(pName)) fMAPIMessage.lpFiles[fMAPIMessage.nFileCount].lpszFileName = strdup(pName); fMAPIMessage.lpFiles[fMAPIMessage.nFileCount].nPosition = -1; // attachment position not indicated fMAPIMessage.lpFiles[fMAPIMessage.nFileCount].lpFileType = NULL; // not specified... fMAPIMessage.nFileCount++; return E_MAPI_MESSAGE_ERROR_SUCCESS; } E_MAPI_MESSAGE_RESULT Text(LPCTSTR pText) { if (fMAPIMessage.lpszNoteText) { free(fMAPIMessage.lpszNoteText); fMAPIMessage.lpszNoteText = NULL; } if (pText) { fText = pText; fMAPIMessage.lpszNoteText = strdup(fText); } return E_MAPI_MESSAGE_ERROR_SUCCESS; } E_MAPI_MESSAGE_RESULT AddRecipient(LPCTSTR pRecipient, ULONG pType) { if (!pRecipient) return E_MAPI_MESSAGE_ERROR_SUCCESS; CString lRecipient = pRecipient; // Add a new MapiRecipDesc structure and initialise it to all zeros fMAPIMessage.lpRecips = (MapiRecipDesc *) realloc(fMAPIMessage.lpRecips, (fMAPIMessage.nRecipCount + 1) * sizeof(MapiRecipDesc)); ATLASSERT(fMAPIMessage.lpRecips); if (fMAPIMessage.lpRecips == ((MapiRecipDesc *) NULL)) return E_MAPI_MESSAGE_TO_FAILED; memset(&fMAPIMessage.lpRecips[fMAPIMessage.nRecipCount], 0, sizeof(MapiRecipDesc)); fMAPIMessage.lpRecips[fMAPIMessage.nRecipCount].lpszName = strdup(lRecipient); fMAPIMessage.lpRecips[fMAPIMessage.nRecipCount].ulRecipClass = pType; fMAPIMessage.nRecipCount++; return E_MAPI_MESSAGE_ERROR_SUCCESS; } }; #endif // T_MAPI_MESSAGE /*------------ TMAPISender.h ------------*/ #ifndef T_MAPI_SENDER #define T_MAPI_SENDER #include "MAPIX.H" #include "MAPI.H" #include "TMAPIHelpers.h" #include "TMAPIMessage.h" #include "TRegKey.h" class TMAPIMessage; typedef SCODE (FAR PASCAL SCMAPIXFROMSMAPI)( LHANDLE lhSimpleSession, ULONG ulFlags, LPCIID lpInterface, LPMAPISESSION FAR * lppMAPISession ); typedef SCMAPIXFROMSMAPI FAR *LPSCMAPIXFROMSMAPI; enum E_MAPI_SENDER_RESULT { E_MAPI_SENDER_ERROR_SUCCESS, E_MAPI_SENDER_NOT_INITIALIZED, E_MAPI_SENDER_MAPI_NOT_AVAILABLE, E_MAPI_SENDER_NO_SESSION, E_MAPI_SENDER_INVALID_MESSAGE, E_MAPI_SENDER_LOGON_FAILED, E_MAPI_SENDER_SENDMAIL_FAILED, E_MAPI_SENDER_LOGOFF_FAILED, E_MAPI_SENDER_UNKNOWN_ERROR, }; class TMAPISender { public: TMAPISender() { m_bInitialized = FALSE; hMAPILibrary = NULL; MAPI_Logon = NULL; MAPI_SendMail = NULL; MAPI_Logoff = NULL; MAPI_ScMAPIXFromSMAPI = NULL; // This initialization is done because under Outlook 5, there is a DLL relocation issue. // The wab32.dll is loaded into memory at an adress when the Logon is done once. // It looks like it sets a property of an hwnd to an afxwndproc. But a little later, the // DLL gets relocated because of a collision, and the afxwndproc is relocated to. So when // the hwnd's property is got and used, there is a CRASH !!! // FIX : We load the wab32.dll into memory at first and never free it, so that it stays // allocated at the same adress between several calls to Logon... if (!gWABInitialized) gWABInitialized = initializeWAB(); initializeModule(); m_hSession = NULL; m_UIParam = NULL; } virtual ~TMAPISender() { if (m_bInitialized) { if (m_hSession) { // A session is open, so we have to logoff... E_MAPI_SENDER_RESULT resLogoff = this->Logoff(); ATLASSERT(resLogoff == E_MAPI_SENDER_ERROR_SUCCESS); } } uninitializeModule(); } protected: HINSTANCE hMAPILibrary; LHANDLE m_hSession; BOOL m_bInitialized; public: E_MAPI_SENDER_RESULT Logon(ULONG pFlags = MAPI_LOGON_UI | MAPI_NEW_SESSION) { ULONG ret; if (!m_bInitialized) InitializeError(); if (m_hSession) { // I already am logged, so I'll first logoff, and then logon again E_MAPI_SENDER_RESULT resLogoff = this->Logoff(); if (resLogoff != E_MAPI_SENDER_ERROR_SUCCESS) return resLogoff; } ret = MAPI_Logon(m_UIParam, NULL, NULL, pFlags, 0, &m_hSession); if ( (ret != SUCCESS_SUCCESS) || (!m_hSession) ) return E_MAPI_SENDER_LOGON_FAILED; return E_MAPI_SENDER_ERROR_SUCCESS; } E_MAPI_SENDER_RESULT Send(TMAPIMessage* pMessage, ULONG pFlags = MAPI_DIALOG) { ULONG ret; if (!m_bInitialized) InitializeError(); if (!m_hSession) return E_MAPI_SENDER_NO_SESSION; if (!pMessage || !(&pMessage->fMAPIMessage)) return E_MAPI_SENDER_INVALID_MESSAGE; ret = MAPI_SendMail( m_hSession, m_UIParam, // no parent window &pMessage->fMAPIMessage, pFlags, NULL); if (ret != SUCCESS_SUCCESS && ret != MAPI_E_USER_ABORT) return E_MAPI_SENDER_SENDMAIL_FAILED; return E_MAPI_SENDER_ERROR_SUCCESS; } E_MAPI_SENDER_RESULT Logoff() { ULONG ret; if (!m_bInitialized) InitializeError(); if (!m_hSession) return E_MAPI_SENDER_NO_SESSION; ret = MAPI_Logoff(m_hSession, m_UIParam, NULL, NULL); if (ret != SUCCESS_SUCCESS) return E_MAPI_SENDER_LOGOFF_FAILED; m_hSession = NULL; return E_MAPI_SENDER_ERROR_SUCCESS; } E_MAPI_SENDER_RESULT InitializeError() { if (!CheckMAPIAvailable()) return E_MAPI_SENDER_MAPI_NOT_AVAILABLE; return E_MAPI_SENDER_NOT_INITIALIZED; } void SetUIParam(HWND pParam) { m_UIParam = (ULONG)pParam; } protected: BOOL initializeModule() { if (m_bInitialized) return TRUE; if (!CheckMAPIAvailable()) return FALSE; // 'MAPI' DLL hMAPILibrary = ::LoadLibrary("MAPI32.DLL"); if (!hMAPILibrary) return FALSE; // ENTRY POINTS MAPI_Logon = (LPMAPILOGON)GetProcAddress(hMAPILibrary, "MAPILogon"); MAPI_SendMail = (LPMAPISENDMAIL)GetProcAddress(hMAPILibrary, "MAPISendMail"); MAPI_Logoff = (LPMAPILOGOFF)GetProcAddress(hMAPILibrary, "MAPILogoff"); if (!MAPI_Logon || !MAPI_SendMail || !MAPI_Logoff) { uninitializeModule(); return FALSE; } MAPI_ScMAPIXFromSMAPI = (LPSCMAPIXFROMSMAPI)GetProcAddress(hMAPILibrary, "ScMAPIXFromSMAPI"); m_bInitialized = TRUE; return TRUE; } BOOL uninitializeModule() { if (hMAPILibrary) { ::FreeLibrary(hMAPILibrary); hMAPILibrary = NULL; } MAPI_Logon = NULL; MAPI_SendMail = NULL; MAPI_Logoff = NULL; MAPI_ScMAPIXFromSMAPI = NULL; m_bInitialized = FALSE; return TRUE; } LPMAPILOGON MAPI_Logon; LPMAPISENDMAIL MAPI_SendMail; LPMAPILOGOFF MAPI_Logoff; LPSCMAPIXFROMSMAPI MAPI_ScMAPIXFromSMAPI; ULONG m_UIParam; private: static BOOL gWABInitialized; BOOL initializeWAB() // FIX an Outlook 5 issue... { BOOL result = FALSE; DWORD res; CRegKey lWindowsAdressBookDllPathKey; res = lWindowsAdressBookDllPathKey.Open(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\WAB\\DLLPath", KEY_READ); if (ERROR_SUCCESS == res) { DWORD lSize = MAX_PATH; TCHAR lDLLPathValue[MAX_PATH]; res = lWindowsAdressBookDllPathKey.QueryValue(lDLLPathValue, NULL, &lSize); if (ERROR_SUCCESS == res) { HINSTANCE lWABLibrary = ::LoadLibrary(lDLLPathValue); if (lWABLibrary) result = TRUE; } } return result; } }; __declspec(selectany) BOOL TMAPISender::gWABInitialized = FALSE; #endif // T_MAPI_SENDER /*------------ TWebBookImportManager.cpp ------------*/ #include "StdAfx.h" #include "Share.h" // INCLUDES #include "TWebBookImportManager.h" #include "TScriptImportExtension.h" #include "TImportWizardData.h" #include "TPtrArray.h" #include "TRunScript.h" #include "TNetHelpers.h" #include "TPath.h" #include "TUrl.h" //#include "TWizardHelper.h" #define T_KEEBOO_WEBBOOK_HEADER_MAX_SIZE 256 #define T_KEEBOO_LEGAL_STATEMENT1 "KeeBook from KeeBoo Corp" #define T_KEEBOO_LEGAL_STATEMENT2 "All rights reserved." TWebBookImportManager::TWebBookImportManager() { } TWebBookImportManager::~TWebBookImportManager() { } BOOL TWebBookImportManager::OpenFile(LPCTSTR pFileName, CFile& pFile, CFile::OpenFlags pMode) { CFileStatus lStatus; CString lFileName(pFileName); if (PathIsURL(lFileName)) { CComPtr<ISevenixCacheEntry> lEntry; CComBSTR lName; HRESULT lResult; lResult = CacheGetEntry(CComBSTR(pFileName), T_NETWORK_CACHE_NAME, &lEntry, T_CACHE_BEST_ELEMENT); ASSERT(SUCCEEDED(lResult) && (lEntry != NULL)); if (FAILED(lResult) || (lEntry == NULL)) return FALSE; lResult = lEntry->getFileName(&lName); ASSERT(SUCCEEDED(lResult)); if (FAILED(lResult)) return FALSE; lFileName = lName; } if (!CFile::GetStatus(lFileName, lStatus) || lStatus.m_size == 0) return FALSE; return pFile.Open(lFileName, pMode); } BOOL TWebBookImportManager::HandleFile(LPCTSTR pFile) { CString lExtension; if (CString(pFile).Find("kbscript:") == 0) return TRUE; lExtension = PathFindExtension(pFile); if (lExtension == ".js") { CFile lFile; if (OpenFile(pFile, lFile, CFile::modeRead)) { if (CheckFileHeader(&lFile)) return TRUE; } } return FALSE; } BOOL TWebBookImportManager::CheckFileHeader(CFile* pFile) { CString lFileHeader; pFile->Read(lFileHeader.GetBufferSetLength(T_KEEBOO_WEBBOOK_HEADER_MAX_SIZE), T_KEEBOO_WEBBOOK_HEADER_MAX_SIZE); lFileHeader.ReleaseBuffer(); pFile->SeekToBegin(); return CheckHeader(lFileHeader); } BOOL TWebBookImportManager::CheckHeader(CString pCode) { if ((pCode.Find(T_KEEBOO_LEGAL_STATEMENT1) != -1) && (pCode.Find(T_KEEBOO_LEGAL_STATEMENT2) != -1)) return TRUE; return FALSE; } HRESULT TWebBookImportManager::LoadScriptFile(LPCTSTR pFileName, CString& pCode, CString& pPath) { HRESULT lResult = E_FAIL; CFile lFile; if (OpenFile(pFileName, lFile, CFile::modeRead)) { long lSize; lSize = lFile.GetLength(); lFile.Read(pCode.GetBufferSetLength(lSize), lSize); if (CheckHeader(pCode)) { lResult = S_OK; CString lFileName(pFileName); TPath lPath(lFileName); if (lPath.IsURL()) { TUrl lUrl(lFileName); LPCTSTR lFile = ::PathFindFileName(lFileName); if (!_tcscmp("generated_file.js", lFile)) { lUrl.CombineUrl("../"); } else { lUrl.CombineUrl(""); } pPath = lUrl.extendedUrlString(); } else { lFileName.Replace('/', '\\'); LPCTSTR lFile = ::PathFindFileName(lFileName); if (!_tcscmp("generated_file.js", lFile)) lPath.RemoveFileSpec(); lPath.RemoveFileSpec(); // lFileName.Replace('\\', '/'); pPath = lFileName + "/"; } } else { pCode.Empty(); lResult = E_FAIL; } lFile.Close(); } return lResult; } void CountOccurence(LPCTSTR pString, LPCTSTR pToken, long& pCount) { while (pString = _tcsstr(pString, pToken)) pCount++, pString++; } long TWebBookImportManager::CountAddLines(LPCTSTR pCode) { long lCount = 0; CountOccurence(pCode, "KBInsertPage", lCount); CountOccurence(pCode, "KBInsertPicture", lCount); CountOccurence(pCode, "KBPushChapter", lCount); return lCount; } void TWebBookImportManager::RemoveOpenBook(CString& pCode) { long lOffset; lOffset = pCode.Find("KBOpenBook"); if (lOffset >= 0) { pCode.SetAt(lOffset, '/'); pCode.SetAt(lOffset + 1, '/'); } } boolean TWebBookImportManager::import(TImportData* pImportData) { TImportWizardData* lElement; long lCount; long lIndex = 0; if (fImportData == NULL) fImportData = pImportData; lCount = pImportData->fModelsToImport->size(); ASSERT(lCount == 1); while (pImportData->fModelsToImport->size()) { CString lCode; CString lPath; CString lFile; lElement = (TImportWizardData*)pImportData->fModelsToImport->elementAt(0); lFile = getInputFileName(); if (lFile.Find("kbscript:") == 0) { // DECLARE_BOOK_WIZARD(lWizard); // lWizard->ImportFromWebBook(CComBSTR(lFile)); lCode = lFile.Mid(9); } else { LoadScriptFile(lFile, lCode, lPath); } if (lCode.GetLength()) { long lCount; lCount = CountAddLines(lCode); if (!pImportData->fOpenLastBook) RemoveOpenBook(lCode); lCode = "// KBScript\n// KBInclude(BookLib)\n" + lCode; CComObject<TScriptImportExtension>* lExtension; CComPtr<IDispatch> lDisp; HRESULT lResult; lResult = CComObject<TScriptImportExtension>::CreateInstance(&lExtension); ASSERT(SUCCEEDED(lResult)); if (lExtension) { lExtension->SetImportManager(this); lExtension->SetPath(CComBSTR(lPath)); lExtension->SetProgressMax(lCount); lResult = lExtension->QueryInterface(&lDisp); ASSERT(SUCCEEDED(lResult)); } if (RunScript(lCode, lDisp) == S_OK) { pImportData->fImportedModels->addElement(lElement); lIndex++; } } pImportData->fModelsToImport->removeElementAt(0); } return lIndex == lCount; } boolean TWebBookImportManager::getBooksInfoForWizard(TPtrArray* pArray) { TImportWizardData* lData; lData = new TImportWizardData(); lData->fIsToImport = TRUE; pArray->addElement(lData); return TRUE; }/*------------ TXMLExportManager.cpp ------------*/ #include "StdAfx.h" // MAIN INCLUDE #ifndef T_XML_EXPORT_MANAGER #include "TXMLExportManager.h" #endif // OTHER INCLUDES #include "TXMLExportUtils.h" #include "TPtrToPtrHashTable.h" #include "TStringToPtrHashTable.h" #include "TObjectModel.h" #include "XMLObjectModel.h" #include "TPtrIterator.h" #include "TStringIterator.h" #include "TExportBuffer.h" #include "TMediaLibraryModel.h" #include "TBookModel.h" #include "TStringToStringHashTable.h" #include "TInteger.h" #include "TPropertyObjectModel.h" #include "TModelNames.h" #include "TBookPropertiesConstants.h" #include "TModelPtr.h" #include "TPtrArray.h" #include "XMLFileDescriptionObject.h" #include "XMLBookAvailableDescription.h" #include "CBase64Coding.h" #include "TGlobalResource.h" #include "SharedResource.h" #include "importExportResource.h" #include "TPath.h" #include "TSystemInfo.h" #include "atlbase.h" #include "shlwapi.h" #include "TProgressHelper.h" #include "TErr.h" ///////////////////// extern HINSTANCE g_hDllMain; /***********************************/ /***** class TXMLExportManager *****/ /***********************************/ // CONSTRUCTORS TXMLExportManager::TXMLExportManager() { fXMLExportUtils = new TXMLExportUtils(); fFilesToCompress = null; fTmpMainXmlFile = null; fProgressHelper = new TProgressHelper(); } // DESTRUCTORS TXMLExportManager::~TXMLExportManager() { if (fXMLExportUtils) { delete fXMLExportUtils; } fXMLExportUtils = null; if (fFilesToCompress) { TStringIterator* strIter = fFilesToCompress->keys(); while (strIter->hasMoreElements()) { TString curKey = strIter->nextElement(); fFilesToCompress->remove(curKey); } delete strIter; delete fFilesToCompress; fFilesToCompress = null; } if (fProgressHelper) { delete fProgressHelper; fProgressHelper = NULL; } } // METHODS TPtrToPtrHashTable* TXMLExportManager::getModelRefToIDTable() { return fModelRefToIDTable; } /* TStringToPtrHashTable* TXMLExportManager::getModelNameToFileTable() { return fModelNameToFileTable; } */ TStringToPtrHashTable* TXMLExportManager::getModelNameToIDTable() { return fModelNameToIDTable; } TXMLExportUtils* TXMLExportManager::getExportUtils() { return fXMLExportUtils; } TExportBuffer* TXMLExportManager::getExportBuffer(TObjectModel* pObj) { if (fModelNameToFileTable == null) fModelNameToFileTable = new TStringToPtrHashTable(); TExportBuffer* file = (TExportBuffer *)fModelNameToFileTable->get(pObj->getID()); if (file == null) { file = new TExportBuffer(); fModelNameToFileTable->put(pObj->getID(), file); } return file; } TExportBuffer* TXMLExportManager::getExportBuffer(LPCTSTR pObjectName) { if (fModelNameToFileTable == null) fModelNameToFileTable = new TStringToPtrHashTable(); TExportBuffer* file = (TExportBuffer *)fModelNameToFileTable->get(pObjectName); if (file == null) { file = new TExportBuffer(); fModelNameToFileTable->put(pObjectName, file); } return file; } long TXMLExportManager::getIDCount(TObjectModel* pObj) { if (fModelNameToIDTable == null) { fModelNameToIDTable = new TStringToPtrHashTable(); } DWORD idPtr = (DWORD)fModelNameToIDTable->get(pObj->getID()); if ((void *)idPtr == null) { idPtr = (DWORD)1; fModelNameToIDTable->put(pObj->getID(),(void *)idPtr); return idPtr; } else { idPtr++; fModelNameToIDTable->put(pObj->getID(),(void *)idPtr); return idPtr; } } long TXMLExportManager::getIDCount(LPCTSTR pObjectName) { if (fModelNameToIDTable == null) { fModelNameToIDTable = new TStringToPtrHashTable(); } DWORD idPtr = (DWORD)fModelNameToIDTable->get(pObjectName); if ((void *)idPtr == null) { idPtr = (DWORD)1; fModelNameToIDTable->put(pObjectName,(void *)idPtr); return idPtr; } else { idPtr++; fModelNameToIDTable->put(pObjectName,(void *)idPtr); return idPtr; } } boolean TXMLExportManager::canExport(TExportData* pExportData, LPCTSTR pOutputFileName) { if (pExportData == null) return false; // Let's check if the output format is compatible if (pExportData->fExportOutputFormat != TExportData::NATIVE_KEEBOOK_FORMAT) { TErr::trace( TErr::D_LOG | TErr::D_BOX, TErr::G_FAT, TErr::NO_ID, __FILE__, __LINE__, "Xml Export Output Format not supported : (%1!d!)", pExportData->fExportOutputFormat); return false; } // Let's check if the output file format is compatible if (pExportData->fExportOutputFileFormat != TExportData::SXB_FILE_FORMAT) { TErr::trace( TErr::D_LOG | TErr::D_BOX, TErr::G_FAT, TErr::NO_ID, __FILE__, __LINE__, "Xml Export Output File Format not supported : (%1!d!)", pExportData->fExportOutputFileFormat); return false; } return TExportManager::canExport(pExportData, pOutputFileName); } boolean TXMLExportManager::export(TExportData* pExportData, LPCTSTR pOutputFileName) { CString statusStr; boolean res = true; if (fExportData == NULL) fExportData = pExportData; // PROGRESS NOTIFICATION if (fExportData->fMessageCallback != NULL) { KBLoadString(IDS_PROGRESS_EXPORT_BEGIN,statusStr); int resVal = (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_STATUS,0,0,(LPSTR)(LPCTSTR)statusStr,NULL,fExportData->fMessageCallbackData); UNUSED_ALWAYS(resVal); } if (!canExport(pExportData,pOutputFileName)) { return false; } /****************/ /***** INIT *****/ /****************/ // ------------------------------ // Progress Helper Initialization // ------------------------------ fLastReportedPercentage = 0; // Phase 1 -> All the exportObject processing // Phase 2 -> putEverythingTogether // Phase 3 -> doCompression float lPhase1TotalPercentage = 70; float lPhase2TotalPercentage = 10; float lPhase3TotalPercentage = 20; fProgressHelper->setPhaseCount(3); fProgressHelper->setTotalPercentageForPhase(1, lPhase1TotalPercentage); fProgressHelper->setTotalPercentageForPhase(2, lPhase2TotalPercentage); fProgressHelper->setTotalPercentageForPhase(3, lPhase3TotalPercentage); // ------------------------------ // PROGRESS NOTIFICATION { // We use the Progress Bar Control if (fExportData->fMessageCallback != NULL) { (void) (fExportData->fMessageCallback)(TExportData::WM_MESSAGE_CALLBACK_PROGRESS_INIT_USE_PROGRESS_BAR,0,0,NULL,NULL,(fExportData->fMessageCallbackData)); } fProgressHelper->setCurrentPercentageForPhase(1,0.0f); reportCurrentGlobalPercentage(); } // let's be sure th