📄 main.cpp
字号:
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 + -