?? employees.cpp
字號(hào):
IRowsetIndex *pIRowsetIndex = NULL; // Provider Interface Pointer
IAccessor *pIAccessor = NULL; // Provider Interface Pointer
ILockBytes *pILockBytes = NULL; // Provider Interface Pointer
IColumnsInfo *pIColumnsInfo = NULL; // Provider Interface Pointer
HACCESSOR hAccessor = DB_NULL_HACCESSOR;// Accessor handle
WCHAR* pwszEmployees[] = { // Employee info Column names
L"EmployeeID",
L"Address",
L"City",
L"Region",
L"PostalCode",
L"Country",
L"HomePhone",
L"Photo"
};
VariantInit(&rowsetprop[0].vValue);
// Validate IDBCreateSession interface
//
if (NULL == m_pIDBCreateSession)
{
hr = E_POINTER;
goto Exit;
}
// Create a session object
//
hr = m_pIDBCreateSession->CreateSession(NULL, IID_IOpenRowset, (IUnknown**) &pIOpenRowset);
if(FAILED(hr))
{
goto Exit;
}
// Set up information necessary to open a table
// using an index and have the ability to seek.
TableID.eKind = DBKIND_NAME;
TableID.uName.pwszName = (WCHAR*)TABLE_EMPLOYEE;
IndexID.eKind = DBKIND_NAME;
IndexID.uName.pwszName = L"PK_Employees";
// Request ability to use IRowsetChange interface
//
rowsetpropset[0].cProperties = 1;
rowsetpropset[0].guidPropertySet= DBPROPSET_ROWSET;
rowsetpropset[0].rgProperties = rowsetprop;
rowsetprop[0].dwPropertyID = DBPROP_IRowsetIndex;
rowsetprop[0].dwOptions = DBPROPOPTIONS_REQUIRED;
rowsetprop[0].colid = DB_NULLID;
rowsetprop[0].vValue.vt = VT_BOOL;
rowsetprop[0].vValue.boolVal = VARIANT_TRUE;
// Open the table using the index
//
hr = pIOpenRowset->OpenRowset( NULL,
&TableID,
&IndexID,
IID_IRowsetIndex,
sizeof(rowsetpropset)/sizeof(rowsetpropset[0]),
rowsetpropset,
(IUnknown**) &pIRowsetIndex);
if(FAILED(hr))
{
goto Exit;
}
// Get IRowset interface
//
hr = pIRowsetIndex->QueryInterface(IID_IRowset, (void**) &pIRowset);
if(FAILED(hr))
{
goto Exit;
}
// Get IColumnsInfo interface
//
hr = pIRowset->QueryInterface(IID_IColumnsInfo, (void **)&pIColumnsInfo);
if(FAILED(hr))
{
goto Exit;
}
// Get the column metadata
//
hr = pIColumnsInfo->GetColumnInfo(&ulNumCols, &pDBColumnInfo, &pStringsBuffer);
if(FAILED(hr) || 0 == ulNumCols)
{
goto Exit;
}
// Create a DBBINDING array.
//
dwBindingSize = sizeof(pwszEmployees)/sizeof(pwszEmployees[0]);
prgBinding = (DBBINDING*)CoTaskMemAlloc(sizeof(DBBINDING)*dwBindingSize);
if (NULL == prgBinding)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Set initial offset for binding position
//
dwOffset = 0;
// Prepare structures to create the accessor
//
for (dwIndex = 0; dwIndex < dwBindingSize; ++dwIndex)
{
if (!GetColumnOrdinal(pDBColumnInfo, ulNumCols, pwszEmployees[dwIndex], &dwOrdinal))
{
hr = E_FAIL;
goto Exit;
}
// Prepare structures to create the accessor
//
prgBinding[dwIndex].iOrdinal = dwOrdinal;
prgBinding[dwIndex].dwPart = DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH;
prgBinding[dwIndex].obLength = dwOffset;
prgBinding[dwIndex].obStatus = prgBinding[dwIndex].obLength + sizeof(ULONG);
prgBinding[dwIndex].obValue = prgBinding[dwIndex].obStatus + sizeof(DBSTATUS);
prgBinding[dwIndex].pTypeInfo = NULL;
prgBinding[dwIndex].pBindExt = NULL;
prgBinding[dwIndex].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
prgBinding[dwIndex].dwFlags = 0;
prgBinding[dwIndex].bPrecision = pDBColumnInfo[dwOrdinal].bPrecision;
prgBinding[dwIndex].bScale = pDBColumnInfo[dwOrdinal].bScale;
switch(pDBColumnInfo[dwOrdinal].wType)
{
case DBTYPE_BYTES: // Column "Photo" binding (BLOB)
// Set up the DBOBJECT structure.
//
dbObject.dwFlags = STGM_READ;
dbObject.iid = IID_ILockBytes;
prgBinding[dwIndex].pObject = &dbObject;
prgBinding[dwIndex].cbMaxLen = sizeof(IUnknown*);
prgBinding[dwIndex].wType = DBTYPE_IUNKNOWN;
break;
case DBTYPE_WSTR:
prgBinding[dwIndex].pObject = NULL;
prgBinding[dwIndex].wType = pDBColumnInfo[dwOrdinal].wType;
prgBinding[dwIndex].cbMaxLen = sizeof(WCHAR)*(pDBColumnInfo[dwOrdinal].ulColumnSize + 1); // Extra buffer for null terminator
break;
default:
prgBinding[dwIndex].pObject = NULL;
prgBinding[dwIndex].wType = pDBColumnInfo[dwOrdinal].wType;
prgBinding[dwIndex].cbMaxLen = pDBColumnInfo[dwOrdinal].ulColumnSize;
break;
}
// Calculate new offset
//
dwOffset = prgBinding[dwIndex].obValue + prgBinding[dwIndex].cbMaxLen;
// Properly align the offset
//
dwOffset = ROUND_UP(dwOffset, COLUMN_ALIGNVAL);
}
// Get IAccessor interface
//
hr = pIRowset->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
if(FAILED(hr))
{
goto Exit;
}
// Create accessor.
//
hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,
dwBindingSize,
prgBinding,
0,
&hAccessor,
NULL);
if(FAILED(hr))
{
goto Exit;
}
// Allocate data buffer for seek and retrieve operation.
//
pData = (BYTE*)CoTaskMemAlloc(dwOffset);
if (NULL == pData)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Set data buffer to zero
//
memset(pData, 0, dwOffset);
// Set data buffer for seek operation
//
*(ULONG*)(pData+prgBinding[0].obLength) = 4;
*(DBSTATUS*)(pData+prgBinding[0].obStatus) = DBSTATUS_S_OK;
*(int*)(pData+prgBinding[0].obValue) = dwEmployeeID;
// Position at a key value within the current range
//
hr = pIRowsetIndex->Seek(hAccessor, 1, pData, DBSEEK_FIRSTEQ);
if(FAILED(hr))
{
goto Exit;
}
// Retrieve a row handle for the row resulting from the seek
//
hr = pIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, &prghRows);
if(FAILED(hr))
{
goto Exit;
}
if (DB_S_ENDOFROWSET != hr)
{
// Fetch actual data
//
hr = pIRowset->GetData(prghRows[0], hAccessor, pData);
if (FAILED(hr))
{
goto Exit;
}
// Clear employee info on the dialog
//
ClearEmployeeInfo();
// Update dialog
// If return a null value or status is not OK, ignore the contents of the value and length parts of the buffer.
//
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[0].obStatus) &&
DBSTATUS_S_OK == *(DBSTATUS *)(pData+prgBinding[0].obStatus))
{
SetDlgItemInt(m_hWndEmployees, IDC_EDIT_EMPLOYEE_ID, *(LONG*)(pData+prgBinding[0].obValue), 0);
}
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[1].obStatus) &&
DBSTATUS_S_OK == *(DBSTATUS *)(pData+prgBinding[1].obStatus))
{
SetDlgItemText(m_hWndEmployees, IDC_EDIT_ADDRESS, (WCHAR*)(pData+prgBinding[1].obValue));
}
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[2].obStatus) &&
DBSTATUS_S_OK == *(DBSTATUS *)(pData+prgBinding[2].obStatus))
{
SetDlgItemText(m_hWndEmployees, IDC_EDIT_CITY, (WCHAR*)(pData+prgBinding[2].obValue));
}
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[3].obStatus) &&
DBSTATUS_S_OK == *(DBSTATUS *)(pData+prgBinding[3].obStatus))
{
SetDlgItemText(m_hWndEmployees, IDC_EDIT_REGION, (WCHAR*)(pData+prgBinding[3].obValue));
}
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[4].obStatus) &&
DBSTATUS_S_OK == *(DBSTATUS *)(pData+prgBinding[4].obStatus))
{
SetDlgItemText(m_hWndEmployees, IDC_EDIT_POSTAL_CODE, (WCHAR*)(pData+prgBinding[4].obValue));
}
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[5].obStatus) &&
DBSTATUS_S_OK == *(DBSTATUS *)(pData+prgBinding[5].obStatus))
{
SetDlgItemText(m_hWndEmployees, IDC_EDIT_COUNTRY, (WCHAR*)(pData+prgBinding[5].obValue));
}
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[6].obStatus) &&
DBSTATUS_S_OK == *(DBSTATUS *)(pData+prgBinding[6].obStatus))
{
SetDlgItemText(m_hWndEmployees, IDC_EDIT_HOME_PHONE, (WCHAR*)(pData+prgBinding[6].obValue));
}
// Update employee photo
//
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[7].obStatus) &&
DBSTATUS_S_OK == *(DBSTATUS *)(pData+prgBinding[7].obStatus))
{
pILockBytes = (*(ILockBytes**) (pData + prgBinding[7].obValue));
LoadEmployeePhoto(pILockBytes);
}
}
// Release the rowset.
//
pIRowset->ReleaseRows(1, prghRows, NULL, NULL, NULL);
Exit:
// Clear Variants
//
VariantClear(&rowsetprop[0].vValue);
// Free allocated memory for row handles.
//
if (prghRows)
{
CoTaskMemFree(prghRows);
prghRows = NULL;
}
// Free allocated DBBinding memory
//
if (prgBinding)
{
CoTaskMemFree(prgBinding);
prgBinding = NULL;
}
// Free allocated column info memory
//
if (pDBColumnInfo)
{
CoTaskMemFree(pDBColumnInfo);
pDBColumnInfo = NULL;
}
// Free allocated column string values buffer
//
if (pStringsBuffer)
{
CoTaskMemFree(pStringsBuffer);
pStringsBuffer = NULL;
}
// Free data record buffer
//
if (pData)
{
CoTaskMemFree(pData);
pData = NULL;
}
// Release interfaces
//
if(pILockBytes)
{
pILockBytes->Release();
}
if(pIAccessor)
{
pIAccessor->ReleaseAccessor(hAccessor, NULL);
pIAccessor->Release();
}
if (pIColumnsInfo)
{
pIColumnsInfo->Release();
}
if(pIRowset)
{
pIRowset->Release();
}
if (pIRowsetIndex)
{
pIRowsetIndex->Release();
}
if(pIOpenRowset)
{
pIOpenRowset->Release();
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////
// Function: LoadEmployeePhoto()
//
// Description: Load employee photo from database.
//
// Returns: NOERROR if succesfull
//
// Notes: This sample only display 24 bit bitmap
//
////////////////////////////////////////////////////////////////////////////////
HRESULT Employees::LoadEmployeePhoto(ILockBytes* pILockBytes)
{
HRESULT hr = NOERROR;
ULONG ulRead;
ULARGE_INTEGER ulStart;
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFO bmpInfo;
BYTE *pPhotoBits;
HDC hDC;
if (m_hBitmap)
{
// Delete bitmap object, release the device contexts,
//
DeleteObject(m_hBitmap);
m_hBitmap = NULL;
}
// Validate ILockBytes interface
//
if (NULL == pILockBytes)
{
return hr;
}
// Read Bitmap file header
//
ulRead = 0;
ulStart.QuadPart = 0;
hr = pILockBytes->ReadAt(ulStart, &bmpFileHeader, sizeof(BITMAPFILEHEADER), &ulRead);
if(FAILED(hr) || sizeof(BITMAPFILEHEADER) != ulRead)
{
return hr;
}
// Read Bitmap info header
//
ulStart.QuadPart += ulRead;
ulRead = 0;
hr = pILockBytes->ReadAt(ulStart, &bmpInfo, sizeof(BITMAPINFOHEADER), &ulRead);
if(FAILED(hr) || sizeof(BITMAPINFOHEADER) != ulRead)
{
return hr;
}
// THIS SAMPLE ONLY SUPPORT 24 BIT BITMAP
//
if (24 != bmpInfo.bmiHeader.biBitCount)
{
return hr;
}
// Retrieve the device context handle
//
hDC = GetDC(m_hWndEmployees);
// Creates a device-independent bitmap (DIB) with bitmap info
//
m_hBitmap = CreateDIBSection( hDC,
&bmpInfo,
DIB_RGB_COLORS,
(void **)&pPhotoBits,
NULL,
0);
// Read bitmap bits
//
ulStart.QuadPart += ulRead;
ulRead = 0;
hr = pILockBytes->ReadAt(ulStart, pPhotoBits, bmpInfo.bmiHeader.biSizeImage, &ulRead);
if(FAILED(hr) || bmpInfo.bmiHeader.biSizeImage != ulRead)
{
// Delete bitmap object, release the device contexts,
//
DeleteObject(m_hBitmap);
m_hBitmap = NULL;
}
ReleaseDC(m_hWndEmployees, hDC);
return hr;
}
////////////////////////////////////////////////////////////////////////////////
// Function: ShowEmployeePhoto()
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -