📄 eztwain.c
字号:
RecordError(ED_BAD_ITEMTYPE);
} else {
pcon->CurrentIndex = TWON_DONTCARE32; // don't change current value
pcon->DefaultIndex = TWON_DONTCARE32; // don't change default value
pcon->NumItems = Intersect16(wPixTypes, (unsigned)pcon->NumItems, (TW_UINT16 far *)pcon->ItemList);
fSuccess = (pcon->NumItems != 0);
if (!fSuccess) RecordError(ED_CAP_SET_EMPTY);
}
break;
}
case TWON_ARRAY: {
// this is technically illegal - TWAIN 1.5, p9-30, Containers for MSG_GET: TW_ENUMERATION, TW_ONEVALUE
TW_ARRAY far *pcon = (TW_ARRAY far *)pv;
if (pcon->NumItems < 1) {
RecordError(ED_CAP_GET_EMPTY);
} else if (pcon->ItemType != TWTY_UINT16 && pcon->ItemType != TWTY_INT16) {
RecordError(ED_BAD_ITEMTYPE);
} else {
pcon->NumItems = Intersect16(wPixTypes, (unsigned)pcon->NumItems, (TW_UINT16 far *)pcon->ItemList);
fSuccess = (pcon->NumItems != 0);
if (!fSuccess) RecordError(ED_CAP_SET_EMPTY);
}
break;
}
case TWON_ONEVALUE: {
TW_ONEVALUE far *pcon = (TW_ONEVALUE far *)pv;
fSuccess = ((1 << pcon->Item) & wPixTypes);
if (!fSuccess) RecordError(ED_CAP_SET_EMPTY);
break;
}
default:
// something we don't understand, abandon negotiations
RecordError(ED_BAD_CONTYPE);
break;
} // switch
GlobalUnlock(cap.hContainer);
if (fSuccess) {
// For enums (and arrays) send intersection back, to restrict it.
// For one vals, don't bother - could only cause confusion.
if (cap.ConType != TWON_ONEVALUE) {
fSuccess = TWAIN_DS(DG_CONTROL, DAT_CAPABILITY, MSG_SET, (TW_MEMREF)&cap);
if (!fSuccess) RecordError(ED_CAP_SET);
}
}
GlobalFree(cap.hContainer);
return fSuccess;
} // TWAIN_NegotiatePixelTypes
int EZTAPI TWAIN_GetCurrentUnits(void)
{
int nUnits = TWUN_INCHES;
TWAIN_GetCapCurrent(ICAP_UNITS, TWTY_UINT16, &nUnits);
return nUnits;
} // TWAIN_GetCurrentUnits
int EZTAPI TWAIN_SetCurrentUnits(int nUnits)
// Negotiate the current pixel type for acquisition.
// Negotiation is only allowed in State 4 (TWAIN_SOURCE_OPEN)
// The source may select this pixel type, but don't assume it will.
{
return TWAIN_SetCapOneValue(ICAP_UNITS, TWTY_UINT16, (TW_UINT16)nUnits);
} // TWAIN_SetCurrentUnits
int EZTAPI TWAIN_GetBitDepth(void)
// Ask the source for the current bitdepth.
// This value depends on the current PixelType.
// Bit depth is per color channel e.g. 24-bit RGB has bit depth 8.
// If anything goes wrong, this function returns 0.
{
int nBits = 0;
TWAIN_GetCapCurrent(ICAP_BITDEPTH, TWTY_UINT16, &nBits);
return nBits;
} // TWAIN_GetBitDepth
int EZTAPI TWAIN_SetBitDepth(int nBits)
// (Try to) set the current bitdepth (for the current pixel type).
{
return TWAIN_SetCapOneValue(ICAP_BITDEPTH, TWTY_UINT16, (TW_UINT16)nBits);
} // TWAIN_SetBitDepth
int EZTAPI TWAIN_GetPixelType(void)
// Ask the source for the current pixel type.
// If anything goes wrong (it shouldn't!), this function returns 0 (TWPT_BW).
{
int nPixType = 0;
TWAIN_GetCapCurrent(ICAP_PIXELTYPE, TWTY_UINT16, &nPixType);
return nPixType;
} // TWAIN_GetPixelType
int EZTAPI TWAIN_SetCurrentPixelType(int nPixType)
// Negotiate the current pixel type for acquisition.
// Negotiation is only allowed in State 4 (TWAIN_SOURCE_OPEN)
// The source may select this pixel type, but don't assume it will.
{
return TWAIN_SetCapOneValue(ICAP_PIXELTYPE, TWTY_UINT16, (TW_UINT16)nPixType);
} // TWAIN_SetCurrentPixelType
/*double EZTAPI TWAIN_GetCurrentResolution(void)
{
TW_FIX32 res;
TWAIN_GetCapCurrent(ICAP_XRESOLUTION, TWTY_FIX32, &res);
return Fix32ToFloat(res);
} // TWAIN_GetCurrentResolution
int EZTAPI TWAIN_SetCurrentResolution(double dRes)
// Negotiate the current resolution for acquisition.
// Negotiation is only allowed in State 4 (TWAIN_SOURCE_OPEN)
// The source may select this resolution, but don't assume it will.
{
return TWAIN_SetCapOneValue(ICAP_XRESOLUTION, TWTY_FIX32, ToFix32(dRes));
} // TWAIN_SetCurrentResolution
*/
int EZTAPI TWAIN_SetCapOneValue(unsigned Cap, unsigned ItemType, long ItemVal)
{
TW_CAPABILITY cap;
pTW_ONEVALUE pv;
BOOL bSuccess;
if (nState != TWAIN_SOURCE_OPEN) {
TWAIN_ErrorBox("Attempt to set capability outside State 4.");
return FALSE;
}
cap.Cap = Cap; // capability id
cap.ConType = TWON_ONEVALUE; // container type
cap.hContainer = GlobalAlloc(GHND, sizeof (TW_ONEVALUE));
if (!cap.hContainer) {
TWAIN_ErrorBox(szInsuffMem);
return FALSE;
}
pv = (pTW_ONEVALUE)GlobalLock(cap.hContainer);
pv->ItemType = ItemType;
pv->Item = ItemVal;
GlobalUnlock(cap.hContainer);
bSuccess = TWAIN_DS(DG_CONTROL, DAT_CAPABILITY, MSG_SET, (TW_MEMREF)&cap);
GlobalFree(cap.hContainer);
return bSuccess;
} // TWAIN_SetCapOneValue
const size_t nTypeSize[13] =
{ sizeof (TW_INT8),
sizeof (TW_INT16),
sizeof (TW_INT32),
sizeof (TW_UINT8),
sizeof (TW_UINT16),
sizeof (TW_UINT32),
sizeof (TW_BOOL),
sizeof (TW_FIX32),
sizeof (TW_FRAME),
sizeof (TW_STR32),
sizeof (TW_STR64),
sizeof (TW_STR128),
sizeof (TW_STR255),
};
// helper function:
int TypeMatch(unsigned nTypeA, unsigned nTypeB)
{
// Integral types match if they are the same size.
// All other types match only if they are equal
return nTypeA == nTypeB ||
(nTypeA <= TWTY_UINT32 &&
nTypeB <= TWTY_UINT32 &&
nTypeSize[nTypeA] == nTypeSize[nTypeB]);
} // TypeMatch
int EZTAPI TWAIN_GetCapCurrent(unsigned Cap, unsigned ItemType, void FAR *pVal)
{
TW_CAPABILITY cap;
void far * pv = NULL;
BOOL bSuccess = FALSE;
assert(pVal != NULL);
if (nState < TWAIN_SOURCE_OPEN) {
TWAIN_ErrorBox("Attempt to get capability value below State 4.");
return FALSE;
}
// Fill in capability structure
cap.Cap = Cap; // capability id
cap.ConType = TWON_ONEVALUE; // favorite type of container (should be ignored...)
cap.hContainer = NULL;
if (TWAIN_DS(DG_CONTROL, DAT_CAPABILITY, MSG_GETCURRENT, (TW_MEMREF)&cap) &&
cap.hContainer &&
(pv = GlobalLock(cap.hContainer))) {
if (cap.ConType == TWON_ENUMERATION) {
TW_ENUMERATION far *pcon = (TW_ENUMERATION far *)pv;
TW_UINT32 index = pcon->CurrentIndex;
if (index < pcon->NumItems && TypeMatch(pcon->ItemType, ItemType)) {
LPSTR pitem = (LPSTR)pcon->ItemList + index*nTypeSize[ItemType];
FMEMCPY(pVal, pitem, nTypeSize[ItemType]);
bSuccess = TRUE;
}
} else if (cap.ConType == TWON_ONEVALUE) {
TW_ONEVALUE far *pcon = (TW_ONEVALUE far *)pv;
if (TypeMatch(pcon->ItemType, ItemType)) {
FMEMCPY(pVal, &pcon->Item, nTypeSize[ItemType]);
bSuccess = TRUE;
}
}
}
if (pv) GlobalUnlock(cap.hContainer);
if (cap.hContainer) GlobalFree(cap.hContainer);
return bSuccess;
}
//-------------------------- The primitive functions
int EZTAPI TWAIN_DS(unsigned long dg, unsigned dat, unsigned msg, void FAR *pd)
// Call the current source with a triplet
{
assert(nState >= 4);
rc = TWRC_FAILURE;
if (pDSM_Entry) {
rc = (*pDSM_Entry)(&AppId, &SourceId,
(TW_UINT32)dg,
(TW_UINT16)dat,
(TW_UINT16)msg,
(TW_MEMREF)pd);
}
return (rc == TWRC_SUCCESS);
} // TWAIN_DS
int EZTAPI TWAIN_Mgr(unsigned long dg, unsigned dat, unsigned msg, void FAR *pd)
// Call the Source Manager with a triplet
{
rc = TWRC_FAILURE;
if (pDSM_Entry) {
rc = (*pDSM_Entry)(&AppId, NULL,
(TW_UINT32)dg,
(TW_UINT16)dat,
(TW_UINT16)msg,
(TW_MEMREF)pd);
}
return (rc == TWRC_SUCCESS);
} // TWAIN_Mgr
unsigned EZTAPI TWAIN_GetResultCode(void)
{
return rc;
} // TWAIN_GetResultCode
unsigned EZTAPI TWAIN_GetConditionCode(void)
{
TW_STATUS twStatus;
if (nState >= 4) {
// get source status if open
TWAIN_DS(DG_CONTROL, DAT_STATUS, MSG_GET, (TW_MEMREF)&twStatus);
} else if (nState == 3) {
// otherwise get source manager status
TWAIN_Mgr(DG_CONTROL, DAT_STATUS, MSG_GET, (TW_MEMREF)&twStatus);
} else {
// nothing open, not a good time to get condition code!
return TWCC_SEQERROR;
}
if (rc == TWRC_SUCCESS) {
return twStatus.ConditionCode;
} else {
return TWCC_BUMMER; // what can I say.
}
} // TWAIN_GetConditionCode
//------------ Private functions
HWND CreateProxyWindow(void)
{
HWND hwnd;
hwnd = CreateWindow("STATIC", // class
"Acquire Proxy", // title
WS_POPUPWINDOW | WS_VISIBLE, // style
CW_USEDEFAULT, CW_USEDEFAULT, // x, y
CW_USEDEFAULT, CW_USEDEFAULT, // width, height
HWND_DESKTOP, // parent window
NULL, // hmenu
hinstLib, // hinst
NULL); // lpvparam
return hwnd;
} // CreateProxyWindow
int RecordError(ErrorDetail ed)
{
if (nErrDetail == ED_NONE) {
nErrDetail = ed;
if (ed > ED_START_TRIPLET_ERRS && ed < ED_END_TRIPLET_ERRS) {
nErrRC = TWAIN_GetResultCode();
nErrCC = TWAIN_GetConditionCode();
} else {
nErrRC = 0;
nErrCC = 0;
}
}
return FALSE;
} // RecordError
void ClearError(void)
{
nErrDetail = ED_NONE;
} // ClearError
void TWAIN_ReportLastError(LPSTR lpzGeneral)
{
/* if (nErrDetail > ED_START_TRIPLET_ERRS && nErrDetail < ED_END_TRIPLET_ERRS) {
wvsprintf(szMsg, "%s\n%s\nRC: %s\nCC: %s",
lpzGeneral, (LPSTR)pszErrDescrip[nErrDetail],
(LPSTR)pszRC[nErrRC], (LPSTR)pszCC[nErrCC]);
} else {
wvsprintf(szMsg, "%s\n%s", lpzGeneral, (LPSTR)pszErrDescrip[nErrDetail]);
}*/
TWAIN_ErrorBox("TWAIN_ReportLastError: an error occurred");
} // ReportLastError; stripped down by dsn to avoid using C RTL
void TWAIN_ErrorBox(const char *szMsg)
{
MessageBox(NULL, (LPSTR)szMsg, "TWAIN Error", MB_ICONEXCLAMATION | MB_OK);
} // TWAIN_ErrorBox
unsigned BitCount(unsigned W)
{
unsigned n = 0;
while (W) {
n += (W & 1);
W >>= 1;
} // while
return n;
} // BitCount
unsigned Intersect16(unsigned wMask, unsigned nItems, TW_UINT16 far *pItem)
{
unsigned wSet;
unsigned i;
// In wSet, construct set of available items.
// Note that items that cannot be represented in wMask are also
// unrepresentable in wSet so are implicitly discarded
for (i = wSet = 0 ; i < nItems; i++) {
wSet |= 1 << pItem[i];
} // for
// Discard anything in wMask that isn't in wSet
wMask &= wSet;
// Re-fill the item table with intersection set
for (i = nItems = 0; wMask ; wMask>>=1,i++) {
if (wMask & 1) {
pItem[nItems++] = i;
}
} // for
return nItems;
}
/*
TW_UINT32 ToFix32(double r)
{
TW_FIX32 fix;
TW_INT32 val = (TW_INT32)(r * 65536.0 + 0.5);
fix.Whole = (TW_INT16)(val >> 16); // most significant 16 bits
fix.Frac = (TW_UINT16)(val & 0xffff); // least
assert(sizeof (TW_FIX32) == sizeof (TW_UINT32));
return *(TW_UINT32*)&fix;
} // ToFix32
double Fix32ToFloat(TW_FIX32 fix)
{
TW_INT32 val = ((TW_INT32)fix.Whole << 16) | ((TW_UINT32)fix.Frac & 0xffff);
return val / 65536.0;
} // Fix32ToFloat
*/
// The routine below is a modified version of code posted by Zafir Anjum
// on www.codeguru.com. The original code was designed for MFC; below it
// has been translated into straight C. Also, one other change is that rather
// than dynamically allocate only the memory needed for pLP, I fix the size of
// the array at the beginning so that it's sufficient for whatever might come
// along so as to eliminate any dependence on the C runtime library.
/*HBITMAP EZTAPI DIBToDDB( HANDLE hDIB )
{
LPBITMAPINFOHEADER lpbi;
HBITMAP hbm;
HPALETTE pal;
HPALETTE pOldPal;
HDC dc;
UINT nSize;
LOGPALETTE *pLP;
BYTE logpalbuffer[5012];
// max size = sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) *256 colors
// = 2 + 2 + 1024 = 1028; theoretically only need this much
// overshoot just in case; above size ought to be PLENTY
int nColors;
int i;
LPVOID lpDIBBits;
BITMAPINFO *bmInfo;
bmInfo = (LPBITMAPINFO) (&hDIB);
if (hDIB == NULL)
return NULL;
dc = GetDC(NULL); // stuff normally taken care of when MFC is used
pal = NULL;
lpbi = (LPBITMAPINFOHEADER)hDIB;
nColors = lpbi->biClrUsed ? lpbi->biClrUsed :
1 << lpbi->biBitCount;
if( bmInfo->bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo->bmiColors +
bmInfo->bmiHeader.biClrUsed) +
((bmInfo->bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo->bmiColors + nColors);
// Create and select a logical palette if needed
if( nColors <= 256 && GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE)
{
nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
pLP = (LOGPALETTE *) logpalbuffer; //new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for(i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = bmInfo->bmiColors[i].rgbRed;
pLP->palPalEntry[i].peGreen = bmInfo->bmiColors[i].rgbGreen;
pLP->palPalEntry[i].peBlue = bmInfo->bmiColors[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pal = CreatePalette( pLP );
// Select and realize the palette
pOldPal = SelectPalette( dc, &pal, FALSE );
RealizePalette(dc);
}
hbm = CreateDIBitmap(dc, // handle to device context
(LPBITMAPINFOHEADER)lpbi, // pointer to bitmap info header
(LONG)CBM_INIT, // initialization flag
lpDIBBits, // pointer to initialization data
(LPBITMAPINFO)lpbi, // pointer to bitmap info
DIB_RGB_COLORS ); // color-data usage
if (pal)
SelectPalette(dc, pOldPal,FALSE);
ReleaseDC(NULL, dc);
return hbm;
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -