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

📄 main.cpp

📁 用测试OLE DB提供者的一个程序。能够测试出OEL DB提供者到底实现了哪些接口?很灵的。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDMENU_REFRESH,				(BOOL)m_pCRowset->m_pIRowset);
	SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDMENU_GETSCHEMAROWSET,		(BOOL)pCSession->m_pIDBSchemaRowset);
//	SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDMENU_INSERTROW,				(BOOL)m_pCRowset->m_pIRowsetChange);
//	SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDMENU_DELETEROWS,			(BOOL)m_pCRowset->m_pIRowsetChange);
//	SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDMENU_SETDATA,				(BOOL)m_pCRowset->m_pIRowsetChange);
	SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDMENU_UPDATE,				(BOOL)m_pCRowset->m_pIRowsetUpdate);
	SendMessage(hWndToolbar, TB_ENABLEBUTTON, IDMENU_UNDO,					(BOOL)m_pCRowset->m_pIRowsetUpdate);

	//Disable ListView window
	EnableWindow(m_hWndListView, (BOOL)m_pCRowset->m_pIUnknown);
	EnableWindow(m_hWndScrollBar, (BOOL)m_pCRowset->m_pIUnknown);

	//Update Window Title (in-case things have changed...)
	UpdateWndTitle();
	return TRUE;
}


////////////////////////////////////////////////////////////////
// CMDIChild::CreateRowset
//
/////////////////////////////////////////////////////////////////
HRESULT CMDIChild::CreateRowset(ROWSETSOURCE eRowsetSource, DBID* pTableID, DBID* pIndexID, ULONG cPropSets, DBPROPSET* rgPropSets, REFIID riid, const GUID* pGuidSchema, ULONG cRestrictions, VARIANT* rgRestrictions)
{
	Busy();
	HRESULT hr = S_OK;
	LONG cRowsAffected = DB_COUNTUNAVAILABLE;

	//Create the rowset, (either from Command, IOpenRowset, or Schema's)
	TESTC(hr = m_pCRowset->CreateRowset(eRowsetSource, cPropSets, rgPropSets, &cRowsAffected, pTableID, pIndexID, riid, pGuidSchema, cRestrictions, rgRestrictions));

	//Empty IRowset
	if(hr==S_FALSE || (m_pCRowset->m_pIUnknown == NULL && m_pCRowset->m_pCDataset->m_pIMDDataset == NULL))
	{ 
		//Display RowsAffect - (if desired)
		if(GetOptionsObj()->m_dwCommandOpts & COMMAND_ROWSAFFECTED)
		{
			if(cRowsAffected == DB_COUNTUNAVAILABLE)
				wMessageBox(m_hWnd, MB_TASKMODAL | MB_ICONWARNING | MB_OK, wsz_INFO, 
					L"RowsAffected = DB_COUNTUNAVAILABLE, No Rowset returned, ");
			else
				wMessageBox(m_hWnd, MB_TASKMODAL | MB_ICONWARNING | MB_OK, wsz_INFO, 
					L"RowsAffected = %d, No Rowset returned", cRowsAffected );
		}
		goto CLEANUP;
	}

	//Delegate - Display the Rowset
	TESTC(hr = DisplayRowset());

CLEANUP:
	RefreshControls();
	Busy(OFF);
	return hr;
}

	 
////////////////////////////////////////////////////////////////
// CMDIChild::DisplayRowset
//
/////////////////////////////////////////////////////////////////
HRESULT CMDIChild::DisplayRowset()
{
	Busy();
	HRESULT hr = S_OK;

	//Reset Cursor
	m_fPrevFetchForward = FALSE;
	m_lCurPos = 0;
	BOOL fBindBookmark = GetOptionsObj()->m_dwRowsetOpts & ROWSET_BINDBOOKMARK;

	//Create ColumnInfo
	TESTC(hr = m_pCRowset->GetColInfo());

	//Create Accessors and Setup bindings
	TESTC(hr = m_pCRowset->CreateAccessors(fBindBookmark));

	//Refresh the Columns and Rows
	TESTC(hr = RefreshData());

CLEANUP:
	RefreshControls();
	Busy(OFF);
	return hr;
}


////////////////////////////////////////////////////////////////
// CMDIChild::ExecuteDataset
//
/////////////////////////////////////////////////////////////////
HRESULT CMDIChild::ExecuteDataset(ROWSETSOURCE eRowsetSource)
{
	HRESULT hr = E_FAIL;
	CHAR szBuffer[MAX_QUERY_LEN+1];
	WCHAR wszBuffer[MAX_QUERY_LEN+1];
	LONG cRowsAffected = DB_COUNTUNAVAILABLE;

	ASSERT(eRowsetSource==ROWSET_FROMCOMMANDDATASET);

	// Get the EditBox value (either TableName or SQL Statement)
	GetEditBoxSelection(m_hWndEditBox, szBuffer, MAX_QUERY_LEN);
		
	// Convert to WCHAR (for ICommand and IOpenRowset)
	ConvertToWCHAR(szBuffer, wszBuffer, MAX_QUERY_LEN);

	TESTC(hr = m_pCRowset->CreateDataset(eRowsetSource, &cRowsAffected, wszBuffer));

	// if IMDDataset is empty
	if (m_pCRowset->m_pCDataset->m_pIMDDataset == NULL)
	{ 
		if (cRowsAffected == DB_COUNTUNAVAILABLE)
			wMessageBox(NULL, MB_TASKMODAL | MB_ICONWARNING | MB_OK, wsz_INFO, 
				L"No Rowset returned, RowsAffected = DB_COUNTUNAVAILABLE");
		else
			wMessageBox(NULL, MB_TASKMODAL | MB_ICONWARNING | MB_OK, wsz_INFO, 
				L"No Rowset returned, RowsAffected = %d rows affected", cRowsAffected );
		goto CLEANUP;
	}

	//Clear ListView object
	TESTC(hr = ClearListView());

CLEANUP:
	RefreshControls();
	return hr;
}


////////////////////////////////////////////////////////////////
// CMDIChild::DisplayColumnInfo
//
/////////////////////////////////////////////////////////////////
HRESULT CMDIChild::DisplayColumnInfo()
{
	LONG	iResult = 0;
	CHAR	szBuffer[MAX_NAME_LEN+1];		// String Buffer

	//Insert the Column Headers.
	//Only display the columns for which are bound in the Accessor
	ULONG cBindings = m_pCRowset->m_cBindings;
	DBBINDING* rgBindings = m_pCRowset->m_rgBindings;
	
	//Insert Row Header
	LV_InsertColumn(m_hWndListView, 0, m_pCRowset->m_eRowsetSource == ROWSET_FROMCOMMANDDATASET ? "Cell Ordinal" : "Row Handle");

	//Loop through the Bindings
	for(ULONG i=0; i<cBindings; i++)
	{
		DBCOLUMNINFO* pColInfo = m_pCRowset->GetColInfo(rgBindings[i].iOrdinal);
		
		//Get ColumnName
		ConvertToMBCS(m_pCRowset->GetColName(pColInfo->iOrdinal), szBuffer, MAX_NAME_LEN);
		iResult = LV_InsertColumn(m_hWndListView, i+1, szBuffer, GetColumnImage(pColInfo));
	}

	//AutoSize Columns, (including "Row-Handle" column)
	for(i=0; i<cBindings+1; i++)
		SendMessage(m_hWndListView, LVM_SETCOLUMNWIDTH, (WPARAM)i,	(LPARAM)LVSCW_AUTOSIZE_USEHEADER);

	//CLEANUP:    
    return iResult == LVM_ERR ? E_FAIL : S_OK;    
}


////////////////////////////////////////////////////////////////
// CMDIChild::DisplayData
//
/////////////////////////////////////////////////////////////////
HRESULT CMDIChild::DisplayData
(
	REFIID			riid,
	HROW			hRow,
	ULONG			iIndex
)
{
	//Always displays upto m_ulMaxViewItems every time.
	//If unable to display m_ulMaxViewItems, the other rows are emptied...
	ASSERT(iIndex >=0 && iIndex<ULONG_MAX);
	HRESULT hr = E_FAIL;
	
	//First, Set Text and save hRow
	CHAR szBuffer[MAX_COL_SIZE+1];
	sprintf(szBuffer, "0x%x", hRow);
	LV_SetItemText(m_hWndListView, iIndex, 0, szBuffer);
	LV_SetItemParam(m_hWndListView, iIndex, 0, hRow);

	//This displays data from any source.  IRowset*::Get*Data,
	//GetData, GetOriginalData, GetVisibleData
	if(riid == IID_IRowset)
	{
		//GetData wrapper with Argument checking...
		hr = m_pCRowset->GetData(hRow);
	}
	else if(riid == IID_IRowsetUpdate)
	{
		//GetOriginalData wrapper with Argument checking...
		hr = m_pCRowset->GetOriginalData(hRow);
	}
	else if(riid == IID_IRowsetResynch)
	{
		//GetVisibleData wrapper with Argument checking...
		hr = m_pCRowset->GetVisibleData(hRow);
	}
	else
	{
		ASSERT(!"Unhandled Data Source!");
	}

	//Relax the errors here.  With Get*Data both DB_S/DB_E will return a bad
	//status for 1 or more columns.  Or DataGrid will just display the column
	//status if not S_OK.  So for these errors just display the data anyway...
	if(FAILED(hr) && hr!= DB_E_ERRORSOCCURRED)
		goto CLEANUP;
	hr = S_OK;
	
	//Display to the ListView
    TESTC(hr = DumpRow
			(
			hRow,
			m_pCRowset->m_cBindings,
			m_pCRowset->m_rgBindings, 
			m_pCRowset->m_pData,			  
			iIndex
			));
	
CLEANUP:
    return hr;
}


////////////////////////////////////////////////////////////////
// CMDIChild::DisplayRows
//
/////////////////////////////////////////////////////////////////
HRESULT CMDIChild::DisplayRows
(
	LONG			lOffset,
	LONG			cRows
)
{
	HRESULT hr = E_FAIL;

	ULONG 	i,cRowsObtained =  0;
	HROW	rghRows[MAX_OPENROWS];
	HROW*	phRow = rghRows;
	LONG    iItems = 0;
	CHAR	szRowHandle[10];

	//Only use dynamic memory allocation if more rows than our static array
	if(abs(cRows) > MAX_OPENROWS)
		phRow = NULL;	

	//Calculate the starting position to place rows
	LONG lStartIndex = m_fPrevFetchForward ? m_lCurPos + lOffset + 1 : m_lCurPos + lOffset;
	lStartIndex = cRows > 0 ? lStartIndex : lStartIndex - 1;

	//Deletgate
	TESTC(hr = GetNextRows(lOffset, cRows, &cRowsObtained, &phRow));
	
	//Obtain total ListItems
	iItems = SendMessage(m_hWndListView, LVM_GETITEMCOUNT, 0, 0);
	ASSERT(iItems >= 0);

	//Only remove the neccessary amount of rows from the existing view.
	//We don't want to have both pgup/pgdn show half filled data views...
	if(SUCCEEDED(hr) && cRowsObtained && 0)
	{
		if(cRowsObtained >= m_ulMaxViewItems)
		{
			SendMessage(m_hWndListView, LVM_DELETEALLITEMS, 0, 0);
			iItems = 0;
		}
		else
		{
			while(cRowsObtained + iItems > m_ulMaxViewItems)
			{
				//If we want to add rows to the top, we need to remove from the bottom
				//If we want to add rows to the bottom, we need to remove from the top
				if(lStartIndex == 0)
				{
					SendMessage(m_hWndListView, LVM_DELETEITEM, iItems-1, 0);
				}
				else
				{
					SendMessage(m_hWndListView, LVM_DELETEITEM, 0, 0);
				}
				iItems--;
			}
		}
	}	

	//Adjust boundaries 
	lStartIndex = max(lStartIndex, 0);
	lStartIndex = min(lStartIndex, iItems);

	//Loop over rows obtained, getting data for each and displaying in the ListView
	for(i=0; i<cRowsObtained; i++ )
	{
		//Calulate which direction to start with the hRows
		HROW hRow = phRow[i];
		if(cRows < 0 && m_pCRowset->m_eRowsetSource != ROWSET_FROMCOMMANDDATASET)
			hRow = phRow[cRowsObtained - 1 - i];
		LONG iIndex = cRows > 0 ? lStartIndex + i : lStartIndex - i;
		
		if(iIndex >= iItems)
		{
			//Insert the New hRow into the ListView
			LV_InsertItem(m_hWndListView, iIndex, 0, "", 0, IMAGE_NORMAL);

			//Display GetData in the ListView
			hr = DisplayData(IID_IRowset, hRow, iIndex);
		}
		else
		{
			//Just update the Row Handle
			sprintf(szRowHandle, "0x%x", hRow);
			LV_SetItemText(m_hWndListView, iIndex, 0, szRowHandle);
			LV_SetItemParam(m_hWndListView, iIndex, 0, hRow);
		}
	}

	//Display the NextFetchPosition
	LV_SetItemImage(m_hWndListView, m_lCurPos, 0, m_fPrevFetchForward ? IMAGE_NFP_AFTER : IMAGE_NFP_BEFORE);
	SendMessage(m_hWndListView, LVM_ENSUREVISIBLE, m_lCurPos, TRUE);

	//Adjust ScrollBar on Success
	if(m_fEndReached)
		SetScroll(m_fPrevFetchForward ? m_ulScrollMax : 0);
	else
		SetScroll(GetScrollPos(m_hWndScrollBar, SB_CTL) + lOffset + cRows);

CLEANUP:
	if(cRows > MAX_OPENROWS)
		SAFE_FREE(phRow);
	return hr;
}


////////////////////////////////////////////////////////////////
// CMDIChild::GetNextRows
//
/////////////////////////////////////////////////////////////////
HRESULT CMDIChild::GetNextRows(LONG lOffset, LONG cRows, ULONG* pcRowsObtained, HROW** prghRows)
{
	HRESULT hr = S_OK;
	LONG    iItems = 0;
	ULONG   cRowsObtained = 0;
	
	//GetNextRows
	if (m_pCRowset->m_eRowsetSource == ROWSET_FROMCOMMANDDATASET)
	{
		TESTC(hr = m_pCRowset->m_pCDataset->GetNextCells(cRows, &cRowsObtained, *prghRows));
	}
	else
	{
		TESTC(hr = m_pCRowset->GetNextRows(lOffset, cRows, &cRowsObtained, prghRows));
	}
	
	//Obtain total ListItems
	iItems = SendMessage(m_hWndListView, LVM_GETITEMCOUNT, 0, 0);
	ASSERT(iItems >= 0);

	//Adjust the Cursor Position
	if(cRowsObtained)
	{
		//Need to remove the "NextFetchPositon" icon from the "old" row
		LV_SetItemImage(m_hWndListView, m_lCurPos, 0, IMAGE_NORMAL);

		if(cRows > 0)
		{
			m_lCurPos += (m_fPrevFetchForward ? lOffset + cRowsObtained : lOffset + cRowsObtained - 1);
		}
		else
		{
			m_lCurPos += (m_fPrevFetchForward ? lOffset - cRowsObtained + 1: lOffset - cRowsObtained);
		}

		m_lCurPos = max(m_lCurPos, 0);
//		m_lCurPos = min(m_lCurPos, (m_ulMaxViewItems && !GetOptionsObj()->m_dwDisplayAllRows) ? (LONG)m_ulMaxViewItems-1 : m_lCurPos);
		m_lCurPos = min(m_lCurPos, (LONG)cRowsObtained + iItems - 1);
	}

	//Adjust last fetch direction.
	m_fPrevFetchForward = (cRows>0 ? TRUE : FALSE);

	//Indicate End or Rowset was reached
	m_fEndReached = FALSE;
	if(hr == DB_S_ENDOFROWSET)
		m_fEndReached = TRUE;
		
CLEANUP:
	if(pcRowsObtained)
		*pcRowsObtained = cRowsObtained;
    return hr;
}


////////////////////////////////////////////////////////////////
// CMDIChild::MoveCursor
//
/////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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