📄 twd_com.cpp
字号:
/***********************************************************************
TWAIN Sample Source
This module contains routines to manipulate containers. Containers are
used in CAPabilty negotiations to exchange information about the input
device between the Source and the App. The information may define data
exchange or input device characteristics.
*************************************************************************/
#include <windows.h>
#include "stdafx.h"
#include "twain.h"
#include "twd_com.h"
/***********************************************************************
* FUNCTION: ExtractEnumerationValue
*
* ARGS: pData 指向属性结构的指针,包含CONTAINER的细节
* pVoid ptr will be set to point to the item on return
* j requested index into the enumeration
*
* RETURNS: pVoid 指向返回项的指针
*
* NOTES: 打开一个CONTAINER并从中吸取各项,这个项目被指针返回
* I will type cast the returned value to that of ItemType.
*
* COMMENTS: only a single value is returned. It is referred to by the 'j'
* index.
*
* BACKGROUND: Protocol: used by MSG_SET calls were Source empties then App frees
* upon return. It is assumed that the APP allocates and fills the container
* prior to this call.
*/
VOID ExtractEnumerationValue (pTW_CAPABILITY pData, LPVOID pVoid, int j)
{
pTW_ENUMERATION pEnumeration;
LPVOID pItemList;
if ((pEnumeration = (pTW_ENUMERATION)GlobalLock(pData->hContainer)) != NULL)
{
// assign base address of ItemList array to 'generic' pointer
pItemList = (LPVOID)pEnumeration->ItemList;
// CAST to type of var caller wants
switch (pEnumeration->ItemType)
{
case TWTY_INT8:
*(pTW_INT8)pVoid = *((pTW_INT8)pItemList+j);
break;
case TWTY_UINT8:
*(pTW_UINT8)pVoid = *((pTW_UINT8)pItemList+j);
break;
case TWTY_INT16:
*(pTW_INT16)pVoid = *((pTW_INT16)pItemList+j);
break;
case TWTY_UINT16:
*(pTW_UINT16)pVoid = *((pTW_UINT16)pItemList+j);
break;
case TWTY_INT32:
*(pTW_INT32)pVoid = *((pTW_INT32)pItemList+j);
break;
case TWTY_UINT32:
*(pTW_UINT32)pVoid = *((pTW_UINT32)pItemList+j);
break;
case TWTY_BOOL:
*(pTW_BOOL)pVoid = *((pTW_BOOL)pItemList+j);
break;
/*
case TWTY_FIX32:
*(pTW_FIX32)pVoid = *((pTW_FIX32)pItemList+j);
break;
case TWTY_FRAME:
*(pTW_FRAME)pVoid = *((pTW_FRAME)pItemList+j);
break;
case TWTY_STR32:
*(pTW_STR32)pVoid = *((pTW_STR32)pItemList+j);
break;
case TWTY_STR64:
*(pTW_STR64)pVoid = *((pTW_STR64)pItemList+j);
break;
case TWTY_STR128:
*(pTW_STR128)pVoid = *((pTW_STR128)pItemList+j);
break;
case TWTY_STR255:
*(pTW_STR255)pVoid = *((pTW_STR255)pItemList+j);
break;
*/
default:
break;
}
GlobalUnlock(pData->hContainer);
}
// free is by the App
return;
} // ExtractEnumerationValue
////////////////////////////////////////////////////////////////////////////
// FUNCTION: BuildUpEnumerationType
//
// ARGS: pData pointer to a capability structure, details about container
// pE ptr to struct that contains the other fields of ENUM struct
// *pList ptr to array of elements to put into the ENUM array
//
// RETURNS: pData->hContainer set to address of the container handle, ptr is
// returned here
//
// NOTES: The routine dynamically allocates a chunk of memory large enough
// to contain all the struct pTW_ENUMERATION as well as store it's ItemList
// array INTERNAL to the struct. The array itself and it's elements must be
// type cast to ItemType. I do not know how to dynamically cast elements
// of an array to ItemType so it is time for a big static switch.>>>
//
// Protocol: Used by MSG_GET.. calls were Source allocates the container and the
// APP uses and then frees the container.
//
//
VOID BuildUpEnumerationType (pTW_CAPABILITY pData, pTW_ENUMERATION pE, void *pList, TW_UINT16 msg)
{
pTW_ENUMERATION pEnumeration; // template for ENUM fields
int j; // anyone with more than 32K array elements
// should crash. Could type on NumItems.
LPVOID pVoid;
if (msg != MSG_SET)
{
// allocate a block large enough for struct and complete enumeration array
if ((pData->hContainer =
(TW_HANDLE)GlobalAlloc(GMEM_MOVEABLE,
(sizeof(TW_ENUMERATION)-sizeof(TW_UINT8))+
pE->NumItems*AltTWItemSize(pE->ItemType))) == NULL)
return;
}
// fill in contype
pData->ConType = TWON_ENUMERATION;
if ((pEnumeration = (pTW_ENUMERATION)GlobalLock(pData->hContainer)) != NULL)
{
pEnumeration->ItemType = pE->ItemType; // TWTY_XXXX
pEnumeration->NumItems = pE->NumItems; // TWPT_XXXX...
pEnumeration->CurrentIndex = pE->CurrentIndex; // current index setting
pEnumeration->DefaultIndex = pE->DefaultIndex; // default index setting
// assign base address of ItemList array to 'generic' pointer
// i.e. reposition the struct pointer to overlay the allocated block
pVoid = (LPVOID)pEnumeration->ItemList;
for (j=0; j<(int)pE->NumItems; j++)
{
// dynamic cast to ItemType of each array element
switch (pE->ItemType)
{
case TWTY_INT8:
*((pTW_INT8)pVoid+j) = *((pTW_INT8)pList+j);
break;
case TWTY_INT16:
*((pTW_INT16)pVoid+j) = *((pTW_INT16)pList+j);
break;
case TWTY_INT32:
*((pTW_INT32)pVoid+j) = *((pTW_INT32)pList+j);
break;
case TWTY_UINT8:
*((pTW_UINT8)pVoid+j) = *((pTW_UINT8)pList+j);
break;
case TWTY_UINT16:
*((pTW_UINT16)pVoid+j) = *((pTW_UINT16)pList+j);
break;
case TWTY_UINT32:
*((pTW_UINT32)pVoid+j) = *((pTW_UINT32)pList+j);
break;
case TWTY_BOOL:
*((pTW_BOOL)pVoid+j) = *((pTW_BOOL)pList+j);
break;
case TWTY_FIX32:
*((pTW_FIX32)pVoid+j) = *((pTW_FIX32)pList+j);
break;
case TWTY_FRAME:
*((pTW_FRAME)pVoid+j) = *((pTW_FRAME)pList+j);
break;
case TWTY_STR32:
*((pTW_STR32)pVoid+j) = *((pTW_STR32)pList+j);
break;
case TWTY_STR64:
*((pTW_STR64)pVoid+j) = *((pTW_STR64)pList+j);
break;
case TWTY_STR128:
*((pTW_STR128)pVoid+j) = *((pTW_STR128)pList+j);
break;
case TWTY_STR255:
*((pTW_STR255)pVoid+j) = *((pTW_STR255)pList+j);
break;
default:
// bad ItemType
break;
} // end of switch
} // end of for loop
GlobalUnlock(pData->hContainer);
}
// now you have a dynamically sized enumeration array WITHIN a struct
return;
}
///////////////////////////////////////////////////////////////////////////
// FUNCTION: BuildUpArrayType
//
// ARGS: pData pointer to a capability structure, details about container
// pA ptr to struct that contains the other fields of ARRAY struct
// *pList ptr to array of elements to put into the ARRAY struct
//
// RETURNS: pData->hContainer set to address of the container handle, ptr is
// returned here
//
// NOTES: The routine dynamically allocates a chunk of memory large enough to
// contain all the struct pTW_ARRAY as well as store it's ItemList array
// INTERNAL to the struct. The array itself and it's elements must be
// type cast to ItemType. I do not know how to dynamically cast elements
// of an array to ItemType so it is time for a big static switch.>>>
//
// Protocol: Used by MSG_GET.. calls were Source allocates the container and the
// APP uses and then frees the container.
//
VOID BuildUpArrayType (pTW_CAPABILITY pData, pTW_ARRAY pA, void *pList, TW_UINT16 msg)
{
pTW_ARRAY pArray;
int j; // anyone with more than 32K array elements
// should crash. Could type on NumItems.
LPVOID pVoid;
if (msg != MSG_SET)
{
// allocate a block large enough for struct and complete array
if ((pData->hContainer =
(TW_HANDLE)GlobalAlloc(GMEM_MOVEABLE,
(sizeof(TW_ARRAY)-sizeof(TW_UINT8))+
pA->NumItems*AltTWItemSize(pA->ItemType))) == NULL)
return;
}
pData->ConType = TWON_ARRAY;
if ((pArray = (pTW_ARRAY)GlobalLock(pData->hContainer)) != NULL)
{
pArray->ItemType = pA->ItemType; // TWTY_XXXX
pArray->NumItems = pA->NumItems; // TWPT_XXXX...
// assign base address of ItemList array to 'generic' pointer
// i.e. reposition the struct pointer to overlay the allocated block
pVoid = (LPVOID)pArray->ItemList;
for (j=0; j<(int)pA->NumItems; j++)
{
// dynamic cast to ItemType of each array element
switch (pA->ItemType)
{
case TWTY_INT8:
*((pTW_INT8)pVoid+j) = *((pTW_INT8)pList+j);
break;
case TWTY_INT16:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -