コード例 #1
0
/*----------------------------------------------------------------------------------------------
	Open a main window on a particular object in a particular database on a particular field
	in a particular object using a particular view.
	Will fail if the specified tool cannot handle the specified top-level object.
	Returns a value which can be used to identify the particular window in subsequent calls.
	@param bstrServerName Name of the MSDE/SQLServer computer.
	@param bstrDbName Name of the database.
	@param hvoLangProj Which languate project within the database.
	@param hvoMainObj The top-level object on which to open the window.
	@param encUi The user-interface writing system.
	@param nTool A tool-dependent identifier of which tool to use.
	@param nParam Another tool-dependent parameter.
	@param prghvo Pointer to an array of object ids.
	@param chvo Number of object ids in prghvo.
	@param prgflid Pointer to an array of flids.
	@param cflid Number of flids in prgflid.
	@param ichCur Cursor offset from beginning of field.
	@param nView The view to display when showing the first object. Use -1 to use the first
		data entry view.
	@param ppidNew Process id of the new main window's process.
	@param phtool Handle to the newly created window.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP AfFwTool::NewMainWndWithSel(BSTR bstrServerName, BSTR bstrDbName, int hvoLangProj,
	int hvoMainObj, int encUi, int nTool, int nParam, const HVO * prghvo, int chvo,
		const int * prgflid, int cflid, int ichCur, int nView, int * ppidNew, long * phtool)
{
	BEGIN_COM_METHOD
	ChkComBstrArg(bstrServerName);
	ChkComBstrArg(bstrDbName);
	ChkComArrayArg(prghvo, chvo);
	ChkComArrayArg(prgflid, cflid);
	ChkComOutPtr(ppidNew);
	ChkComOutPtr(phtool);

	const CLSID * pclsid = AfApp::Papp()->GetAppClsid();
	DWORD dwRegister = 0;
	if (pclsid)
	{
		// Check to see if the application is already running.
		IRunningObjectTablePtr qrot;
		CheckHr(::GetRunningObjectTable(0, &qrot));
		IMonikerPtr qmnk;
		CheckHr(::CreateClassMoniker(*pclsid, &qmnk));
		IUnknownPtr qunk;
		IFwToolPtr qtool;
		if (SUCCEEDED(qrot->GetObject(qmnk, &qunk)))
		{
			if (SUCCEEDED(qunk->QueryInterface(IID_IFwTool, (void **)&qtool)) &&
				qtool.Ptr() != this)
			{
				// The document is already open in another process, so create a new
				// window in that process.
				qtool->NewMainWndWithSel(bstrServerName, bstrDbName, hvoLangProj, hvoMainObj,
					encUi, nTool, nParam, prghvo, chvo, prgflid, cflid, ichCur, nView,
					ppidNew, phtool);
				// After we create the new window in the other process, we exit here.
				// When the IFwTool pointer pointing to 'this' goes out of scope, the
				// second process (if it was launched from Windows Explorer or the
				// command line) will shut down automatically.
				return S_OK;
			}
		}
		else
		{
			// Note: ROTFLAGS_ALLOWANYCLIENT causes an error on Win2K (The class is
			// configured to run as a security ID different from the caller).
			CheckHr(qrot->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, this, qmnk,
				&dwRegister));
		}
	}
	AfApp::Papp()->NewMainWndWithSel(bstrServerName, bstrDbName, hvoLangProj, hvoMainObj,
		encUi, nTool, nParam, prghvo, chvo, prgflid, cflid, ichCur, nView, dwRegister);
	// The handle we return is actually the hwnd of the top-level window.
	// ENHANCE JohnT: we should probably make htool a long...
	*phtool = (long)(AfApp::Papp()->GetCurMainWnd()->Hwnd());
	if (ppidNew)
		*ppidNew = (int)::GetCurrentProcessId();

	return S_OK;

	END_COM_METHOD(g_fact, IID_IFwTool);
}
コード例 #2
0
/*----------------------------------------------------------------------------------------------
	Read an array of ITsTextProps from a byte array and return it. If cpttpMax == 0, return
	in cpttpRet the number of items present. Return S_FALSE if the array is not totally
	consumed, but at least one ITsTextProps is successfully read.

	For runs that have duplicate properties (ie, where the offsets into the properties stuff
	are identical), returns duplicate pointers in rgpttp.

	Also return the character counts for each run, so that we can reconstruct the
	run information later on.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP TsPropsFact::DeserializeRgPropsRgb(int cpttpMax, const BYTE * prgb, int * pcb,
		int * pcpttpRet, ITsTextProps ** rgpttp, int * rgich)
{
	BEGIN_COM_METHOD;
	ChkComArgPtr(pcb);
	ChkComOutPtr(pcpttpRet);
	ChkComArrayArg(prgb, *pcb);
	ChkComArrayArg(rgpttp, cpttpMax);
	ChkComArrayArg(rgich, cpttpMax);

	DataReaderRgb drrHdr(prgb, *pcb);
	int crun;
	drrHdr.ReadInt(&crun);
	if (cpttpMax == 0)
	{
		*pcpttpRet = crun;
	}
	else
	{
		Vector<int> vcbOffsets;
		vcbOffsets.Resize(crun);

		const byte * pbRun0 = prgb + isizeof(int) + (crun * isizeof(int) * 2);

		for (int irun = 0; irun < min(cpttpMax, crun); irun++)
		{
			drrHdr.ReadInt(rgich + irun); // character min
			int cbOffsetThisRun;
			drrHdr.ReadInt(&cbOffsetThisRun);
			vcbOffsets[irun] = cbOffsetThisRun;

			// Check for a duplicate set of properties.
			int irunDup;
			for (irunDup = 0; irunDup < irun; irunDup++)
			{
				if (cbOffsetThisRun == vcbOffsets[irunDup])
				{
					// Duplicate offset: copy the previous ITsTextProps.
					rgpttp[irun] = rgpttp[irunDup];
					rgpttp[irun]->AddRef();
					break;
				}
			}
			if (irunDup >= irun) // didn't find duplicate
			{
				const byte * pbThisRun = pbRun0 + cbOffsetThisRun;
				// Note that the buffer size is provided below simply as a sanity check. The
				// data itself is structured so that the deserialize method knows how much
				// to read for each run.
				DataReaderRgb drr(pbThisRun, (*pcb - (pbThisRun - prgb)));
				TsTextProps::DeserializeDataReader(&drr, rgpttp + irun);
			}
		}
		*pcpttpRet = min(cpttpMax, crun);
	}

	END_COM_METHOD(g_factPropsFact, IID_ITsPropsFactory);
}
コード例 #3
0
ファイル: LgIcuCollator.cpp プロジェクト: FieldDB/FieldWorks
/*----------------------------------------------------------------------------------------------
	Generate a sort key.
	If output pointer is null, just gives the needed length in *pcchOut.
	This is the main interesting routine, which uses Windows system code to actually make
	the sort key.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgIcuCollator::SortKeyRgch(const OLECHAR * pch, int cchIn,
	LgCollatingOptions colopt, int cchMaxOut, OLECHAR * pchKey, int * pcchOut)
{
	BEGIN_COM_METHOD
	ChkComArrayArg(pch, cchIn);
	ChkComArrayArg(pchKey, cchMaxOut);

	return E_NOTIMPL;

	END_COM_METHOD(g_fact, IID_ILgCollatingEngine);
}
コード例 #4
0
/*----------------------------------------------------------------------------------------------
	Write the given number of bytes to the stream / file.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FileStream::Write(const void * pv, ULONG cb, ULONG * pcbWritten)
{
	BEGIN_COM_METHOD;
	ChkComArrayArg((byte *)pv, cb);
	ChkComArgPtrN(pcbWritten);

	if (m_hfile == NULL)
		ThrowHr(WarnHr(E_UNEXPECTED));
	if (cb == 0)
	{
		if (pcbWritten)
			*pcbWritten = 0;
		return S_OK;
	}

	if (!SetFilePosRaw())
		ThrowHr(WarnHr(STG_E_SEEKERROR));
	DWORD cbWritten = 0;
	if (!WriteFile(m_hfile, pv, cb, &cbWritten, NULL))
		ThrowHr(WarnHr(STG_E_WRITEFAULT));

	m_ibFilePos.QuadPart += cbWritten;
	if (pcbWritten)
		*pcbWritten = cbWritten;

	END_COM_METHOD(g_fact, IID_IStream);
}
コード例 #5
0
ファイル: FwGrEngine.cpp プロジェクト: bbriggs/FieldWorks
/*----------------------------------------------------------------------------------------------
	Return a list of the feature IDs. If cMax is zero, pcfid returns the number of features
	supported. Otherwise it contains the number put into the array.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FwGrEngine::GetFeatureIDs(int cMax, int * prgFids, int * pcfid)
{
	BEGIN_COM_METHOD;
	ChkComOutPtr(pcfid);
	ChkComArrayArg(prgFids, cMax);

	if (!m_pfont)
	{
		Assert(false);
		return E_UNEXPECTED;
	}

	std::pair<FeatureIterator, FeatureIterator> pairIt = m_pfont->getFeatures();
	int cfid = pairIt.second - pairIt.first;
	FeatureIterator fit = pairIt.first;
	if (cMax == 0)
	{
		*pcfid = cfid;
		return S_OK;
	}

	*pcfid = min(cMax, cfid);
	for (int i = 0;
		fit != pairIt.second;
		++fit, i++)
	{
		if (i >= *pcfid)
			break;
		prgFids[i] = (*fit);
	}

	END_COM_METHOD(g_fact, IID_IRenderingFeatures);
}
コード例 #6
0
/*----------------------------------------------------------------------------------------------
	Create a property with the given writing system, old writing system, and named style (ktptNamedStyle).
	Note that ktptCharStyle (which this used to use) is effectively obsolete.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP TsPropsFact::MakePropsRgch(const OLECHAR * prgch, int cch,	int ws, int ows,
	ITsTextProps ** ppttp)
{
	BEGIN_COM_METHOD;
	ChkComArrayArg(prgch, cch);
	ChkComOutPtr(ppttp);
	if ((uint)ws > kwsLim)
		ThrowInternalError(E_INVALIDARG, "Magic writing system invalid in string");

	TsIntProp tip;
	TsStrProp tsp;
	int ctip = 0;
	int ctsp = 0;

	tip.m_nVal = ws;
	tip.m_nVar = ows;
	tip.m_tpt = ktptWs;
	ctip = 1;
	if (cch)
	{
		StrUni stu(prgch, cch);
		TsStrHolder * ptsh = TsStrHolder::GetStrHolder();
		tsp.m_hstuVal = ptsh->GetCookieFromString(stu);
		tsp.m_tpt = ktptNamedStyle;
		ctsp = 1;
	}
	TsTextProps::Create(ctip ? &tip : NULL, ctip, ctsp ? &tsp : NULL, ctsp, ppttp);

	END_COM_METHOD(g_factPropsFact, IID_ITsPropsFactory);
}
コード例 #7
0
/*----------------------------------------------------------------------------------------------
	Read the given number of bytes from the stream / file.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FileStream::Read(void * pv, ULONG cb, ULONG * pcbRead)
{
	BEGIN_COM_METHOD;
	ChkComArrayArg((byte *)pv, cb);
	ChkComArgPtrN(pcbRead);

	if (m_hfile == NULL)
		ThrowHr(WarnHr(E_UNEXPECTED));

	if (cb == 0)
	{
		if (pcbRead)
			*pcbRead = 0;
		return S_OK;
	}

	if (!SetFilePosRaw())
		ThrowHr(WarnHr(STG_E_SEEKERROR));
	DWORD cbRead = 0;
	if (!ReadFile(m_hfile, pv, cb, &cbRead, NULL))
		ThrowHr(WarnHr(STG_E_READFAULT));
	m_ibFilePos.QuadPart += cbRead;
	if (pcbRead)
		*pcbRead = cbRead;

	END_COM_METHOD(g_fact, IID_IStream);
}
コード例 #8
0
/*----------------------------------------------------------------------------------------------
	Retrieves a specified number of items in the enumeration sequence.

	Retrieves the next celt items in the enumeration sequence. If there are fewer than the
	requested number of elements left in the sequence, it retrieves the remaining elements.
	The number of elements actually retrieved is returned through pceltFetched (unless the
	caller passed in NULL for that parameter).

	This is a standard COM IEnumFORMATETC method.

	@param celt Desired number of elements to retrieve.
	@param rgelt Pointer to an array for returning the retrieved elements.
	@param pceltFetched Pointer to a count of the number of elements actually retrieved, or
					NULL.

	@return S_OK (if celt items retrieved), S_FALSE (if fewer than celt items retrieved), or
					E_POINTER.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgTsEnumFORMATETC::Next(ULONG celt, FORMATETC * rgelt, ULONG * pceltFetched)
{
	BEGIN_COM_METHOD;
	ChkComArrayArg(rgelt, celt);
	ChkComArgPtrN(pceltFetched);

	if (celt == 0)
	{
		if (pceltFetched)
			*pceltFetched = 0;
		return S_OK;
	}
	int cfmteAvail = kcfmteLim - m_ifmte;
	if (cfmteAvail <= 0)
	{
		if (pceltFetched)
			*pceltFetched = 0;
		return S_FALSE;
	}
	int cfmte;
	if (celt > static_cast<ULONG>(cfmteAvail))
		cfmte = cfmteAvail;
	else
		cfmte = celt;
	if (pceltFetched)
		*pceltFetched = cfmte;
	memcpy(rgelt, &g_rgfmte[m_ifmte], cfmte * isizeof(FORMATETC));
	m_ifmte += cfmte;
	if (m_ifmte > kcfmteLim)
		m_ifmte = kcfmteLim;
	return celt == static_cast<ULONG>(cfmte) ? S_OK : S_FALSE;

	END_COM_METHOD(g_factEnum, IID_IEnumFORMATETC);
}
コード例 #9
0
/*----------------------------------------------------------------------------------------------
	Initialize an instance, typically from a ClassInitMoniker

	To create a suitable moniker, do something like this:

	const wchar * psz = L"Times New Roman;Helvetica,Arial;Courier";
	IClassInitMonikerPtr qcim;
	hr = qcim.CreateInstance(CLSID_ClassInitMoniker);
	hr = qcim->InitNew(CLSID_LgSystemCollater, (const BYTE *)psz, StrLen(psz) * isizeof(wchar));

	Commas separate font names in a list; semi-colons separate lists for Serif, SansSerif,
	and Monospace (in that order).

	ENHANCE JohnT: should we verify that the fonts in question are installed?
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgInputMethodEditor::InitNew(const BYTE * prgb, int cb)
{
	BEGIN_COM_METHOD;
	ChkComArrayArg(prgb, cb);

	return S_OK;

	END_COM_METHOD(g_fact, IID_ISimpleInit);
}
コード例 #10
0
/*----------------------------------------------------------------------------------------------
	Store the writing system codes for the available writing systems.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FwCppStylesDlg::SetWritingSystemsOfInterest(int * rgws, int cws)
{
    BEGIN_COM_METHOD;
    ChkComArrayArg(rgws, cws);

    m_vwsAvailable.InsertMulti(0, cws, rgws);

    END_COM_METHOD(g_factOPD, IID_IFwCppStylesDlg);
}
コード例 #11
0
/*----------------------------------------------------------------------------------------------
	Set the text properties for paragraph and character styles.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FwCppStylesDlg::SetTextProps(ITsTextProps ** rgpttpPara, int cttpPara,
        ITsTextProps ** rgpttpChar, int cttpChar)
{
    BEGIN_COM_METHOD;
    ChkComArrayArg(rgpttpPara, cttpPara);
    ChkComArrayArg(rgpttpChar, cttpChar);

    // Note: need to increment reference counts on these COM objects.
    int ittp;
    m_vqttpPara.Resize(cttpPara);
    for (ittp = 0; ittp < cttpPara; ++ittp)
        m_vqttpPara[ittp] = rgpttpPara[ittp];

    m_vqttpChar.Resize(cttpChar);
    for (ittp = 0; ittp < cttpChar; ++ittp)
        m_vqttpChar[ittp] = rgpttpChar[ittp];

    END_COM_METHOD(g_factOPD, IID_IFwCppStylesDlg);
}
コード例 #12
0
/*----------------------------------------------------------------------------------------------
	Initialize an instance from a ClassInitMoniker

	To create a suitable moniker, do something like this:

	IClassInitMonikerPtr qcim;
	hr = qcim.CreateInstance(CLSID_ClassInitMoniker);
	hr = qcim->InitNew(CLSID_LgUnicodeCollater, NULL, 0);

	Note that this version takes no data because it does not require initialization; it uses
	standard Unicode properties.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgUnicodeCollater::InitNew(const BYTE * prgb, int cb)
{
	BEGIN_COM_METHOD
	ChkComArrayArg(prgb, cb);

	if (cb != 0)
		ThrowHr(WarnHr(E_INVALIDARG));

	// Nothing to do at present.
	return S_OK;

	END_COM_METHOD(g_fact, IID_ILgCollatingEngine);
}
コード例 #13
0
/*----------------------------------------------------------------------------------------------
	Read an ITsTextProps from a byte array and return it.  Return S_FALSE if the array is not
	totally consumed, but an ITsTextProps is successfully read.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP TsPropsFact::DeserializePropsRgb(const byte * prgb, int * pcb,
	ITsTextProps ** ppttp)
{
	BEGIN_COM_METHOD;
	ChkComArgPtr(pcb);
	ChkComOutPtr(ppttp);
	ChkComArrayArg(prgb, *pcb);

	DataReaderRgb drr(prgb, *pcb);
	TsTextProps::DeserializeDataReader(&drr, ppttp);
	return drr.IbCur() < drr.Size() ? S_FALSE : S_OK;

	END_COM_METHOD(g_factPropsFact, IID_ITsPropsFactory);
}
コード例 #14
0
ファイル: FwGrEngine.cpp プロジェクト: bbriggs/FieldWorks
/*----------------------------------------------------------------------------------------------
	Return a list of recognized values for the given feature. If cfvalMax is zero,
	pcfval returns the total number of values. Otherwise, it returns the number entered into
	the array.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FwGrEngine::GetFeatureValues(int fid, int cfvalMax,
	int * prgfval, int * pcfval, int * pfvalDefault)
{
	BEGIN_COM_METHOD;
	ChkComOutPtr(pcfval);
	ChkComOutPtr(pfvalDefault);
	ChkComArrayArg(prgfval, cfvalMax);

	if (!m_pfont)
	{
		Assert(false);
		return E_UNEXPECTED;
	}

	FeatureIterator fit = m_pfont->featureWithID(fid);
	std::pair<FeatureSettingIterator, FeatureSettingIterator> pairIt
		= m_pfont->getFeatureSettings(fit);

	FeatureSettingIterator fsit = pairIt.first;
	FeatureSettingIterator fsitEnd = pairIt.second;
	int cfval = fsitEnd - fsit;
	if (cfvalMax == 0)
	{
		*pcfval = cfval;
		return S_OK;
	}

	*pcfval = min(cfvalMax, cfval);
	for (int i = 0;
		fsit != pairIt.second;
		++fsit, i++)
	{
		if (i >= *pcfval)
			break;
		prgfval[i] = (*fsit);
	}

	FeatureSettingIterator fsitDefault = m_pfont->getDefaultFeatureValue(fit);
	*pfvalDefault = *fsitDefault;
	for (int ifeat = 0; ifeat < m_cfeatWDefaults; ifeat++)
	{
		if (m_rgfsetDefaults[ifeat].id == fid)
		{
			*pfvalDefault = m_rgfsetDefaults[ifeat].value;
			break;
		}
	}

	END_COM_METHOD(g_fact, IID_IRenderingFeatures);
}
コード例 #15
0
/*----------------------------------------------------------------------------------------------
	Specifies a set of style contexts that should be used to determine which styles can be
	applied. Selecting any style having a context not in this array will cause the Apply
	button to be grayed out.

	@param rgnRoles Array of integers that represent style contexts.
	@param cpnRoles Number of contexts in rgnContexts.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FwCppStylesDlg::SetApplicableStyleContexts(int * rgnContexts, int cpnContexts)
{
    BEGIN_COM_METHOD;
    ChkComArrayArg(rgnContexts, cpnContexts);

    m_vApplicableContexts.Clear();
    m_vApplicableContexts.InsertMulti(0, cpnContexts, rgnContexts);

    // In the test code, it is possible (and VERY likely) that this method could be called
    // after we simulate the showing of the modal dialog. If so, we need to pass this vector
    // along immediately.
    if (m_qafsd)
        m_qafsd->SetApplicableStyleContexts(m_vApplicableContexts);

    END_COM_METHOD(g_factOPD, IID_IFwCppStylesDlg);
}
コード例 #16
0
ファイル: ResourceStrm.cpp プロジェクト: bbriggs/FieldWorks
/*----------------------------------------------------------------------------------------------
	Read a specified number of bytes from this stream into memory, starting at the current seek
	pointer.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP ResourceStream::Read(void * pv, UCOMINT32 cb, UCOMINT32 * pcbRead)
{
	BEGIN_COM_METHOD;
	ChkComArrayArg((byte *)pv, cb);
	ChkComArgPtrN(pcbRead);
	UCOMINT32 cbRead;

	//Avoid reading past end of resource data.
	if (m_pbCur + cb > m_prgbData + m_cbData)
		cbRead = m_cbData - (m_pbCur - m_prgbData);
	else
		cbRead = cb;
	if (cbRead != 0)
		CopyBytes(m_pbCur, pv, cbRead);
	m_pbCur += cbRead;
	if (pcbRead)
		*pcbRead = cbRead;

	END_COM_METHOD(g_fact, IID_IStream);
}
コード例 #17
0
ファイル: FileStrm.cpp プロジェクト: FieldDB/FieldWorks
/*----------------------------------------------------------------------------------------------
	Write the given number of bytes to the stream / file.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP FileStream::Write(const void * pv, UCOMINT32 cb, UCOMINT32 * pcbWritten)
{
	BEGIN_COM_METHOD;
	ChkComArrayArg((byte *)pv, cb);
	ChkComArgPtrN(pcbWritten);

#if WIN32
	if (m_hfile == NULL)
		ThrowHr(WarnHr(E_UNEXPECTED));
#else
	if (m_file < 0)
		ThrowHr(WarnHr(E_UNEXPECTED));
#endif
	if (cb == 0)
	{
		if (pcbWritten)
			*pcbWritten = 0;
		return S_OK;
	}

#if WIN32
	if (!SetFilePosRaw())
		ThrowHr(WarnHr(STG_E_SEEKERROR));
	DWORD cbWritten = 0;
	if (!WriteFile(m_hfile, pv, cb, &cbWritten, NULL))
		ThrowHr(WarnHr(STG_E_WRITEFAULT));

	m_ibFilePos.QuadPart += cbWritten;
#else // !WIN32
	ssize_t cbWritten = -1;
	cbWritten = write(m_file, pv, cb);
	if (cbWritten < 0)
		ThrowHr(WarnHr(STG_E_WRITEFAULT));
#endif // !WIN32

	if (pcbWritten)
		*pcbWritten = cbWritten;

	END_COM_METHOD(g_fact, IID_IStream);
}
コード例 #18
0
ファイル: VwAccessRoot.cpp プロジェクト: agran147/FieldWorks
STDMETHODIMP VwAccessRoot::Next(unsigned long celt, VARIANT FAR * prgvar, unsigned long FAR* pceltFetched)
{
	BEGIN_COM_METHOD;
	if (pceltFetched)
		*pceltFetched = 0;
	ChkComArrayArg(prgvar, celt);
	for (uint i=0; i<celt; i++)
		VariantInit(&prgvar[i]);
	uint iaccMin = m_iaccCurrent;
	uint iaccLim = std::min(iaccMin + celt, (unsigned long)m_pbox->ChildCount());
	for (uint iacc = iaccMin; iacc < iaccLim; iacc++)
	{
		prgvar[iacc - m_iaccCurrent].vt = VT_DISPATCH;
		GetAccessFor(m_pbox->ChildAt(iacc), &prgvar[iacc - m_iaccCurrent].pdispVal);
	}
	m_iaccCurrent += iaccLim - iaccMin;
	if (pceltFetched)
		*pceltFetched = iaccLim - iaccMin;
	if (iaccLim - iaccMin < celt)
		return S_FALSE;  // didn't get all asked for.

	END_COM_METHOD(g_fact, IID_IEnumVARIANT);
}
コード例 #19
0
/*----------------------------------------------------------------------------------------------
	Generate a sort key.
	If output pointer is null, just gives the needed length in *pcchKey.
	prgchSource: string sort key is to be generated for.
	cchSource: number of characters in prgchSource.
	cchMaxKey: space available in prgchKey.
	prgchKey: variable that will contain sort key.
	pcchKey: Number of characters in prgchKey.
	This method generates a sort key with full decompositions, it takes into consideration
	ignorable characters (fVariant).  It also establishes collating elements for expansions.
	ENHANCE: As of now, this method does not support contractions,  reordering
		  or direction.
----------------------------------------------------------------------------------------------*/
STDMETHODIMP LgUnicodeCollater::SortKeyRgch(const OLECHAR * prgchSource, int cchSource,
			LgCollatingOptions colopt, int cchMaxKey, OLECHAR * prgchKey, int * pcchKey)
{
	BEGIN_COM_METHOD
	ChkComArrayArg(prgchSource, cchSource);
	ChkComArrayArg(prgchKey, cchMaxKey);
	if ((uint) colopt > (uint)fcoLim)
		ThrowInternalError(E_INVALIDARG, "Invalid collating options");
	ChkComArgPtr(pcchKey);

	// Create a pointer to LgCharacterPropertyEngine to access get_FullDecomp
	// ENHANCE JohnT: Should this be the default character property engine or a ws-specific one?
	if (!m_qcpe) //m_qcpe is initialized to null in constructor.
	{
		CheckHr(LgIcuCharPropEngine::GetUnicodeCharProps(&m_qcpe));
	}
	const OLECHAR * pchSource;	// points to next char to process, in prgchSource
	OLECHAR * pch;			// points to next char to process, in rgchDecomp
	OLECHAR * pchLim;
	#define MAXDECOMP 256
	OLECHAR rgchDecomp[MAXDECOMP];	// holds decompositions
	int cchDecomp;			// character count in decomposition

	OLECHAR * pchKey = prgchKey;

	const OLECHAR * pchLimSource = prgchSource + cchSource;
	CollatingElement * pcolel; // pointer to next collating element to do
	CollatingElement * pcolelLim; //will be assigned limit address in "multiple" loop
	int cchOut = 0;				// count of characters we have output
	bool fEven = true;      // true for first char of pair at levels 2 and 3

	int cchMaxOut = cchMaxKey;
	if (!cchMaxKey)
	{
		// Set a large limit so we don't report errors below, and ensure we don't output
		// anything, even if we were given a pointer to a real buffer
		cchMaxOut = INT_MAX;
		pchKey = NULL;
	}

	//Enter weight 1's into sort key
	for (pchSource = prgchSource; pchSource < pchLimSource; pchSource++)
	{
		ComBool fHasDecomp;
		// If there is no decomposition, this routine copies the one character we passed into
		// rgchDecomp.  Otherwise, it puts the decomposition there.
		CheckHr(m_qcpe->FullDecompRgch(*pchSource, MAXDECOMP, rgchDecomp, &cchDecomp,
						&fHasDecomp));
		pchLim = rgchDecomp + cchDecomp;
		for (pch = rgchDecomp; pch < pchLim; pch++)
		{
			int icolel = FindColel(*pch);
			if(icolel == -1)//an index of -1 means the weights are the standard (U, 0x20, 2)
			{
				cchOut++;
				if(cchOut > cchMaxOut)
					return E_FAIL;
				if(pchKey)
					*pchKey++ = *pch;
				continue;
			}
			pcolel = const_cast <CollatingElement *> (g_prgcolel + icolel);
			if((colopt & fcoDontIgnoreVariant) == 0)
			{
				if(pcolel->Variant())
					continue;
			}
			int ccolel = 1; // by default we have just one, the one we point at now
			if (pcolel->Multiple())
			{
				// there are several to process
				ccolel = pcolel->uWeight3; // before we change pcolel!
				// move pcolel to point at the list in the multiple array
				pcolel = const_cast<CollatingElement *>(g_prgcolelMultiple + pcolel->MultipleIndex());
			}
			pcolelLim = pcolel + ccolel;
			for(;pcolel < pcolelLim; pcolel++)
			{
				int nWeight;
				nWeight = pcolel->uWeight1;
				if (nWeight)
				{
					cchOut++;
					if (cchOut > cchMaxOut)
						return E_FAIL;
					if (pchKey)
						*pchKey++ = (OLECHAR) nWeight;
				}
			}
		}
	}

	//enter level separator into array
	if(pchKey)
	{
		*pchKey++ = 0x0001;
	}
	cchOut++;
	if(cchOut > cchMaxOut)
		return E_FAIL;

	//Packing weight 2's two per character.  If there is an odd number of weight 2's, the LSB of the
	//last character is padded with zero.
	for (pchSource = prgchSource; pchSource < pchLimSource; pchSource++)
	{
		ComBool fHasDecomp;
		// If there is no decomposition, this routine copies the one character we passed into
		// rgchDecomp.  Otherwise, it puts the decomposition there.
		CheckHr(m_qcpe->FullDecompRgch(*pchSource, MAXDECOMP, rgchDecomp, &cchDecomp,
												&fHasDecomp));
		pchLim = rgchDecomp + cchDecomp;
		for (pch = rgchDecomp; pch < pchLim; pch++)
		{
			int icolel = FindColel(*pch);
			if(icolel == -1)
			{
				if (!PackWeights(pchKey, cchOut, cchMaxOut, 0x20, fEven))
					return E_FAIL;
				continue;
			}
			pcolel = const_cast<CollatingElement *>(g_prgcolel + icolel);
			if((colopt & fcoDontIgnoreVariant) == 0)
			{
				if(pcolel->Variant())
					continue;
			}

			int ccolel = 1; // by default we have just one, the one we point at now
			if (pcolel->Multiple())
			{
				// there are several to process
				ccolel = pcolel->uWeight3; // before we change pcolel!
				// move pcolel to point at the list in the multiple array
				pcolel =const_cast<CollatingElement *>(g_prgcolelMultiple + pcolel->MultipleIndex());
			}
			pcolelLim = pcolel + ccolel;
			for(;pcolel < pcolelLim; pcolel++)
			{
				int nWeight;
				nWeight = pcolel->uWeight2;
				if (nWeight)
				{
					if (!PackWeights(pchKey, cchOut, cchMaxOut, nWeight, fEven))
						return E_FAIL;
				}
			}
		}
	}
	//uWeight3 is normally a case indicator.  If fcoIgnoreCase is set, case is ignored,
	//therefore uWeight3 is ignored in the sort key.
	if(colopt & fcoIgnoreCase)
	{
		*pcchKey = cchOut;
		return S_OK;
	}
	//enter level separator into array
	if(pchKey)
	{
		*pchKey++ = 0x0001;
	}
	cchOut++;
	if(cchOut > cchMaxOut)
		return E_FAIL;
	fEven = true;

	//Treating weight 3's like weight 2's
	for (pchSource = prgchSource; pchSource < pchLimSource; pchSource++)
	{
		ComBool fHasDecomp;
		// If there is no decomposition, this routine copies the one character we passed into
		// rgchDecomp.  Otherwise, it puts the decomposition there.
		CheckHr(m_qcpe->FullDecompRgch(*pchSource, MAXDECOMP, rgchDecomp, &cchDecomp,
												&fHasDecomp));
		pchLim = rgchDecomp + cchDecomp;
		for (pch = rgchDecomp; pch < pchLim; pch++)
		{
			int icolel = FindColel(*pch);
			if(icolel == -1) //use the standard weights
			{
				if (!PackWeights(pchKey, cchOut, cchMaxOut, 0x02, fEven))
					return E_FAIL;
				continue;
			}
			pcolel = const_cast<CollatingElement *>(g_prgcolel + icolel);
			if((colopt & fcoDontIgnoreVariant) == 0)
			{
				if(pcolel->Variant())
					continue;
			}

			int ccolel = 1; // by default we have just one, the one we point at now
			if (pcolel->Multiple())
			{
				// there are several to process
				ccolel = pcolel->uWeight3; // before we change pcolel!
				// move pcolel to point at the list in the multiple array
				pcolel = const_cast<CollatingElement *>(g_prgcolelMultiple + pcolel->MultipleIndex());
			}
			pcolelLim = pcolel + ccolel;
			for(;pcolel < pcolelLim; pcolel++)
			{
				int nWeight;
				nWeight = pcolel->uWeight3;
				if (nWeight)
				{
					if (!PackWeights(pchKey, cchOut, cchMaxOut, nWeight, fEven))
						return E_FAIL;
				}
			}
		}
	}
	if(pchKey)//level separator
	{
		*pchKey++ = 0x0001;
	}
	cchOut++;
	if(cchOut > cchMaxOut)
		return E_FAIL;

	//add the actual characters to the sort key
	for (pchSource = prgchSource; pchSource < pchLimSource; pchSource++)
	{
		cchOut++;
		if (cchOut > cchMaxOut)
			return E_FAIL;
		if (pchKey)
			*pchKey++ = *pchSource;
	}
	*pcchKey = cchOut;
	END_COM_METHOD(g_fact, IID_ILgCollatingEngine);
}