/3rdparty/DelphiTwain/DelphiTwain.pas
https://bitbucket.org/reiniero/papertiger · Pascal · 2927 lines · 1889 code · 288 blank · 750 comment · 184 complexity · 571be27bc8bfc481a395d7a5b2dda35e MD5 · raw file
Large files are truncated click here to view the full file
- {DELPHI IMPLEMENTATION OF TWAIN INTERFACE}
- {Initially created by Gustavo Daud December 2003}
-
- {This is my newest contribution for Delphi comunity, a powerfull}
- {implementation of latest Twain features. As you know, twain is }
- {the most common library to acquire images from most acquisition}
- {devices such as Scanners and Web-Cameras.}
-
- {Twain library is a bit different from other libraries, because}
- {most of the hard work can be done by a a single method. Also it}
- {automatically changes in the application message loop, which is}
- {not a simple task, at least in delphi VCL.}
-
- {It is not 100% sure to to Twain not to be installed in Windows,}
- {as it ships with Windows and later and with most of the }
- {acquisition device drivers (automatically with their installation)}
- {This library dynamically calls the library, avoiding the application}
- {hang when it is not present.}
-
- {Also, as in most of my other components, I included a trigger}
- {to allow the component to work without the heavy delphi VCL}
- {for small final executables. To enable, edit DelphiTwain.inc}
-
-
- {
- CHANGE LOG:
-
- 2014/04/29 - Fix for unloading library cancelling acquire window on Lazarus
- Typo fixes in language constants; cosmetic fixes.
-
- 2013/12/18 - FireMonkey support, color bug fix.
-
- 2013/08/18 - New method OnTransferComplete: fired when all documents are
- scanned or the scan is canceled. Thanks to Andrei Galatyn.
-
- 2013/07/26 - Color problems solved (thanks to Marco & Christian).
- TWAIN drivers did not respond - now both WIA and TWAIN can be used.
-
- 2012/11/01 - Ondrej Pokorny: small changes for Lazarus and 64bit compiler
-
- 2009/11/10 - Some changes to make it work in Delphi 2009, and above
-
- 2004/01/20 - Some updates and bug fixes by Nemeth Peter
- }
-
- unit DelphiTwain;
-
- {$I DelphiTwain.inc}
-
- interface
-
- {$IFDEF FPC}
- {$MODE delphi}
- {$ENDIF}
-
- {Used units}
- uses
- SysUtils, Windows, Messages,
- {$IFDEF FPC}Classes, {$ENDIF}
- Twain, DelphiTwainUtils;
-
- const
- {Name of the Twain library for 32 bits enviroment}
- {$IFDEF WIN64}
- TWAINLIBRARY: String = 'TWAINDSM.DLL';
- {$ELSE}
- TWAINLIBRARY: String = 'TWAIN_32.DLL';
- {$ENDIF}
-
- const
- {Error codes}
- ERROR_BASE = 300;
- ERROR_INT16: TW_INT16 = HIGH(TW_INT16);
-
- type
- {From twain}
- TW_STR255 = Twain.TW_STR255;
-
- {Forward declaration}
- TCustomDelphiTwain = class;
-
- {Component kinds}
- TTwainComponent = TObject;
-
- {File formats}
- TTwainFormat = (tfTIFF, tfPict, tfBMP, tfXBM, tfJPEG, tfFPX,
- tfTIFFMulti, tfPNG, tfSPIFF, tfEXIF, tfUnknown);
- {Twain units}
- TTwainUnit = (tuInches, tuCentimeters, tuPicas, tuPoints, tuTwips,
- tuPixels, tuUnknown);
- TTwainUnitSet = set of TTwainUnit;
- {Twain pixel flavor}
- TTwainPixelFlavor = (tpfChocolate, tpfVanilla, tpfUnknown);
- TTwainPixelFlavorSet = set of TTwainPixelFlavor;
- {Orientation}
- TTwainOrientation = (torPortrait, torLandscape);
- {Paper size}
- TTwainPaperSize = (tpsA4, tpsA5, tpsB4, tpsB5, tpsB6, tpsUSLetter, tpsUSLegal);
- {Twain pixel type}
- TTwainPixelType = (tbdBw, tbdGray, tbdRgb, tbdPalette, tbdCmy, tbdCmyk,
- tbdYuv, tbdYuvk, tbdCieXYZ, tbdUnknown, tbdUnknown1, tbdUnknown2, tbdBgr);
- TTwainPixelTypeSet = set of TTwainPixelType;
- {Twain bit depth}
- TTwainBitDepth = array of TW_UINT16;
- {Twain resolutions}
- TTwainResolution = array of Extended;
-
- {Events}
- TOnTwainError = procedure(Sender: TObject; const Index: Integer; ErrorCode,
- Additional: Integer) of object;
- TOnSourceNotify = procedure(Sender: TObject; const Index: Integer) of object;
- TOnTransferComplete = procedure(Sender: TObject; const Index: Integer; const Canceled: Boolean) of object;
- TOnSourceFileTransfer = procedure(Sender: TObject; const Index: Integer;
- Filename: TW_STR255; Format: TTwainFormat; var Cancel: Boolean) of object;
-
- {Available twain languages}
- TTwainLanguage = ({-1}tlUserLocale=-1, tlDanish, tlDutch, tlInternationalEnglish,
- tlFrenchCanadian, tlFinnish, tlFrench, tlGerman, tlIcelandic, tlItalian,
- tlNorwegian, tlPortuguese, tlSpanish, tlSwedish, tlUsEnglish,
- tlAfrikaans, tlAlbania, tlArabic, tlArabicAlgeria, tlArabicBahrain, {18}
- tlArabicEgypt, tlArabicIraq, tlArabJordan, tlArabicKuwait,
- tlArabicLebanon, tlArabicLibya, tlArabicMorocco, tlArabicOman,
- tlArabicQatar, tlArabicSaudiarabia, tlArabicSyria, tlArabicTunisia,
- tlArabicUae, tlArabicYemen, tlBasque, tlByelorussian, tlBulgarian, {35}
- tlCatalan, tlChinese, tlChineseHongkong, tlChinesePeoplesRepublic,
- tlChineseSingapore, tlChineseSimplified, tlChineseTwain, {42}
- tlChineseTraditional, tlCroatia, tlCzech, tlDutchBelgian, {46}
- tlEnglishAustralian, tlEnglishCanadian, tlEnglishIreland,
- tlEnglishNewZealand, tlEnglishSouthAfrica, tlEnglishUk, {52}
- tlEstonian, tlFaeroese, tlFarsi, tlFrenchBelgian, tlFrenchLuxembourg, {57}
- tlFrenchSwiss, tlGermanAustrian, tlGermanLuxembourg, tlGermanLiechtenstein,
- tlGermanSwiss, tlGreek, tlHebrew, tlHungarian, tlIndonesian, {66}
- tlItalianSwiss, tlJapanese, tlKorean, tlKoreanJohab, tlLatvian, {71}
- tlLithuanian, tlNorewgianBokmal, tlNorwegianNynorsk, tlPolish, {75}
- tlPortugueseBrazil, tlRomanian, tlRussian, tlSerbianLatin,
- tlSlovak, tlSlovenian, tlSpanishMexican, tlSpanishModern, tlThai,
- tlTurkish, tlUkranian, tlAssamese, tlBengali, tlBihari, tlBodo,
- tlDogri, tlGujarati {92}, tlHarayanvi, tlHindi, tlKannada, tlKashmiri,
- tlMalayalam, tlMarathi, tlMarwari, tlMeghalayan, tlMizo, tlNaga {102},
- tlOrissi, tlPunjabi, tlPushtu, tlSerbianCyrillic, tlSikkimi,
- tlSwedishFinland, tlTamil, tlTelugu, tlTripuri, tlUrdu, tlVietnamese);
- {Twain supported groups}
- TTwainGroups = set of (tgControl, tgImage, tgAudio);
-
- {Transfer mode for twain}
- TTwainTransferMode = (ttmFile, ttmNative, ttmMemory);
-
- {rect for LAYOUT; npeter 2004.01.12.}
- TTwainRect =
- record
- Left: double;
- Top: double;
- Right: double;
- Bottom: double;
- end;
-
- {Object to handle TW_IDENTITY}
- TTwainIdentity = class(TObject)
- private
- {Sets application language property}
- procedure SetLanguage(const Value: TTwainLanguage);
- {Sets text values}
- procedure SetString(const Index: Integer; const Value: String);
- {Sets avaliable groups}
- procedure SetGroups(const Value: TTwainGroups);
- protected
- {Structure which should be filled}
- Structure: TW_IDENTITY;
- {Returns application language property}
- function GetLanguage(): TTwainLanguage;
- {Returns text values}
- function GetString(const Index: integer): String;
- {Returns avaliable groups}
- function GetGroups(): TTwainGroups;
- public
- {Object being created}
- constructor Create;
- {Copy properties from another TTwainIdentity}
- procedure Assign(Source: TObject);
- public
- {Application major version}
- property MajorVersion: TW_UINT16 read Structure.Version.MajorNum
- write Structure.Version.MajorNum;
- {Application minor version}
- property MinorVersion: TW_UINT16 read Structure.Version.MinorNum
- write Structure.Version.MinorNum;
- {Language}
- property Language: TTwainLanguage read GetLanguage write SetLanguage;
- {Country code}
- property CountryCode: word read Structure.Version.Country write
- Structure.Version.Country;
- {Supported groups}
- property Groups: TTwainGroups read GetGroups write SetGroups;
- {Text values}
- property VersionInfo: String index 0 read GetString write
- SetString;
- {Scanner manufacturer}
- property Manufacturer: String index 1 read GetString write
- SetString;
- {Scanner product family}
- property ProductFamily: String index 2 read GetString write
- SetString;
- {Scanner product name}
- property ProductName: String index 3 read GetString write
- SetString;
- end;
-
- {Return set for capability retrieving/setting}
- TCapabilityRet = (crSuccess, crUnsupported, crBadOperation, crDependencyError,
- crLowMemory, crInvalidState, crInvalidContainer);
- {Kinds of capability retrieving}
- TRetrieveCap = (rcGet, rcGetCurrent, rcGetDefault, rcReset);
- {Capability list type}
- TGetCapabilityList = array of string;
- TSetCapabilityList = array of pointer;
-
- {Source object}
- TTwainSource = class(TTwainIdentity)
- private
- {Holds the item index}
- fIndex: Integer;
- {Transfer mode for the images}
- fTransferMode: TTwainTransferMode;
- {Stores if user interface should be shown}
- fShowUI: Boolean;
- {Stores if the source window is modal}
- fModal: Boolean;
- {Stores if the source is enabled}
- fEnabled: Boolean;
- {Stores if the source is loaded}
- fLoaded: Boolean;
- {Stores the owner}
- fOwner: TCustomDelphiTwain;
- {Used with property SourceManagerLoaded to test if the source manager}
- {is loaded or not.}
- function GetSourceManagerLoaded(): Boolean;
- {Returns a pointer to the application}
- function GetAppInfo(): pTW_IDENTITY;
- {Sets if the source is loaded}
- procedure SetLoaded(const Value: Boolean);
- {Sets if the source is enabled}
- procedure SetEnabled(const Value: Boolean);
- {Returns a pointer to the source pTW_IDENTITY}
- function GetStructure: pTW_IDENTITY;
- {Returns a resolution}
- function GetResolution(Capability: TW_UINT16; var Return: Extended;
- var Values: TTwainResolution; Mode: TRetrieveCap): TCapabilityRet;
- protected
- {Reads a native image}
- procedure ReadNative(Handle: TW_UINT32; var Cancel: Boolean);
- {Reads the file image}
- procedure ReadFile(Name: TW_STR255; Format: TW_UINT16; var Cancel: Boolean);
- {Call event for memory image}
- procedure ReadMemory(Image: HBitmap; var Cancel: Boolean);
- protected
- {Prepare image memory transference}
- function PrepareMemXfer(var BitmapHandle: HBitmap;
- var PixelType: TW_INT16): TW_UINT16;
- {Transfer image memory}
- function TransferImageMemory(var ImageHandle: HBitmap;
- {%H-}PixelType: TW_INT16): TW_UINT16;
- {Returns a pointer to the TW_IDENTITY for the application}
- property AppInfo: pTW_IDENTITY read GetAppInfo;
- {Method to transfer the images}
- procedure TransferImages();
- {Returns if the source manager is loaded}
- property SourceManagerLoaded: Boolean read GetSourceManagerLoaded;
- {Source configuration methods}
- {************************}
- protected
- {Gets an item and returns it in a string}
- procedure GetItem(var Return: String; ItemType: TW_UINT16; Data: Pointer);
- {Converts from a result to a TCapabilityRec}
- function ResultToCapabilityRec(const Value: TW_UINT16): TCapabilityRet;
- {Sets a capability}
- function SetCapabilityRec(const Capability, ConType: TW_UINT16;
- Data: HGLOBAL): TCapabilityRet;
- public
- {Message received in the event loop}
- function ProcessMessage(const Msg: TMsg): Boolean;
- {Returns a capability strucutre}
- function GetCapabilityRec(const Capability: TW_UINT16;
- var Handle: HGLOBAL; Mode: TRetrieveCap;
- var Container: TW_UINT16): TCapabilityRet;
- {************************}
- {Returns an one value capability}
- function GetOneValue(Capability: TW_UINT16;
- var ItemType: TW_UINT16; var Value: string;
- Mode: TRetrieveCap{$IFDEF DEFAULTPARAM}=rcGet{$ENDIF};
- MemHandle: HGLOBAL{$IFDEF DEFAULTPARAM}=0{$ENDIF}): TCapabilityRet;
- {Returns an range capability}
- function GetRangeValue(Capability: TW_UINT16; var ItemType: TW_UINT16;
- var Min, Max, Step, Default, Current: String;
- MemHandle: HGLOBAL{$IFDEF DEFAULTPARAM}=0{$ENDIF}): TCapabilityRet;
- {Returns an enumeration capability}
- function GetEnumerationValue(Capability: TW_UINT16;
- var ItemType: TW_UINT16; var List: TGetCapabilityList; var Current,
- Default: Integer; Mode: TRetrieveCap{$IFDEF DEFAULTPARAM}=rcGet{$ENDIF};
- MemHandle: HGLOBAL{$IFDEF DEFAULTPARAM}=0{$ENDIF}): TCapabilityRet;
- {Returns an array capability}
- function GetArrayValue(Capability: TW_UINT16; var ItemType: TW_UINT16;
- var List: TGetCapabilityList; MemHandle: HGLOBAL
- {$IFDEF DEFAULTPARAM}=0{$ENDIF}): TCapabilityRet;
- {************************}
- {Sets an one value capability}
- function SetOneValue(Capability: TW_UINT16; ItemType: TW_UINT16;
- Value: Pointer): TCapabilityRet;
- {Sets a range capability}
- function SetRangeValue(Capability, ItemType: TW_UINT16; Min, Max, Step,
- Current: TW_UINT32): TCapabilityRet;
- {Sets an enumeration capability}
- function SetEnumerationValue(Capability, ItemType: TW_UINT16;
- CurrentIndex: TW_UINT32; List: TSetCapabilityList): TCapabilityRet;
- {Sets an array capability}
- function SetArrayValue(Capability, ItemType: TW_UINT16;
- List: TSetCapabilityList): TCapabilityRet;
- public
- {Setup file transfer}
- function SetupFileTransfer(Filename: String; Format: TTwainFormat): Boolean;
- protected
- {Used with property PendingXfers}
- function GetPendingXfers(): TW_INT16;
- public
- {Set source transfer mode}
- //function ChangeTransferMode(NewMode: TTwainTransferMode): TCapabilityRet;
- {Transfer mode for transfering images from the source to}
- {the component and finally to the application}
- property TransferMode: TTwainTransferMode read fTransferMode write fTransferMode;
- public
- {Returns return status information}
- function GetReturnStatus(): TW_UINT16;
- {Capability setting}
- {Set the number of images that the application wants to receive}
- function SetCapXferCount(Value: SmallInt): TCapabilityRet;
- {Returns the number of images that the source will return}
- function GetCapXferCount(var Return: SmallInt;
- Mode: TRetrieveCap{$IFDEF DEFAULTPARAM}=rcGet{$ENDIF}): TCapabilityRet;
- {Retrieve the unit measure for all quantities}
- function GetICapUnits(var Return: TTwainUnit;
- var Supported: TTwainUnitSet; Mode: TRetrieveCap
- {$IFDEF DEFAULTPARAM}=rcGet{$ENDIF}): TCapabilityRet;
- {Set the unit measure}
- function SetICapUnits(Value: TTwainUnit): TCapabilityRet;
- {npeter 2004.01.12 begin}
- function SetImagelayoutFrame(const fLeft,fTop,fRight,
- fBottom: double): TCapabilityRet;
- function SetIndicators(Value: boolean): TCapabilityRet;
- {npeter 2004.01.12 end}
- {Retrieve the pixel flavor values}
- function GetIPixelFlavor(var Return: TTwainPixelFlavor;
- var Supported: TTwainPixelFlavorSet; Mode: TRetrieveCap
- {$IFDEF DEFAULTPARAM}=rcGet{$ENDIF}): TCapabilityRet;
- {Set the pixel flavor values}
- function SetIPixelFlavor(Value: TTwainPixelFlavor): TCapabilityRet;
- {Set orientation}
- function SetOrientation(Value: TTwainOrientation): TCapabilityRet;
- {Set paper size}
- function SetPaperSize(Value: TTwainPaperSize): TCapabilityRet;
- {Returns bitdepth values}
- function GetIBitDepth(var Return: Word;
- var Supported: TTwainBitDepth; Mode: TRetrieveCap
- {$IFDEF DEFAULTPARAM}=rcGet{$ENDIF}): TCapabilityRet;
- {Set current bitdepth value}
- function SetIBitDepth(Value: Word): TCapabilityRet;
- {Returns pixel type values}
- function GetIPixelType(var Return: TTwainPixelType;
- var Supported: TTwainPixelTypeSet; Mode: TRetrieveCap
- {$IFDEF DEFAULTPARAM}=rcGet{$ENDIF}): TCapabilityRet;
- {Set the pixel type value}
- function SetIPixelType(Value: TTwainPixelType): TCapabilityRet;
- {Returns X and Y resolutions}
- function GetIXResolution(var Return: Extended; var Values: TTwainResolution;
- Mode: TRetrieveCap {$IFDEF DEFAULTPARAM}=rcGet{$ENDIF}): TCapabilityRet;
- function GetIYResolution(var Return: Extended; var Values: TTwainResolution;
- Mode: TRetrieveCap {$IFDEF DEFAULTPARAM}=rcGet{$ENDIF}): TCapabilityRet;
- {Sets X and X resolutions}
- function SetIXResolution(Value: Extended): TCapabilityRet;
- function SetIYResolution(Value: Extended): TCapabilityRet;
- {Returns physical width and height}
- function GetIPhysicalWidth(var Return: Extended; Mode: TRetrieveCap
- {$IFDEF DEFAULTPARAM}=rcGet{$ENDIF}): TCapabilityRet;
- function GetIPhysicalHeight(var Return: Extended; Mode: TRetrieveCap
- {$IFDEF DEFAULTPARAM}=rcGet{$ENDIF}): TCapabilityRet;
- {Returns if user interface is controllable}
- function GetUIControllable(var Return: Boolean): TCapabilityRet;
- {Returns feeder is loaded or not}
- function GetFeederLoaded(var Return: Boolean): TCapabilityRet;
- {Returns/sets if feeder is enabled}
- function GetFeederEnabled(var Return: Boolean): TCapabilityRet;
- function SetFeederEnabled(Value: WordBool): TCapabilityRet;
- {Returns/sets if auto feed is enabled}
- function GetAutofeed(var Return: Boolean): TCapabilityRet;
- function SetAutoFeed(Value: WordBool): TCapabilityRet;
- {Returns number of pending transfer}
- property PendingXfers: TW_INT16 read GetPendingXfers;
- public
- {Enables the source}
- function EnableSource(ShowUI, Modal: Boolean): Boolean;
- {Disables the source}
- function DisableSource: Boolean;
- {Loads the source}
- function LoadSource(): Boolean;
- {Unloads the source}
- function UnloadSource(): Boolean;
- {Returns a pointer to the source identity}
- property SourceIdentity: pTW_IDENTITY read GetStructure;
- {Returns/sets if the source is enabled}
- property Enabled: Boolean read fEnabled write SetEnabled;
- {Returns/sets if this source is loaded}
- property Loaded: Boolean read fLoaded write SetLoaded;
- {Object being created/destroyed}
- constructor Create(AOwner: TCustomDelphiTwain);
- destructor Destroy; override;
- {Returns owner}
- property Owner: TCustomDelphiTwain read fOwner;
- {Source window is modal}
- property Modal: Boolean read fModal write fModal;
- {Sets if user interface should be shown}
- property ShowUI: Boolean read fShowUI write fShowUI;
- {Returns the item index}
- property Index: Integer read fIndex;
- {Convert properties from write/read to read only}
- {(read description on TTwainIdentity source)}
- property MajorVersion: TW_UINT16 read Structure.Version.MajorNum;
- property MinorVersion: TW_UINT16 read Structure.Version.MinorNum;
- property Language: TTwainLanguage read GetLanguage;
- property CountryCode: word read Structure.Version.Country;
- property Groups: TTwainGroups read GetGroups;
- property VersionInfo: String index 0 read GetString;
- property Manufacturer: String index 1 read GetString;
- property ProductFamily: String index 2 read GetString;
- property ProductName: String index 3 read GetString;
- end;
-
- {Component part}
- TCustomDelphiTwain = class(TTwainComponent)
- private
- {Should contain the number of Twain sources loaded}
- fSourcesLoaded: Integer;
- private
- {Event pointer holders}
- fOnSourceDisable: TOnSourceNotify;
- fOnAcquireCancel: TOnSourceNotify;
- fOnSourceSetupFileXfer: TOnSourceNotify;
- fOnSourceFileTransfer: TOnSourceFileTransfer;
- fOnAcquireError: TOnTwainError;
- fOnTransferComplete: TOnTransferComplete;
- private
- fSelectedSourceIndex: Integer;
- {Temp variable to allow SourceCount to be displayed in delphi}
- {property editor}
- fDummySourceCount: Integer;
- {Contains list of source devices}
- DeviceList: TPointerList;
- {Contains a pointer to the structure with the application}
- {information}
- AppInfo: pTW_IDENTITY;
- {Holds the object to allow the user to set the application information}
- fInfo: TTwainIdentity;
- {Holds the handle for the virtual window which will receive}
- {twain message notifications}
- {Will hold Twain library handle}
- fHandle: HInst;
- {Holds if the component has enumerated the devices}
- fHasEnumerated: Boolean;
- {Holds twain dll procedure handle}
- fTwainProc: TDSMEntryProc;
- {Holds the transfer mode to be used}
- fTransferMode: TTwainTransferMode;
- {Contains if the library is loaded}
- fLibraryLoaded: Boolean;
- {Contains if the source manager was loaded}
- fSourceManagerLoaded: Boolean;
- {Set to true if the host application does not create any windows}
- fIsConsoleApplication: Boolean;
- {Procedure to load and unload twain library and update property}
- procedure SetLibraryLoaded(const Value: Boolean);
- {Procedure to load or unloaded the twain source manager}
- procedure SetSourceManagerLoaded(const Value: Boolean);
- {Updates the application information object}
- procedure SetInfo(const Value: TTwainIdentity);
- {Returns the number of sources}
- function GetSourceCount(): Integer;
- {Returns a source from the list}
- function GetSource(Index: Integer): TTwainSource;
- {Finds a matching source index}
- function FindSource(Value: pTW_IDENTITY): Integer;
- //Gets selected source
- function GetSelectedSource: TTwainSource;
- //Gets selected source index
- function GetSelectedSourceIndex: Integer;
- //Sets selected source index
- procedure SetSelectedSourceIndex(const Value: Integer);
- //Refresh the VirtualWindow - usually needed when transfer was completed
- procedure RefreshVirtualWindow;
- protected
- fVirtualWindow: THandle;
-
- {Returns the default source}
- function GetDefaultSource: Integer;
-
- procedure DoCreate; virtual;
- procedure DoDestroy; virtual;
- procedure MessageTimer_Enable; virtual; abstract;
- procedure MessageTimer_Disable; virtual; abstract;
- function CustomSelectSource: Integer; virtual; abstract;
- function CustomGetParentWindow: TW_HANDLE; virtual; abstract;
-
- procedure DoTwainAcquire(Sender: TObject; const Index: Integer; Image:
- HBitmap; var Cancel: Boolean); virtual; abstract;
- procedure DoAcquireProgress(Sender: TObject; const Index: Integer;
- const Image: HBitmap; const Current, Total: Integer); virtual; abstract;
- public
- {Clears the list of sources}
- procedure ClearDeviceList();
- public
- {Allows Twain to display a dialog to let the user choose any source}
- {and returns the source index in the list}
- function SelectSource(): Integer;
- {Returns the number of loaded sources}
- property SourcesLoaded: Integer read fSourcesLoaded;
- {Enumerate the avaliable devices after Source Manager is loaded}
- function EnumerateDevices(): Boolean;
- {Object being created}
- constructor Create; virtual;
- {Object being destroyed}
- destructor Destroy; override;
- {Loads twain library and returns if it loaded sucessfully}
- function LoadLibrary(): Boolean;
- {Unloads twain and returns if it unloaded sucessfully}
- function UnloadLibrary(): Boolean;
- {Loads twain source manager}
- function LoadSourceManager(): Boolean;
- {Unloads the source manager}
- function UnloadSourceManager(forced: boolean): Boolean;
- {Returns the application TW_IDENTITY}
- property AppIdentity: pTW_IDENTITY read AppInfo;
- {Returns Twain library handle}
- property Handle: HInst read fHandle;
- {Returns virtual window that receives messages}
- property VirtualWindow: THandle read fVirtualWindow;
- {Returns a pointer to Twain only procedure}
- property TwainProc: TDSMEntryProc read fTwainProc;
- {Holds if the component has enumerated the devices}
- property HasEnumerated: Boolean read fHasEnumerated;
- {Returns a source}
- property Source[Index: Integer]: TTwainSource read GetSource;
- {Set to true if the host application does not create any windows}
- property IsConsoleApplication: Boolean read fIsConsoleApplication write fIsConsoleApplication default False;
- public
- {Events}
- {Source being disabled}
- property OnSourceDisable: TOnSourceNotify read fOnSourceDisable
- write fOnSourceDisable;
- {Acquire cancelled}
- property OnAcquireCancel: TOnSourceNotify read fOnAcquireCancel
- write fOnAcquireCancel;
- {User should set information to prepare for the file transfer}
- property OnSourceSetupFileXfer: TOnSourceNotify read fOnSourceSetupFileXfer
- write fOnSourceSetupFileXfer;
- {File transfered}
- property OnSourceFileTransfer: TOnSourceFileTransfer read
- fOnSourceFileTransfer write fOnSourceFileTransfer;
- {Acquire error}
- property OnAcquireError: TOnTwainError read fOnAcquireError
- write fOnAcquireError;
- {All images transfered}
- property OnTransferComplete: TOnTransferComplete read fOnTransferComplete
- write fOnTransferComplete;
- public
- {Default transfer mode to be used with sources}
- property TransferMode: TTwainTransferMode read fTransferMode
- write fTransferMode;
- {Returns the number of sources, after Library and Source Manager}
- {has being loaded}
- property SourceCount: Integer read GetSourceCount write fDummySourceCount;
- //Selected source in a dialog
- property SelectedSourceIndex: Integer read GetSelectedSourceIndex write SetSelectedSourceIndex;
- //Selected source in a dialog
- property SelectedSource: TTwainSource read GetSelectedSource;
- {User should fill the application information}
- property Info: TTwainIdentity read fInfo write SetInfo;
- {Loads or unload Twain library}
- property LibraryLoaded: Boolean read fLibraryLoaded write SetLibraryLoaded;
- {Loads or unloads the source manager}
- property SourceManagerLoaded: Boolean read fSourceManagerLoaded write
- SetSourceManagerLoaded;
- end;
-
- {Puts a string inside a TW_STR255}
- {$IFDEF UNICODE}
- function StrToStr255(Value: RawByteString): TW_STR255;
- {$ELSE}
- function StrToStr255(Value: String): TW_STR255;
- {$ENDIF}
- {This method returns if Twain is installed in the current machine}
- function IsTwainInstalled(): Boolean;
- {Called by Delphi to register the component}
- {Returns the size of a twain type}
- function TWTypeSize(TypeName: TW_UINT16): Integer;
-
- function MakeMsg(const Handle: THandle; uMsg: UINT; wParam: WPARAM;
- lParam: LPARAM): TMsg;
-
- implementation
-
- {Returns the size of a twain type}
- function TWTypeSize(TypeName: TW_UINT16): Integer;
- begin
- {Test the type to return the size}
- case TypeName of
- TWTY_INT8 : Result := sizeof(TW_INT8);
- TWTY_UINT8 : Result := sizeof(TW_UINT8);
- TWTY_INT16 : Result := sizeof(TW_INT16);
- TWTY_UINT16: Result := sizeof(TW_UINT16);
- TWTY_INT32 : Result := sizeof(TW_INT32);
- TWTY_UINT32: Result := sizeof(TW_UINT32);
- TWTY_FIX32 : Result := sizeof(TW_FIX32);
- TWTY_FRAME : Result := sizeof(TW_FRAME);
- TWTY_STR32 : Result := sizeof(TW_STR32);
- TWTY_STR64 : Result := sizeof(TW_STR64);
- TWTY_STR128: Result := sizeof(TW_STR128);
- TWTY_STR255: Result := sizeof(TW_STR255);
- //npeter: the following types were not implemented
- //especially the bool caused problems
- TWTY_BOOL: Result := sizeof(TW_BOOL);
- TWTY_UNI512: Result := sizeof(TW_UNI512);
- TWTY_STR1024: Result := sizeof(TW_STR1024);
- else Result := 0;
- end {case}
- end;
-
- {Puts a string inside a TW_STR255}
- {$IFDEF UNICODE}
- function StrToStr255(Value: RawByteString): TW_STR255;
- {$ELSE}
- function StrToStr255(Value: String): TW_STR255;
- {$ENDIF}
- begin
- {Clean result}
- Fillchar({%H-}Result, sizeof(TW_STR255), #0);
- {If value fits inside the TW_STR255, copy memory}
- if Length(Value) <= sizeof(TW_STR255) then
- CopyMemory(@Result[0], @Value[1], Length(Value))
- else CopyMemory(@Result[0], @Value[1], sizeof(TW_STR255));
- end;
-
- {Returns full Twain directory (usually in Windows directory)}
- function GetTwainDirectory(): String;
- var
- i: TDirectoryKind;
- Dir: String;
- begin
- {Searches in all the directories}
- FOR i := LOW(TDirectoryKind) TO HIGH(TDirectoryKind) DO
- begin
-
- {Directory to search}
- Dir := GetCustomDirectory(i);
- {Tests if the file exists in this directory}
- if FileExists(Dir + String(TWAINLIBRARY)) then
- begin
- {In case it exists, returns this directory and exit}
- {the for loop}
- Result := Dir;
- Break;
- end {if FileExists}
-
- end {FOR i}
- end;
-
- {This method returns if Twain is installed in the current machine}
- function IsTwainInstalled(): Boolean;
- begin
- {If GetTwainDirectory function returns an empty string, it means}
- {that Twain was not found}
- Result := (GetTwainDirectory() <> '');
- end;
-
- { TTwainIdentity object implementation }
-
- {Object being created}
- constructor TTwainIdentity.Create;
- begin
- {Allows ancestor to work}
- inherited Create;
-
- {Set initial properties}
- FillChar(Structure, sizeof(Structure), #0);
- Language := tlUserLocale;
- CountryCode := 1;
- MajorVersion := 1;
- VersionInfo := 'Application name';
- Structure.ProtocolMajor := TWON_PROTOCOLMAJOR;
- Structure.ProtocolMinor := TWON_PROTOCOLMINOR;
- Groups := [tgImage, tgControl];
- Manufacturer := 'Application manufacturer';
- ProductFamily := 'App product family';
- ProductName := 'App product name';
- end;
-
- {Sets a text value}
- procedure TTwainIdentity.SetString(const Index: Integer;
- const Value: String);
- var
- PropStr: PAnsiChar;
- begin
- {Select and copy pointer}
- case Index of
- 0: PropStr := @Structure.Version.Info[0];
- 1: PropStr := @Structure.Manufacturer[0];
- 2: PropStr := @Structure.ProductFamily[0];
- else PropStr := @Structure.ProductName[0];
- end {case};
-
- {Set value}
- Fillchar(PropStr^, sizeof(TW_STR32), #0);
- if Length(Value) > sizeof(TW_STR32) then
- CopyMemory(PropStr, @Value[1], sizeof(TW_STR32))
- else
- CopyMemory(PropStr, @Value[1], Length(Value));
- end;
-
- {Returns a text value}
- function TTwainIdentity.GetString(const Index: Integer): String;
- begin
- {Test for the required property}
- case Index of
- 0: Result := string(Structure.Version.Info);
- 1: Result := string(Structure.Manufacturer);
- 2: Result := string(Structure.ProductFamily);
- else Result := string(Structure.ProductName);
- end {case}
- end;
-
- {Returns application language property}
- function TTwainIdentity.GetLanguage(): TTwainLanguage;
- begin
- Result := TTwainLanguage(Structure.Version.Language + 1);
- end;
-
- {Sets application language property}
- procedure TTwainIdentity.SetLanguage(const Value: TTwainLanguage);
- begin
- Structure.Version.Language := Word(Value) - 1;
- end;
-
- {Copy properties from another TTwainIdentity}
- procedure TTwainIdentity.Assign(Source: TObject);
- begin
- {The source should also be a TTwainIdentity}
- if Source is TTwainIdentity then begin
- {Copy properties}
- Structure := TTwainIdentity(Source).Structure
- end;
- end;
-
- {Returns avaliable groups}
- function TTwainIdentity.GetGroups(): TTwainGroups;
- begin
- {Convert from Structure.SupportedGroups to TTwainGroups}
- Result := [];
- Include(Result, tgControl);
- if DG_IMAGE AND Structure.SupportedGroups <> 0 then
- Include(Result, tgImage);
- if DG_AUDIO AND Structure.SupportedGroups <> 0 then
- Include(Result, tgAudio);
- end;
-
- {Sets avaliable groups}
- procedure TTwainIdentity.SetGroups(const Value: TTwainGroups);
- begin
- {Convert from TTwainGroups to Structure.SupportedGroups}
- Structure.SupportedGroups := DG_CONTROL;
- if tgImage in Value then
- Structure.SupportedGroups := Structure.SupportedGroups or DG_IMAGE;
- if tgAudio in Value then
- Structure.SupportedGroups := Structure.SupportedGroups or DG_AUDIO;
- end;
-
- { TCustomDelphiTwain component implementation }
-
- {Loads twain library and returns if it loaded sucessfully}
- function TCustomDelphiTwain.LoadLibrary(): Boolean;
- var
- TwainDirectory: String;
- begin
- {The library must not be already loaded}
- if (not LibraryLoaded) then
- begin
- Result := FALSE; {Initially returns FALSE}
- {Searches for Twain directory}
- TwainDirectory := GetTwainDirectory();
- {Continue only if twain is installed in an known directory}
- if TwainDirectory <> '' then
- begin
-
- fHandle := Windows.LoadLibrary(PChar(TwainDirectory + TWAINLIBRARY));
- {If the library was sucessfully loaded}
- if (fHandle <> INVALID_HANDLE_VALUE) then
- begin
-
- {Obtains method handle}
- @fTwainProc := GetProcAddress(fHandle, MAKEINTRESOURCE(1));
- {Returns TRUE/FALSE if the method was obtained}
- Result := (@fTwainProc <> nil);
-
- {If the method was not obtained, also free the library}
- if not Result then
- begin
- {Free the handle and clears the variable}
- Windows.FreeLibrary(fHandle);
- fHandle := 0;
- end {if not Result}
- end
- else
- {If it was not loaded, clears handle value}
- fHandle := 0;
-
- end {if TwainDirectory <> ''};
-
- end
- else
- {If it was already loaded, returns true, since that is}
- {what was supposed to happen}
- Result := TRUE;
-
- {In case the method was sucessful, updates property}
- if Result then fLibraryLoaded := TRUE;
- end;
-
-
- {Unloads twain and returns if it unloaded sucessfully}
- function TCustomDelphiTwain.UnloadLibrary(): Boolean;
- begin
- {The library must not be already unloaded}
- if (LibraryLoaded) then
- begin
- {Unloads the source manager}
- SourceManagerLoaded := FALSE;
- {Just call windows method to unload}
- Result := Windows.FreeLibrary(Handle);
- {If it was sucessfull, also clears handle value}
- if Result then fHandle := 0;
- {Updates property}
- fLibraryLoaded := not Result;
- end
- else
- {If it was already unloaded, returns true, since that is}
- {what was supposed to happen}
- Result := TRUE;
-
- {In case the method was sucessful, updates property}
- {if Result then }fLibraryLoaded := FALSE;
- MessageTimer_Disable;
- end;
-
- {Enumerate the avaliable devices after Source Manager is loaded}
- function TCustomDelphiTwain.EnumerateDevices(): Boolean;
- var
- NewSource: TTwainSource;
- CallRes : TW_UINT16;
- begin
- {Booth library and source manager must be loaded}
- if (LibraryLoaded and SourceManagerLoaded) then
- begin
- {Clears the preview list of sources}
- ClearDeviceList();
-
- {Allocate new identity and tries to enumerate}
- NewSource := TTwainSource.Create(Self);
- CallRes := TwainProc(AppInfo, nil, DG_CONTROL, DAT_IDENTITY,
- MSG_GETFIRST, @NewSource.Structure);
- if CallRes = TWRC_SUCCESS then
- repeat
-
- {Add this item to the list}
- DeviceList.Add(NewSource);
- {Allocate memory for the next}
- NewSource := TTwainSource.Create(Self);
- NewSource.TransferMode := Self.TransferMode;
- NewSource.fIndex := DeviceList.Count;
-
- {Try to get the next item}
- until TwainProc(AppInfo, nil, DG_CONTROL, DAT_IDENTITY,
- MSG_GETNEXT, @NewSource.Structure) <> TWRC_SUCCESS;
-
- {Set that the component has enumerated the devices}
- {if everything went correctly}
- Result := TRUE;
- fHasEnumerated := Result;
-
- {Dispose un-needed source object}
- NewSource.Free;
-
- end
- else Result := FALSE; {If library and source manager aren't loaded}
- end;
-
- {Procedure to load and unload twain library and update property}
- procedure TCustomDelphiTwain.SetLibraryLoaded(const Value: Boolean);
- begin
- {The value must be changing to activate}
- if (Value <> fLibraryLoaded) then
- begin
- {Depending on the parameter load/unload the library and updates}
- {property whenever it loaded or unloaded sucessfully}
- if Value then LoadLibrary()
- else {if not Value then} UnloadLibrary();
-
- end {if (Value <> fLibraryLoaded)}
- end;
-
- {Loads twain source manager}
- function TCustomDelphiTwain.LoadSourceManager(): Boolean;
- begin
- {The library must be loaded}
- if LibraryLoaded and not SourceManagerLoaded then begin
- {Loads source manager}
- Result := (fTwainProc(AppInfo, nil, DG_CONTROL, DAT_PARENT,
- MSG_OPENDSM, @VirtualWindow) = TWRC_SUCCESS);
- end else begin
- {The library is not loaded, thus the source manager could}
- {not be loaded}
- Result := FALSE or SourceManagerLoaded;
- end;
-
- {In case the method was sucessful, updates property}
- if Result then fSourceManagerLoaded := TRUE;
- end;
-
- procedure TCustomDelphiTwain.RefreshVirtualWindow;
- begin
- //BUG WORKAROUND
- DoDestroy;
- DoCreate;
-
- if LoadLibrary then
- SourceManagerLoaded := True;
- end;
-
- {UnLoads twain source manager}
- function TCustomDelphiTwain.UnloadSourceManager(forced: boolean): Boolean;
- begin
- {The library must be loaded}
- if LibraryLoaded and SourceManagerLoaded then
- begin
- {Clears the list of sources}
- ClearDeviceList();
- {Unload source manager}
- if not forced then
- Result := (TwainProc(AppInfo, nil, DG_CONTROL, DAT_PARENT, MSG_CLOSEDSM, @VirtualWindow) = TWRC_SUCCESS)
- else result:=true;
- end
- else
- {The library is not loaded, meaning that the Source Manager isn't either}
- Result := TRUE;
-
- {In case the method was sucessful, updates property}
- if Result then fSourceManagerLoaded := FALSE;
- end;
-
- procedure TCustomDelphiTwain.DoCreate;
- begin
- {Create source list}
- DeviceList := TPointerList.Create;
- {Clear variables}
- fSourcesLoaded := 0;
- fHandle := 0;
- @fTwainProc := nil;
- fSourceManagerLoaded := FALSE;
- fHasEnumerated := FALSE;
- fTransferMode := ttmNative;
-
- {Creates the object to allow the user to set the application}
- {information to inform twain source manager and sources}
- fInfo := TTwainIdentity.Create;
- AppInfo := @fInfo.Structure;
- end;
-
- procedure TCustomDelphiTwain.DoDestroy;
- begin
- {Completely unload the library}
- LibraryLoaded := FALSE;
-
- {Free the object}
- fInfo.Free;
- {Clears and free source list}
- ClearDeviceList();
- DeviceList.Free();
- end;
-
- {Returns a TMsg structure}
- function MakeMsg(const Handle: THandle; uMsg: UINT; wParam: WPARAM;
- lParam: LPARAM): TMsg;
- begin
- {Fill structure with the parameters}
- Result.hwnd := Handle;
- Result.message := uMsg;
- Result.wParam := wParam;
- Result.lParam := lParam;
- GetCursorPos(Result.pt);
- end;
-
- {Procedure to load or unloaded the twain source manager}
- procedure TCustomDelphiTwain.SetSelectedSourceIndex(const Value: Integer);
- begin
- fSelectedSourceIndex := Value;
- end;
-
- procedure TCustomDelphiTwain.SetSourceManagerLoaded(const Value: Boolean);
- begin
- {The library must be loaded to have access to the method}
- if LibraryLoaded and (Value <> fSourceManagerLoaded) then
- begin
- {Load/unload the source manager}
- if Value then LoadSourceManager()
- else {if not Value then} UnloadSourceManager(false);
- end {if LibraryLoaded}
- end;
-
- {Clears the list of sources}
- procedure TCustomDelphiTwain.ClearDeviceList();
- var
- i: Integer;
- begin
- {Deallocate pTW_IDENTITY}
- FOR i := 0 TO DeviceList.Count - 1 DO
- TTwainSource(DeviceList.Item[i]).Free;
- {Clears the list}
- DeviceList.Clear;
- {Set trigger to tell that it has not enumerated again yet}
- fHasEnumerated := FALSE;
-
- end;
-
- {Finds a matching source index}
- function TCustomDelphiTwain.FindSource(Value: pTW_IDENTITY): Integer;
- var
- i : Integer;
- begin
- Result := -1; {Default result}
-
- {Search for this source in the list}
- for i := 0 TO SourceCount - 1 DO
- if CompareMem(@Source[i].Structure, PAnsiChar(Value), SizeOf(TW_IDENTITY)) then
- begin
- {Return index and exit}
- Result := i;
- break;
- end; {if CompareMem, for i}
- end;
-
- {Allows Twain to display a dialog to let the user choose any source}
- {and returns the source index in the list}
- function TCustomDelphiTwain.SelectSource: Integer;
- begin
- Result := -1; {Default result}
- {Booth library and source manager must be loaded}
- if (LibraryLoaded and SourceManagerLoaded) then
- begin
- Result := CustomSelectSource;
-
- SelectedSourceIndex := Result;
- end {(LibraryLoaded and SourceManagerLoaded)}
- end;
-
- {Returns the number of sources}
- function TCustomDelphiTwain.GetSourceCount(): Integer;
- begin
- {Library and source manager must be loaded}
- if (LibraryLoaded and SourceManagerLoaded) then
- begin
- {Enumerate devices, if needed}
- if not HasEnumerated then EnumerateDevices();
- {Returns}
- Result := DeviceList.Count;
- end
- {In case library and source manager aren't loaded, returns 0}
- else Result := 0
- end;
-
- {Returns the default source}
- function TCustomDelphiTwain.GetDefaultSource: Integer;
- var
- Identity: TW_IDENTITY;
- begin
- {Call twain to display the dialog}
- if SourceManagerLoaded and (TwainProc(AppInfo, nil, DG_CONTROL, DAT_IDENTITY,
- MSG_GETDEFAULT, @Identity) = TWRC_SUCCESS) then
- Result := FindSource(@Identity)
- else Result := 0 {Returns}
- end;
-
- {Returns a source from the list}
- function TCustomDelphiTwain.GetSelectedSource: TTwainSource;
- begin
- if SourceCount = 0 then begin
- Result := nil;
- end else begin
- if (fSelectedSourceIndex >= 0) and (fSelectedSourceIndex < SourceCount) then
- Result := Source[fSelectedSourceIndex]
- else
- Result := nil;
- end;
- end;
-
- function TCustomDelphiTwain.GetSelectedSourceIndex: Integer;
- begin
- Result := fSelectedSourceIndex;
- end;
-
- function TCustomDelphiTwain.GetSource(Index: Integer): TTwainSource;
- begin
- {Both library and source manager must be loaded}
- if (LibraryLoaded and SourceManagerLoaded) then
- begin
-
- {If index is in range, returns}
- {(Call to SourceCount property enumerates the devices, if needed)}
- if Index in [0..SourceCount - 1] then
- Result := DeviceList.Item[Index]
- else if (Index = -1) and (SourceCount > 0) then
- Result := DeviceList.Item[GetDefaultSource]
- {Unknown object, returns nil}
- else Result := nil;
-
- end
- {In case either the library or the source manager aren't}
- {loaded, it returns nil}
- else Result := nil
- end;
-
- {Object being created}
- constructor TCustomDelphiTwain.Create;
- begin
- inherited Create;
-
- fLibraryLoaded:=false;
- fSelectedSourceIndex := -1;
-
- DoCreate;
- end;
-
- {Object being destroyed}
- destructor TCustomDelphiTwain.Destroy;
- begin
- DoDestroy;
-
- {Let ancestor class handle}
- inherited Destroy;
- end;
-
- {Updates the application information object}
- procedure TCustomDelphiTwain.SetInfo(const Value: TTwainIdentity);
- begin
- {Assign one object to another}
- fInfo.Assign(Value);
- end;
-
- { TTwainSource object implementation }
-
- {Used with property SourceManagerLoaded to test if the source manager}
- {is loaded or not.}
- function TTwainSource.GetSourceManagerLoaded: Boolean;
- begin
- {Obtain information from owner TCustomDelphiTwain}
- Result := Owner.SourceManagerLoaded;
- end;
-
- {Sets if the source is loaded}
- procedure TTwainSource.SetLoaded(const Value: Boolean);
- begin
- {Value should be changing}
- if (Value <> fLoaded) then
- begin
- {Loads or unloads the source}
- if Value then LoadSource()
- else {if not Value then} UnloadSource();
- end {if (Value <> fLoaded)}
- end;
-
- {Sets if the source is enabled}
- procedure TTwainSource.SetEnabled(const Value: Boolean);
- begin
- {Source must be already enabled and value changing}
- if (Loaded) and (Value <> fEnabled) then
- begin
- {Enables/disables}
- if Value then EnableSource(ShowUI, Modal)
- else {if not Value then} DisableSource();
- end {if (Loaded) and (Value <> fEnabled)}
- end;
-
- {Enables the source}
- function TTwainSource.EnableSource(ShowUI, Modal: Boolean): Boolean;
- var
- twUserInterface: TW_USERINTERFACE;
- begin
- {Source must be loaded and the value changing}
- if (Loaded) and (not Enabled) then
- begin
- {Builds UserInterface structure}
- twUserInterface.ShowUI := ShowUI;
- twUserInterface.ModalUI := Modal;
- twUserInterface.hParent := Owner.CustomGetParentWindow;
-
- //npeter may be it is better to send messages to VirtualWindow
- //I am not sure, but it seems more stable with a HP TWAIN driver
- //it was: := GetActiveWindow;
- //fEnabled := TRUE;
- Owner.MessageTimer_Enable;
- {Call method}
- Result := (Owner.TwainProc(AppInfo, @Structure, DG_CONTROL,
- DAT_USERINTERFACE, MSG_ENABLEDS, @twUserInterface) in
- [TWRC_SUCCESS, TWRC_CHECKSTATUS]);
- end
- else {If it's either not loaded or already enabled}
- {If it is not loaded}
- Result := FALSE or Enabled;
-
- {Updates property}
- if (Result = TRUE) then fEnabled := TRUE;
- end;
-
- {Disables the source}
- function TTwainSource.DisableSource(): Boolean;
- var
- twUserInterface: TW_USERINTERFACE;
- begin
- {Source must be loaded and the value changing}
- if (Loaded) and (Enabled) then
- begin
-
- {Call method}
- Result := (Owner.TwainProc(AppInfo, @Structure, DG_CONTROL,
- DAT_USERINTERFACE, MSG_DISABLEDS, @twUserInterface) = TWRC_SUCCESS);
- {Call notification event if being used}
- if (Result) and (Assigned(Owner.OnSourceDisable)) then
- Owner.OnSourceDisable(Owner, Index);
-
- end
- else {If it's either not loaded or already disabled}
- {If it is not loaded}
- Result := TRUE;
-
- {Updates property}
- //if (Result = TRUE) then fEnabled := FALSE;
- fEnabled := False;
- Owner.MessageTimer_Disable;
- end;
-
- {Loads the source}
- function TTwainSource.LoadSource: Boolean;
- begin
- {Only loads if it is not already loaded}
- if Not Loaded then
- begin
- Result := (Owner.TwainProc(AppInfo, nil, DG_CONTROL, DAT_IDENTITY,
- MSG_OPENDS, @Structure) = TWRC_SUCCESS);
- {Increase the loaded sources count variable}
- if Result then inc(Owner.fSourcesLoaded);
- end
- else
- {If it was already loaded, returns true}
- Result := TRUE;
-
- {In case the method was sucessful, updates property}
- if Result then
- fLoaded := TRUE;
-
- end;
-
- {Unloads the source}
- function TTwainSource.UnloadSource: Boolean;
- begin
- {Only unloads if it is loaded}
- if Loaded then
- begin
- {If the source was enabled, disable it}
- DisableSource();
- {Call method to load}
- Result := (Owner.TwainProc(AppInfo, nil, DG_CONTROL, DAT_IDENTITY,
- MSG_CLOSEDS, @Structure) = TWRC_SUCCESS);
- {Decrease the loaded sources count variable}
- if Result then dec(Owner.fSourcesLoaded);
- end
- else
- {If it was already unloaded, returns true}
- Result := TRUE;
-
- {In case the method was sucessful, updates property}
- fLoaded := FALSE;
- end;
-
- {Object being destroyed}
- destructor TTwainSource.Destroy;
- begin
- {If loaded, unloads source}
- UnloadSource();
- {Let ancestor class process}
- inherited Destroy;
- end;
-
- {Returns a pointer to the application}
- function TTwainSource.GetAppInfo: pTW_IDENTITY;
- begin
- Result := Owner.AppInfo;
- end;
-
- {Returns a pointer to the source identity}
- function TTwainSource.GetStructure: pTW_IDENTITY;
- begin
- Result := @Structure;
- end;
-
- {Object being created}
- constructor TTwainSource.Create(AOwner: TCustomDelphiTwain);
- begin
- {Allows ancestor class to process}
- inherited Create;
-
- {Initial values}
- fTransferMode := AOwner.TransferMode;
- fLoaded := FALSE;
- fShowUI := TRUE;
- fEnabled := FALSE;
- fModal := TRUE;
- {Stores owner}
- fOwner := AOwner;
- end;
-
- {Set source transfer mode}
- {function TTwainSource.ChangeTransferMode(
- NewMode: TTwainTransferMode): TCapabilityRet;
- const
- TransferModeToTwain: Array[TTwainTransferMode] of TW_UINT16 =
- (TWSX_FILE, TWSX_NATIVE, TWSX_MEMORY);
- var
- Value: TW_UINT16;
- begin
- //Set transfer mode method
- Value := TransferModeToTwain[NewMode];
- Result := SetOneValue(ICAP_XFERMECH, TWTY_UINT16, @Value);
- TransferMode := NewMode;
- end;}
-
- {Message received in the event loop}
- function TTwainSource.ProcessMessage(const Msg: TMsg): Boolean;
- var
- twEvent: TW_EVENT;
- begin
- {Make twEvent structure}
- twEvent.TWMessage := MSG_NULL;
- twEvent.pEvent := TW_MEMREF(@Msg);
- {Call Twain procedure to handle message}
- Result := (Owner.TwainProc(AppInfo, @Structure, DG_CONTROL, DAT_EVENT,
- MSG_PROCESSEVENT, @twEvent) = TWRC_DSEVENT);
-
- {If it is a message from the source, process}
- if Result then
- case twEvent.TWMessage of
- {No message from the source}
- MSG_NULL: exit;
- {Requested to close the source}
- MSG_CLOSEDSREQ:
- begin
- {Call notification event}
- if (Assigned(Owner.OnAcquireCancel)) then
- Owner.OnAcquireCancel(Owner, Index);
- if Assigned(Owner.OnTransferComplete) then
- Owner.OnTransferComplete(Owner, Index, True);
- {Disable the source}
- DisableSource();
- Owner.RefreshVirtualWindow;
- end;
- {Ready to transfer the images}
- MSG_XFERREADY:
- {Call method to transfer}
- TransferImages();
-
- MSG_CLOSEDSOK:
- result:=true;
-
- MSG_DEVICEEVENT:
- result:=true;
-
- end {case twEvent.TWMessage}
- end;
-
- {Returns return status information}
- function TTwainSource.GetReturnStatus: TW_UINT16;
- var
- StatusInfo: TW_STATUS;
- begin
- {The source must be loaded in order to get the status}
- if Loaded then
- begin
- {Call method to get the information}
- Owner.TwainProc(AppInfo, @Structure, DG_CONTROL, DAT_STATUS, MSG_GET,
- @StatusInfo);
- Result := StatusInfo.ConditionCode;
- end else Result := 0 {In case it was called while the source was not loaded}
- end;
-
- {Converts from a result to a TCapabilityRec}
- function TTwainSource.ResultToCapabilityRec(
- const Value: TW_UINT16): TCapabilityRet;
- begin
-
- {Test result code to return}
- case Value of
- {Successull, copy handle and return a success value}
- TWRC_SUCCESS: Result := crSuccess;
- {Error, get more on the error, and return result}
- {case} else
- case GetReturnStatus() of
- TWCC_CAPUNSUPPORTED: Result := crUnsupported;…