Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
This example uses the AppendChunk and GetChunk methods to fill an image field with data from another record.
// BeginAppendChunkCpp.cpp
// compile with: /EHsc /c
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")
#define ChunkSize 100
#include <ole2.h>
#include <stdio.h>
#include "conio.h"
#include "malloc.h"
#include "icrsint.h"
// extracts pubid, prinfo.
class CPubInfoRs : public CADORecordBinding {
BEGIN_ADO_BINDING(CPubInfoRs)
ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_sz_pubid, sizeof(m_sz_pubid), l_pubid, TRUE)
ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_sz_prinfo, sizeof(m_sz_prinfo), l_prinfo, TRUE)
END_ADO_BINDING()
public:
CHAR m_sz_pubid[10];
ULONG l_pubid;
CHAR m_sz_prinfo[200];
ULONG l_prinfo;
};
//Function declarations
inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };
void AppendChunkX();
void PrintProviderError(_ConnectionPtr pConnection);
inline int myscanf(char* strDest, int n) {
char strExBuff[10];
char* pstrRet = fgets(strDest, n, stdin);
if (pstrRet == NULL)
return 0;
if (!strrchr(strDest, '\n'))
// Exhaust the input buffer.
do {
fgets(strExBuff, sizeof(strExBuff), stdin);
} while (!strrchr(strExBuff, '\n'));
else
// Replace '\n' with '\0'
strDest[strrchr(strDest, '\n') - strDest] = '\0';
return strlen(strDest);
}
inline char* mygets(char* strDest, int n) {
char strExBuff[10];
char* pstrRet = fgets(strDest, n, stdin);
if (pstrRet == NULL)
return NULL;
if (!strrchr(strDest, '\n'))
// Exhaust the input buffer.
do {
fgets(strExBuff, sizeof(strExBuff), stdin);
} while (!strrchr(strExBuff, '\n'));
else
// Replace '\n' with '\0'
strDest[strrchr(strDest, '\n') - strDest] = '\0';
return pstrRet;
}
int main() {
HRESULT hr = S_OK;
if (FAILED(::CoInitialize(NULL)))
return -1;
AppendChunkX();
::CoUninitialize();
}
void AppendChunkX() {
// Define ADO object pointers, initialize pointers on define. These are in the ADODB:: namespace.
_RecordsetPtr pRstPubInfo = NULL;
_ConnectionPtr pConnection = NULL;
char * token1;
// Define other variables
IADORecordBinding *picRs = NULL; // Interface Pointer declared.(VC++ Extensions)
CPubInfoRs pubrs; // C++ class object
HRESULT hr = S_OK;
_bstr_t strCnn("Provider='sqloledb'; Data Source='My_Data_Source'; Initial Catalog='pubs'; Integrated Security='SSPI';");
_bstr_t strMessage,strPubID,strPRInfo;
_variant_t varChunk;
long lngOffSet,lngLogoSize;
char pubId[50];
lngOffSet = 0;
UCHAR chData;
SAFEARRAY FAR *psa;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = ChunkSize;
try {
// Open a Connection.
TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
hr = pConnection->Open(strCnn, "", "", adConnectUnspecified);
TESTHR(hr= pRstPubInfo.CreateInstance(__uuidof(Recordset)));
pRstPubInfo->CursorType = adOpenKeyset;
pRstPubInfo->LockType = adLockOptimistic;
hr = pRstPubInfo->Open("pub_info", _variant_t((IDispatch*)pConnection,true),
adOpenKeyset, adLockOptimistic, adCmdTable);
// Open an IADORecordBinding interface pointer for Binding Recordset to a class
TESTHR(pRstPubInfo->QueryInterface(__uuidof(IADORecordBinding), (LPVOID*)&picRs));
// Bind the Recordset to a C++ Class here
TESTHR(picRs->BindToRecordset(&pubrs));
// Display the available logos here
strMessage = "Available logos are: " + (_bstr_t)"\n\n";
printf(strMessage);
int Counter = 0;
while (!(pRstPubInfo->EndOfFile)) {
printf("\n%s", pubrs.m_sz_pubid);
printf("\n%s", strtok_s(pubrs.m_sz_prinfo, ",", &token1));
// Display 5 records at a time and wait for user to continue..
if (++Counter >= 5) {
Counter = 0;
printf("\nPress any key to continue...");
_getch();
}
pRstPubInfo->MoveNext();
}
// Prompt For a Logo to Copy
printf("\nEnter the ID of a logo to copy: ");
myscanf(pubId, sizeof(pubId));
strPubID = pubId;
// Copy the logo to a variable in chunks
pRstPubInfo->Filter = "pub_id = '" + strPubID + "'";
lngLogoSize = pRstPubInfo->Fields->Item["logo"]->ActualSize;
// Create a safe array to store the array of BYTES
rgsabound[0].cElements = lngLogoSize;
psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
long index1 = 0;
while (lngOffSet < lngLogoSize) {
varChunk = pRstPubInfo->Fields->Item["logo"]->GetChunk(ChunkSize);
// Copy the data only up to the Actual Size of Field.
for (long index = 0 ; index <= (ChunkSize - 1) ; index++) {
hr = SafeArrayGetElement(varChunk.parray, &index, &chData);
if (SUCCEEDED(hr)) {
// Take BYTE by BYTE and advance Memory Location
hr = SafeArrayPutElement(psa, &index1, &chData);
index1++;
}
else
break;
}
lngOffSet = lngOffSet + ChunkSize;
}
lngOffSet = 0;
printf("Enter a new Pub Id: ");
myscanf(pubrs.m_sz_pubid, sizeof(pubrs.m_sz_pubid));
strPubID = pubrs.m_sz_pubid;
printf("Enter descriptive text: " );
mygets(pubrs.m_sz_prinfo, sizeof(pubrs.m_sz_prinfo));
pRstPubInfo->AddNew();
pRstPubInfo->Fields->GetItem("pub_id")->PutValue(strPubID);
pRstPubInfo->Fields->GetItem("pr_info")->PutValue(pubrs.m_sz_prinfo);
// Assign the Safe array to a variant.
varChunk.vt = VT_ARRAY|VT_UI1;
varChunk.parray = psa;
hr = pRstPubInfo->Fields->GetItem("logo")->AppendChunk(varChunk);
// Update the table
pRstPubInfo->Update();
lngLogoSize = pRstPubInfo->Fields->Item["logo"]->ActualSize;
// Show the newly added record.
printf("New Record : %s\n Description : %s\n Logo Size : %s",
pubrs.m_sz_pubid,
pubrs.m_sz_prinfo,(LPCSTR)(_bstr_t)pRstPubInfo->Fields->
Item["logo"]->ActualSize);
// Delete new record because this is demonstration.
pConnection->Execute("DELETE FROM PUB_INFO WHERE pub_id = '"
+ strPubID +"'", NULL,adCmdText);
}
catch(_com_error &e) {
// Notify the user of errors if any.
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
PrintProviderError(pConnection);
printf("Source : %s \n Description : %s\n", (LPCSTR)bstrSource,
(LPCSTR)bstrDescription);
}
// Clean up objects before exit.
if (pRstPubInfo)
if (pRstPubInfo->State == adStateOpen)
pRstPubInfo->Close();
if (pConnection)
if (pConnection->State == adStateOpen)
pConnection->Close();
}
void PrintProviderError(_ConnectionPtr pConnection) {
// Print Provider Errors from Connection object.
// pErr is a record object in the Connection's Error collection.
ErrorPtr pErr = NULL;
long nCount = 0;
long i = 0;
if ( (pConnection->Errors->Count) > 0) {
nCount = pConnection->Errors->Count;
// Collection ranges from 0 to nCount -1.
for (i = 0 ; i < nCount ; i++) {
pErr = pConnection->Errors->GetItem(i);
printf("\t Error number: %x\t%s", pErr->Number, (LPCSTR) pErr->Description);
}
}
}