Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De WIA-service is afhankelijk van de informatie die in de MINIDRV_TRANSFER_CONTEXT structuur wordt verstrekt om een juiste gegevensoverdracht uit te voeren.
De leden van deze structuur die relevant zijn voor de WIA minidriver zijn:
bClassDrvAllocBuf − WIA-servicetoewijzing Booleaanse waarde.
pTransferBuffer − Aanwijzer naar geheugen toegewezen voor de overgedragen gegevens.
lBufferSize – Grootte van het geheugen dat wordt verwezen door het lid pTransferBuffer .
Als het lid bClassDrvAllocBuf van de MINIDRV_TRANSFER_CONTEXT structuur is ingesteld op TRUE, wordt het toegewezen geheugen voor de minidriver door de WIA-service toegewezen. Als het lid bClassDrvAllocBuf is ingesteld op FALSE, heeft de WIA-service geen geheugen toegewezen voor de minidriver.
De minidriver moet geheugen toewijzen met behulp van de functie CoTaskMemAlloc (beschreven in de Microsoft Windows SDK-documentatie). De minidriver moet vervolgens de aanwijzer opslaan op de geheugenlocatie in pTransferBuffer en de grootte van het geheugen in lBufferSize (in bytes).
Het lid bClassDrvAllocBuff is alleen ingesteld op FALSE als de eigenschap WIA_IPA_TYMED is ingesteld op TYMED_FILE of TYMED_MULTIPAGE_FILE en de eigenschap WIA_IPA_ITEM_SIZE is ingesteld op nul.
De minidriver moet voorzichtig zijn om de buffer niet te overvullen die door het lid pTransferBuffer wordt verwezen. U kunt dit voorkomen door gegevens te schrijven in hoeveelheden die kleiner zijn dan of gelijk zijn aan de waarde die is opgeslagen in het lid lBufferSize .
Prestaties van gegevensoverdracht verbeteren met behulp van minimale buffergrootte
De WIA minidriver kan de hoeveelheid geheugen bepalen die tijdens de gegevensoverdracht wordt gebruikt door de eigenschappen WIA_IPA_ITEM_SIZE en WIA_IPA_BUFFER_SIZE in te stellen.
Een WIA-toepassing maakt gebruik van de eigenschap WIA_IPA_BUFFER_SIZE om de minimale overdrachtbuffergrootte te bepalen die moet worden aangevraagd tijdens een geheugenoverdracht. Hoe groter deze waarde is, hoe groter de aangevraagde bandgrootte is. Als een WIA-toepassing een buffer aanvraagt die kleiner is dan de waarde in de eigenschap WIA_IPA_BUFFER_SIZE, negeert de WIA-service deze aangevraagde grootte en vraagt de WIA-minidriver voor een buffer die WIA_IPA_BUFFER_SIZE bytes groot is. De WIA-service vraagt altijd aan de WIA-minidriver om buffers die minstens WIA_IPA_BUFFER_SIZE bytes groot zijn.
De waarde die de eigenschap WIA_IPA_BUFFER_SIZE bevat, is de minimale hoeveelheid gegevens die een toepassing op elk gewenst moment kan aanvragen. Hoe groter de buffergrootte, hoe groter de aanvragen voor het apparaat zijn. Buffergrootten die te klein zijn, kunnen de prestaties van de gegevensoverdracht vertragen.
Het wordt aanbevolen om de eigenschap WIA_IPA_BUFFER_SIZE in te stellen op een redelijke grootte, zodat het apparaat gegevens met een efficiënte snelheid kan overdragen. Doe dit door het aantal aanvragen (buffergrootte niet te klein) en het aantal tijdrovende aanvragen (buffer te groot) voor uw apparaat te verdelen om optimale prestaties te garanderen.
Stel de eigenschap WIA_IPA_ITEM_SIZE in op nul als de WIA minidriver gegevens kan overdragen. Als het overdrachtstype is TYMED_FILE of TYMED_MULTIPAGE_FILE, is het de verantwoordelijkheid van de minidriver om geheugen toe te wijzen aan de gegevensbuffer die wordt doorgegeven aan de WIA-servicefunctie die naar het bestand schrijft. Dit biedt consistentie in de implementatie van de methode IWiaMiniDrv::d rvAcquireItemData .
De methode IWiaMiniDrv::d rvAcquireItemData wordt aangeroepen door de WIA-service wanneer het van plan is om gegevens van het apparaat naar een toepassing over te dragen. Het WIA-stuurprogramma moet bepalen welk type overdracht (via de WIA-service) de applicatie probeert uit te voeren, door het tymed-lid van de MINIDRV_TRANSFER_CONTEXT te lezen.
Het tymed-lid, dat door de applicatie is ingesteld, kan een van de volgende vier waarden hebben.
TYMED_FILE
Gegevens overdragen naar een bestand.
TYMED_MEERPAGINA_BESTAND
Gegevens overdragen naar een bestandsindeling met meerdere pagina's.
TYMED_CALLBACK
Gegevens overdragen naar het geheugen.
TYMED_MULTIPAGE_CALLBACK
Meerdere pagina's met gegevens overbrengen naar het geheugen.
De verschillende TYMED-instellingen XXX_CALLBACK en XXX_FILE het gebruik van het aanroepen van de callback-interface van de toepassing wijzigen.
TYMED_CALLBACK en TYMED_MULTIPAGE_CALLBACK
Voor een geheugenoverdracht geeft u een IWiaMiniDrvCallBack::MiniDrvCallback callback uit:
(pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback in de volgende voorbeeldbroncode)
Maak de callback met behulp van de volgende waarden:
IT_MSG_DATA
Het stuurprogramma draagt gegevens over.
IT_STATUS_OVERDRACHT_NAAR_KLANT
Het bericht over de gegevensoverdracht.
lPercentComplete
Het percentage van de overdracht dat is voltooid.
pmdtc-cbOffset>
Werk dit bij naar de huidige locatie waar de toepassing het volgende gegevenssegment moet schrijven.
lBytesReceived
Het aantal bytes in het gegevenssegment dat naar de toepassing wordt verzonden.
pmdtc
Wijs een MINIDRV_TRANSFER_CONTEXT structuur aan die de gegevensoverdrachtwaarden bevat.
TYMED_FILE en TYMED_MULTIPAGE_FILE
Voor een bestandsoverdracht geeft u een IWiaMiniDrvCallBack::MiniDrvCallback callback ::
(pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback in de volgende voorbeeldbroncode)
Maak de callback met behulp van de volgende waarden.
IT_MSG_STATUS
Het stuurprogramma verzendt alleen de status (geen gegevens).
STATUS_OVERDRACHT_NAAR_KLANT
Het bericht over de gegevensoverdracht.
lPercentComplete
Het percentage van de overdracht dat is voltooid.
Als het lid ItemSize van de MINIDRV_TRANSFER_CONTEXT-structuur is ingesteld op nul, geeft dit aan de toepassing aan dat het WIA-stuurprogramma de resulterende afbeeldingsgrootte niet kent en vervolgens zijn eigen gegevensbuffers toewijst. Het WIA-stuurprogramma leest de eigenschap WIA_IPA_BUFFER_SIZE en wijst geheugen toe voor één band met gegevens. Het WIA-stuurprogramma kan hier elke hoeveelheid geheugen toewijzen die nodig is, maar het wordt aanbevolen om de toewijzing klein te houden.
Als u wilt zien of de WIA-service geheugen voor het stuurprogramma heeft toegewezen, controleert u de vlag pmdtc-bClassDrvAllocBuf>. Als deze is ingesteld op TRUE, heeft de WIA-service geheugen toegewezen voor het stuurprogramma. Als u wilt zien hoeveel geheugen is toegewezen, controleert u de waarde in pmdtc-lBufferSize>.
Als u uw eigen geheugen wilt toewijzen, gebruikt u CoTaskMemAlloc (beschreven in de Microsoft Windows SDK-documentatie) en gebruikt u de aanwijzer in pmdtc-pTransferBuffer>. (Houd er rekening mee dat het stuurprogramma dit geheugen heeft toegewezen, dus het stuurprogramma moet het ook vrij maken.) Stel pmdtc-lBufferSize> in op de grootte die u hebt toegewezen. Zoals eerder vermeld, wijst dit WIA-voorbeeldstuurprogramma een buffer toe waarvan de grootte, in bytes, gelijk is aan de waarde in WIA_IPA_BUFFER_SIZE. Het stuurprogramma gebruikt vervolgens dat geheugen.
In het volgende voorbeeld ziet u een implementatie van de methode IWiaMiniDrv::d rvAcquireItemData . In dit voorbeeld kunnen beide gevallen van geheugentoewijzing worden verwerkt.
HRESULT _stdcall CWIADevice::drvAcquireItemData(
BYTE *pWiasContext,
LONG lFlags,
PMINIDRV_TRANSFER_CONTEXT pmdtc,
LONG *plDevErrVal)
{
//
// If the caller did not pass in the correct parameters,
// then fail the call with E_INVALIDARG.
//
if (!pWiasContext) {
return E_INVALIDARG;
}
if (!pmdtc) {
return E_INVALIDARG;
}
if (!plDevErrVal) {
return E_INVALIDARG;
}
*plDevErrVal = 0;
HRESULT hr = E_FAIL;
LONG lBytesTransferredToApplication = 0;
LONG lClassDrvAllocSize = 0;
//
// (1) Memory allocation
//
if (pmdtc->bClassDrvAllocBuf) {
//
// WIA allocated the buffer for data transfers
//
lClassDrvAllocSize = pmdtc->lBufferSize;
hr = S_OK;
} else {
//
// Driver allocated the buffer for data transfers
//
hr = wiasReadPropLong(pWiasContext, WIA_IPA_BUFFER_SIZE, &lClassDrvAllocSize,NULL,TRUE);
if (FAILED(hr)) {
//
// no memory was allocated, here so we can return early
//
return hr;
}
//
// allocate memory of WIA_IPA_BUFFER_SIZE (own min buffer size)
//
pmdtc->pTransferBuffer = (PBYTE) CoTaskMemAlloc(lClassDrvAllocSize);
if (!pmdtc->pTransferBuffer) {
//
// no memory was allocated, here so we can return early
//
return E_OUTOFMEMORY;
}
//
// set the lBufferSize member
//
pmdtc->lBufferSize = lClassDrvAllocSize;
}
//
// (2) Gather all information about data transfer settings and
// calculate the total data amount to transfer
//
if (hr == S_OK) {
//
// WIA service will populate the MINIDRV_TRANSFER_CONTEXT by reading the WIA properties.
//
// The following values will be written as a result of the
// wiasGetImageInformation() call
//
// pmdtc->lWidthInPixels
// pmdtc->lLines
// pmdtc->lDepth
// pmdtc->lXRes
// pmdtc->lYRes
// pmdtc->lCompression
// pmdtc->lItemSize
// pmdtc->guidFormatID
// pmdtc->tymed
//
// if the FORMAT is set to BMP or MEMORYBMP, the
// following values will also be set automatically
//
// pmdtc->cbWidthInBytes
// pmdtc->lImageSize
// pmdtc->lHeaderSize
// pmdtc->lItemSize (will be updated using the known image format information)
//
hr = wiasGetImageInformation(pWiasContext,0,pmdtc);
if (hr == S_OK) {
//
// (3) Send the image data to the application
//
LONG lDepth = 0;
hr = wiasReadPropLong(pWiasContext, WIA_IPA_DEPTH, &lDepth,NULL,TRUE);
if (hr == S_OK) {
LONG lPixelsPerLine = 0;
hr = wiasReadPropLong(pWiasContext, WIA_IPA_PIXELS_PER_LINE, &lPixelsPerLine,NULL,TRUE);
if (hr == S_OK) {
LONG lBytesPerLineRaw = ((lPixelsPerLine * lDepth) + 7) / 8;
LONG lBytesPerLineAligned = (lPixelsPerLine * lDepth) + 31;
lBytesPerLineAligned = (lBytesPerLineAligned / 8) & 0xfffffffc;
LONG lTotalImageBytes = pmdtc->lImageSize + pmdtc->lHeaderSize;
LONG lBytesReceived = pmdtc->lHeaderSize;
lBytesTransferredToApplication = 0;
pmdtc->cbOffset = 0;
while ((lBytesReceived)) {
LONG lPercentComplete = (LONG)(((float)lBytesTransferredToApplication/(float)lTotalImageBytes) * 100.0f);
switch (pmdtc->tymed) {
case TYMED_MULTIPAGE_CALLBACK:
case TYMED_CALLBACK:
{
hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(IT_MSG_DATA,IT_STATUS_TRANSFER_TO_CLIENT,
lPercentComplete,pmdtc->cbOffset,lBytesReceived,pmdtc,0);
pmdtc->cbOffset += lBytesReceived;
lBytesTransferredToApplication += lBytesReceived;
}
break;
case TYMED_MULTIPAGE_FILE:
case TYMED_FILE:
{
//
// lItemSize is the amount that wiasWriteBufToFile will write to FILE
//
pmdtc->lItemSize = lBytesReceived;
hr = wiasWriteBufToFile(0,pmdtc);
if (FAILED(hr)) {
break;
}
hr = pmdtc->pIWiaMiniDrvCallBack->MiniDrvCallback(IT_MSG_STATUS,IT_STATUS_TRANSFER_TO_CLIENT,
lPercentComplete,0,0,NULL,0);
lBytesTransferredToApplication += lBytesReceived;
}
break;
default:
{
hr = E_FAIL;
}
break;
}
//
// scan from device, requesting ytesToReadFromDevice
//
LONG lBytesRemainingToTransfer = (lTotalImageBytes - lBytesTransferredToApplication);
if (lBytesRemainingToTransfer <= 0) {
break;
}
//
// calculate number of bytes to request from device
//
LONG lBytesToReadFromDevice = (lBytesRemainingToTransfer > pmdtc->lBufferSize) ? pmdtc->lBufferSize : lBytesRemainingToTransfer;
// RAW data request
lBytesToReadFromDevice = (lBytesToReadFromDevice / lBytesPerLineAligned) * lBytesPerLineRaw;
// Aligned data request
// lBytesToReadFromDevice = (lBytesToReadFromDevice / lBytesPerLineAligned) * lBytesPerLineAligned;
if ((hr == S_FALSE)||FAILED(hr)) {
//
// user canceled or the callback failed for some reason
//
break;
}
//
// request byte amount from device
//
hr = GetDataFromMyDevice(pmdtc->pTransferBuffer, lBytesToReadFromDevice, (DWORD*)&lBytesReceived);
if (FAILED(hr)) {
break;
}
//
// this device returns raw data. If your device does this too, then you should call the AlignInPlace
// helper function to align the data.
//
lBytesReceived = AlignMyRawData(pmdtc->pTransferBuffer,lBytesReceived,lBytesPerLineAligned,lBytesPerLineRaw);
} // while ((lBytesReceived))
}
}
}
}
//
// free any allocated memory for buffers
//
if (!pmdtc->bClassDrvAllocBuf) {
CoTaskMemFree(pmdtc->pTransferBuffer);
pmdtc->pTransferBuffer = NULL;
pmdtc->lBufferSize = 0;
}
return hr;
}