⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtlcom.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 2 页
字号:
	{
		MTLVERIFY(::VariantClear(this) == NOERROR);
	}

	operator LPVARIANT()
	{
		return this;
	}

	operator LPCVARIANT() const
	{
		return this;
	}

	DWORD GetDim()
	{
		return ::SafeArrayGetDim(parray);
	}

	DWORD GetElemSize()
	{
		return ::SafeArrayGetElemsize(parray);
	}

// Operations
	void Attach(VARIANT& varSrc)
	{
		ATLASSERT(varSrc.vt & VT_ARRAY);

		// Free up previous safe array if necessary
		Clear();

		// give control of data to CComSafeArray
		::memcpy(this, &varSrc, sizeof(varSrc));
		varSrc.vt = VT_EMPTY;
	}

	VARIANT Detach()
	{
		VARIANT varResult = *this;
		vt = VT_EMPTY;
		return varResult;
	}

// Assignment operators
	CComSafeArray& operator=(const CComSafeArray& saSrc)
	{
		ATLASSERT(saSrc.vt & VT_ARRAY);

		MtlCheckError(::VariantCopy(this, (LPVARIANT)&saSrc));
		return *this;
	}

	CComSafeArray& operator=(const VARIANT& varSrc)
	{
		ATLASSERT(varSrc.vt & VT_ARRAY);

		MtlCheckError(::VariantCopy(this, (LPVARIANT)&varSrc));
		return *this;
	}

	CComSafeArray& operator=(LPCVARIANT pSrc)
	{
		ATLASSERT(pSrc->vt & VT_ARRAY);

		MtlCheckError(::VariantCopy(this, (LPVARIANT)pSrc));
		return *this;
	}

	CComSafeArray& operator=(const CComVariant& varSrc)
	{
		ATLASSERT(varSrc.vt & VT_ARRAY);

		MtlCheckError(::VariantCopy(this, (LPVARIANT)&varSrc));
		return *this;
	}

// Comparison operators
	bool operator==(const SAFEARRAY& saSrc) const
	{
		return _MtlCompareSafeArrays(parray, (LPSAFEARRAY)&saSrc);
	}

	bool operator==(LPCSAFEARRAY pSrc) const
	{
		return _MtlCompareSafeArrays(parray, (LPSAFEARRAY)pSrc);
	}

	bool operator==(const CComSafeArray& saSrc) const
	{
		if (vt != saSrc.vt)
			return false;

		return _MtlCompareSafeArrays(parray, saSrc.parray);
	}

	bool operator==(const VARIANT& varSrc) const
	{
		if (vt != varSrc.vt)
			return false;

		return _MtlCompareSafeArrays(parray, varSrc.parray);
	}

	bool operator==(LPCVARIANT pSrc) const
	{
		if (vt != pSrc->vt)
			return false;

		return _MtlCompareSafeArrays(parray, pSrc->parray);
	}

	bool operator==(const CComVariant& varSrc) const
	{
		if (vt != varSrc.vt)
			return false;

		return _MtlCompareSafeArrays(parray, varSrc.parray);
	}

	void CreateOneDim(VARTYPE vtSrc, DWORD dwElements,
		const void* pvSrcData = NULL, long nLBound = 0)
	{
		ATLASSERT(dwElements > 0);

		// Setup the bounds and create the array
		SAFEARRAYBOUND rgsabound;
		rgsabound.cElements = dwElements;
		rgsabound.lLbound = nLBound;
		Create(vtSrc, 1, &rgsabound);

		// Copy over the data if neccessary
		if (pvSrcData != NULL)
		{
			void* pvDestData;
			AccessData(&pvDestData);
			memcpy(pvDestData, pvSrcData, GetElemSize() * dwElements);
			UnaccessData();
		}
	}

	DWORD GetOneDimSize()
	{
		ATLASSERT(GetDim() == 1);

		long nUBound, nLBound;

		GetUBound(1, &nUBound);
		GetLBound(1, &nLBound);

		return nUBound + 1 - nLBound;
	}

	void ResizeOneDim(DWORD dwElements)
	{
		ATLASSERT(GetDim() == 1);

		SAFEARRAYBOUND rgsabound;

		rgsabound.cElements = dwElements;
		rgsabound.lLbound = 0;

		Redim(&rgsabound);
	}

	void Create(VARTYPE vtSrc, DWORD dwDims, DWORD* rgElements)
	{
		ATLASSERT(rgElements != NULL);

		// Allocate and fill proxy array of bounds (with lower bound of zero)
		SAFEARRAYBOUND* rgsaBounds = new SAFEARRAYBOUND[dwDims];

		for (DWORD dwIndex = 0; dwIndex < dwDims; dwIndex++)
		{
			// Assume lower bound is 0 and fill in element count
			rgsaBounds[dwIndex].lLbound = 0;
			rgsaBounds[dwIndex].cElements = rgElements[dwIndex];
		}

		Create(vtSrc, dwDims, rgsaBounds);
		delete[] rgsaBounds;
	}

	void Create(VARTYPE vtSrc, DWORD dwDims, SAFEARRAYBOUND* rgsabound)
	{
		ATLASSERT(dwDims > 0);
		ATLASSERT(rgsabound != NULL);

		// Validate the VARTYPE for SafeArrayCreate call
		ATLASSERT(!(vtSrc & VT_ARRAY));
		ATLASSERT(!(vtSrc & VT_BYREF));
		ATLASSERT(!(vtSrc & VT_VECTOR));
		ATLASSERT(vtSrc != VT_EMPTY);
		ATLASSERT(vtSrc != VT_NULL);

		// Free up old safe array if necessary
		Clear();

		ATLTRY(parray = ::SafeArrayCreate(vtSrc, dwDims, rgsabound));
		if (parray == NULL)
		{
			ATLTRACE2(atlTraceDBProvider, 0, "CComSafeArray::Create Error : OOM\n");
			return;
		}

		vt = unsigned short(vtSrc | VT_ARRAY);
		m_dwDims = dwDims;
		m_dwElementSize = GetElemSize();
	}

	void AccessData(void** ppvData)
	{
		MtlCheckError(::SafeArrayAccessData(parray, ppvData));
	}

	void UnaccessData()
	{
		MtlCheckError(::SafeArrayUnaccessData(parray));
	}

	void AllocData()
	{
		MtlCheckError(::SafeArrayAllocData(parray));
	}

	void AllocDescriptor(DWORD dwDims)
	{
		MtlCheckError(::SafeArrayAllocDescriptor(dwDims, &parray));
	}

	void Copy(LPSAFEARRAY* ppsa)
	{
		MtlCheckError(::SafeArrayCopy(parray, ppsa));
	}

	void GetLBound(DWORD dwDim, long* pLbound)
	{
		MtlCheckError(::SafeArrayGetLBound(parray, dwDim, pLbound));
	}

	void GetUBound(DWORD dwDim, long* pUbound)
	{
		MtlCheckError(::SafeArrayGetUBound(parray, dwDim, pUbound));
	}

	void GetElement(long* rgIndices, void* pvData)
	{
		MtlCheckError(::SafeArrayGetElement(parray, rgIndices, pvData));
	}

	void PtrOfIndex(long* rgIndices, void** ppvData)
	{
		MtlCheckError(::SafeArrayPtrOfIndex(parray, rgIndices, ppvData));
	}

	void PutElement(long* rgIndices, void* pvData)
	{
		MtlCheckError(::SafeArrayPutElement(parray, rgIndices, pvData));
	}

	void Redim(SAFEARRAYBOUND* psaboundNew)
	{
		MtlCheckError(::SafeArrayRedim(parray, psaboundNew));
	}

	void Lock()
	{
		MtlCheckError(::SafeArrayLock(parray));
	}

	void Unlock()
	{
		MtlCheckError(::SafeArrayUnlock(parray));
	}

	void Destroy()
	{
		MtlCheckError(::SafeArrayDestroy(parray));
	}

	void DestroyData()
	{
		MtlCheckError(::SafeArrayDestroyData(parray));
	}

	void DestroyDescriptor()
	{
		MtlCheckError(::SafeArrayDestroyDescriptor(parray));
	}
};

/////////////////////////////////////////////////////////////////////////////
// Helper for iter to CComSafeArray
inline void _MtlCreateOneDimArray(VARIANT& varSrc, DWORD dwSize)
{
	UINT nDim;

	// Clear VARIANT and re-create SafeArray if necessary
	if (varSrc.vt != (VT_UI1 | VT_ARRAY) ||
		(nDim = ::SafeArrayGetDim(varSrc.parray)) != 1)
	{
		MTLVERIFY(::VariantClear(&varSrc) == NOERROR);
		varSrc.vt = VT_UI1 | VT_ARRAY;

		SAFEARRAYBOUND bound;
		bound.cElements = dwSize;
		bound.lLbound = 0;
		ATLTRY(varSrc.parray = ::SafeArrayCreate(VT_UI1, 1, &bound));
		if (varSrc.parray == NULL)
			ATLTRACE2(atlTraceDBProvider, 0, "MtlCheckError Error : OOM\n");
	}
	else
	{
		// Must redimension array if necessary
		long lLower, lUpper;
		MtlCheckError(::SafeArrayGetLBound(varSrc.parray, 1, &lLower));
		MtlCheckError(::SafeArrayGetUBound(varSrc.parray, 1, &lUpper));

		// Upper bound should always be greater than lower bound
		long lSize = lUpper - lLower;
		if (lSize < 0)
		{
			ATLASSERT(FALSE);
			lSize = 0;

		}

		if ((DWORD)lSize != dwSize)
		{
			SAFEARRAYBOUND bound;
			bound.cElements = dwSize;
			bound.lLbound = lLower;
			MtlCheckError(::SafeArrayRedim(varSrc.parray, &bound));
		}
	}
}

inline void _MtlCopyBinaryData(SAFEARRAY* parray, const void* pvSrc, DWORD dwSize)
{
	// Access the data, copy it and unaccess it.
	void* pDest;
	MtlCheckError(::SafeArrayAccessData(parray, &pDest));
	::memcpy(pDest, pvSrc, dwSize);
	MtlCheckError(::SafeArrayUnaccessData(parray));
}

inline void MtlInitVariantFromArray(CComVariant& v, CSimpleArray<BYTE>& arrSrc)
{
	int nSize = arrSrc.GetSize();

	// Set the correct type and make sure SafeArray can hold data
	_MtlCreateOneDimArray(v, (DWORD)nSize);

	// Copy the data into the SafeArray
	_MtlCopyBinaryData(v.parray, arrSrc.GetData(), (DWORD)nSize);
}

inline void MtlInitVariantFromItemIDList(CComVariant& v, LPCITEMIDLIST pidl)
{
	if (pidl != NULL)
	{
		// walk through entries in the list and accumulate their size

		UINT cbTotal = 0;
		SAFEARRAY *psa = NULL;
		LPCITEMIDLIST pidlWalker = pidl;

		while (pidlWalker->mkid.cb)
		{
			cbTotal += pidlWalker->mkid.cb;
			pidlWalker = (LPCITEMIDLIST)
				(((LPBYTE)pidlWalker) + pidlWalker->mkid.cb);
		}

		// add the base structure size
		cbTotal += sizeof(ITEMIDLIST);

		// get a safe array for them
		psa = ::SafeArrayCreateVector(VT_UI1, 0, cbTotal);

		// copy it and set members
		if (psa != NULL)
		{
			::memcpy(psa->pvData, (LPBYTE) pidl, cbTotal);
			v.vt = VT_ARRAY | VT_UI1;
			v.parray = psa;
		}
	}
}

////////////////////////////////////////////////////////////////////////////
} // namespace MTL

#endif // __MTLCOM_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -