?? employees.cpp
字號:
if(pIRowset)
{
pIRowset->Release();
}
if(pIOpenRowset)
{
pIOpenRowset->Release();
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////
// Function: SaveEmployeePhoto()
//
// Description: Save employee photo to database.
//
// Returns: NOERROR if succesfull
//
// Notes:
//
////////////////////////////////////////////////////////////////////////////////
HRESULT Employees::SaveEmployeePhoto(ISequentialStream* pISequentialStream, DWORD dwPhotoID)
{
HRESULT hr = E_FAIL;
HRSRC hrSrc;
HGLOBAL hPhoto;
BYTE *pPhotoData = NULL;
DWORD dwSize;
DWORD dwWritten;
// Determine the location of the employee photo resource
//
hrSrc = FindResource(m_hInstance, MAKEINTRESOURCE(dwPhotoID), TEXT("PHOTO"));
if (NULL == hrSrc)
{
goto Exit;
}
// Load the employee photo resource into memory
//
hPhoto = LoadResource(m_hInstance, hrSrc);
if (NULL == hPhoto)
{
goto Exit;
}
// Lock the resource in memory
// Get a pointer to the first byte of the resource
//
pPhotoData = (BYTE*)LockResource(hPhoto);
if (NULL == pPhotoData)
{
goto Exit;
}
// Get the size, in bytes, of the resource
//
dwSize = SizeofResource(m_hInstance, hrSrc);
if (0 == dwSize)
{
goto Exit;
}
// Write the photo data into the stream object
//
hr = pISequentialStream->Write(pPhotoData, dwSize, &dwWritten);
if(FAILED(hr) || (dwWritten != dwSize))
{
goto Exit;
}
hr = NOERROR;
Exit:
// Release memory
if (hPhoto)
{
DeleteObject(hPhoto);
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////
// Function: PopulateEmployeeNameList()
//
// Description: Populate combobox with employee name list.
//
// Returns: NOERROR if succesfull
//
// Notes:
//
////////////////////////////////////////////////////////////////////////////////
HRESULT Employees::PopulateEmployeeNameList()
{
HRESULT hr = NOERROR; // Error code reporting
DBID TableID; // Used to open/create table
DBID IndexID; // Used to open/create index
DBPROPSET rowsetpropset[1]; // Used when opening integrated index
DBPROP rowsetprop[1]; // Used when opening integrated index
DBBINDING *prgBinding = NULL; // Binding used to create accessor
HROW rghRows[1]; // Array of row handles obtained from the rowset object
HROW* prghRows = rghRows; // Row handle(s) pointer
ULONG cRowsObtained; // Number of rows obtained from the rowset object
BYTE *pData = NULL; // Record data
DBCOLUMNINFO *pDBColumnInfo = NULL; // Record column metadata
WCHAR *pwszName = NULL; // Record employee name
DWORD dwIndex = 0;
DWORD dwOffset = 0;
DWORD dwBindingSize = 0;
DWORD dwOrdinal = 0;
ULONG ulNumCols = 0;
WCHAR *pStringsBuffer = NULL;
IOpenRowset *pIOpenRowset = NULL; // Provider Interface Pointer
IRowset *pIRowset = NULL; // Provider Interface Pointer
IColumnsInfo *pIColumnsInfo = NULL; // Provider Interface Pointer
IAccessor* pIAccessor = NULL; // Provider Interface Pointer
HACCESSOR hAccessor = DB_NULL_HACCESSOR;// Accessor handle
WCHAR* pwszEmployees[] = { // Info to retrieve employee names
L"EmployeeID",
L"LastName",
L"FirstName"
};
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 IRowsetIndex 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_IRowset,
sizeof(rowsetpropset)/sizeof(rowsetpropset[0]),
rowsetpropset,
(IUnknown**)&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;
}
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].wType = pDBColumnInfo[dwOrdinal].wType;
prgBinding[dwIndex].pTypeInfo = NULL;
prgBinding[dwIndex].pObject = 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(prgBinding[dwIndex].wType)
{
case DBTYPE_WSTR:
prgBinding[dwIndex].cbMaxLen = sizeof(WCHAR)*(pDBColumnInfo[dwOrdinal].ulColumnSize + 1); // Extra buffer for null terminator
break;
default:
prgBinding[dwIndex].cbMaxLen = pDBColumnInfo[dwOrdinal].ulColumnSize;
break;
}
// Calculate the offset, and properly align it
//
dwOffset = prgBinding[dwIndex].obValue + prgBinding[dwIndex].cbMaxLen;
dwOffset = ROUND_UP(dwOffset, COLUMN_ALIGNVAL);
}
// Get IAccessor
//
hr = pIRowset->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
if(FAILED(hr))
{
goto Exit;
}
// Create the accessor
//
hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,
dwBindingSize,
prgBinding,
0,
&hAccessor,
NULL);
if(FAILED(hr))
{
goto Exit;
}
// Allocate data buffer.
//
pData = (BYTE*)CoTaskMemAlloc(dwOffset);
if (NULL == pData)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Allocate a memory big enough to held employee name
// LastName + ', ' + FirstName
//
pwszName = (WCHAR*)CoTaskMemAlloc(prgBinding[1].cbMaxLen + prgBinding[2].cbMaxLen + 2);
if (NULL == pwszName)
{
hr = E_OUTOFMEMORY;
goto Exit;
}
// Retrive a row
//
hr = pIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, &prghRows);
while (SUCCEEDED(hr) && DB_S_ENDOFROWSET != hr)
{
// Set data buffer to zero
//
memset(pData, 0, dwOffset);
// Fetch actual data
hr = pIRowset->GetData(prghRows[0], hAccessor, pData);
if (FAILED(hr))
{
// Release the rowset.
//
pIRowset->ReleaseRows(1, prghRows, NULL, NULL, NULL);
goto Exit;
}
// If return a null value, ignore the contents of the value and length parts of the buffer.
//
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[0].obStatus))
{
// If return a null value, ignore the contents of the value and length parts of the buffer.
//
if (DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[1].obStatus) &&
DBSTATUS_S_ISNULL != *(DBSTATUS *)(pData+prgBinding[2].obStatus))
{
// Combine employee last name and first name
//
wcscpy(pwszName, (WCHAR*)(pData+prgBinding[1].obValue));
wcscat(pwszName, L", ");
wcscat(pwszName, (WCHAR*)(pData+prgBinding[2].obValue));
// Add new item into combobox
//
dwIndex = SendDlgItemMessage(m_hWndEmployees, IDC_COMBO_NAME, CB_ADDSTRING, 0, (LPARAM)pwszName);
if (CB_ERR != dwIndex)
{
// Set item assocaited data to employee id.
SendDlgItemMessage( m_hWndEmployees,
IDC_COMBO_NAME,
CB_SETITEMDATA,
dwIndex,
*(LONG*)(pData+prgBinding[0].obValue));
}
}
}
// Release the rowset.
//
hr = pIRowset->ReleaseRows(1, prghRows, NULL, NULL, NULL);
if(FAILED(hr))
{
goto Exit;
}
// Free allocated memory for row handles.
//
if (prghRows)
{
CoTaskMemFree(prghRows);
prghRows = NULL;
}
// Fetches next row.
hr = pIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, &prghRows);
}
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;
}
// Free employee name buffer
//
if (pwszName)
{
CoTaskMemFree(pwszName);
pwszName = NULL;
}
// Release interfaces
//
if(pIAccessor)
{
pIAccessor->ReleaseAccessor(hAccessor, NULL);
pIAccessor->Release();
}
if (pIColumnsInfo)
{
pIColumnsInfo->Release();
}
if(pIRowset)
{
pIRowset->Release();
}
if(pIOpenRowset)
{
pIOpenRowset->Release();
}
return hr;
}
////////////////////////////////////////////////////////////////////////////////
// Function: LoadEmployeeInfo()
//
// Description: Update employee info based on employee id.
//
// Returns: NOERROR if succesfull
//
// Notes:
//
////////////////////////////////////////////////////////////////////////////////
HRESULT Employees::LoadEmployeeInfo(DWORD dwEmployeeID)
{
HRESULT hr = NOERROR; // Error code reporting
DBBINDING *prgBinding = NULL; // Binding used to create accessor
HROW rghRows[1]; // Array of row handles obtained from the rowset object
HROW *prghRows = rghRows; // Row handle(s) pointer
DBID TableID; // Used to open/create table
DBID IndexID; // Used to create index
DBPROPSET rowsetpropset[1]; // Used when opening integrated index
DBPROP rowsetprop[1]; // Used when opening integrated index
ULONG cRowsObtained = 0; // Number of rows obtained from the rowset object
DBOBJECT dbObject; // DBOBJECT data.
DBCOLUMNINFO *pDBColumnInfo = NULL; // Record column metadata
BYTE *pData = NULL; // record data
WCHAR *pStringsBuffer = NULL;
DWORD dwBindingSize = 0;
DWORD dwIndex = 0;
DWORD dwOffset = 0;
DWORD dwOrdinal = 0;
ULONG ulNumCols;
IOpenRowset *pIOpenRowset = NULL; // Provider Interface Pointer
IRowset *pIRowset = NULL; // Provider Interface Pointer
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -