📄 caps.cpp
字号:
//Twain标准中用来设置属性的函数集合
//
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include <ctype.h>
#include "stdafx.h"
#include "twain.h"
#include "twd_type.h"
#include "twd_com.h"
#include "caps.h"
extern char SourceControl[MAX_TWPATH];
static char destination[50];
//////////////////////////////////////////////////////////////////////////////////
// ResetValues -- Set the current values in the source control to the default entry
// and return the cap structure to the app. In all cases the allowed values are also
// reset if needed or not (to PowerOn settings). Note that a container type
// of range would do this.
//////////////////////////////////////////////////////////////////////////////////
TW_UINT16 ResetValues(char cap[])
{
char capabilities[80];
char reset[80];
// ensure that the operation is legal
GetPrivateProfileString(cap,"Reset","",reset,sizeof(reset),SourceControl);
if (memcmp(reset,"TWCC_BADPROTOCOL",sizeof("TWCC_BADPROTOCOL"))==0)
return(TWCC_BADPROTOCOL);
lstrcpyn(destination,"Current",sizeof(destination));
if (memcmp(reset,"TWON_RANGE",sizeof("TWON_RANGE"))==0 || memcmp(reset,"TWON_ENUMERATION",sizeof("TWON_ENUMERATION"))==0)
lstrcpyn(destination,"Allowed",sizeof(destination));
GetPrivateProfileString(cap,"PowerON","",capabilities,sizeof(capabilities),SourceControl);
WritePrivateProfileString(cap,"Allowed",capabilities,SourceControl);
GetPrivateProfileString(cap,"Default","",capabilities,sizeof(capabilities),SourceControl);
WritePrivateProfileString(cap,"Current",capabilities,SourceControl);
return(TWCC_SUCCESS);
}
//////////////////////////////////////////////////////////////////////
// SetValues -- Packs the container structure based first on the type
// of container as listed in the .src file and secondly on the ammount
// and type of data present in the list
//设置属性值
TW_UINT16 SetValues(pTW_CAPABILITY pData,TW_UINT16 msg, char cap[])
{
char buffer[80];
char capabilities[80];
char container[120];
int contype;
char datatype[80];
void *value;
TW_UINT16 valueType;
char IniFile[200];
//属性值的数据类型
TW_ENUMERATION Enum;
TW_RANGE Range;
TW_ARRAY Array;
TW_UINT16 Types[10] = {99,99,99,99,99,99,99,99,99,99};
char *token;
TW_FIX32 fix32;
// 获取TWACKER.INI的路径,将内容拷入数组INIFILE中
GetWindowsDirectory(IniFile,sizeof(IniFile));
lstrcat(IniFile,"\\twain_32\\MTIscanner\\twacker.ini");
switch(msg)
{
case MSG_GET:
GetPrivateProfileString(cap,"Get","",container,sizeof(container),SourceControl);
if (lstrcmp(container,"TWON_ONEVALUE")==0)
GetPrivateProfileString(cap,"Current","NONE",capabilities,sizeof(capabilities),SourceControl);
else
GetPrivateProfileString(cap,"Allowed","NONE",capabilities,sizeof(capabilities),SourceControl);
break;
case MSG_GETDEFAULT://获取属性值为缺省值
GetPrivateProfileString(cap,"Default","NONE",capabilities,sizeof(capabilities),SourceControl);
GetPrivateProfileString(cap,"GetDefault","",container,sizeof(container),SourceControl);
break;
case MSG_GETCURRENT://获取属性当前值
GetPrivateProfileString(cap,"Current","NONE",capabilities,sizeof(capabilities),SourceControl);
GetPrivateProfileString(cap,"GetCurrent","",container,sizeof(container),SourceControl);
break;
case MSG_RESET://恢复属性值
GetPrivateProfileString(cap,"Reset","",container,sizeof(container),SourceControl);
if (lstrcmp(container,"TWON_ONEVALUE")==0)
GetPrivateProfileString(cap,"Current","NONE",capabilities,sizeof(capabilities),SourceControl);
else
GetPrivateProfileString(cap,"Allowed","NONE",capabilities,sizeof(capabilities),SourceControl);
break;
case MSG_SET://应用程序设置属性值
GetPrivateProfileString(cap,destination,"NONE",capabilities,sizeof(capabilities),SourceControl);
GetPrivateProfileString(cap,"Set","",container,sizeof(container),SourceControl);
break;
}
// notify that something went wrong -- probably a bad or unsupported capability
if (lstrcmp(capabilities,"NONE")==0)
{
sprintf(buffer,"Unsupported capability. %s",cap);
MessageBox(NULL,buffer,"Sample Source",MB_OK);
return(TWCC_BADCAP);//属性错误
}
// 判断数据类型
GetPrivateProfileString(cap,"Type","",datatype,sizeof(datatype),SourceControl);
//从TWACKER的ITEMTYPE中获取与DATATYPE相关的整数如为4
valueType = (TW_UINT16)GetPrivateProfileInt("ItemType",datatype,99,IniFile);
//在TWACKER中的CONTYPE项获取与CONTAINER相关的整数,若无此项则为缺省值99
contype = GetPrivateProfileInt("ConType",container,99,IniFile);
if (strstr(container,",") != NULL) // there is more than one option
{
if (strstr(capabilities,"to") != NULL)
contype = TWON_RANGE;
else
if (strstr(capabilities,"[") != NULL)
contype = TWON_ARRAY;
else
if (strstr(capabilities,",") != NULL)
contype = TWON_ENUMERATION;
else
contype = TWON_ONEVALUE;
}
// pack up the containers and return the data
switch(contype)
{
case TWON_ONEVALUE://单值
if (isalpha(capabilities[0]))
value = (void *)GetPrivateProfileInt(cap,capabilities,99,IniFile);
else
{
if (valueType == TWTY_FIX32)
{
fix32 = FloatToFIX32((float)atof(capabilities));
value = (void *)*((pTW_UINT32)(&fix32));
}
else
value = (void *)atoi(capabilities);
}
//调用函数设置属性值
BuildUpOneValue((pTW_CAPABILITY)pData,valueType,value,msg);
break;
case TWON_ENUMERATION://枚举类型
//在属性字符串中查找下一个“,”标志
token = strtok(capabilities,",");
Enum.NumItems=0;
while(token != NULL)
{
if (isalpha(token[0]))
Types[Enum.NumItems] = GetPrivateProfileInt(cap,token,99,IniFile);
else
Types[Enum.NumItems] = atoi(token);
token = strtok(NULL,",");
Enum.NumItems++;
}
Enum.ItemType = valueType;
//调用函数确定属性值在枚举值空间的位置
Enum.CurrentIndex = GetIndex(MSG_GETCURRENT,cap);
Enum.DefaultIndex = GetIndex(MSG_GETDEFAULT,cap);
BuildUpEnumerationType ((pTW_CAPABILITY)pData,&Enum,Types,msg);
break;
case TWON_RANGE://范围值
Range.ItemType = valueType;
Range.MinValue = RangeMinimum(capabilities,Range.ItemType);
Range.MaxValue = RangeMaximum(capabilities,Range.ItemType);
Range.StepSize = RangeStep(capabilities,Range.ItemType);
Range.DefaultValue = 0;
Range.CurrentValue = 0;
BuildUpRangeType((pTW_CAPABILITY)pData,&Range,msg);
break;
case TWON_ARRAY://数组类型
lstrcpy(capabilities,&capabilities[1]);
capabilities[lstrlen(capabilities)-1] = '\0';
token = strtok(capabilities,",");
Array.NumItems = 0;
Array.ItemType = valueType;
while(token != NULL)
{
if (isalpha(token[0]))
Types[Array.NumItems] = GetPrivateProfileInt(cap,token,99,IniFile);
else
Types[Array.NumItems] = atoi(token);
token = strtok(NULL,",");
Array.NumItems++;
}
BuildUpArrayType((pTW_CAPABILITY)pData,&Array,Types,msg);
break;
}
return(TWRC_SUCCESS);
}
///////////////////////////////////////////////////////////////////////////
// GetIndex -- Determines the position of the current or default attribute
// within the scope of the ItemList for the capabilities
//确定当前或缺省的属性值在范围值中的位置
int GetIndex(int msg,char cap[])
{
char string[10];
char index[80];
char buffer[256];
int position = 0;
char *token;
if (msg == MSG_GETDEFAULT)
lstrcpyn(string,"default",sizeof(string));
else
lstrcpyn(string,"current",sizeof(string));
GetPrivateProfileString(cap,"Allowed","",buffer,sizeof(buffer),SourceControl);
GetPrivateProfileString(cap,string,"",index,sizeof(index),SourceControl);
token = strtok(buffer,",");
while(token != NULL)
{
if (memcmp(index,token,8)==0)
return(position);
token = strtok(NULL,",");
position++;
}
return(0);
}
////////////////////////////////////////////////////////////////////////////
// SetNewCap -- Sets the current capability to the user's selection. Will
// not return success if the item does not exist or can not be set. If the
// container is ONEVALUE or ARRAY, the current values are set, otherwise the
// allowed values will be set. Note that there is no validation when setting
// the allowed values.
//
TW_INT16 SetNewCap(pTW_CAPABILITY pData,char capstring[])
{
char container[40]={'0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0','0','0',
'0','0','0','0','0','0','0','0','0','0' };
char twacker[MAX_TWPATH];
char attribute[MAX_TWPATH];
char current[20];
char def[20];
pTW_ONEVALUE pValOneValue;
pTW_ENUMERATION pValEnum;
pTW_RANGE pValRange;
pTW_ARRAY pValArray;
TW_INT16 CapNum=0;
TW_UINT16 index;
char buffer[80];
BOOL found=FALSE;
char *token;
GetWindowsDirectory(twacker,sizeof(twacker));
lstrcat(twacker,"\\twain_32\\MTIscanner\\twacker.ini");
// Check if this cap can be set at all. There may be multiple caps, so check each
GetPrivateProfileString(capstring,"Set","",container,sizeof(container),SourceControl);
token = strtok(container,",");
while(token != NULL)
{
sprintf(buffer,"%ld",pData->ConType);
if (GetPrivateProfileInt("ConType",token,99,twacker)==(TW_UINT16)pData->ConType)
found = TRUE;
token = strtok(NULL,",");
}
if (!found)
{
return(TWCC_BADVALUE);
}
switch(pData->ConType)
{
case TWON_ONEVALUE:
// check if the new cap is in the allowed list
pValOneValue = (pTW_ONEVALUE)GlobalLock(pData->hContainer);
CapNum = (TW_INT16)pValOneValue->Item;
// Doesn't check for validity of floats
if (pValOneValue->ItemType == TWTY_FIX32)
{
pTW_FIX32 fix;
fix = (pTW_FIX32)&(pValOneValue->Item);
sprintf(attribute,"%.6f",FIX32ToFloat(*fix));
}
else
{
if (IsCapAllowed(CapNum, capstring, attribute)==FALSE)
{
MessageBox(NULL,"IsCapAllowed",NULL,MB_OK);
return(TWCC_BADVALUE);
}
}
GlobalUnlock(pData->hContainer);
lstrcpyn(destination,"Current",sizeof(destination));
break;
case TWON_ENUMERATION:
memset(attribute,'\0',sizeof(attribute));
pValEnum = (pTW_ENUMERATION)GlobalLock(pData->hContainer);
// put the items list together into a comma delimited string
for (index=0;index<pValEnum->NumItems;index++)
{
memset(buffer,'\0',sizeof(buffer));
ConvertAttributeToText(pValEnum->ItemList[index],buffer,capstring);
lstrcat(attribute,buffer);
lstrcat(attribute,",");
}
// remove last comma
attribute[lstrlen(attribute)-1] = '\0';
GlobalUnlock(pData->hContainer);
lstrcpyn(destination,"Allowed",sizeof(destination));
break;
case TWON_RANGE:
pValRange = (pTW_RANGE)GlobalLock(pData->hContainer);
// build the string of the format min_to_max,step
if (pValRange->ItemType == TWTY_FIX32)
{
pTW_FIX32 fix1,fix2,fix3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -