int OmnisTools::getIntFromEXTFldVal(EXTfldval& fVal, qlong firstID, qlong lastID) { if (getType(fVal).valType == fftInteger) { return getIntFromEXTFldVal(fVal); } else if (getType(fVal).valType == fftConstant) { return getIntFromEXTFldVal(fVal); } int retNum = -1; // Get string that needs to be matched std::wstring matchString = getWStringFromEXTFldVal(fVal); // Get map iterator for searching std::map<std::wstring,int>::iterator it; it = constCache.find(matchString); if (it != constCache.end()) { retNum = it->second; } else { // Unable to find match, must loop constants in range and look for it int tildePos, colonPos, numPos, constNum; EXTfldval convVar; str255 resourceValue; std::wstring resourceMatch, resourceString; std::wstring numString = L""; for( int i = firstID; i <= lastID; ++i) { // Load resource and put into std::wstring for easy substr RESloadString(gInstLib,i,resourceValue); convVar.setChar(resourceValue, dpDefault); resourceString = getWStringFromEXTFldVal(convVar); tildePos = resourceString.find(L"~") + 1; colonPos = resourceString.find(L":"); if (colonPos != -1) { // All constants should have colons. If it doesn't then don't interpret the line resourceMatch = resourceString.substr(tildePos, colonPos-tildePos); // While looping add items to the const cache numPos = colonPos + 1; numString.clear(); while (resourceString[numPos] != L':' && numPos < static_cast<int>(resourceString.length())) { numString += resourceString[numPos++]; } try { constNum = lexical_cast<int>(numString); } catch(bad_lexical_cast &) { constNum = -1; } constCache[resourceMatch] = constNum; // Add constant to cache } } // Locate constant now that all the constants have been cached it = constCache.find(matchString); if (it != constCache.end()) { retNum = it->second; } } return retNum; }
// Get an EXTfldval for a defined constant void OmnisTools::getEXTFldValFromConstant(EXTfldval& fVal, qlong constID, qlong prefixID) { // Check for prefix str80 prefixRead; str255 constantValue; if (prefixID > 0) { // Read string from resource, and assign it to return parameter RESloadString(gInstLib,prefixID,prefixRead); constantValue.concat(prefixRead); } // Read complete resource string str255 resourceValue; RESloadString(gInstLib,constID,resourceValue); // Translate into std::wstring for easy substring EXTfldval convVar; convVar.setChar(resourceValue, dpDefault); std::wstring resourceString = getWStringFromEXTFldVal(convVar); // Get substring between tilde (sometimes used for categories) and first colon. int tildePos = resourceString.find(L"~") + 1; int colonPos = resourceString.find(L":"); std::wstring constantString = resourceString.substr(tildePos,colonPos-tildePos); getEXTFldValFromWString(convVar, constantString); // Add constant to EXTfldval constantValue.concat(convVar.getChar()); fVal.setConstant(constantValue); }
// Set an existing EXTfldval object from a std::string void OmnisTools::getEXTFldValFromString(EXTfldval& fVal, const std::string readString) { qlong length; qchar* omnisString = getQCharFromString(readString, length); fVal.setChar(omnisString, length); // Set value of character field, but exclude the last character since it will be the null terminator from the C String // Clean-up delete [] omnisString; }
qbool OmnisTools::ensurePosixPath(EXTfldval& pathVal) { #ifdef ismac str255 posixCheck, posixPath; qshort def = dpFcharacter; posixCheck = pathVal.getChar().cString(); qlong err; std::wstring path = getWStringFromEXTFldVal(pathVal); if (path[0] != L'/') { err = ECOconvertHFSToPosix(posixCheck, posixPath); if (err != 0) { return qfalse; } pathVal.setChar(posixPath, def); } #endif return qtrue; }
extern "C" qlong OMNISWNDPROC NVObjWndProc(HWND hwnd, LPARAM Msg, WPARAM wParam, LPARAM lParam, EXTCompInfo* eci) { ECOsetupCallbacks(hwnd, eci); // Initialize callback tables - THIS MUST BE DONE // Message Dispatch switch (Msg) { // ECM_OBJCONSTRUCT - this is a message to create a new object. case ECM_OBJCONSTRUCT: { // Check if object already exists (if it does there is nothing more to do) NVObjBase* nvObj = (NVObjBase*) ECOfindNVObject(eci->mOmnisInstance, lParam ); if ( nvObj ) { return qtrue; } // Build thread data tThreadData threadData(eci); // Allocate a new object qlong propID = eci->mCompId; // Get ID of object nvObj = createObject(propID, (qobjinst)lParam, &threadData ); if (nvObj) { // and insert into a chain of objects. The OMNIS library will maintain this chain ECOinsertNVObject( eci->mOmnisInstance, lParam, nvObj ); return qtrue; } return qfalse; } // ECM_OBJDESTRUCT - this is a message to inform you to delete the object case ECM_OBJDESTRUCT: { if (ECM_WPARAM_OBJINFO == wParam) // Make sure its when the NV object is really meant to go (as opposed to $destruct being called) { // First find the object in the libraries chain of objects, // this call, if ok, also removes the object from the chain. void* obj = ECOremoveNVObject( eci->mOmnisInstance, lParam ); if ( obj ) { // Now you can delete the object you previously allocated. // Note: The hwnd passed on ECM_OBJCONSTRUCT should not be deleted, as // it was created (and will be destroyed by) OMNIS qlong propID = eci->mCompId; // Get ID of object removeObject(propID, (NVObjBase*) obj); } } return qtrue; } // ECM_CONNECT - this message is sent once per OMNIS session and should not be confused // with ECM_OBJCONSTRUCT which is sent once per object. ECM_CONNECT can be used to load other libraries // once or other general global actions that need to be done only once. // // For most components this can be removed - see other BLYTH component examples case ECM_CONNECT: { return EXT_FLAG_LOADED|EXT_FLAG_NVOBJECTS|EXT_FLAG_REMAINLOADED|EXT_FLAG_ALWAYS_USABLE; // Return external flags. Loaded & Has Non-Visual Objects } // ECM_DISCONNECT - this message is sent only once when the OMNIS session is ending and should not be confused // with ECM_OBJDESTRUCT which is sent once per object. ECM_DISCONNECT can be used to free other libraries // loaded on ECM_CONNECT or other general global actions that need to be done only once. // // For most components this can be removed - see other BLYTH component examples case ECM_DISCONNECT: { return qtrue; } // ECM_OBJECT_COPY - this message is called when an object needs to be copied by Omnis (and you must do so in C++ as well). case ECM_OBJECT_COPY: { tThreadData threadData(eci); objCopyInfo* copyInfo = (objCopyInfo*)lParam; qlong propID = eci->mCompId; // Get ID of object copyObject(propID, copyInfo, &threadData); } // ECM_GETSTATICOBJECT - this is sent by OMNIS to retrieve a list of static methods case ECM_GETSTATICOBJECT: { tThreadData threadData(eci); return returnStaticMethods( &threadData ); } // ECM_GETMETHODNAME - this is sent by OMNIS to retrieve a list of methods for object instances case ECM_GETMETHODNAME: { tThreadData threadData(eci); qlong objID = eci->mCompId; // Get ID of object // Create a temporary object, use it to retrieve the methods, and destruct it. NVObjBase* obj = createObject( objID, 0, &threadData ); // 0 = no qobjinst (because this isn't being created by Omnis) qlong ret = obj->returnMethods( &threadData ); // Call virtual method to get properties for the requested object removeObject( objID, obj ); return ret; } // ECM_METHODCALL - this is sent by OMNIS to call a method in the non-visual object case ECM_METHODCALL: { tThreadData threadData(eci); void* obj = ECOfindNVObject( eci->mOmnisInstance, lParam ); if ( NULL != obj ) { // Method from Object Instance NVObjBase* nvObj = reinterpret_cast<NVObjBase*>(obj); return nvObj->methodCall(&threadData); } else { // Static method return staticMethodCall( &threadData ); } return qfalse; } // ECM_GETPROPNAME - this is sent by OMNIS to find out which properties an object has case ECM_GETPROPNAME: { tThreadData threadData(eci); qlong objID = eci->mCompId; // Get ID of object // Create a temporary object, use it to retrieve the properties, and destruct it. NVObjBase* obj = createObject( objID, 0, &threadData ); // 0 = no qobjinst (because this isn't being created by Omnis) qlong ret = obj->returnProperties( &threadData ); // Call virtual method to get properties for the requested object removeObject( objID, obj ); return ret; } // ECM_PROPERTYCANASSIGN - this is sent by OMNIS to find out if a specific property can be assigned or not case ECM_PROPERTYCANASSIGN: { tThreadData threadData(eci); // Get ID of property qlong propID = ECOgetId( eci ); // Get the instance of the object NVObjBase* nvObj = reinterpret_cast<NVObjBase*>(ECOfindNVObject(eci->mOmnisInstance, lParam)); if( NULL != nvObj ) // Get the property from that instance return nvObj->canAssignProperty( &threadData, propID ); else return qfalse; } // ECM_GETPROPERTY - this is sent by OMNIS to determine the value of a specific property case ECM_GETPROPERTY: { tThreadData threadData(eci); // Get the instance of the object NVObjBase* nvObj = reinterpret_cast<NVObjBase*>(ECOfindNVObject(eci->mOmnisInstance, lParam)); if( NULL != nvObj ) // Get the property from that instance return nvObj->getProperty( &threadData ); else return 0L; } // ECM_SETPROPERTY - this is sent by OMNIS to set the value of a specific property case ECM_SETPROPERTY: { tThreadData threadData(eci); NVObjBase* nvObj = reinterpret_cast<NVObjBase*>(ECOfindNVObject(eci->mOmnisInstance, lParam)); if( NULL != nvObj ) // Set the property in the instance return nvObj->setProperty( &threadData ); else return 0L; } // ECM_GETCONSTPREFIX - this is sent by OMNIS to get the prefix that is used for all constants in this component case ECM_CONSTPREFIX: { EXTfldval exfldval; str80 conPrefix; // Read string from resource, and assign it to return parameter RESloadString(gInstLib,kConstResourcePrefix,conPrefix); exfldval.setChar(conPrefix); ECOaddParam(eci,&exfldval); return qtrue; } // ECM_GETCONSTNAME - this is sent by OMNIS to get all the names of the constants in the component case ECM_GETCONSTNAME: { return ECOreturnConstants( gInstLib, eci, kConstResourceStart, kConstResourceEnd ); } // ECM_GETCOMPLIBINFO - this is sent by OMNIS to find out the name of the library, and // the number of visual components this library supports case ECM_GETCOMPLIBINFO: { return ECOreturnCompInfo( gInstLib, eci, LIB_RES_NAME, 0 ); } // ECM_GETOBJECT - this is sent by OMNIS to find out which Omnis objects this component is responsible for case ECM_GETOBJECT: { return ECOreturnObjects( gInstLib, eci, &objectsTable[0], cObjCount ); } // ECM_GETVERSION - this is sent by OMNIS to find out the version of your external case ECM_GETVERSION: { return ECOreturnVersion(VERSION_MAJOR,VERSION_MINOR); } // ECM_ISUNICODE - this is sent by OMNIS to find out if your external supports unicode case ECM_ISUNICODE: { return qtrue; // This external is Studio 5.0+ only } } // As a final result this must ALWAYS be called. It handles all other messages that this component // decides to ignore. return WNDdefWindowProc(hwnd,Msg,wParam,lParam,eci); }