// load an external type library VOID FAR LoadExtTypeLib ( LPIMPORTLIB lpImpLib ) { ITypeLib FAR* lptlib; HRESULT res; BSTR bstrName; SETITEMCUR(lpImpLib->lpszFileName); // get * to ITypeLib interface CHECKRESULT(LoadTypeLib(ToW(lpImpLib->lpszFileName), &lptlib)); lpImpLib->lptlib = lptlib; // get name of this library CHECKRESULT(lptlib->GetDocumentation(-1, &bstrName, NULL, NULL, NULL)); // copy library name from the BSTR lpImpLib->lpszLibName = _fstrdup(ToA(bstrName)); SysFreeString(bstrName); // free the BSTR // get * to ITypeComp interface CHECKRESULT(lptlib->GetTypeComp(&(lpImpLib->lptcomp))); // get library attributes CHECKRESULT(lptlib->GetLibAttr(&(lpImpLib->lptlibattr))); }
int main() { int mid = 0; int Array[] = {0,1,2,3,4,1,6,1,8,1,100}; //int Array[] = {0,2,2,3,4,1,11,1}; printf("Initial list is : "); displayList(Array, 0, N); mid = ToW(Array, 0, N-1, 0, 0); printf("List one is : "); displayList(Array, 0, mid); printf("List Two is : "); displayList(Array, mid, N); }
int ToW(int Array[N], int L1, int L2, int Sum1, int Sum2) { int i = 0, high = L1; if(L1 == L2) { printf("Sum of lists are %d and %d and difference of List is %d\n", Sum1, Sum2, (Sum1-Sum2) > 0 ?Sum1-Sum2:Sum2-Sum1); return L2; } for(i = L1; i <= L2; i++) { if(Array[i] > Array[high]) { high = i; } } if(Sum1 < Sum2) { Sum1 = Sum1 + Array[high]; Swap(Array, L1, high); ToW(Array, L1+1, L2, Sum1, Sum2); } else { Sum2 = Sum2 + Array[high]; Swap(Array, L2, high); ToW(Array, L1, L2-1, Sum1, Sum2); } }
cNewO_CombineCple::cNewO_CombineCple(const cStructMergeTieP< cFixedSizeMergeTieP<2,Pt2dr> > & aMap,ElRotation3D * aTestSol) : mCurStep (1<<NbPow2), mNbStepTeta (4 * NbDecoup0PIS2 * mCurStep), mCurRot (3,3), mW (0) { // REDONDANT AVEC FONCTION GLOBALES FAITE APRES .... PackReduit /******************************************************/ /* */ /* A- Selection des sommets */ /* */ /******************************************************/ //------------------------------------------------------------------------ // A- 1- Preselrection purement aleatoire d'un nombre raisonnable depoints //------------------------------------------------------------------------ const std::list<tMerge *> & aLM = aMap.ListMerged(); RMat_Inertie aMat; { cRandNParmiQ aSelec(NbMaxInit, (int)aLM.size()); for (std::list<tMerge *>::const_iterator itM=aLM.begin() ; itM!=aLM.end() ; itM++) { if (aSelec.GetNext()) { mVAllCdt.push_back(cCdtCombTiep(*itM)); Pt2dr aP1 = (*itM)->GetVal(0); aMat.add_pt_en_place(aP1.x,aP1.y); } } } aMat = aMat.normalize(); int aNbSomTot = int(mVAllCdt.size()); double aSurfType = sqrt (aMat.s11()* aMat.s22() - ElSquare(aMat.s12())); double aDistType = sqrt(aSurfType/aNbSomTot); double aSzW = 800; if (1) { mP0W = aMap.ValInf(0); Pt2dr aP1 = aMap.ValSup(0); Pt2dr aSz = aP1-mP0W; mP0W = mP0W - aSz * 0.1; aP1 = aP1 + aSz * 0.1; aSz = aP1-mP0W; mScaleW = aSzW /ElMax(aSz.x,aSz.y) ; mW = Video_Win::PtrWStd(round_ni(aSz*mScaleW)); } //------------------------------------------------------------------------ // A-2 Calcul d'une fonction de deponderation //------------------------------------------------------------------------ for (int aKS1 = 0 ; aKS1 <aNbSomTot ; aKS1++) { for (int aKS2 = aKS1 ; aKS2 <aNbSomTot ; aKS2++) { // sqrt pour attenuer la ponderation double aDist = sqrt(dist48( mVAllCdt[aKS1].mP1-mVAllCdt[aKS2].mP1) / 2.0); // aDist=1; // double aDist = (dist48( mVAllCdt[aKS1].mP1-mVAllCdt[aKS2].mP1) / 2.0); double aPds = 1 / (aDistType+aDist); mVAllCdt[aKS1].mPdsOccup += aPds; mVAllCdt[aKS2].mPdsOccup += aPds; } if (mW) mW->draw_circle_abs(ToW( mVAllCdt[aKS1].mP1),2.0,mW->pdisc()(P8COL::blue)); } for (int aKSom = 0 ; aKSom <aNbSomTot ; aKSom++) { cCdtCombTiep & aCdt = mVAllCdt[aKSom]; aCdt.mPdsOccup *= ElSquare(aCdt.mMerge->NbArc()); } int aNbSomSel = ElMin(aNbSomTot,NbTieP); //------------------------------------------------------------------------ // A-3 Calcul de aNbSomSel points biens repartis //------------------------------------------------------------------------ ElTimer aChrono; for (int aKSel=0 ; aKSel<aNbSomSel ; aKSel++) { // Recherche du cdt le plus loin double aMaxDMin = 0; cCdtCombTiep * aBest = 0; for (int aKSom = 0 ; aKSom <aNbSomTot ; aKSom++) { cCdtCombTiep & aCdt = mVAllCdt[aKSom]; double aDist = aCdt.mDMin * aCdt.mPdsOccup; if ((!aCdt.mTaken) && (aDist > aMaxDMin)) { aMaxDMin = aDist; aBest = & aCdt; } } ELISE_ASSERT(aBest!=0,"cNewO_CombineCple"); for (int aKSom = 0 ; aKSom <aNbSomTot ; aKSom++) { cCdtCombTiep & aCdt = mVAllCdt[aKSom]; aCdt.mDMin = ElMin(aCdt.mDMin,dist48(aCdt.mP1-aBest->mP1)); } aBest->mQ1 = vunit(Pt3dr(aBest->mP1.x,aBest->mP1.y,1.0)); Pt2dr aP2 = aBest->mMerge->GetVal(1); aBest->mQ2Init = vunit(Pt3dr(aP2.x,aP2.y,1.0)); mVCdtSel.push_back(aBest); if (mW) mW->draw_circle_abs(ToW( aBest->mP1),3.0,mW->pdisc()(P8COL::red)); } /******************************************************/ /* */ /* B- Calcul des arcs */ /* */ /******************************************************/ // B-1 Au max le nombre d'arc possible int aNbA = NbCple; while (aNbA > ((aNbSomSel * (aNbSomSel-1)) /2)) aNbA--; int aNbIter = (aNbA-1) / aNbSomSel + 1; cRandNParmiQ aSelec(aNbA- (aNbIter-1) * aNbSomSel,aNbSomSel); int aNbAMaj = aNbIter * aNbSomSel; std::vector<int> aPermut = RandPermut(aNbA); // B-2 Recherche des arsc int aKA=0; for (int aCptAMaj = 0 ; aCptAMaj < aNbAMaj ; aCptAMaj++) { // Tous les sommets sont equi repartis, sauf a la fin on choisit a hasard bool aSelK = true; if ( (aCptAMaj/aNbSomSel)== (aNbIter-1)) // Si derniere iter, test special { aSelK = aSelec.GetNext(); } if (aSelK) { int aKP1 = (aCptAMaj%aNbSomSel); double aTeta = (aPermut[aKA] * 2 * PI) / aNbA; Pt2dr aDir = Pt2dr::FromPolar(1.0,aTeta); // std::cout << "teta " << aTeta << "\n"; double aBestSc=-1.0; int aBestK=-1; for (int aKP2 = 0 ; aKP2 < aNbSomSel ; aKP2++) { if (aKP2!=aKP1) { Pt2dr aV = (mVCdtSel[aKP2]->mP1- mVCdtSel[aKP1]->mP1) / aDir; Pt2dr aU = vunit(aV); // Favorise les llongs arc et homogeneise les directions double aSc = NRrandom3() * euclid(aV) * (1/(1+ElSquare(5.0*aU.y))); if ((aSc>aBestSc) && (aKP2!=aKP1)) { aBestSc= aSc; aBestK = aKP2; } } } ELISE_ASSERT((aBestK>=0),"No Best Arc"); mLArcs.push_back(Pt2di(aKP1,aBestK)); if (mW) { mW->draw_seg(ToW( mVCdtSel[aKP1]->mP1),ToW( mVCdtSel[aBestK]->mP1),mW->pdisc()(P8COL::green)); } aKA++; } } /******************************************************/ /* */ /* */ /* */ /******************************************************/ if (mW) mW->clik_in(); if (aTestSol) { ElRotation3D aR = * aTestSol; // Le sens corret a ete retabli (j'espere !!) // SetCurRot(aR.Mat()); // std::cout << "Test Externe : " << CalculCostCur() <<"\n"; // aR = aR.inv(); SetCurRot(aR.Mat()); std::cout << "Test Externe I : " << CalculCostCur() <<"\n"; std::cout << "CostBase " << CostOneBase(aR.tr()) << "\n"; // ElRotation3D * } std::cout << "cNewO_CombineCple::cNewO_CombineCple " << aNbSomTot << "\n"; Pt3di aP; std::list<Pt3di> aLPMin; double aCostMin = 1e10; Pt3di aPMin(1000,1000,1000); for (aP.x = -NbDecoup0PIS2 ; aP.x <= NbDecoup0PIS2 ; aP.x ++) { std::cout << "DECx " << aP.x << "\n"; for (aP.y = -NbDecoup0PIS2 ; aP.y <= NbDecoup0PIS2 ; aP.y ++) { for (aP.z = - (2*NbDecoup0PIS2) ; aP.z < (2*NbDecoup0PIS2) ; aP.z ++) { double aVC = GetCost(aP*mCurStep); bool IsMinLoc = (aVC < GetCost((aP+Pt3di( 1,0,0)) * mCurStep)) && (aVC < GetCost((aP+Pt3di(-1,0,0)) * mCurStep)) && (aVC < GetCost((aP+Pt3di(0, 1,0)) * mCurStep)) && (aVC < GetCost((aP+Pt3di(0,-1,0)) * mCurStep)) && (aVC < GetCost((aP+Pt3di(0,0, 1)) * mCurStep)) && (aVC < GetCost((aP+Pt3di(0,0,-1)) * mCurStep)); int aDelta = 2; for (int aDx=-aDelta ; (aDx<=aDelta) && IsMinLoc ; aDx++) { for (int aDy=-aDelta ; (aDy<=aDelta) && IsMinLoc ; aDy++) { for (int aDz=-aDelta ; (aDz<=aDelta) && IsMinLoc ; aDz++) { if ((aDx!=0) || (aDy!=0) || (aDz!=0)) { IsMinLoc = IsMinLoc && (aVC<GetCost( (aP+Pt3di(aDx,aDy,aDz))*mCurStep)); } } } } if (IsMinLoc) { std::cout << " IisssMinn " << aP << " " << aVC << "\n"; aLPMin.push_back(aP*mCurStep); } if (aVC<aCostMin) { aPMin = aP*mCurStep; aCostMin = aVC; } } } } std::cout << "COST " << aCostMin << " PMIN " << PInt2Tetas(aPMin ) << " NbMinLoc " << aLPMin.size() << "\n"; Pt3dr aTeta = PInt2Tetas(aPMin); ElMatrix<double> aR = ElMatrix<double>::Rotation(aTeta.z,aTeta.y,aTeta.x); for (int aY=0 ; aY<3 ; aY++) { for (int aX=0 ; aX<3 ; aX++) { std::cout << aR(aX,aY) << " "; } std::cout << "\n"; } /* std::cout << "Sssz " << aLPMin.size() << "\n"; if ( aLPMin.size()>0) std::cout << "PP00 " << *(aLPMin.begin()) << "\n"; */ }
WeightConverter(FromW const& from, ToW& to) { to = ToW(from.getValue()); }
std::wstring ToW(const std::string& str) { return ToW(str.c_str(), str.length()); }
VOID NEAR OutputElems ( ICreateTypeInfo FAR* lpdtinfo, LPELEM pElemList, TYPEKIND tkind ) { LPELEM pElem; HRESULT res; UINT iElem = 0; // element index VARDESC VarDesc; if (pElemList == NULL) return; pElem = (LPELEM)ListFirst(pElemList); // point to first entry for (;;) { // First fill in the VARDESC structure with the element's info SETITEMCUR(pElem->szElemName); VarDesc.memid = DISPID_UNKNOWN; // assume not a dispinterface // Set up varkind switch (tkind) { case TKIND_ENUM: // for enum elements case TKIND_MODULE: // for const's VarDesc.varkind = VAR_CONST; VarDesc.lpvarValue = pElem->lpElemVal; // * to value if (tkind == TKIND_MODULE) goto DoLoadElemDesc; // set up the tdesc // For ENUM elements, can't call LoadElemDesc, because // we have no pElem->elemType. Do the required work here. VarDesc.elemdescVar.tdesc.vt = VT_INT; // element type // is an INT VarDesc.elemdescVar.idldesc.wIDLFlags = 0; // no IDL info #ifdef WIN16 VarDesc.elemdescVar.idldesc.bstrIDLInfo = NULL; #else //WIN16 VarDesc.elemdescVar.idldesc.dwReserved = 0; #endif //WIN16 break; case TKIND_RECORD: case TKIND_UNION: VarDesc.varkind = VAR_PERINSTANCE; goto DoLoadElemDesc; default: #if FV_PROPSET Assert(tkind == TKIND_DISPATCH || tkind == TKIND_PROPSET); #else //FV_PROPSET Assert(tkind == TKIND_DISPATCH); #endif //FV_PROPSET VarDesc.varkind = VAR_DISPATCH; // id' attribute required Assert (pElem->attr.fAttr & fID); VarDesc.memid = pElem->attr.lId; DoLoadElemDesc: // Set up elemdescVar. Contains name, and type of item. LoadElemDesc(lpdtinfo, &(VarDesc.elemdescVar), pElem); } // VarDesc.oInst is not used when doing AddVarDesc VarDesc.wVarFlags = 0; if (pElem->attr.fAttr & fREADONLY) VarDesc.wVarFlags |= (WORD)VARFLAG_FREADONLY; if (pElem->attr.fAttr & fSOURCE) VarDesc.wVarFlags |= (WORD)VARFLAG_FSOURCE; if (pElem->attr.fAttr & fBINDABLE) VarDesc.wVarFlags |= (WORD)VARFLAG_FBINDABLE; if (pElem->attr.fAttr & fREQUESTEDIT) VarDesc.wVarFlags |= (WORD)VARFLAG_FREQUESTEDIT; if (pElem->attr.fAttr & fDISPLAYBIND) VarDesc.wVarFlags |= (WORD)VARFLAG_FDISPLAYBIND; if (pElem->attr.fAttr & fDEFAULTBIND) VarDesc.wVarFlags |= (WORD)VARFLAG_FDEFAULTBIND; if (pElem->attr.fAttr & fHIDDEN) VarDesc.wVarFlags |= (WORD)VARFLAG_FHIDDEN; // Now define the element CHECKRESULT(lpdtinfo->AddVarDesc(iElem, &VarDesc)); // Lastly, set element's remaining attributes: CHECKRESULT(lpdtinfo->SetVarName(iElem, ToW(pElem->szElemName))); if (pElem->attr.fAttr & fHELPSTRING) CHECKRESULT(lpdtinfo->SetVarDocString(iElem, ToW(pElem->attr.lpszHelpString))); if (pElem->attr.fAttr & fHELPCONTEXT) CHECKRESULT(lpdtinfo->SetVarHelpContext(iElem, pElem->attr.lHelpContext)); // advance to next entry if not all done if (pElem == (LPELEM)ListLast(pElemList)) break; // exit if all done pElem = pElem->pNext; iElem++; // advance element counter } }
VOID NEAR OutputFuncs ( ICreateTypeInfo FAR* lpdtinfo, LPENTRY pEntry, LPFUNC pFuncList, TYPEKIND tkind ) { LPFUNC pFunc; LPELEM pArg; HRESULT res; UINT iFunc = 0; // function index LPOLESTR lpszDllName; LPSTR lpszProcName; SHORT i; FUNCDESC FuncDesc; LPOLESTR FAR* lplpszArgName; if (pFuncList == NULL) // just return if no functions to output return; FuncDesc.lprgelemdescParam = rgFuncArgs; // set up array of args pFunc = (LPFUNC)ListFirst(pFuncList); // point to first entry #if FV_UNICODE_OLE lpszDllName = (pEntry->attr.fAttr & fDLLNAME ? ToNewW(pEntry->attr.lpszDllName) : NULL); #else lpszDllName = pEntry->attr.lpszDllName; #endif for (;;) { // Fill in the FUNCDESC structure with the function's info // set up funckind switch (tkind) { case TKIND_MODULE: FuncDesc.funckind = FUNC_STATIC; break; case TKIND_INTERFACE: FuncDesc.funckind = FUNC_PUREVIRTUAL; break; case TKIND_DISPATCH: FuncDesc.funckind = FUNC_DISPATCH; break; default: Assert(FALSE); } // set up invkind FuncDesc.invkind = INVOKE_FUNC; // default if (pFunc->func.attr.fAttr & fPROPGET) FuncDesc.invkind = INVOKE_PROPERTYGET; else if (pFunc->func.attr.fAttr & fPROPPUT) FuncDesc.invkind = INVOKE_PROPERTYPUT; else if (pFunc->func.attr.fAttr & fPROPPUTREF) FuncDesc.invkind = INVOKE_PROPERTYPUTREF; // set up callconv if (pFunc->func.attr.fAttr2 & f2PASCAL) // CC_MACPASCAL if /mac specified, CC_MSCPASCAL otherwise FuncDesc.callconv = (CALLCONV)(SysKind == SYS_MAC ? CC_MACPASCAL: CC_MSCPASCAL); else if (pFunc->func.attr.fAttr2 & f2CDECL) FuncDesc.callconv = CC_CDECL; else if (pFunc->func.attr.fAttr2 & f2STDCALL) FuncDesc.callconv = CC_STDCALL; #ifdef DEBUG else Assert(FALSE); #endif //DEBUG FuncDesc.wFuncFlags = 0; if (pFunc->func.attr.fAttr & fRESTRICTED) FuncDesc.wFuncFlags |= (WORD)FUNCFLAG_FRESTRICTED; if (pFunc->func.attr.fAttr & fSOURCE) FuncDesc.wFuncFlags |= (WORD)FUNCFLAG_FSOURCE; if (pFunc->func.attr.fAttr & fBINDABLE) FuncDesc.wFuncFlags |= (WORD)FUNCFLAG_FBINDABLE; if (pFunc->func.attr.fAttr & fREQUESTEDIT) FuncDesc.wFuncFlags |= (WORD)FUNCFLAG_FREQUESTEDIT; if (pFunc->func.attr.fAttr & fDISPLAYBIND) FuncDesc.wFuncFlags |= (WORD)FUNCFLAG_FDISPLAYBIND; if (pFunc->func.attr.fAttr & fDEFAULTBIND) FuncDesc.wFuncFlags |= (WORD)FUNCFLAG_FDEFAULTBIND; if (pFunc->func.attr.fAttr & fHIDDEN) FuncDesc.wFuncFlags |= (WORD)FUNCFLAG_FHIDDEN; // set up cParams & cParamsOpt FuncDesc.cParams = pFunc->cArgs; FuncDesc.cParamsOpt = pFunc->cOptArgs; //NOTE: cParamsOpt can be set to -1, to note that last parm is a //NOTE: [safe] array of variant args. This corresponds to the //NOTE: 'vararg' attribute in the input description. If this was //NOTE: specified, the parser set pFunc->cOptArgs to -1 for us. // set up misc unused stuff FuncDesc.oVft = 0; // only used for FUNC_VIRTUAL FuncDesc.cScodes = -1; // list of SCODEs unknown FuncDesc.lprgscode = NULL; // set id field if 'id' attribute specified if (pFunc->func.attr.fAttr & fID) FuncDesc.memid = pFunc->func.attr.lId; else FuncDesc.memid = DISPID_UNKNOWN; // set up elemdescFunc // Contains the ID, name, and return type of the function LoadElemDesc(lpdtinfo, &(FuncDesc.elemdescFunc), &pFunc->func); // save function name lplpszArgName = rgszFuncArgNames; *lplpszArgName++ = ToNewW(pFunc->func.szElemName); SETITEMCUR(pFunc->func.szElemName); // set up the lprgelemdescParam array of info for each parameter pArg = pFunc->argList; // point to last arg, if any for (i = 0; i < pFunc->cArgs; i++) { pArg = pArg->pNext; // point to next arg (first arg // first time through loop) LoadElemDesc(lpdtinfo, &(FuncDesc.lprgelemdescParam[i]), pArg); *lplpszArgName++ = ToNewW(pArg->szElemName); // save arg name } // Define the function item: CHECKRESULT(lpdtinfo->AddFuncDesc(iFunc, &FuncDesc)); // set the names of the function and the parameters Assert(i == pFunc->cArgs); // don't set the name of the last param for proput/putref functions if (pFunc->func.attr.fAttr & (fPROPPUT | fPROPPUTREF)) { i--; } CHECKRESULT(lpdtinfo->SetFuncAndParamNames(iFunc, rgszFuncArgNames, i+1)); #if FV_UNICODE_OLE // free the unicode function & param names lplpszArgName = rgszFuncArgNames; for (i = 0; i <= pFunc->cArgs; i++) { _ffree(*lplpszArgName); // done with unicode name lplpszArgName++; } #endif //FV_UNICODE_OLE // Set the function item's remaining attributes: if (pFunc->func.attr.fAttr & fHELPSTRING) CHECKRESULT(lpdtinfo->SetFuncDocString(iFunc, ToW(pFunc->func.attr.lpszHelpString))); if (pFunc->func.attr.fAttr & fHELPCONTEXT) CHECKRESULT(lpdtinfo->SetFuncHelpContext(iFunc, pFunc->func.attr.lHelpContext)); // Handle case of a DLL entrypoint if (pFunc->func.attr.fAttr & fENTRY) { // If high word of name is zero, then call by ordnal // If high word of name is non-zero, then call by name // (same as GetProcAddress) lpszProcName = pFunc->func.attr.lpszProcName; #if FV_UNICODE_OLE if (HIWORD(lpszProcName)) { lpszProcName = (LPSTR)ToW(lpszProcName); } #endif //FV_UNICODE_OLE CHECKRESULT(lpdtinfo->DefineFuncAsDllEntry(iFunc, lpszDllName, (LPOLESTR)lpszProcName)); } // advance to next entry if not all done if (pFunc == (LPFUNC)ListLast(pFuncList)) break; // exit if all done pFunc = (LPFUNC)pFunc->func.pNext; iFunc++; // advance function counter } #if FV_UNICODE_OLE if (lpszDllName) _ffree(lpszDllName); // done with unicode name #endif //FV_UNICODE_OLE }
// For each library entry, creates a typeinfo in the typelib, // and fills it in. VOID NEAR OutputTypeInfos ( ICreateTypeLib FAR * lpdtlib ) { LPENTRY pEntry; TYPEKIND tkind; HRESULT res; ICreateTypeInfo FAR* lpdtinfo; WORD wTypeFlags; // First allocate an array of ELEMDESCs to hold the max # of // args of any function we need to describe. rgFuncArgs = (ELEMDESC FAR*)_fmalloc(cArgsMax * sizeof(ELEMDESC)); rgszFuncArgNames = (LPOLESTR FAR *)_fmalloc((cArgsMax+1) * sizeof(LPOLESTR)); if (rgFuncArgs == NULL || rgszFuncArgNames == NULL) ParseError(ERR_OM); // pass 1 -- create the typeinfo's pEntry = (LPENTRY)ListFirst(typlib.pEntry); // point to first entry for (;;) { // determine if we are going to create a typeinfo for this guy switch (pEntry->type.tentrykind) { case tTYPEDEF: if (pEntry->attr.fAttr) // create lpdtinfo only if break; // this is a 'PUBLIC' typedef NoTypeInfos: pEntry->lpdtinfo = NULL; // no lpdtinfo for this case tREF: // no typeinfo's made for these case tINTRINSIC: goto Next_Entry1; default: // no typeinfo's made for forward declarations if (pEntry->type.tentrykind & tFORWARD) goto NoTypeInfos; if (pEntry->type.tentrykind & tIMPORTED) goto Next_Entry1; // nothing for imported types break; } // 1. determine kind of typeinfo to create tkind = rgtkind[pEntry->type.tentrykind]; // 2. Create type library entry (TypeInfo) of a given name/and // type, getting a pointer to the ICreateTypeInfo interface SETITEMCUR(pEntry->type.szName); CHECKRESULT(lpdtlib->CreateTypeInfo(ToW(pEntry->type.szName), tkind, &lpdtinfo)); pEntry->lpdtinfo = lpdtinfo; // 3. Set the item's attributes: if (pEntry->attr.fAttr & fUUID) CHECKRESULT(lpdtinfo->SetGuid(*pEntry->attr.lpUuid)); if (pEntry->attr.fAttr & fHELPSTRING) CHECKRESULT(lpdtinfo->SetDocString(ToW(pEntry->attr.lpszHelpString))); if (pEntry->attr.fAttr & fHELPCONTEXT) CHECKRESULT(lpdtinfo->SetHelpContext(pEntry->attr.lHelpContext)); if (pEntry->attr.fAttr & fVERSION) CHECKRESULT(lpdtinfo->SetVersion(pEntry->attr.wVerMajor, pEntry->attr.wVerMinor)); // 4. save lptinfo for this guy in case somebody references it CHECKRESULT(lpdtinfo->QueryInterface(IID_ITypeInfo, (VOID FAR* FAR*)&pEntry->type.lptinfo)); // if this type has a forward declaration if (pEntry->lpEntryForward) { // copy "real" type info over top of forward declaration, // because folks have pointers to the forward declaration pEntry->lpEntryForward->type.tdesc = pEntry->type.tdesc; pEntry->lpEntryForward->type.lptinfo = pEntry->type.lptinfo; // Only need to copy these 2 fields from the type (the // others aren't referenced at type creation time. } Next_Entry1: // advance to next entry if not all done if (pEntry == (LPENTRY)ListLast(typlib.pEntry)) break; // exit if all done pEntry = (LPENTRY)pEntry->type.pNext; } // pass 2 -- process each entry pEntry = (LPENTRY)ListFirst(typlib.pEntry); // point to first entry for (;;) { // 1. Get our lpdtinfo again if we have one switch (pEntry->type.tentrykind) { case tREF: case tINTRINSIC: goto Next_Entry2; // these guys don't have lpdtinfo field default: if (pEntry->type.tentrykind & tIMPORTED) goto Next_Entry2; // no lpdtinfo field break; } lpdtinfo = pEntry->lpdtinfo; if (lpdtinfo == NULL) // skip if no lpdtinfo created goto Next_Entry2; // (forward decl or non-public typedef) // set up for error reporting SETITEMCUR(pEntry->type.szName); // 2. determine kind of typeinfo we're dealing with tkind = rgtkind[pEntry->type.tentrykind]; // 2a. Set the typeinfo flags wTypeFlags = 0; if (tkind == TKIND_COCLASS) { // COCLASSs always have FCANCREATE bit set wTypeFlags |= TYPEFLAG_FCANCREATE; // these are only valid on COCLASSs if (pEntry->attr.fAttr & fAPPOBJECT) wTypeFlags |= (WORD)TYPEFLAG_FAPPOBJECT; if (pEntry->attr.fAttr & fLICENSED) wTypeFlags |= (WORD)TYPEFLAG_FLICENSED; if (pEntry->attr.fAttr & fPREDECLID) wTypeFlags |= (WORD)TYPEFLAG_FPREDECLID; } if (pEntry->attr.fAttr & fHIDDEN) wTypeFlags |= (WORD)TYPEFLAG_FHIDDEN; if (pEntry->attr.fAttr2 & f2CONTROL) wTypeFlags |= (WORD)TYPEFLAG_FCONTROL; if (pEntry->attr.fAttr2 & f2NONEXTENSIBLE) wTypeFlags |= (WORD)TYPEFLAG_FNONEXTENSIBLE; if (pEntry->attr.fAttr2 & f2DUAL) // DUAL implies OLEAUTOMATION wTypeFlags |= (WORD)(TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION); if (pEntry->attr.fAttr2 & f2OLEAUTOMATION) wTypeFlags |= (WORD)TYPEFLAG_FOLEAUTOMATION; CHECKRESULT(lpdtinfo->SetTypeFlags(wTypeFlags)); // 3. now process each kind of entry switch (tkind) { case TKIND_ALIAS: OutputAlias(lpdtinfo, pEntry->type.td.ptypeAlias); break; case TKIND_RECORD: // struct's, enum's, and union's are case TKIND_ENUM: // all very similar case TKIND_UNION: OutputElems(lpdtinfo, pEntry->type.structenum.elemList, tkind); break; case TKIND_MODULE: OutputFuncs(lpdtinfo, pEntry, pEntry->module.funcList, tkind); OutputElems(lpdtinfo, pEntry->module.constList, tkind); break; case TKIND_INTERFACE: OutputInterface(lpdtinfo, pEntry); break; case TKIND_DISPATCH: OutputDispinter(lpdtinfo, pEntry); break; case TKIND_COCLASS: OutputClass(lpdtinfo, pEntry); break; #if FV_PROPSET case TKIND_PROPSET: // CONSIDER: (FV_PROPSET) do something with base_propset name OutputElems(lpdtinfo, pEntry->propset.propList, tkind); break; #endif //FV_PROPSET default: Assert(FALSE); }; // 3a. Set the alignment for this TypeInfo. Must be done before // Layout(). CHECKRESULT(lpdtinfo->SetAlignment(iAlignMax)); // 4. Compile this typeinfo we've just created. SETITEMCUR(pEntry->type.szName); CHECKRESULT(lpdtinfo->LayOut()); // 5. Cleanup. All done with lpdtinfo. lpdtinfo->Release(); Next_Entry2: // advance to next entry if not all done if (pEntry == (LPENTRY)ListLast(typlib.pEntry)) break; // exit if all done pEntry = (LPENTRY)pEntry->type.pNext; } // now clean up everything else _ffree(rgFuncArgs); // done with function args we allocated _ffree(rgszFuncArgNames); }
VOID FAR OutputTyplib ( CHAR * szTypeLibFile ) { HRESULT res; ICreateTypeLib FAR * lpdtlib; #ifndef MAC CHAR szTypeLibFileTmp[128]; #endif //!MAC WORD wLibFlags; fDoingOutput = TRUE; // signal to error reporting code SETITEMCUR(typlib.szLibName); #ifndef MAC // pre-pend ".\" to filename if unqualified name, to work-around OLE path // searching bug. if (!XStrChr(szTypeLibFile, '\\') && !XStrChr(szTypeLibFile, '/') && *(szTypeLibFile+1) != ':') { // if unqualified name strcpy(szTypeLibFileTmp, ".\\"); strcpy(szTypeLibFileTmp+2, szTypeLibFile); // this name is used later -- don't free it //free(szTypeLibFile); szTypeLibFile = szTypeLibFileTmp; } #endif // 1. Get * to ICreateTypeLib interface CHECKRESULT(CreateTypeLib(SysKind, ToW(szTypeLibFile), &lpdtlib)); // WARNING: SetLCID must be called before the anything in the nammgr is used // it needs to be called even if the user doesn't specifiy an lcid // (in which case we default to an lcid of 0). CHECKRESULT(lpdtlib->SetLcid( (typlib.attr.fAttr & fLCID) ? typlib.attr.lLcid : 0 )); // 2. Set the library name: CHECKRESULT(lpdtlib->SetName(ToW(typlib.szLibName))); // 3. Set the library attributes, if present: if (typlib.attr.fAttr & fHELPSTRING) CHECKRESULT(lpdtlib->SetDocString(ToW(typlib.attr.lpszHelpString))); if (typlib.attr.fAttr & fHELPCONTEXT) CHECKRESULT(lpdtlib->SetHelpContext(typlib.attr.lHelpContext)); if (typlib.attr.fAttr & fHELPFILE) CHECKRESULT(lpdtlib->SetHelpFileName(ToW(typlib.attr.lpszHelpFile))); if (typlib.attr.fAttr & fVERSION) CHECKRESULT(lpdtlib->SetVersion(typlib.attr.wVerMajor, typlib.attr.wVerMinor)); if (typlib.attr.fAttr & fUUID) CHECKRESULT(lpdtlib->SetGuid(*typlib.attr.lpUuid)); wLibFlags = 0; if (typlib.attr.fAttr & fRESTRICTED) wLibFlags |= LIBFLAG_FRESTRICTED; if (typlib.attr.fAttr2 & f2CONTROL) wLibFlags |= LIBFLAG_FCONTROL; if (typlib.attr.fAttr & fHIDDEN) wLibFlags |= LIBFLAG_FHIDDEN; CHECKRESULT(lpdtlib->SetLibFlags(wLibFlags)); // 4. Output all the typinfo's into the type library if (typlib.pEntry) // if any entries OutputTypeInfos(lpdtlib); // 5. Save the typlib to the give file SETITEMCUR(typlib.szLibName); CHECKRESULT(lpdtlib->SaveAllChanges()); // 6. Cleanup. All done -- release release the ICreateTypeLib. lpdtlib->Release(); // release the ICreateTypeLib }
// find type defined in an external type library, // and add it to the type table if found. // lpszLibName is NULL if we're to look in ALL external type libraries. LPTYPE FAR FindExtType ( LPSTR lpszLibName, LPSTR lpszTypeName ) { LPIMPORTLIB lpImpLib; HRESULT res; ULONG lHashVal; ITypeInfo FAR* lptinfo; ITypeComp FAR* lptcomp; Assert (lpszTypeName != NULL); if (typlib.pImpLib != NULL) // if any imported type libraries { // point to first imported library entry lpImpLib = (LPIMPORTLIB)ListFirst(typlib.pImpLib); for (;;) { // if we're to look in all libraries, or this specific lib if (lpszLibName == NULL || !FCmpCaseIns(lpszLibName, lpImpLib->lpszLibName)) { SETITEMCUR(lpImpLib->lpszFileName); lHashVal = LHashValOfNameSysA(lpImpLib->lptlibattr->syskind, lpImpLib->lptlibattr->lcid, lpszTypeName); CHECKRESULT(lpImpLib->lptcomp->BindType(ToW(lpszTypeName), lHashVal, &lptinfo, &lptcomp)); if (lptinfo) // if found { // create a type table entry for this guy ListInsert(&typlib.pEntry, sizeof(TYPE)); // lpszTypeName will get freed by caller. // We must allocate new memory for it. typlib.pEntry->type.szName = _fstrdup(lpszTypeName); // CONSIDER: do a GetTypeAttr on this guy, // to ensure it's not a 'module' type typlib.pEntry->type.tdesc.vt = VT_USERDEFINED; // init this now in case of error, since // error cleanup code looks at this. typlib.pEntry->type.lptinfo = NULL; LPTYPEATTR ptypeattr; TENTRYKIND tentrykind; CHECKRESULT(lptinfo->GetTypeAttr(&ptypeattr)); // Get the interface typeinfo instead of // the Dispinteface version. if (ptypeattr->wTypeFlags & TYPEFLAG_FDUAL){ ITypeInfo FAR* lptinfo2; HREFTYPE hreftype; CHECKRESULT(lptinfo->GetRefTypeOfImplType((unsigned int)-1, &hreftype)); CHECKRESULT(lptinfo->GetRefTypeInfo(hreftype, &lptinfo2)); lptinfo->Release(); lptinfo->ReleaseTypeAttr(ptypeattr); lptinfo = lptinfo2; CHECKRESULT(lptinfo->GetTypeAttr(&ptypeattr)); } typlib.pEntry->type.lptinfo = lptinfo; // assume generic imported type tentrykind = (TENTRYKIND)(rgtentrykind[ptypeattr->typekind] | tIMPORTED); if (lpszLibName) { tentrykind = (TENTRYKIND)(tentrykind | tQUAL); } typlib.pEntry->type.tentrykind = tentrykind; typlib.pEntry->type.import.wTypeFlags = ptypeattr->wTypeFlags; lptinfo->ReleaseTypeAttr(ptypeattr); return &(typlib.pEntry->type); // all done } } // advance to next entry if not all done if (lpImpLib == (LPIMPORTLIB)ListLast(typlib.pImpLib)) break; // exit if all done lpImpLib = lpImpLib->pNext; } // WHILE } return (LPTYPE)NULL; //type not found }