Title: Do you want TWAIN?
Question: Do you want TWAIN?
Answer:
////////////////////////////////////////////////////////////////////////
// //
// Delphi Scanner Support Framework //
// //
// Copyright (C) 1999 by Uli Tessel //
// //
////////////////////////////////////////////////////////////////////////
// //
// Modified and rewritten as a Delphi component by: //
// //
// M. de Haan //
// //
// June 2002 //
// //
////////////////////////////////////////////////////////////////////////
Unit
TWAIN;
Interface
Uses
SysUtils, // Exceptions
Forms, // TMessageEvent
Windows, // HMODULE
Graphics, // TBitmap
IniFiles, // Inifile
Controls, // TCursor
Classes; // Class
Const
// Messages
MSG_GET = $0001; // Get one or more values
MSG_GETCURRENT = $0002; // Get current value
MSG_GETDEFAULT = $0003; // Get default (e.g. power up) value
MSG_GETFIRST = $0004; // Get first of a series of items,
// e.g. Data Sources
MSG_GETNEXT = $0005; // Iterate through a series of items
MSG_SET = $0006; // Set one or more values
MSG_RESET = $0007; // Set current value to default value
MSG_QUERYSUPPORT = $0008; // Get supported operations on the
// capacities
// Messages used with DAT_NULL
// ---------------------------
MSG_XFERREADY = $0101; // The data source has data ready
MSG_CLOSEDSREQ = $0102; // Request for the application to close
// the Data Source
MSG_CLOSEDSOK = $0103; // Tell the application to save the
// state
MSG_DEVICEEVENT = $0104; // Some event has taken place
// Messages used with a pointer to a DAT_STATUS structure
// ------------------------------------------------------
MSG_CHECKSTATUS = $0201; // Get status information
// Messages used with a pointer to DAT_PARENT data
// -----------------------------------------------
MSG_OPENDSM = $0301; // Open the Data Source Manager
MSG_CLOSEDSM = $0302; // Close the Data Source Manager
// Messages used with a pointer to a DAT_IDENTITY structure
// --------------------------------------------------------
MSG_OPENDS = $0401; // Open a Data Source
MSG_CLOSEDS = $0402; // Close a Data Source
MSG_USERSELECT = $0403; // Put up a dialog of all Data Sources
// The user can select a Data Source
// Messages used with a pointer to a DAT_USERINTERFACE structure
// -------------------------------------------------------------
MSG_DISABLEDS = $0501; // Disable data transfer in the Data
// Source
MSG_ENABLEDS = $0502; // Enable data transfer in the Data
// Source
MSG_ENABLEDSUIONLY = $0503; // Enable for saving Data Source state
// only
// Messages used with a pointer to a DAT_EVENT structure
// -----------------------------------------------------
MSG_PROCESSEVENT = $0601;
// Messages used with a pointer to a DAT_PENDINGXFERS structure
// ------------------------------------------------------------
MSG_ENDXFER = $0701;
MSG_STOPFEEDER = $0702;
// Messages used with a pointer to a DAT_FILESYSTEM structure
// ----------------------------------------------------------
MSG_CHANGEDIRECTORY = $0801;
MSG_CREATEDIRECTORY = $0802;
MSG_DELETE = $0803;
MSG_FORMATMEDIA = $0804;
MSG_GETCLOSE = $0805;
MSG_GETFIRSTFILE = $0806;
MSG_GETINFO = $0807;
MSG_GETNEXTFILE = $0808;
MSG_RENAME = $0809;
MSG_COPY = $080A;
MSG_AUTOMATICCAPTUREDIRECTORY = $080B;
// Messages used with a pointer to a DAT_PASSTHRU structure
// --------------------------------------------------------
MSG_PASSTHRU = $0901;
Const
DG_CONTROL = $0001; // data pertaining to control
DG_IMAGE = $0002; // data pertaining to raster images
Const
// Data Argument Types for the DG_CONTROL Data Group.
DAT_CAPABILITY = $0001; // TW_CAPABILITY
DAT_EVENT = $0002; // TW_EVENT
DAT_IDENTITY = $0003; // TW_IDENTITY
DAT_PARENT = $0004; // TW_HANDLE,
// application win handle in Windows
DAT_PENDINGXFERS = $0005; // TW_PENDINGXFERS
DAT_SETUPMEMXFER = $0006; // TW_SETUPMEMXFER
DAT_SETUPFILEXFER = $0007; // TW_SETUPFILEXFER
DAT_STATUS = $0008; // TW_STATUS
DAT_USERINTERFACE = $0009; // TW_USERINTERFACE
DAT_XFERGROUP = $000A; // TW_UINT32
DAT_IMAGEMEMXFER = $0103; // TW_IMAGEMEMXFER
DAT_IMAGENATIVEXFER = $0104; // TW_UINT32, loword is hDIB, PICHandle
DAT_IMAGEFILEXFER = $0105; // Null data
Const
// Condition Codes: Application gets these by doing DG_CONTROL
// DAT_STATUS MSG_GET.
TWCC_CUSTOMBASE = $8000;
TWCC_SUCCESS = 00; // It worked!
TWCC_BUMMER = 01; // Failure due to unknown causes
TWCC_LOWMEMORY = 02; // Not enough memory to perform operation
TWCC_NODS = 03; // No Data Source
TWCC_MAXCONNECTIONS = 04; // Data Source is connected to maximum
// number of possible applications
TWCC_OPERATIONERROR = 05; // Data Source or Data Source Manager
// reported error, application
// shouldn't report an error
TWCC_BADCAP = 06; // Unknown capability
TWCC_BADPROTOCOL = 09; // Unrecognized MSG DG DAT combination
TWCC_BADVALUE = 10; // Data parameter out of range
TWCC_SEQERROR = 11; // DG DAT MSG out of expected sequence
TWCC_BADDEST = 12; // Unknown destination Application /
// Source in DSM_Entry
TWCC_CAPUNSUPPORTED = 13; // Capability not supported by source
TWCC_CAPBADOPERATION = 14; // Operation not supported by
// capability
TWCC_CAPSEQERROR = 15; // Capability has dependancy on other
// capability
TWCC_DENIED = 16; // File System operation is denied
// (file is protected)
TWCC_FILEEXISTS = 17; // Operation failed because file
// already exists
TWCC_FILENOTFOUND = 18; // File not found
TWCC_NOTEMPTY = 19; // Operation failed because directory
// is not empty
TWCC_PAPERJAM = 20; // The feeder is jammed
TWCC_PAPERDOUBLEFEED = 21; // The feeder detected multiple pages
TWCC_FILEWRITEERROR = 22; // Error writing the file (meant for
// things like disk full conditions)
TWCC_CHECKDEVICEONLINE = 23; // The device went offline prior to or
// during this operation
Const
// Flags used in TW_MEMORY structure
TWMF_APPOWNS = $01;
TWMF_DSMOWNS = $02;
TWMF_DSOWNS = $04;
TWMF_POINTER = $08;
TWMF_HANDLE = $10;
Const
// Flags for country, which seems to be equal to their telephone
// number
TWCY_AFGHANISTAN = 1001;
TWCY_ALGERIA = 0213;
TWCY_AMERICANSAMOA = 0684;
TWCY_ANDORRA = 0033;
TWCY_ANGOLA = 1002;
TWCY_ANGUILLA = 8090;
TWCY_ANTIGUA = 8091;
TWCY_ARGENTINA = 0054;
TWCY_ARUBA = 0297;
TWCY_ASCENSIONI = 0247;
TWCY_AUSTRALIA = 0061;
TWCY_AUSTRIA = 0043;
TWCY_BAHAMAS = 8092;
TWCY_BAHRAIN = 0973;
TWCY_BANGLADESH = 0880;
TWCY_BARBADOS = 8093;
TWCY_BELGIUM = 0032;
TWCY_BELIZE = 0501;
TWCY_BENIN = 0229;
TWCY_BERMUDA = 8094;
TWCY_BHUTAN = 1003;
TWCY_BOLIVIA = 0591;
TWCY_BOTSWANA = 0267;
TWCY_BRITAIN = 0006;
TWCY_BRITVIRGINIS = 8095;
TWCY_BRAZIL = 0055;
TWCY_BRUNEI = 0673;
TWCY_BULGARIA = 0359;
TWCY_BURKINAFASO = 1004;
TWCY_BURMA = 1005;
TWCY_BURUNDI = 1006;
TWCY_CAMAROON = 0237;
TWCY_CANADA = 0002;
TWCY_CAPEVERDEIS = 0238;
TWCY_CAYMANIS = 8096;
TWCY_CENTRALAFREP = 1007;
TWCY_CHAD = 1008;
TWCY_CHILE = 0056;
TWCY_CHINA = 0086;
TWCY_CHRISTMASIS = 1009;
TWCY_COCOSIS = 1009;
TWCY_COLOMBIA = 0057;
TWCY_COMOROS = 1010;
TWCY_CONGO = 1011;
TWCY_COOKIS = 1012;
TWCY_COSTARICA = 0506;
TWCY_CUBA = 0005;
TWCY_CYPRUS = 0357;
TWCY_CZECHOSLOVAKIA = 0042;
TWCY_DENMARK = 0045;
TWCY_DJIBOUTI = 1013;
TWCY_DOMINICA = 8097;
TWCY_DOMINCANREP = 8098;
TWCY_EASTERIS = 1014;
TWCY_ECUADOR = 0593;
TWCY_EGYPT = 0020;
TWCY_ELSALVADOR = 0503;
TWCY_EQGUINEA = 1015;
TWCY_ETHIOPIA = 0251;
TWCY_FALKLANDIS = 1016;
TWCY_FAEROEIS = 0298;
TWCY_FIJIISLANDS = 0679;
TWCY_FINLAND = 0358;
TWCY_FRANCE = 0033;
TWCY_FRANTILLES = 0596;
TWCY_FRGUIANA = 0594;
TWCY_FRPOLYNEISA = 0689;
TWCY_FUTANAIS = 1043;
TWCY_GABON = 0241;
TWCY_GAMBIA = 0220;
TWCY_GERMANY = 0049;
TWCY_GHANA = 0233;
TWCY_GIBRALTER = 0350;
TWCY_GREECE = 0030;
TWCY_GREENLAND = 0299;
TWCY_GRENADA = 8099;
TWCY_GRENEDINES = 8015;
TWCY_GUADELOUPE = 0590;
TWCY_GUAM = 0671;
TWCY_GUANTANAMOBAY = 5399;
TWCY_GUATEMALA = 0502;
TWCY_GUINEA = 0224;
TWCY_GUINEABISSAU = 1017;
TWCY_GUYANA = 0592;
TWCY_HAITI = 0509;
TWCY_HONDURAS = 0504;
TWCY_HONGKONG = 0852;
TWCY_HUNGARY = 0036;
TWCY_ICELAND = 0354;
TWCY_INDIA = 0091;
TWCY_INDONESIA = 0062;
TWCY_IRAN = 0098;
TWCY_IRAQ = 0964;
TWCY_IRELAND = 0353;
TWCY_ISRAEL = 0972;
TWCY_ITALY = 0039;
TWCY_IVORYCOAST = 0225;
TWCY_JAMAICA = 8010;
TWCY_JAPAN = 0081;
TWCY_JORDAN = 0962;
TWCY_KENYA = 0254;
TWCY_KIRIBATI = 1018;
TWCY_KOREA = 0082;
TWCY_KUWAIT = 0965;
TWCY_LAOS = 1019;
TWCY_LEBANON = 1020;
TWCY_LIBERIA = 0231;
TWCY_LIBYA = 0218;
TWCY_LIECHTENSTEIN = 0041;
TWCY_LUXENBOURG = 0352;
TWCY_MACAO = 0853;
TWCY_MADAGASCAR = 1021;
TWCY_MALAWI = 0265;
TWCY_MALAYSIA = 0060;
TWCY_MALDIVES = 0960;
TWCY_MALI = 1022;
TWCY_MALTA = 0356;
TWCY_MARSHALLIS = 0692;
TWCY_MAURITANIA = 1023;
TWCY_MAURITIUS = 0230;
TWCY_MEXICO = 0003;
TWCY_MICRONESIA = 0691;
TWCY_MIQUELON = 0508;
TWCY_MONACO = 0033;
TWCY_MONGOLIA = 1024;
TWCY_MONTSERRAT = 8011;
TWCY_MOROCCO = 0212;
TWCY_MOZAMBIQUE = 1025;
TWCY_NAMIBIA = 0264;
TWCY_NAURU = 1026;
TWCY_NEPAL = 0977;
TWCY_NETHERLANDS = 0031;
TWCY_NETHANTILLES = 0599;
TWCY_NEVIS = 8012;
TWCY_NEWCALEDONIA = 0687;
TWCY_NEWZEALAND = 0064;
TWCY_NICARAGUA = 0505;
TWCY_NIGER = 0227;
TWCY_NIGERIA = 0234;
TWCY_NIUE = 1027;
TWCY_NORFOLKI = 1028;
TWCY_NORWAY = 0047;
TWCY_OMAN = 0968;
TWCY_PAKISTAN = 0092;
TWCY_PALAU = 1029;
TWCY_PANAMA = 0507;
TWCY_PARAGUAY = 0595;
TWCY_PERU = 0051;
TWCY_PHILLIPPINES = 0063;
TWCY_PITCAIRNIS = 1030;
TWCY_PNEWGUINEA = 0675;
TWCY_POLAND = 0048;
TWCY_PORTUGAL = 0351;
TWCY_QATAR = 0974;
TWCY_REUNIONI = 1031;
TWCY_ROMANIA = 0040;
TWCY_RWANDA = 0250;
TWCY_SAIPAN = 0670;
TWCY_SANMARINO = 0039;
TWCY_SAOTOME = 1033;
TWCY_SAUDIARABIA = 0966;
TWCY_SENEGAL = 0221;
TWCY_SEYCHELLESIS = 1034;
TWCY_SIERRALEONE = 1035;
TWCY_SINGAPORE = 0065;
TWCY_SOLOMONIS = 1036;
TWCY_SOMALI = 1037;
TWCY_SOUTHAFRICA = 0027;
TWCY_SPAIN = 0034;
TWCY_SRILANKA = 0094;
TWCY_STHELENA = 1032;
TWCY_STKITTS = 8013;
TWCY_STLUCIA = 8014;
TWCY_STPIERRE = 0508;
TWCY_STVINCENT = 8015;
TWCY_SUDAN = 1038;
TWCY_SURINAME = 0597;
TWCY_SWAZILAND = 0268;
TWCY_SWEDEN = 0046;
TWCY_SWITZERLAND = 0041;
TWCY_SYRIA = 1039;
TWCY_TAIWAN = 0886;
TWCY_TANZANIA = 0255;
TWCY_THAILAND = 0066;
TWCY_TOBAGO = 8016;
TWCY_TOGO = 0228;
TWCY_TONGAIS = 0676;
TWCY_TRINIDAD = 8016;
TWCY_TUNISIA = 0216;
TWCY_TURKEY = 0090;
TWCY_TURKSCAICOS = 8017;
TWCY_TUVALU = 1040;
TWCY_UGANDA = 0256;
TWCY_USSR = 0007;
TWCY_UAEMIRATES = 0971;
TWCY_UNITEDKINGDOM = 0044;
TWCY_USA = 0001;
TWCY_URUGUAY = 0598;
TWCY_VANUATU = 1041;
TWCY_VATICANCITY = 0039;
TWCY_VENEZUELA = 0058;
TWCY_WAKE = 1042;
TWCY_WALLISIS = 1043;
TWCY_WESTERNSAHARA = 1044;
TWCY_WESTERNSAMOA = 1045;
TWCY_YEMEN = 1046;
TWCY_YUGOSLAVIA = 0038;
TWCY_ZAIRE = 0243;
TWCY_ZAMBIA = 0260;
TWCY_ZIMBABWE = 0263;
TWCY_ALBANIA = 0355;
TWCY_ARMENIA = 0374;
TWCY_AZERBAIJAN = 0994;
TWCY_BELARUS = 0375;
TWCY_BOSNIAHERZGO = 0387;
TWCY_CAMBODIA = 0855;
TWCY_CROATIA = 0385;
TWCY_CZECHREPUBLIC = 0420;
TWCY_DIEGOGARCIA = 0246;
TWCY_ERITREA = 0291;
TWCY_ESTONIA = 0372;
TWCY_GEORGIA = 0995;
TWCY_LATVIA = 0371;
TWCY_LESOTHO = 0266;
TWCY_LITHUANIA = 0370;
TWCY_MACEDONIA = 0389;
TWCY_MAYOTTEIS = 0269;
TWCY_MOLDOVA = 0373;
TWCY_MYANMAR = 0095;
TWCY_NORTHKOREA = 0850;
TWCY_PUERTORICO = 0787;
TWCY_RUSSIA = 0007;
TWCY_SERBIA = 0381;
TWCY_SLOVAKIA = 0421;
TWCY_SLOVENIA = 0386;
TWCY_SOUTHKOREA = 0082;
TWCY_UKRAINE = 0380;
TWCY_USVIRGINIS = 0340;
TWCY_VIETNAM = 0084;
Const
// Flags for languages
TWLG_DAN = 000; // Danish
TWLG_DUT = 001; // Dutch
TWLG_ENG = 002; // English
TWLG_FCF = 003; // French Canadian
TWLG_FIN = 004; // Finnish
TWLG_FRN = 005; // French
TWLG_GER = 006; // German
TWLG_ICE = 007; // Icelandic
TWLG_ITN = 008; // Italian
TWLG_NOR = 009; // Norwegian
TWLG_POR = 010; // Portuguese
TWLG_SPA = 011; // Spannish
TWLG_SWE = 012; // Swedish
TWLG_USA = 013;
TWLG_AFRIKAANS = 014;
TWLG_ALBANIA = 015;
TWLG_ARABIC = 016;
TWLG_ARABIC_ALGERIA = 017;
TWLG_ARABIC_BAHRAIN = 018;
TWLG_ARABIC_EGYPT = 019;
TWLG_ARABIC_IRAQ = 020;
TWLG_ARABIC_JORDAN = 021;
TWLG_ARABIC_KUWAIT = 022;
TWLG_ARABIC_LEBANON = 023;
TWLG_ARABIC_LIBYA = 024;
TWLG_ARABIC_MOROCCO = 025;
TWLG_ARABIC_OMAN = 026;
TWLG_ARABIC_QATAR = 027;
TWLG_ARABIC_SAUDIARABIA = 028;
TWLG_ARABIC_SYRIA = 029;
TWLG_ARABIC_TUNISIA = 030;
TWLG_ARABIC_UAE = 031; // United Arabic Emirates
TWLG_ARABIC_YEMEN = 032;
TWLG_BASQUE = 033;
TWLG_BYELORUSSIAN = 034;
TWLG_BULGARIAN = 035;
TWLG_CATALAN = 036;
TWLG_CHINESE = 037;
TWLG_CHINESE_HONGKONG = 038;
TWLG_CHINESE_PRC = 039; // People's Republic of China
TWLG_CHINESE_SINGAPORE = 040;
TWLG_CHINESE_SIMPLIFIED = 041;
TWLG_CHINESE_TAIWAN = 042;
TWLG_CHINESE_TRADITIONAL = 043;
TWLG_CROATIA = 044;
TWLG_CZECH = 045;
TWLG_DANISH = TWLG_DAN;
TWLG_DUTCH = TWLG_DUT;
TWLG_DUTCH_BELGIAN = 046;
TWLG_ENGLISH = TWLG_ENG;
TWLG_ENGLISH_AUSTRALIAN = 047;
TWLG_ENGLISH_CANADIAN = 048;
TWLG_ENGLISH_IRELAND = 049;
TWLG_ENGLISH_NEWZEALAND = 050;
TWLG_ENGLISH_SOUTHAFRICA = 051;
TWLG_ENGLISH_UK = 052;
TWLG_ENGLISH_USA = TWLG_USA;
TWLG_ESTONIAN = 053;
TWLG_FAEROESE = 054;
TWLG_FARSI = 055;
TWLG_FINNISH = TWLG_FIN;
TWLG_FRENCH = TWLG_FRN;
TWLG_FRENCH_BELGIAN = 056;
TWLG_FRENCH_CANADIAN = TWLG_FCF;
TWLG_FRENCH_LUXEMBOURG = 057;
TWLG_FRENCH_SWISS = 058;
TWLG_GERMAN = TWLG_GER;
TWLG_GERMAN_AUSTRIAN = 059;
TWLG_GERMAN_LUXEMBOURG = 060;
TWLG_GERMAN_LIECHTENSTEIN = 061;
TWLG_GERMAN_SWISS = 062;
TWLG_GREEK = 063;
TWLG_HEBREW = 064;
TWLG_HUNGARIAN = 065;
TWLG_ICELANDIC = TWLG_ICE;
TWLG_INDONESIAN = 066;
TWLG_ITALIAN = TWLG_ITN;
TWLG_ITALIAN_SWISS = 067;
TWLG_JAPANESE = 068;
TWLG_KOREAN = 069;
TWLG_KOREAN_JOHAB = 070;
TWLG_LATVIAN = 071;
TWLG_LITHUANIAN = 072;
TWLG_NORWEGIAN = TWLG_NOR;
TWLG_NORWEGIAN_BOKMAL = 073;
TWLG_NORWEGIAN_NYNORSK = 074;
TWLG_POLISH = 075;
TWLG_PORTUGUESE = TWLG_POR;
TWLG_PORTUGUESE_BRAZIL = 076;
TWLG_ROMANIAN = 077;
TWLG_RUSSIAN = 078;
TWLG_SERBIAN_LATIN = 079;
TWLG_SLOVAK = 080;
TWLG_SLOVENIAN = 081;
TWLG_SPANISH = TWLG_SPA;
TWLG_SPANISH_MEXICAN = 082;
TWLG_SPANISH_MODERN = 083;
TWLG_SWEDISH = TWLG_SWE;
TWLG_THAI = 084;
TWLG_TURKISH = 085;
TWLG_UKRANIAN = 086;
TWLG_ASSAMESE = 087;
TWLG_BENGALI = 088;
TWLG_BIHARI = 089;
TWLG_BODO = 090;
TWLG_DOGRI = 091;
TWLG_GUJARATI = 092;
TWLG_HARYANVI = 093;
TWLG_HINDI = 094;
TWLG_KANNADA = 095;
TWLG_KASHMIRI = 096;
TWLG_MALAYALAM = 097;
TWLG_MARATHI = 098;
TWLG_MARWARI = 099;
TWLG_MEGHALAYAN = 100;
TWLG_MIZO = 101;
TWLG_NAGA = 102;
TWLG_ORISSI = 103;
TWLG_PUNJABI = 104;
TWLG_PUSHTU = 105;
TWLG_SERBIAN_CYRILLIC = 106;
TWLG_SIKKIMI = 107;
TWLG_SWEDISH_FINLAND = 108;
TWLG_TAMIL = 109;
TWLG_TELUGU = 110;
TWLG_TRIPURI = 111;
TWLG_URDU = 112;
TWLG_VIETNAMESE = 113;
Const
TWRC_SUCCESS = 0;
TWRC_FAILURE = 1; // Application may get TW_STATUS for
// info on failure
TWRC_CHECKSTATUS = 2; // tried hard to get the status
TWRC_CANCEL = 3;
TWRC_DSEVENT = 4;
TWRC_NOTDSEVENT = 5;
TWRC_XFERDONE = 6;
TWRC_ENDOFLIST = 7; // After MSG_GETNEXT if nothing left
TWRC_INFONOTSUPPORTED = 8;
TWRC_DATANOTAVAILABLE = 9;
Const
TWON_ONEVALUE = $05; // indicates TW_ONEVALUE container
TWON_DONTCARE8 = $FF;
Const
ICAP_XFERMECH = $0103;
Const
TWTY_UINT16 = $0004; // Means: item is a TW_UINT16
Const
// ICAP_XFERMECH values (SX_ means Setup XFer)
TWSX_NATIVE = 0;
TWSX_FILE = 1;
TWSX_MEMORY = 2;
TWSX_FILE2 = 3;
Type
TW_UINT16 = WORD; // unsigned short TW_UINT16
pTW_UINT16 = ^TW_UINT16;
TTWUInt16 = TW_UINT16;
PTWUInt16 = pTW_UINT16;
Type
TW_BOOL = WORDBOOL; // unsigned short TW_BOOL
pTW_BOOL = ^TW_BOOL;
TTWBool = TW_BOOL;
PTWBool = pTW_BOOL;
Type
TW_STR32 = Array[0..33] of Char; // char TW_STR32[34]
pTW_STR32 = ^TW_STR32;
TTWStr32 = TW_STR32;
PTWStr32 = pTW_STR32;
Type
TW_STR255 = Array[0..255] of Char; // char TW_STR255[256]
pTW_STR255 = ^TW_STR255;
TTWStr255 = TW_STR255;
PTWStr255 = pTW_STR255;
Type
TW_INT16 = SmallInt; // short TW_INT16
pTW_INT16 = ^TW_INT16;
TTWInt16 = TW_INT16;
PTWInt16 = pTW_INT16;
Type
TW_UINT32 = ULONG; // unsigned long TW_UINT32
pTW_UINT32 = ^TW_UINT32;
TTWUInt32 = TW_UINT32;
PTWUInt32 = pTW_UINT32;
Type
TW_HANDLE = THandle;
TTWHandle = TW_HANDLE;
TW_MEMREF = Pointer;
TTWMemRef = TW_MEMREF;
Type
// DAT_PENDINGXFERS. Used with MSG_ENDXFER to indicate additional
// data
TW_PENDINGXFERS = Packed record
Count : TW_UINT16;
Case Boolean of
False : (EOJ : TW_UINT32);
True : (Reserved : TW_UINT32);
End;
pTW_PENDINGXFERS = ^TW_PENDINGXFERS;
TTWPendingXFERS = TW_PENDINGXFERS;
PTWPendingXFERS = pTW_PENDINGXFERS;
Type
// DAT_EVENT. For passing events down from the application to the DS
TW_EVENT = Packed record
pEvent : TW_MEMREF; // Windows pMSG or Mac pEvent.
TWMessage : TW_UINT16; // TW msg from data source, e.g.
// MSG_XFERREADY
End;
pTW_EVENT = ^TW_EVENT;
TTWEvent = TW_EVENT;
PTWEvent = pTW_EVENT;
Type
// TWON_ONEVALUE. Container for one value
TW_ONEVALUE = Packed record
ItemType : TW_UINT16;
Item : TW_UINT32;
End;
pTW_ONEVALUE = ^TW_ONEVALUE;
TTWOneValue = TW_ONEVALUE;
PTWOneValue = pTW_ONEVALUE;
Type
// DAT_CAPABILITY. Used by application to get/set capability from/in
// a data source.
TW_CAPABILITY = Packed record
Cap : TW_UINT16; // id of capability to set or get, e.g.
// CAP_BRIGHTNESS
ConType : TW_UINT16; // TWON_ONEVALUE, _RANGE, _ENUMERATION or
// _ARRAY
hContainer : TW_HANDLE; // Handle to container of type Dat
End;
pTW_CAPABILITY = ^TW_CAPABILITY;
TTWCapability = TW_CAPABILITY;
PTWCapability = pTW_CAPABILITY;
Type
// DAT_STATUS. Application gets detailed status info from a data
// source with this
TW_STATUS = Packed record
ConditionCode : TW_UINT16; // Any TWCC_xxx constant
Reserved : TW_UINT16; // Future expansion space
End;
pTW_STATUS = ^TW_STATUS;
TTWStatus = TW_STATUS;
PTWStatus = pTW_STATUS;
Type
// No DAT needed. Used to manage memory buffers
TW_MEMORY = Packed record
Flags : TW_UINT32; // Any combination of the TWMF_ constants
Length : TW_UINT32; // Number of bytes stored in buffer TheMem
TheMem : TW_MEMREF; // Pointer or handle to the allocated memory
// buffer
End;
pTW_MEMORY = ^TW_MEMORY;
TTWMemory = TW_MEMORY;
PTWMemory = pTW_MEMORY;
Const
// ICAP_IMAGEFILEFORMAT values (FF_means File Format
TWFF_TIFF = 0; // Tagged Image File Format
TWFF_PICT = 1; // Macintosh PICT
TWFF_BMP = 2; // Windows Bitmap
TWFF_XBM = 3; // X-Windows Bitmap
TWFF_JFIF = 4; // JPEG File Interchange Format
TWFF_FPX = 5; // Flash Pix
TWFF_TIFFMULTI = 6; // Multi-page tiff file
TWFF_PNG = 7; // Portable Network Graphic
TWFF_SPIFF = 8;
TWFF_EXIF = 9;
Type
// DAT_SETUPFILEXFER. Sets up DS to application data transfer via a
// file
TW_SETUPFILEXFER = Packed record
FileName : TW_STR255;
Format : TW_UINT16; // Any TWFF_xxx constant
VRefNum : TW_INT16; // Used for Mac only
End;
pTW_SETUPFILEXFER = ^TW_SETUPFILEXFER;
TTWSetupFileXFER = TW_SETUPFILEXFER;
PTWSetupFileXFER = pTW_SETUPFILEXFER;
Type
// DAT_SETUPFILEXFER2. Sets up DS to application data transfer via a
// file. }
TW_SETUPFILEXFER2 = Packed record
FileName : TW_MEMREF; // Pointer to file name text
FileNameType : TW_UINT16; // TWTY_STR1024 or TWTY_UNI512
Format : TW_UINT16; // Any TWFF_xxx constant
VRefNum : TW_INT16; // Used for Mac only
parID : TW_UINT32; // Used for Mac only
End;
pTW_SETUPFILEXFER2 = ^TW_SETUPFILEXFER2;
TTWSetupFileXFER2 = TW_SETUPFILEXFER2;
PTWSetupFileXFER2 = pTW_SETUPFILEXFER2;
Type
// DAT_SETUPMEMXFER. Sets up Data Source to application data
// transfer via a memory buffer
TW_SETUPMEMXFER = Packed record
MinBufSize : TW_UINT32;
MaxBufSize : TW_UINT32;
Preferred : TW_UINT32;
End;
pTW_SETUPMEMXFER = ^TW_SETUPMEMXFER;
TTWSetupMemXFER = TW_SETUPMEMXFER;
PTWSetupMemXFER = pTW_SETUPMEMXFER;
Type
TW_VERSION = Packed record
MajorNum : TW_UINT16; // Major revision number of the software.
MinorNum : TW_UINT16; // Incremental revision number of the
// software
Language : TW_UINT16; // e.g. TWLG_SWISSFRENCH
Country : TW_UINT16; // e.g. TWCY_SWITZERLAND
Info : TW_STR32; // e.g. "1.0b3 Beta release"
End;
pTW_VERSION = ^TW_VERSION;
PTWVersion = pTW_VERSION;
TTWVersion = TW_VERSION;
Type
TW_IDENTITY = Packed record
Id : TW_UINT32; // Unique number. In Windows,
// application hWnd
Version : TW_VERSION; // Identifies the piece of code
ProtocolMajor : TW_UINT16; // Application and DS must set to
// TWON_PROTOCOLMAJOR
ProtocolMinor : TW_UINT16; // Application and DS must set to
// TWON_PROTOCOLMINOR
SupportedGroups : TW_UINT32; // Bit field OR combination of DG_
// constants
Manufacturer : TW_STR32; // Manufacturer name, e.g.
// "Hewlett-Packard"
ProductFamily : TW_STR32; // Product family name, e.g.
// "ScanJet"
ProductName : TW_STR32; // Product name, e.g. "ScanJet Plus"
End;
pTW_IDENTITY = ^TW_IDENTITY;
Type
// DAT_USERINTERFACE. Coordinates UI between application and data
// source
TW_USERINTERFACE = Packed record
ShowUI : TW_BOOL; // TRUE if DS should bring up its UI
ModalUI : TW_BOOL; // For Mac only - true if the DS's UI is modal
hParent : TW_HANDLE; // For Windows only - Application handle
End;
pTW_USERINTERFACE = ^TW_USERINTERFACE;
TTWUserInterface = TW_USERINTERFACE;
PTWUserInterface = pTW_USERINTERFACE;
////////////////////////////////////////////////////////////////////////
// //
// END OF TWAIN TYPES AND CONSTANTS //
// //
////////////////////////////////////////////////////////////////////////
Const
TWAIN_DLL_Name = 'TWAIN_32.DLL';
DSM_Entry_Name = 'DSM_Entry';
Ini_File_Name = 'WIN.INI';
CrLf = #13 + #10;
Resourcestring // Errorstrings:
ERR_DSM_ENTRY_NOT_FOUND = 'Unable to find the entry of the Data ' +
'Source Manager in: TWAIN_32.DLL';
ERR_TWAIN_NOT_LOADED = 'Unable to load or find: TWAIN_32.DLL';
ERR_DSM_CALL_FAILED = 'A call to the Data Source Manager failed ' +
'in module %s';
ERR_UNKNOWN = 'A call to the Data Source Manager failed ' +
'in module %s: Code %.04x';
ERR_DSM_OPEN = 'Unable to close the Data Source Manager. ' +
'Maybe a source is still in use';
ERR_STATUS = 'Unable to get the status';
ERR_DSM = 'Data Source Manager error in module %s:' +
CrLf + '%s';
ERR_DS = 'Data Source error in module %s:' +
CrLf + '%s';
Type
ETwainError = Class(Exception);
TImageType = (ffTIFF,ffPICT,ffBMP,ffXBM,ffJFIF,ffFPX,
ffTIFFMULTI,ffPNG,ffSPIFF,ffEXIF,ffUNKNOWN);
TTransferType = (xfNative,xfMemory,xfFile);
TLanguageType = (lgDutch, lgEnglish,
lgFrench, lgGerman,
lgAmerican, lgItalian,
lgSpanish, lgNorwegian,
lgFinnish, lgDanish,
lgRussian, lgPortuguese,
lgSwedish, lgPolish,
lgGreek, lgTurkish);
TCountryType = (ctNetherlands,ctEngland,
ctFrance, ctGermany,
ctUSA, ctSpain,
ctItaly, ctDenmark,
ctFinland, ctNorway,
ctRussia, ctPortugal,
ctSweden, ctPoland,
ctGreece, ctTurkey);
TTWAIN = Class(TComponent)
Private
// Private declarations
fBitmap : TBitmap; // the actual bmp used for
// scanning, must be
// removed
HDSMDLL : HMODULE; // = 0, the library handle:
// will stay global
appId : TW_IDENTITY; // our (Application) ID.
// (may stay global)
dsId : TW_IDENTITY; // Data Source ID (will
// become member of DS
// class)
fhWnd : HWND; // = 0, maybe will be
// removed, use
// application.handle
// instead
fXfer : TTransferType; // = xfNative;
bDataSourceManagerOpen : Boolean; // = False, flag, may stay
// global
bDataSourceOpen : Boolean; // = False, will become
// member of DS class
bDataSourceEnabled : Boolean; // = False, will become
// member of DS class
fScanReady : TNotifyEvent; // notifies that the scan
// is ready
sDefaultSource : String; // remember old data source
fOldOnMessageHandler : TMessageEvent; // Save old OnMessage event
fShowUI : Boolean; // Show User Interface
fSetupFileXfer : TW_SETUPFILEXFER; // Not used yet
fSetupMemoryXfer : TW_SETUPMEMXFER; // Not used yet
fMemory : TW_MEMORY; // Not used yet
Function fLoadTwain : Boolean;
Procedure fUnloadTwain;
Function fNativeXfer : Boolean;
Function fMemoryXfer : Boolean; // Not used yet
Function fFileXfer : Boolean; // Not used yet
Function fGetDestination : TTransferType;
Procedure fSetDestination(dest : TTransferType);
Function Condition2String(ConditionCode : TW_UINT16) : String;
Procedure RaiseLastDataSourceManagerCondition(module : String);
Procedure RaiseLastDataSourceCondition(module : String);
Procedure TwainCheckDataSourceManager(res : TW_UINT16;
module : String);
Procedure TwainCheckDataSource(res : TW_UINT16;
module : string);
Function CallDataSourceManager(pOrigin : pTW_IDENTITY;
DG : TW_UINT32;
DAT : TW_UINT16;
MSG : TW_UINT16;
pData : TW_MEMREF) : TW_UINT16;
Function CallDataSource (DG : TW_UINT32;
DAT : TW_UINT16;
MSG : TW_UINT16;
pData : TW_MEMREF) : TW_UINT16;
Procedure XferMech;
Procedure fSetProductname(pn : String);
Function fGetProductname : String;
Procedure fSetManufacturer(mf : String);
Function fGetManufacturer : String;
Procedure fSetProductFamily(pf : String);
Function fGetProductFamily : String;
Procedure fSetLanguage(lg : TLanguageType);
Function fGetLanguage : TLanguageType;
Procedure fSetCountry(ct : TCountryType);
Function fGetCountry : TCountryType;
Procedure SaveDefaultSourceEntry;
Procedure RestoreDefaultSourceEntry;
Procedure fSetCursor(cr : TCursor);
Function fGetCursor : TCursor;
Procedure fSetImageType(it : TImageType);
Function fGetImageType : TImageType;
Procedure fSetFilename(fn : String);
Function fGetFilename : String;
Procedure fSetVersionInfo(vi : String);
Function fGetVersionInfo : String;
Procedure fSetVersionMajor(vmaj : WORD);
Procedure fSetVersionMinor(vmin : WORD);
Function fGetVersionMajor : WORD;
Function fGetVersionMinor : WORD;
Protected
Procedure ScanReady; dynamic; // Notifies when image transfer is
// ready
Procedure fNewOnMessageHandler(Var Msg : TMsg;
Var Handled : Boolean); virtual;
Public
// Public declarations
Constructor Create(AOwner : TComponent); override;
Destructor Destroy; override;
Procedure Acquire(aBmp : TBitmap);
Procedure OpenDataSource;
Procedure CloseDataSource;
Procedure InitTWAIN;
Procedure OpenDataSourceManager;
Procedure CloseDataSourceManager;
Function IsDataSourceManagerOpen : Boolean;
Procedure EnableDataSource;
// Procedure TWEnableDSUIOnly(ShowUI : Boolean);
Procedure DisableDataSource;
Function IsDataSourceOpen : Boolean;
Function IsDataSourceEnabled : Boolean;
Procedure SelectDataSource;
Function IsTwainDriverAvailable : Boolean;
Function ProcessSourceMessage(Var Msg : TMsg): Boolean;
Published
// Published declarations
// Properties, methods
Property Destination : TTransferType
Read fGetDestination write fSetDestination;
Property TwainDriverFound : Boolean
Read IsTwainDriverAvailable;
Property Productname : String
Read fGetProductname write fSetProductname;
Property Manufacturer : String
Read fGetManufacturer write fSetManufacturer;
Property ProductFamily : String
Read fGetProductFamily write fSetProductFamily;
Property Language : TLanguageType
Read fGetLanguage write fSetLanguage;
Property Country : TCountryType
Read fGetCountry write fSetCountry;
Property ShowUI : Boolean
Read fShowUI write fShowUI;
Property Cursor : TCursor
Read fGetCursor write fSetCursor;
Property FileFormat : TImageType
Read fGetImageType write fSetImageType;
Property Filename : String
Read fGetFilename write fSetFilename;
Property VersionInfo : String
Read fGetVersionInfo write fSetVersionInfo;
Property VersionMajor : WORD
Read fGetVersionMajor write fSetVersionMajor;
Property VersionMinor : WORD
Read fGetVersionMinor Write fSetVersionMinor;
// Events
Property OnScanReady : TNotifyEvent
Read fScanReady write fScanReady;
End;
Procedure Register;
Type
DSMENTRYPROC = Function(pOrigin : pTW_IDENTITY;
pDest : pTW_IDENTITY;
DG : TW_UINT32;
DAT : TW_UINT16;
MSG : TW_UINT16;
pData : TW_MEMREF) : TW_UINT16; stdcall;
TDSMEntryProc = DSMENTRYPROC;
Type
DSENTRYPROC = Function( pOrigin : pTW_IDENTITY;
DG : TW_UINT32;
DAT : TW_UINT16;
MSG : TW_UINT16;
pData : TW_MEMREF) : TW_UINT16; stdcall;
TDSEntryProc = DSENTRYPROC;
Var
DS_Entry : TDSEntryProc = nil; // Initialize
DSM_Entry : TDSMEntryProc = nil; // Initialize
Implementation
//---------------------------------------------------------------------
Constructor TTWAIN.Create(AOwner : TComponent);
Begin
Inherited Create(AOwner);
// Initialize variables
appID.Version.Info := 'Twain component';
appID.Version.Country := TWCY_USA;
appID.Version.Language := TWLG_USA;
appID.Productname := 'SimpelSoft TWAIN module'; // This is the one that you are
// going to see in the UI
appID.ManuFacturer := 'SimpelSoft';
appID.ProductFamily := 'SimpelSoft components';
appID.Version.MajorNum := 1;
appID.Version.MinorNum := 0;
// appID.ID := Application.Handle;
fSetFilename('C:\TWAIN.BMP');
// fSetupFileXfer.FileName := 'C:\TWAIN.TMP':
fSetImageType(ffBMP);
// fSetupFileXfer.Format := TWFF_BMP;
// fSetupFileXfer.VRefNum := xx; // For Mac
// fSetupMemoryXfer.MinBufSize := xx;
// fSetupMemoryXfer.MaxBufSize := yy;
// fSetupMemoryXfer.Preferred := zz;
fMemory.Flags := TWFF_BMP;
// fMemory.Length := SizeOf(Mem);
// fMemory.TheMem := @Mem;
// fhWnd := Application.Handle;
fShowUI := True;
HDSMDLL := 0;
sDefaultSource := '';
fXfer := xfNative;
bDataSourceManagerOpen := False;
bDataSourceOpen := False;
bDataSourceEnabled := False;
End;
//---------------------------------------------------------------------
Destructor TTWAIN.Destroy;
Begin
If bDataSourceEnabled then
DisableDataSource;
If bDataSourceOpen then
CloseDataSource;
If bDataSourceManagerOpen then
CloseDataSourceManager;
fUnLoadTwain; // Loose the TWAIN_32.DLL
If sDefaultSource '' then
RestoreDefaultSourceEntry; // Write old entry back in WIN.INI
Application.OnMessage := fOldOnMessageHandler; // Restore old OnMessage
// handler
Inherited Destroy;
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetVersionMajor : WORD;
Begin
Result := appID.Version.MajorNum;
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetVersionMinor : WORD;
Begin
Result := appID.Version.MinorNum;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetVersionMajor(vmaj : WORD);
Begin
appID.Version.MajorNum := vmaj;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetVersionMinor(vmin : WORD);
Begin
appID.Version.MinorNum := vmin;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetVersionInfo(vi : String);
Var
I,L : Integer;
Begin
FillChar(appID.Version.Info,SizeOf(appID.Version.Info),#0);
L := Length(vi);
If L = 0 then
Exit;
If L 32 then
L := 32;
For I := 1 to L do
appID.Version.Info[I - 1] := vi[I];
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetVersionInfo : String;
Var
I : Integer;
Begin
Result := '';
I := 0;
If appID.Version.Info[I] #0 then
Repeat
Result := Result + appID.Version.Info[I];
Inc(I);
Until appID.Version.Info[I] = #0;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetImageType(it : TImageType);
Begin
fSetupFileXfer.Format := TWFF_BMP; // Initialize
fMemory.Flags := TWFF_BMP; // Initialize
Case it of
ffTIFF : Begin
fSetupFileXfer.Format := TWFF_TIFF;
fMemory.Flags := TWFF_TIFF;
End;
ffPICT : Begin
fSetupFileXfer.Format := TWFF_PICT;
fMemory.Flags := TWFF_PICT;
End;
ffBMP : Begin
fSetupFileXfer.Format := TWFF_BMP;
fMemory.Flags := TWFF_BMP;
End;
ffXBM : Begin
fSetupFileXfer.Format := TWFF_XBM;
fMemory.Flags := TWFF_XBM;
End;
ffJFIF : Begin
fSetupFileXfer.Format := TWFF_JFIF;
fMemory.Flags := TWFF_JFIF;
End;
ffFPX : Begin
fSetupFileXfer.Format := TWFF_FPX;
fMemory.Flags := TWFF_FPX;
End;
ffTIFFMULTI : Begin
fSetupFileXfer.Format := TWFF_TIFFMULTI;
fMemory.Flags := TWFF_TIFFMULTI;
End;
ffPNG : Begin
fSetupFileXfer.Format := TWFF_PNG;
fMemory.Flags := TWFF_PNG;
End;
ffSPIFF : Begin
fSetupFileXfer.Format := TWFF_SPIFF;
fMemory.Flags := TWFF_SPIFF;
End;
ffEXIF : Begin
fSetupFileXfer.Format := TWFF_EXIF;
fMemory.Flags := TWFF_EXIF;
End;
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetFilename(fn : String);
Var
L,I : Integer;
Begin
FillChar(fSetupFileXfer.FileName,SizeOf(fSetupFileXfer.Filename),#0);
L := Length(fn);
If L 0 then
For I := 1 to L do
fSetupFileXfer.Filename[I - 1] := fn[I];
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetFilename : String;
Var
I : Integer;
Begin
Result := '';
I := 0;
If fSetupFileXfer.Filename[I] #0 then
Repeat
Result := Result + fSetupFileXfer.Filename[I];
Inc(I);
Until fSetupFileXfer.Filename[I] = #0;
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetImageType : TImageType;
Begin
Result := ffUNKNOWN; // Initialize
Case fSetupFileXfer.Format of
TWFF_TIFF : Result := ffTIFF;
TWFF_PICT : Result := ffPICT;
TWFF_BMP : Result := ffBMP;
TWFF_XBM : Result := ffXBM;
TWFF_JFIF : Result := ffJFIF;
TWFF_FPX : Result := ffFPX;
TWFF_TIFFMULTI : Result := ffTIFFMULTI;
TWFF_PNG : Result := ffPNG;
TWFF_SPIFF : Result := ffSPIFF;
TWFF_EXIF : Result := ffEXIF;
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetCursor(cr : TCursor);
Begin
Screen.Cursor := cr;
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetCursor : TCursor;
Begin
Result := Screen.Cursor;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetCountry(ct : TCountryType);
Begin
Case ct of
ctDenmark : appID.Version.Country := TWCY_DENMARK;
ctNetherlands : appID.Version.Country := TWCY_NETHERLANDS;
ctEngland : appID.Version.Country := TWCY_BRITAIN;
ctFinland : appID.Version.Country := TWCY_FINLAND;
ctFrance : appID.Version.Country := TWCY_FRANCE;
ctGermany : appID.Version.Country := TWCY_GERMANY;
ctItaly : appID.Version.Country := TWCY_ITALY;
ctNorWay : appID.Version.Country := TWCY_NORWAY;
ctSpain : appID.Version.Country := TWCY_SPAIN;
ctUSA : appID.Version.Country := TWCY_USA;
ctRussia : appID.Version.Country := TWCY_RUSSIA;
ctPortugal : appID.Version.Country := TWCY_PORTUGAL;
ctSweden : appID.Version.Country := TWCY_SWEDEN;
ctPoland : appID.Version.Country := TWCY_POLAND;
ctGreece : appID.Version.Country := TWCY_GREECE;
ctTurkey : appID.Version.Country := TWCY_TURKEY;
End;
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetCountry : TCountryType;
Begin
Result := ctNetherlands; // Initialize
Case appID.Version.Country of
TWCY_NETHERLANDS : Result := ctNetherlands;
TWCY_DENMARK : Result := ctDenmark;
TWCY_BRITAIN : Result := ctEngland;
TWCY_FINLAND : Result := ctFinland;
TWCY_FRANCE : Result := ctFrance;
TWCY_GERMANY : Result := ctGermany;
TWCY_NORWAY : Result := ctNorway;
TWCY_ITALY : Result := ctItaly;
TWCY_SPAIN : Result := ctSpain;
TWCY_USA : Result := ctUSA;
TWCY_RUSSIA : Result := ctRussia;
TWCY_PORTUGAL : Result := ctPortugal;
TWCY_SWEDEN : Result := ctSweden;
TWCY_TURKEY : Result := ctTurkey;
TWCY_GREECE : Result := ctGreece;
TWCY_POLAND : Result := ctPoland;
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetLanguage(lg : TLanguageType);
Begin
Case lg of
lgDanish : appID.Version.Language := TWLG_DAN;
lgDutch : appID.Version.Language := TWLG_DUT;
lgEnglish : appID.Version.Language := TWLG_ENG;
lgFinnish : appID.Version.Language := TWLG_FIN;
lgFrench : appID.Version.Language := TWLG_FRN;
lgGerman : appID.Version.Language := TWLG_GER;
lgNorwegian : appID.Version.Language := TWLG_NOR;
lgItalian : appID.Version.Language := TWLG_ITN;
lgSpanish : appID.Version.Language := TWLG_SPA;
lgAmerican : appID.Version.Language := TWLG_USA;
lgRussian : appID.Version.Language := TWLG_RUSSIAN;
lgPortuguese : appID.Version.Language := TWLG_POR;
lgSwedish : appID.Version.Language := TWLG_SWE;
lgPolish : appID.Version.Language := TWLG_POLISH;
lgGreek : appID.Version.Language := TWLG_GREEK;
lgTurkish : appID.Version.Language := TWLG_TURKISH;
End;
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetLanguage : TLanguageType;
Begin
Result := lgDutch; // Initialize
Case appID.Version.Language of
TWLG_DAN : Result := lgDanish;
TWLG_DUT : Result := lgDutch;
TWLG_ENG : Result := lgEnglish;
TWLG_FIN : Result := lgFinnish;
TWLG_FRN : Result := lgFrench;
TWLG_GER : Result := lgGerman;
TWLG_ITN : Result := lgItalian;
TWLG_NOR : Result := lgNorwegian;
TWLG_SPA : Result := lgSpanish;
TWLG_USA : Result := lgAmerican;
TWLG_RUSSIAN : Result := lgRussian;
TWLG_POR : Result := lgPortuguese;
TWLG_SWE : Result := lgSwedish;
TWLG_POLISH : Result := lgPolish;
TWLG_GREEK : Result := lgGreek;
TWLG_TURKISH : Result := lgTurkish;
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetManufacturer(mf : String);
Var
I,L : Integer;
Begin
FillChar(appID.Manufacturer,SizeOf(appID.Manufacturer),#0);
L := Length(mf);
If L = 0 then
Exit;
If L 32 then
L := 32;
For I := 1 to L do
appID.Manufacturer[I - 1] := mf[I];
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetManufacturer : String;
Var
I : Integer;
Begin
Result := '';
I := 0;
If appID.Manufacturer[I] #0 then
Repeat
Result := Result + appID.Manufacturer[I];
Inc(I);
Until appID.Manufacturer[I] = #0;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetProductname(pn : String);
Var
I,L : Integer;
Begin
FillChar(appID.Productname,SizeOf(appID.Productname),#0);
L := Length(pn);
If L = 0 then
Exit;
If L 32 then
L := 32;
For I := 1 to L do
appID.Productname[I - 1] := pn[I];
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetProductName : String;
Var
I : Integer;
Begin
Result := '';
I := 0;
If appID.ProductName[I] #0 then
Repeat
Result := Result + appID.ProductName[I];
Inc(I);
Until appID.ProductName[I] = #0;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetProductFamily(pf : String);
Var
I,L : Integer;
Begin
FillChar(appID.ProductFamily,SizeOf(appID.ProductFamily),#0);
L := Length(pf);
If L = 0 then
Exit;
If L 32 then
L := 32;
For I := 1 to L do
appID.ProductFamily[I - 1] := pf[I];
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetProductFamily : String;
Var
I : Integer;
Begin
Result := '';
I := 0;
If appID.ProductFamily[I] #0 then
Repeat
Result := Result + appID.ProductFamily[I];
Inc(I);
Until appID.ProductFamily[I] = #0;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.ScanReady;
Begin
if Assigned(fScanReady) then
fScanReady(Self);
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fSetDestination(dest : TTransferType);
Begin
fXfer := dest;
End;
//---------------------------------------------------------------------
Function TTWAIN.fGetDestination : TTransferType;
Begin
Result := fXfer;
End;
//----------------------------------------------------------------------
Function UpCaseStr(const s : String) : String;
Var
I,L : Integer;
Begin
Result := s;
L := Length(Result);
If L 0 then
Begin
For I := 1 to L do
Result[I] := UpCase(Result[I]);
End;
// Result := s; // Minor bug, changed 23/05/03
End;
//----------------------------------------------------------------------
// Internal routine
//----------------------------------------------------------------------
Function GetWinDir : String;
Var
WD : Array[0..MAX_PATH] of Char;
L : WORD;
Begin
WD := #0;
GetWindowsDirectory(WD,MAX_PATH);
Result := StrPas(WD);
L := Length(Result);
// Remove the "\" if any
If L 0 then
If Result[L] = '\' then
Result := Copy(Result,1,L - 1);
End;
//----------------------------------------------------------------------
// Internal routine
//----------------------------------------------------------------------
Procedure FileFindSubDir(const ffsPath : String;
var ffsBo : Boolean);
Var
sr : TSearchRec;
Begin
If FindFirst(ffsPath + '\*.*',faAnyFile,sr) = 0 then
Repeat
If sr.Name '.' then
If sr.Name '..' then
If sr.Attr and faDirectory = faDirectory then
Begin
FileFindSubDir(ffsPath + '\' + sr.name,ffsBo);
End
else
Begin
If UpCaseStr(ExtractFileExt(sr.Name)) = '.DS' then
If UpCaseStr(sr.Name) 'WIATWAIN.DS' then
ffsBo := True;
End;
Until FindNext(sr) 0;
// Error if SysUtils is not added in front of FindClose!
SysUtils.FindClose(sr);
End;
//----------------------------------------------------------------------
Function TTWAIN.IsTwainDriverAvailable : Boolean;
Var
sr : TSearchRec;
s : String;
Bo : Boolean;
Begin
// This routine might not be failsafe!
// Under circumstances the twain drivers found in the directory
// %WINDOWS%\TWAIN_32\*.ds and below could be not properly installed!
Bo := False;
s := GetWinDir + '\TWAIN_32';
FileFindSubDir(s,Bo);
Result := Bo;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.SaveDefaultSourceEntry;
Var
WinIni : TIniFile;
Begin
If sDefaultSource '' then
Exit;
WinIni := TIniFile.Create(Ini_File_Name);
sDefaultSource := WinIni.ReadString('TWAIN','DEFAULT SOURCE','');
WinIni.Free;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.RestoreDefaultSourceEntry;
Var
WinIni : TIniFile;
Begin
If sDefaultSource = '' then
Exit; // It is not changed by this component or it is not there...
WinIni := TIniFile.Create(Ini_File_Name);
WinIni.WriteString('TWAIN','DEFAULT SOURCE',sDefaultSource);
WinIni.Free;
sDefaultSource := '';
End;
//---------------------------------------------------------------------
Procedure TTWAIN.InitTWAIN;
Begin
appID.ID := Application.Handle;
fHwnd := Application.Handle;
fLoadTwain; // Load TWAIN_32.DLL
fOldOnMessageHandler := Application.OnMessage; // Save old pointer
Application.OnMessage := fNewOnMessageHandler; // Set to our handler
OpenDataSourceManager; // Open DS
End;
//---------------------------------------------------------------------
Function TTWAIN.fLoadTwain : Boolean;
Begin
If HDSMDLL = 0 then
Begin
HDSMDLL := LoadLibrary(TWAIN_DLL_Name);
DSM_Entry := GetProcAddress(HDSMDLL,DSM_Entry_Name);
// if @DSM_Entry = nil then
// raise ETwainError.Create(SErrDSMEntryNotFound);
End;
Result := (HDSMDLL 0);
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fUnloadTwain;
Begin
If HDSMDLL 0 then
Begin
DSM_Entry := nil;
FreeLibrary(HDSMDLL);
HDSMDLL := 0;
End;
End;
//---------------------------------------------------------------------
Function TTWAIN.Condition2String(ConditionCode : TW_UINT16) : String;
Begin
// Texts copied from PDF Documentation: Rework needed
Case ConditionCode of
TWCC_BADCAP : Result :=
'Capability not supported by source or operation (get,' + CrLf +
'set) is not supported on capability, or capability had' + CrLf +
'dependencies on other capabilities and cannot be' + CrLf +
'operated upon at this time';
TWCC_BADDEST : Result := 'Unknown destination in DSM_Entry.';
TWCC_BADPROTOCOL : Result := 'Unrecognized operation triplet.';
TWCC_BADVALUE : Result :=
'Data parameter out of supported range.';
TWCC_BUMMER : Result :=
'General failure. Unload Source immediately.';
TWCC_CAPUNSUPPORTED : Result := 'Capability not supported by ' +
'Data Source.';
TWCC_CAPBADOPERATION: Result := 'Operation not supported on ' +
'capability.';
TWCC_CAPSEQERROR : Result :=
'Capability has dependencies on other capabilities and ' + CrLf +
'cannot be operated upon at this time.';
TWCC_DENIED : Result :=
'File System operation is denied (file is protected).';
TWCC_PAPERDOUBLEFEED,
TWCC_PAPERJAM : Result :=
'Transfer failed because of a feeder error';
TWCC_FILEEXISTS : Result :=
'Operation failed because file already exists.';
TWCC_FILENOTFOUND : Result := 'File not found.';
TWCC_LOWMEMORY : Result :=
'Not enough memory to complete the operation.';
TWCC_MAXCONNECTIONS : Result :=
'Data Source is connected to maximum supported number of ' +
CrLf + 'applications.';
TWCC_NODS : Result :=
'Data Source Manager was unable to find the specified Data ' +
'Source.';
TWCC_NOTEMPTY : Result :=
'Operation failed because directory is not empty.';
TWCC_OPERATIONERROR : Result :=
'Data Source or Data Source Manager reported an error to the' +
CrLf + 'user and handled the error. No application action ' +
'required.';
TWCC_SEQERROR : Result :=
'Illegal operation for current Data Source Manager' + CrLf +
'and Data Source state.';
TWCC_SUCCESS : Result := 'Operation was succesful.';
else
Result := Format('Unknown condition %.04x',[ConditionCode]);
End;
End;
///////////////////////////////////////////////////////////////////////
// RaiseLastDSMCondition (idea: like RaiseLastWin32Error) //
// Tries to get the status from the DSM and raises an exception //
// with it. //
///////////////////////////////////////////////////////////////////////
Procedure TTWAIN.RaiseLastDataSourceManagerCondition(module : String);
Var
status : TW_STATUS;
Begin
Assert(@DSM_Entry nil);
If DSM_Entry(@appId,nil,DG_CONTROL,DAT_STATUS,MSG_GET,@status)
TWRC_SUCCESS then
Raise ETwainError.Create(ERR_STATUS)
else
Raise ETwainError.CreateFmt(ERR_DSM,[module,
Condition2String(status.ConditionCode)]);
End;
///////////////////////////////////////////////////////////////////////
// RaiseLastDSCondition //
// same again, but for the actual DS //
// (should be a method of DS) //
///////////////////////////////////////////////////////////////////////
Procedure TTWAIN.RaiseLastDataSourceCondition(module : String);
Var
status : TW_STATUS;
Begin
Assert(@DSM_Entry nil);
If DSM_Entry(@appId,@dsID,DG_CONTROL,DAT_STATUS,MSG_GET,@status)
TWRC_SUCCESS then
Raise ETwainError.Create(ERR_STATUS)
else
Raise ETwainError.CreateFmt(ERR_DSM,[module,
Condition2String(status.ConditionCode)]);
End;
///////////////////////////////////////////////////////////////////////
// TwainCheckDSM (idea: like Win32Check or GDICheck in Graphics.pas) //
///////////////////////////////////////////////////////////////////////
Procedure TTWAIN.TwainCheckDataSourceManager(res : TW_UINT16;
module : String);
Begin
If res TWRC_SUCCESS then
Begin
If res = TWRC_FAILURE then
RaiseLastDataSourceManagerCondition(module)
else
Raise ETwainError.CreateFmt(ERR_UNKNOWN,[module,res]);
End;
End;
///////////////////////////////////////////////////////////////////////
// TwainCheckDS //
// same again, but for the actual DS //
// (should be a method of DS) //
///////////////////////////////////////////////////////////////////////
Procedure TTWAIN.TwainCheckDataSource(res : TW_UINT16;
module : string);
Begin
If res TWRC_SUCCESS then
Begin
If res = TWRC_FAILURE then
RaiseLastDataSourceCondition(module)
else
Raise ETwainError.CreateFmt(ERR_UNKNOWN,[module,res]);
End;
End;
///////////////////////////////////////////////////////////////////////
// CallDSMEntry: //
// Short form for DSM Calls: appId is not needed as parameter //
///////////////////////////////////////////////////////////////////////
Function TTWAIN.CallDataSourceManager(pOrigin : pTW_IDENTITY;
DG : TW_UINT32;
DAT : TW_UINT16;
MSG : TW_UINT16;
pData : TW_MEMREF) : TW_UINT16;
Begin
Assert(@DSM_Entry nil);
Result := DSM_Entry(@appID,
pOrigin,
DG,
DAT,
MSG,
pData);
If (Result TWRC_SUCCESS) and (DAT DAT_EVENT) then
Begin
End;
End;
///////////////////////////////////////////////////////////////////////
// Short form for (actual) DS Calls. appId and dsID are not needed //
// (this should be a DS class method) //
///////////////////////////////////////////////////////////////////////
Function TTWAIN.CallDataSource(DG : TW_UINT32;
DAT : TW_UINT16;
MSG : TW_UINT16;
pData : TW_MEMREF) : TW_UINT16;
Begin
Assert(@DSM_Entry nil);
Result := DSM_Entry(@appID,
@dsID,
DG,
DAT,
MSG,
pData);
End;
///////////////////////////////////////////////////////////////////////
// A lot of the following code is a conversion from the //
// twain example program (and some comments are copied, too) //
// (The error handling is done differently) //
// Most functions should be moved to a DSM or DS class //
///////////////////////////////////////////////////////////////////////
Procedure TTWAIN.OpenDataSourceManager;
Begin
If not bDataSourceManagerOpen then
Begin
Assert(appID.ID 0);
If not fLoadTwain then
Raise ETwainError.Create(ERR_TWAIN_NOT_LOADED);
// appID.Id := fhWnd;
// appID.Version.MajorNum := 1;
// appID.Version.MinorNum := 0;
// appID.Version.Language := TWLG_USA;
// appID.Version.Country := TWCY_USA;
// appID.Version.Info := 'Twain Component';
appID.ProtocolMajor := 1; // TWON_PROTOCOLMAJOR;
appID.ProtocolMinor := 7; // TWON_PROTOCOLMINOR;
appID.SupportedGroups := DG_IMAGE or DG_CONTROL;
// appID.Productname := 'HP ScanJet 5p';
// appId.ProductFamily := 'ScanJet';
// appId.Manufacturer := 'Hewlett-Packard';
TwainCheckDataSourceManager(CallDataSourceManager(nil,
DG_CONTROL,
DAT_PARENT,
MSG_OPENDSM,
@fhWnd),
'OpenDataSourceManager');
bDataSourceManagerOpen := True;
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.CloseDataSourceManager;
Begin
If bDataSourceOpen then
Raise ETwainError.Create(ERR_DSM_OPEN);
If bDataSourceManagerOpen then
Begin
// This call performs one important function:
// - tells the SM which application, appID.id, is requesting SM to
// close
// - be sure to test return code, failure indicates SM did not
// close !!
TwainCheckDataSourceManager(CallDataSourceManager(nil,
DG_CONTROL,
DAT_PARENT,
MSG_CLOSEDSM,
@fhWnd),
'CloseDataSourceManager');
bDataSourceManagerOpen := False;
End;
fUnLoadTwain; // Loose the DLL
If sDefaultSource '' then
RestoreDefaultSourceEntry;
End;
//---------------------------------------------------------------------
Function TTWAIN.IsDataSourceManagerOpen : Boolean;
Begin
Result := bDataSourceManagerOpen;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.OpenDataSource;
Begin
Assert(bDataSourceManagerOpen,'Data Source Manager must be open');
If not bDataSourceOpen then
Begin
TwainCheckDataSourceManager(CallDataSourceManager(nil,
DG_CONTROL,
DAT_IDENTITY,
MSG_OPENDS,
@dsID),
'OpenDataSource');
bDataSourceOpen := True;
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.CloseDataSource;
Begin
Assert(bDataSourceManagerOpen,'Data Source Manager must be open');
If bDataSourceOpen then
Begin
TwainCheckDataSourceManager(CallDataSourceManager(nil,
DG_CONTROL,
DAT_IDENTITY,
MSG_CLOSEDS,
@dsID),
'CloseDataSource');
bDataSourceOpen := False;
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.EnableDataSource;
Var
twUI : TW_USERINTERFACE;
Begin
Assert(bDataSourceOpen,'Data Source must be open');
If not bDataSourceEnabled then
Begin
FillChar(twUI,SizeOf(twUI),#0);
twUI.hParent := fhWnd;
twUI.ShowUI := fShowUI;
twUI.ModalUI := True;
TwainCheckDataSourceManager(CallDataSourceManager(@dsID,
DG_CONTROL,
DAT_USERINTERFACE,
MSG_ENABLEDS,
@twUI),
'EnableDataSource');
bDataSourceEnabled := True;
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.DisableDataSource;
Var
twUI : TW_USERINTERFACE;
Begin
Assert(bDataSourceOpen,'Data Source must be open');
If bDataSourceEnabled then
Begin
twUI.hParent := fhWnd;
twUI.ShowUI := TW_BOOL(TWON_DONTCARE8); (*!!!!*)
TwainCheckDataSourceManager(CallDataSourceManager(@dsID,
DG_CONTROL,
DAT_USERINTERFACE,
MSG_DISABLEDS,
@twUI),
'DisableDataSource');
bDataSourceEnabled := False;
End;
End;
//---------------------------------------------------------------------
Function TTWAIN.IsDataSourceOpen : Boolean;
Begin
Result := bDataSourceOpen;
End;
//---------------------------------------------------------------------
Function TTWAIN.IsDataSourceEnabled : Boolean;
Begin
Result := bDataSourceEnabled;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.SelectDataSource;
Var
NewDSIdentity : TW_IDENTITY;
twRC : TW_UINT16;
Begin
SaveDefaultSourceEntry;
Assert(not bDataSourceOpen,'Data Source must be closed');
TwainCheckDataSourceManager(CallDataSourceManager(nil,
DG_CONTROL,
DAT_IDENTITY,
MSG_GETDEFAULT,
@NewDSIdentity),
'SelectDataSource1');
twRC := CallDataSourceManager(nil,
DG_CONTROL,
DAT_IDENTITY,
MSG_USERSELECT,
@NewDSIdentity);
Case twRC of
TWRC_SUCCESS : dsID := NewDSIdentity; // log in new Source
TWRC_CANCEL : ; // keep the current Source
else
TwainCheckDataSourceManager(twRC,'SelectDataSource2');
End;
End;
(*******************************************************************
Functions from CAPTEST.C
*******************************************************************)
Procedure TTWAIN.XferMech;
Var
cap : TW_CAPABILITY;
pVal : pTW_ONEVALUE;
Begin
fXfer := xfNative; // Override
cap.Cap := ICAP_XFERMECH;
cap.ConType := TWON_ONEVALUE;
cap.hContainer := GlobalAlloc(GHND,SizeOf(TW_ONEVALUE));
Assert(cap.hContainer 0);
Try
pval := pTW_ONEVALUE(GlobalLock(cap.hContainer));
Assert(pval nil);
Try
pval.ItemType := TWTY_UINT16;
Case fXfer of
xfMemory : pval.Item := TWSX_MEMORY;
xfFile : pval.Item := TWSX_FILE;
xfNative : pval.Item := TWSX_NATIVE;
End;
Finally
GlobalUnlock(cap.hContainer);
End;
TwainCheckDataSource(CallDataSource(DG_CONTROL,
DAT_CAPABILITY,
MSG_SET,
@cap),
'XferMech');
Finally
GlobalFree(cap.hContainer);
End;
End;
///////////////////////////////////////////////////////////////////////
Function TTWAIN.ProcessSourceMessage(var Msg : TMsg): Boolean;
Var
twRC : TW_UINT16;
event : TW_EVENT;
pending : TW_PENDINGXFERS;
Begin
Result := False;
If bDataSourceManagerOpen and bDataSourceOpen then
Begin
event.pEvent := @Msg;
event.TWMessage := 0;
twRC := CallDataSource(DG_CONTROL,
DAT_EVENT,
MSG_PROCESSEVENT,
@event);
Case event.TWMessage of
MSG_XFERREADY : Begin
Case fXfer of
xfNative : fNativeXfer;
xfMemory : fMemoryXfer;
xfFile : fFileXfer;
End;
TwainCheckDataSource(CallDataSource(DG_CONTROL,
DAT_PENDINGXFERS,
MSG_ENDXFER,
@pending),
'Check for Pending Transfers');
If pending.Count 0 then
TwainCheckDataSource(CallDataSource(
DG_CONTROL,
DAT_PENDINGXFERS,
MSG_RESET,
@pending),
'Abort Pending Transfers');
DisableDataSource;
CloseDataSource;
ScanReady; // Event
End;
MSG_CLOSEDSOK,
MSG_CLOSEDSREQ : Begin
DisableDataSource;
CloseDataSource;
ScanReady // Event
End;
End;
Result := not (twRC = TWRC_NOTDSEVENT);
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.Acquire(aBmp : TBitmap);
Begin
// fOldOnMessageHandler := Application.OnMessage; // Save old pointer
// Application.OnMessage := fNewOnMessageHandler; // Set to our handler
// OpenDataSourceManager; // Open DS
fBitmap := aBmp;
OpenDataSourceManager;
OpenDataSource;
XferMech; // Must be written for xfMemory and xfFile
EnableDataSource;
End;
//---------------------------------------------------------------------
// Must be written!
Function TTWAIN.fMemoryXfer : Boolean;
Var
twRC : TW_UINT16;
Begin
Result := False;
twRC := CallDataSource(DG_IMAGE,
DAT_IMAGEMEMXFER,
MSG_GET,
nil);
Case twRC of
TWRC_XFERDONE : Result := True;
TWRC_CANCEL : ;
TWRC_FAILURE : ;
End;
End;
//---------------------------------------------------------------------
// Must be written!
Function TTWAIN.fFileXfer : Boolean;
Var
twRC : TW_UINT16;
Begin
// Not yet implemented!
Result := False;
twRC := CallDataSource(DG_IMAGE,
DAT_IMAGEFILEXFER,
MSG_GET,
nil);
Case twRC of
TWRC_XFERDONE : Result := True;
TWRC_CANCEL : ;
TWRC_FAILURE : ;
End;
End;
//---------------------------------------------------------------------
Function TTWAIN.fNativeXfer : Boolean;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Function DibNumColors(dib : Pointer) : Integer;
Var
lpbi : PBITMAPINFOHEADER;
lpbc : PBITMAPCOREHEADER;
bits : Integer;
Begin
lpbi := dib;
lpbc := dib;
If lpbi.biSize SizeOf(BITMAPCOREHEADER) then
Begin
If lpbi.biClrUsed 0 then
Begin
Result := lpbi.biClrUsed;
Exit;
End;
bits := lpbi.biBitCount;
End
else
bits := lpbc.bcBitCount;
Case bits of
1 : Result := 2;
4 : Result := 16; // 4?
8 : Result := 256; // 8?
else
Result := 0;
End;
End;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Var
twRC : TW_UINT16;
hDIB : TW_UINT32;
hBmp : HBITMAP;
lpDib : ^TBITMAPINFO;
lpBits : PChar;
ColorTableSize : Integer;
dc : HDC;
Begin
Result := False;
twRC := CallDataSource(DG_IMAGE,DAT_IMAGENATIVEXFER,MSG_GET,@hDIB);
Case twRC of
TWRC_XFERDONE : Begin
lpDib := GlobalLock(hDIB);
Try
ColorTableSize := (DibNumColors(lpDib) *
SizeOf(RGBQUAD));
lpBits := PChar(lpDib);
Inc(lpBits,lpDib.bmiHeader.biSize);
Inc(lpBits,ColorTableSize);
dc := GetDC(0);
Try
hBMP := CreateDIBitmap(dc,lpdib.bmiHeader,
CBM_INIT,lpBits,lpDib^,DIB_RGB_COLORS);
fBitmap.Handle := hBMP;
Result := True;
Finally
ReleaseDC(0,dc);
End;
Finally
GlobalUnlock(hDIB);
GlobalFree(hDIB);
End;
End;
TWRC_CANCEL : ;
TWRC_FAILURE : RaiseLastDataSourceManagerCondition('Native Transfer');
End;
End;
//---------------------------------------------------------------------
Procedure TTWAIN.fNewOnMessageHandler(Var Msg : TMsg;
Var Handled : Boolean);
Begin
Handled := ProcessSourceMessage(Msg);
If Assigned(fOldOnMessageHandler) then
fOldOnMessageHandler(Msg,Handled)
End;
//---------------------------------------------------------------------
Procedure Register;
Begin
RegisterComponents('Samples',[TTWAIN]);
End;
//---------------------------------------------------------------------
End.
//---------------------------------------------------------------------