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

📄 occsite.cpp

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 CPP
📖 第 1 页 / 共 5 页
字号:
const IID CLSID_DataAdapter = {0x3A08E130L,0x8F65,0x11D0,{0x94,0x84,0x00,0xA0,0xC9,0x11,0x10,0xED}};

HRESULT CDataSourceControl::Initialize()
{
	// The following is a work around for RDC behaviour when on an invisible dlg
	// When the dlg is invisible it cannot display the ODBC connect dialog
	// So check if visible, if not make it so and move it to the center
	// of the screen with null size. Then do the connect dialog
	// Finally put it all back like it was.
	CWnd* pParent = m_pClientSite->m_pWndCtrl->GetTopLevelParent();
	BOOL bHidden = !pParent->IsWindowVisible();
	CRect rcParent;
	if (bHidden)
	{
		CRect rcDesktop;
		CWnd::GetDesktopWindow()->GetWindowRect(&rcDesktop);
		pParent->GetWindowRect(&rcParent);
		pParent->MoveWindow((rcDesktop.right - rcDesktop.left)/2, (rcDesktop.bottom - rcDesktop.top)/2, 0, 0, FALSE);
		pParent->ShowWindow(SW_SHOWNORMAL);
	}
	IVBDSC* pDSC;
	HRESULT hRes;

	hRes = m_pClientSite->m_pObject->QueryInterface(IID_IDataSource, (void**)&m_pDataSource);
	if (SUCCEEDED(hRes))
	{
		hRes = m_pDataSource->GetDataMember(NULL, &IID_IRowPosition, (IUnknown**)&m_pRowPosition);
		if (m_pRowPosition == NULL)
			hRes = E_POINTER;

		if (FAILED(hRes))
		{
			if (bHidden)
			{
				pParent->MoveWindow(rcParent.left, rcParent.top, rcParent.right - rcParent.left, rcParent.bottom - rcParent.top, FALSE);
				pParent->ShowWindow(SW_HIDE);
			}
			return hRes;
		}
	}
	else
	{
		hRes = m_pClientSite->m_pObject->QueryInterface(IID_IVBDSC, (void**)&pDSC);
		if (FAILED(hRes))
			return hRes;
		ICursor* pCursor;
		pDSC->CreateCursor(&pCursor);
		pDSC->Release();
		if (!pCursor)
			return E_FAIL;

		hRes = pCursor->QueryInterface(IID_ICursorMove,
			(LPVOID *)&m_pCursorMove);

		pCursor->Release();

		if (FAILED(hRes))
			return hRes;

		hRes = m_pCursorMove->QueryInterface(IID_ICursorUpdateARow,
			(LPVOID *)&m_pCursorUpdateARow);
	}

	hRes = GetMetaData();

	if (bHidden)
	{
		pParent->MoveWindow(rcParent.left, rcParent.top, rcParent.right - rcParent.left, rcParent.bottom - rcParent.top, FALSE);
		pParent->ShowWindow(SW_HIDE);
	}

	return hRes;
}

IUnknown* CDataSourceControl::GetCursor()
{
	ASSERT(m_pClientSite != NULL);

	if (m_pDataSource != NULL)
	{
		if(m_pRowset != NULL)
			return m_pDataSource;
		return NULL;
	}

	ICursor* pCursor;
	if (!m_pCursorMove)
	{
		IVBDSC* pDSC;
		HRESULT hRes;
		hRes = m_pClientSite->m_pObject->QueryInterface(IID_IVBDSC, (void**)&pDSC);
		if (FAILED(hRes))
			return NULL;
		pDSC->CreateCursor(&pCursor);
		pDSC->Release();
		if (!pCursor)
			return NULL;
		return pCursor;
	}
	if (SUCCEEDED(m_pCursorMove->QueryInterface(IID_ICursor, (LPVOID *) &pCursor)))
			return pCursor;

	ASSERT(FALSE); // DSC Cursor Not Found
	return NULL;
}

HRESULT CDataSourceControl::GetMetaData()
{
	HRESULT hRes;
	METAROWTYPE* pOldMetaData = m_pMetaRowData;
	int nOldColumns = m_nColumns;

	if (m_pDataSource != NULL)
	{
		IRowset* pRowset;

		hRes = m_pRowPosition->GetRowset(IID_IRowset, reinterpret_cast<IUnknown**>(&pRowset));
		if (FAILED(hRes))
			return hRes;

		{
			LPCONNECTIONPOINTCONTAINER pConnPtCont;

			if (SUCCEEDED(pRowset->QueryInterface(IID_IConnectionPointContainer,
					(LPVOID*)&pConnPtCont)))
			{
				ASSERT(pConnPtCont != NULL);
				LPCONNECTIONPOINT pConnPt = NULL;

				if (SUCCEEDED(pConnPtCont->FindConnectionPoint(IID_IRowsetNotify, &pConnPt)))
				{
					ASSERT(pConnPt != NULL);
					pConnPt->Advise(&m_pClientSite->m_xRowsetNotify, &m_dwRowsetNotify);
					pConnPt->Release();
				}

				pConnPtCont->Release();
			}
		}

		m_pRowset = new CRowset(pRowset);
		pRowset->Release();
		m_pRowset->SetupOptionalRowsetInterfaces();
		m_pDynamicAccessor = new CDynamicAccessor;
		m_pDynamicAccessor->BindColumns(m_pRowset->m_spRowset);
		m_pRowset->SetAccessor(m_pDynamicAccessor);
		m_nColumns = m_pDynamicAccessor->GetColumnCount();
		m_pMetaRowData = (METAROWTYPE*)::CoTaskMemAlloc(sizeof(METAROWTYPE) * m_nColumns);
		ASSERT(m_pMetaRowData);
		memset(m_pMetaRowData, 0, sizeof(METAROWTYPE) * m_nColumns);
		m_pRowset->MoveFirst();
		m_pRowset->ReleaseRows();
	}
	else
	{
		ULONG nRows;
		ICursor* pCursor = (LPCURSOR)m_pCursorMove;
		ICursor* pColumnCursor;

		if (pCursor == NULL)
			return S_OK;

		hRes = pCursor->GetColumnsCursor(IID_ICursor, (IUnknown **) &pColumnCursor, &nRows);
		if (FAILED(hRes))
			return hRes;

		DBCOLUMNBINDING MetaColumns[2];
		CopyColumnID(&MetaColumns[0].columnID, &COLUMN_COLUMNID);
		MetaColumns[0].obData = offsetof(METAROWTYPE, idColumnID);
		MetaColumns[0].cbMaxLen = DB_NOMAXLENGTH;
		MetaColumns[0].obInfo = offsetof(METAROWTYPE, dwColumnID);
		MetaColumns[0].obVarDataLen = DB_NOVALUE;
		MetaColumns[0].dwBinding = DBBINDING_DEFAULT;
		MetaColumns[0].dwDataType = DBTYPE_COLUMNID;

		CopyColumnID(&MetaColumns[1].columnID, &COLUMN_NAME);
		MetaColumns[1].obData = offsetof(METAROWTYPE, lpstrName);
		MetaColumns[1].cbMaxLen = DB_NOMAXLENGTH;
		MetaColumns[1].obInfo = offsetof(METAROWTYPE, dwName);
		MetaColumns[1].obVarDataLen = DB_NOVALUE;
		MetaColumns[1].dwBinding = DBBINDING_DEFAULT;
		MetaColumns[1].dwDataType = VT_LPSTR;

		hRes = pColumnCursor->SetBindings(2, MetaColumns, sizeof(METAROWTYPE),
			DBCOLUMNBINDOPTS_REPLACE);
		if (FAILED(hRes))
		{
			pColumnCursor->Release();
			return hRes;
		}

		DBFETCHROWS FetchRows;
		FetchRows.cRowsRequested = nRows;
		FetchRows.dwFlags = DBROWFETCH_CALLEEALLOCATES;
		FetchRows.pData = NULL;
		FetchRows.pVarData = NULL;
		FetchRows.cbVarData = 0;

		LARGE_INTEGER dlZero;
		LISet32(dlZero, 0);
		hRes = pColumnCursor->GetNextRows(dlZero, &FetchRows);
		if (FAILED(hRes))
		{
			pColumnCursor->Release();
			return hRes;
		}

		m_pMetaRowData = (METAROWTYPE *)FetchRows.pData;
		ASSERT(m_pMetaRowData);
		nRows = FetchRows.cRowsReturned;       // in case it changed
		m_pVarData = FetchRows.pVarData;

		m_nColumns = nRows;

		pColumnCursor->Release();
	}

	for (int nCol=0; nCol<m_nColumns; nCol++)
		m_pMetaRowData[nCol].m_pClientList = new CPtrList;

	// re-establish all bound property sites and then delete old meta-data
	if (pOldMetaData != NULL)
	{
		for (int nCol=0; nCol<nOldColumns; nCol++)
		{
			POSITION pos = pOldMetaData[nCol].m_pClientList->GetHeadPosition();
			while (pos)
			{
				COleControlSite* pSite = (COleControlSite *)
					m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
				BindProp(pSite, TRUE);
			}
			pOldMetaData[nCol].m_pClientList->RemoveAll();
			delete pOldMetaData[nCol].m_pClientList;
		}
		::CoTaskMemFree(pOldMetaData);
	}

	return hRes;
}

BOOL CDataSourceControl::CopyColumnID(
	DBCOLUMNID* pcidDst, DBCOLUMNID const *pcidSrc)
{
	pcidDst->dwKind = pcidSrc->dwKind;

	switch (pcidSrc->dwKind)
	{
	case DBCOLKIND_GUID_NUMBER:
		pcidDst->guid = pcidSrc->guid;
		pcidDst->lNumber = pcidSrc->lNumber;
		break;
	case DBCOLKIND_GUID_NAME:
		pcidDst->guid = pcidSrc->guid;
		// fall through
	case DBCOLKIND_NAME:
		pcidDst->lpdbsz = (LPDBSTR) ::CoTaskMemAlloc(sizeof(DBCHAR) * (ldbstrlen(pcidSrc->lpdbsz) + 1));
		if (!pcidDst->lpdbsz)
			return FALSE;
		ldbstrcpy(pcidDst->lpdbsz, pcidSrc->lpdbsz);
		break;
	}
	return TRUE;
}

// Make a bound control/bound property a consumer to a particular column in this DSC
void CDataSourceControl::BindProp(COleControlSite* pClientSite, BOOL bBind)
{
	ASSERT(pClientSite);

	if (bBind)
	{
		BindProp(pClientSite, FALSE);
		ASSERT(pClientSite->m_pDSCSite == m_pClientSite);
		if (m_pDataSource != NULL)
		{
			for (int nCol=0; nCol<m_nColumns; nCol++)
			{
				if (pClientSite->m_strDataField == m_pDynamicAccessor->GetColumnName(nCol + 1))
				{
					m_pMetaRowData[nCol].m_pClientList->AddTail(pClientSite);
					return;
				}
			}
		}
		else
		{
			for (int nCol=0; nCol<m_nColumns; nCol++)
			{
				if (m_pMetaRowData[nCol].lpstrName == NULL)
					continue;
				if (pClientSite->m_strDataField == m_pMetaRowData[nCol].lpstrName)
				{
					m_pMetaRowData[nCol].m_pClientList->AddTail(pClientSite);
					return;
				}
			}
		}
		pClientSite->m_pDSCSite = NULL;
		return;
	}
	UpdateCursor();
	// UnBind
	for (int nCol=0; nCol<m_nColumns; nCol++)
	{
		POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
		POSITION prev;
		while (pos)
		{
			prev = pos;
			COleControlSite* pSite = (COleControlSite *)
				m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
			if (pSite == pClientSite)
			{
				m_pMetaRowData[nCol].m_pClientList->RemoveAt(prev);
				return;
			}
		}
	}
}

// Make a cursor bound control property a client to this control
void CDataSourceControl::BindProp(CDataBoundProperty* pProperty, BOOL bBind)
{
	ASSERT(pProperty);

	if (bBind)
	{
		BindProp(pProperty, FALSE);
		m_CursorBoundProps.AddTail(pProperty);
	}
	else
	{
		UpdateCursor();
		POSITION pos = m_CursorBoundProps.Find(pProperty);
		if (pos != NULL)
			m_CursorBoundProps.RemoveAt(pos);
	}
}

void CDataSourceControl::BindColumns()
{
	if (m_pDataSource != NULL)
	{
		// this is done automatically by CDynamicAccessor
		GetBoundClientRow();
		UpdateControls();
		return;
	}
	if (m_pValues)
	{
		for (int i=0; i<m_nBindings; i++)
			::VariantClear(&m_pValues[i]);
		if (m_nBindings > 0)
		{
			delete[] m_pValues;
			delete[] m_pColumnBindings;
		}
		m_pValues = NULL;
	}
	m_nBindings = 0;
	for (int nCol=0; nCol<m_nColumns; nCol++)
	{
		m_nBindings += m_pMetaRowData[nCol].m_pClientList->GetCount();
	}
	if (m_nBindings > 0)
		m_pColumnBindings = new DBCOLUMNBINDING[m_nBindings];
	int nItem = 0;
	for (nCol=0; nCol<m_nColumns; nCol++)
	{
		POSITION pos = m_pMetaRowData[nCol].m_pClientList->GetHeadPosition();
		while (pos)
		{
			COleControlSite* pSite = (COleControlSite *)
				m_pMetaRowData[nCol].m_pClientList->GetNext(pos);
			CopyColumnID(&m_pColumnBindings[nItem].columnID, &m_pMetaRowData[nCol].idColumnID);
			m_pColumnBindings[nItem].obData = sizeof(VARIANT) * nItem;
			m_pColumnBindings[nItem].cbMaxLen = DB_NOMAXLENGTH;
			m_pColumnBindings[nItem].obInfo = DB_NOVALUE;
			m_pColumnBindings[nItem].obVarDataLen = DB_NOVALUE;
			m_pColumnBindings[nItem].dwBinding = DBBINDING_VARIANT;
			m_pColumnBindings[nItem].dwDataType = pSite->m_dwType;
			nItem++;
		}
	}
	m_pCursorMove->SetBindings(m_nBindings, m_pColumnBindings,
		sizeof(VARIANT) * m_nBindings, DBCOLUMNBINDOPTS_REPLACE);

	if (m_nBindings)
		m_pValues = new VARIANT[m_nBindings];

	for (int i=0; i<m_nBindings; i++)
	{
		memset(&m_pValues[i], 0, sizeof(VARIANT));
		m_pValues[i].vt = VT_EMPTY;
	}

	GetBoundClientRow();
	UpdateControls();
}

HRESULT CDataSourceControl::GetBoundClientRow()
{
	DBFETCHROWS FetchRows;

	if (m_pDataSource != NULL)
	{
		if(m_pRowset == NULL)
			return S_OK;

		if(m_pRowset->m_hRow == NULL)
			return S_OK;

		return m_pRowset->GetData();
	}

	if (m_nBindings == 0)
		return S_OK;

	FetchRows.pData = m_pValues;
	FetchRows.pVarData = NULL;
	FetchRows.cbVarData = NULL;
	FetchRows.cRowsRequested = 1;
	FetchRows.dwFlags = 0;

	LARGE_INTEGER dl = { 0, 0};

	return m_pCursorMove->Move(1, (LPVOID)&DBBMK_CURRENT, dl, &FetchRows);
}

COleVariant CDataSourceControl::ToVariant(int nCol)
{
	ASSERT(m_pDataSource != NULL);
	ASSERT(m_pDynamicAccessor != NULL);
	COleVariant vt;
	DBSTATUS dbStatus;
	DBTYPE dbType;

	m_pDynamicAccessor->GetStatus(nCol, &dbStatus);
	if(dbStatus == DBSTATUS_S_ISNULL)
		return vt;                      // just return a blank variant

	if(!m_pDynamicAccessor->GetColumnType(nCol, &dbType))
		return vt;
	switch (dbType)
	{
	case DBTYPE_VARIANT:
		vt = COleVariant((LPCVARIANT)m_pDynamicAccessor->GetValue(nCol));
		break;
	case DBTYPE_STR:
		vt = COleVariant(CString((LPCSTR)m_pDynamicAccessor->GetValue(nCol)), VT_BSTR);
		break;
	case DBTYPE_WSTR:
	case DBTYPE_BSTR:
		vt = COleVariant(CString((LPCWSTR)m_pDynamicAccessor->GetValue(nCol)), VT_BSTR);
		break;
	case DBTYPE_I1:
	case DBTYPE_UI1:
		vt = COleVariant(*((BYTE*)m_pDynamicAccessor->GetValue(nCol)));
		break;
	case DBTYPE_I2:
	case DBTYPE_UI2:
		vt = COleVariant(*((short*)m_pDynamicAccessor->GetValue(nCol)));
		break;
	case DBTYPE_I4:
	case DBTYPE_UI4:
		vt = COleVariant(*((long*)m_pDynamicAccessor->GetValue(nCol)));
		break;
	case DBTYPE_R4:
		vt = COleVariant(*((float*)m_pDynamicAccessor->GetValue(nCol)));
		break;
	case DBTYPE_R8:
		vt = COleVariant(*((double*)m_pDynamicAccessor->GetValue(nCol)));
		break;
	case DBTYPE_BOOL:
		vt = COleVariant((short)*(BOOL*)m_pDynamicAccessor->GetValue(nCol), VT_BOOL);
		break;
	case DBTYPE_DATE:
		{
			COleDateTime dt(*((DATE*)m_pDynamicAccessor->GetValue(nCol)));
			vt = COleVariant(dt);
		}
		break;
	case DBTYPE_CY:
		{
			COleCurrency cy(*((CURRENCY*)m_pDynamicAccessor->GetValue(nCol)));
			vt = COleVariant(cy);
		}
		break;
	case DBTYPE_NUMERIC:
		{
			DB_NUMERIC num;

			if(m_pDynamicAccessor->GetValue(nCol, &num))
			{
				double dbl;

				dbl = (double)*((__int64*)num.val);
				while(num.scale-- > 0)
					dbl /= 10;
				if(num.sign == 0)
					dbl = -dbl;
				vt = COleVariant(dbl);
			}
		}
		break;
	case DBTYPE_DBDATE:
		{
			DBDATE dbDate;

			if(m_pDynamicAccessor->GetValue(nCol, &dbDate))
			{
				COleDateTime dt;

⌨️ 快捷键说明

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