(* ImageEn Build 7.0.0.06.2637 @ 7-4-17 14:58:42.679 *) (* Copyright (c) 1998-2017 by Carlotta Calandra. All rights reserved. Copyright (c) 2011-2017 by Xequte Software. This software comes without express or implied warranty. In no case shall the author be liable for any damage or unwanted behavior of any computer hardware and/or software. Author grants you the right to include the component in your application, whether COMMERCIAL, SHAREWARE, or FREEWARE. ImageEn, IEvolution and ImageEn ActiveX may not be included in any commercial, shareware or freeware libraries or components. www.ImageEn.com *) (* File version 1015 *) unit iewia; {$R-} {$Q-} {$I ie.inc} interface {$IFDEF IEINCLUDEIEXACQUIRE} uses Windows, Classes, Sysutils, Graphics, comctrls, iexBitmaps, hyiedefs; const // Image types WiaImgFmt_UNDEFINED : TGUID = '{b96b3ca9-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_RAWRGB : TGUID = '{bca48b55-f272-4371-b0f1-4a150d057bb4}'; WiaImgFmt_MEMORYBMP : TGUID = '{b96b3caa-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_BMP : TGUID = '{b96b3cab-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_EMF : TGUID = '{b96b3cac-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_WMF : TGUID = '{b96b3cad-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_JPEG : TGUID = '{b96b3cae-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_PNG : TGUID = '{b96b3caf-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_GIF : TGUID = '{b96b3cb0-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_TIFF : TGUID = '{b96b3cb1-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_EXIF : TGUID = '{b96b3cb2-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_PHOTOCD : TGUID = '{b96b3cb3-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_FLASHPIX : TGUID = '{b96b3cb4-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_ICO : TGUID = '{b96b3cb5-0728-11d3-9d7b-0000f81ef32e}'; WiaImgFmt_CIFF : TGUID = '{9821a8ab-3a7e-4215-94e0-d27a460c03b2}'; // Camera Image File Format WiaImgFmt_PICT : TGUID = '{a6bc85d8-6b3e-40ee-a95c-25d482e41adc}'; // Quickdraw Image Format WiaImgFmt_JPEG2K : TGUID = '{344ee2b2-39db-4dde-8173-c4b75f8f1e49}'; // JPEG 2000 baseline file format WiaImgFmt_JPEG2KX : TGUID = '{43e14614-c80a-4850-baf3-4b152dc8da27}'; // JPEG 2000 extended file format // Document and other types WiaImgFmt_RTF : TGUID = '{573dd6a3-4834-432d-a9b5-e198dd9e890d}'; WiaImgFmt_XML : TGUID = '{b9171457-dac8-4884-b393-15b471d5f07e}'; WiaImgFmt_HTML : TGUID = '{c99a4e62-99de-4a94-acca-71956ac2977d}'; WiaImgFmt_TXT : TGUID = '{fafd4d82-723f-421f-9318-30501ac44b59}'; WiaImgFmt_MPG : TGUID = '{ecd757e4-d2ec-4f57-955d-bcf8a97c4e52}'; WiaImgFmt_AVI : TGUID = '{32f8ca14-087c-4908-b7c4-6757fe7e90ab}'; WiaImgFmt_ASF : TGUID = '{8d948ee9-d0aa-4a12-9d9a-9cc5de36199b}'; WiaImgFmt_SCRIPT : TGUID = '{fe7d6c53-2dac-446a-b0bd-d73e21e924c9}'; WiaImgFmt_EXEC : TGUID = '{485da097-141e-4aa5-bb3b-a5618d95d02b}'; WiaImgFmt_UNICODE16 : TGUID = '{1b7639b6-6357-47d1-9a07-12452dc073e9}'; WiaImgFmt_DPOF : TGUID = '{369eeeab-a0e8-45ca-86a6-a83ce5697e28}'; // Audio types WiaAudFmt_WAV : TGUID = '{f818e146-07af-40ff-ae55-be8f2c065dbe}'; WiaAudFmt_MP3 : TGUID = '{0fbc71fb-43bf-49f2-9190-e6fecff37e54}'; WiaAudFmt_AIFF : TGUID = '{66e2bf4f-b6fc-443f-94c8-2f33c8a65aaf}'; WiaAudFmt_WMA : TGUID = '{d61d6413-8bc2-438f-93ad-21bd484db6a1}'; WIA_DIP_DEV_ID = 2; WIA_DIP_DEV_NAME = 7; WIA_DIP_SERVER_NAME = 8; WIA_DIP_DEV_DESC = 4; WIA_DIP_DEV_TYPE = 5; WIA_DIP_DRIVER_VERSION = 15; WIA_DIP_PORT_NAME = 6; WIA_DIP_VEND_DESC = 3; StiDeviceTypeDefault = 0; StiDeviceTypeScanner = 1; StiDeviceTypeDigitalCamera = 2; StiDeviceTypeStreamingVideo = 3; WiaItemTypeFree = $00000000; WiaItemTypeImage = $00000001; WiaItemTypeFile = $00000002; WiaItemTypeFolder = $00000004; WiaItemTypeRoot = $00000008; WiaItemTypeAnalyze = $00000010; WiaItemTypeAudio = $00000020; WiaItemTypeDevice = $00000040; WiaItemTypeDeleted = $00000080; WiaItemTypeDisconnected = $00000100; WiaItemTypeHPanorama = $00000200; WiaItemTypeVPanorama = $00000400; WiaItemTypeBurst = $00000800; WiaItemTypeStorage = $00001000; WiaItemTypeTransfer = $00002000; WiaItemTypeGenerated = $00004000; WiaItemTypeHasAttachments = $00008000; WiaItemTypeVideo = $00010000; WiaItemTypeTwainCapabilityPassThrough = $00020000; WiaItemTypeRemoved = $80000000; WiaItemTypeMask = $8003FFFF; TYMED_HGLOBAL = 1; TYMED_FILE = 2; TYMED_ISTREAM = 4; TYMED_ISTORAGE = 8; TYMED_GDI = 16; TYMED_MFPICT = 32; TYMED_ENHMF = 64; TYMED_NULL = 0; // IImageTransfer Callback Status. Messages must be a single value IT_MSG_DATA_HEADER = $0001; IT_MSG_DATA = $0002; IT_MSG_STATUS = $0003; IT_MSG_TERMINATION = $0004; IT_MSG_NEW_PAGE = $0005; IT_MSG_FILE_PREVIEW_DATA = $0006; IT_MSG_FILE_PREVIEW_DATA_HEADER = $0007; // IImageTransfer TYMED WIA_TYMED_CALLBACK = 128; WIA_TYMED_MULTIPAGE_FILE = 256; WIA_TYMED_MULTIPAGE_CALLBACK = 512; WIA_RESERVED_FOR_NEW_PROPS = 1024; WIA_DIP_FIRST = 2; WIA_DPA_FIRST = WIA_DIP_FIRST + WIA_RESERVED_FOR_NEW_PROPS; WIA_DPC_FIRST = WIA_DPA_FIRST + WIA_RESERVED_FOR_NEW_PROPS; WIA_DPS_FIRST = WIA_DPC_FIRST + WIA_RESERVED_FOR_NEW_PROPS; WIA_IPA_FIRST = WIA_DPS_FIRST + WIA_RESERVED_FOR_NEW_PROPS; WIA_IPC_FIRST = WIA_IPA_FIRST + WIA_RESERVED_FOR_NEW_PROPS; WIA_DIP_REMOTE_DEV_ID = 9; WIA_DIP_UI_CLSID = 10; WIA_DIP_HW_CONFIG = 11; WIA_DIP_BAUDRATE = 12; WIA_DIP_STI_GEN_CAPABILITIES = 13; WIA_DIP_WIA_VERSION = 14; // Common device properties WIA_DPA_FIRMWARE_VERSION = WIA_DPA_FIRST + 0; WIA_DPA_CONNECT_STATUS = WIA_DPA_FIRST + 1; WIA_DPA_DEVICE_TIME = WIA_DPA_FIRST + 2; WIA_DPA_LAST = WIA_DPA_FIRST + 3; // WIA Scanner item properties WIA_IPS_FIRST = WIA_IPC_FIRST + WIA_RESERVED_FOR_NEW_PROPS; WIA_IPS_CUR_INTENT = WIA_IPS_FIRST + 0; WIA_IPS_XRES = WIA_IPS_FIRST + 1; WIA_IPS_YRES = WIA_IPS_FIRST + 2; WIA_IPS_XPOS = WIA_IPS_FIRST + 3; WIA_IPS_YPOS = WIA_IPS_FIRST + 4; WIA_IPS_XEXTENT = WIA_IPS_FIRST + 5; WIA_IPS_YEXTENT = WIA_IPS_FIRST + 6; WIA_IPS_PHOTOMETRIC_INTERP = WIA_IPS_FIRST + 7; WIA_IPS_BRIGHTNESS = WIA_IPS_FIRST + 8; WIA_IPS_CONTRAST = WIA_IPS_FIRST + 9; WIA_IPS_ORIENTATION = WIA_IPS_FIRST + 10; WIA_IPS_ROTATION = WIA_IPS_FIRST + 11; WIA_IPS_MIRROR = WIA_IPS_FIRST + 12; WIA_IPS_THRESHOLD = WIA_IPS_FIRST + 13; WIA_IPS_INVERT = WIA_IPS_FIRST + 14; WIA_IPS_WARM_UP_TIME = WIA_IPS_FIRST + 15; // WIA Scanner device properties WIA_DPS_HORIZONTAL_BED_SIZE = WIA_DPS_FIRST + 0; WIA_DPS_VERTICAL_BED_SIZE = WIA_DPS_FIRST + 1; WIA_DPS_HORIZONTAL_SHEET_FEED_SIZE = WIA_DPS_FIRST + 2; WIA_DPS_VERTICAL_SHEET_FEED_SIZE = WIA_DPS_FIRST + 3; WIA_DPS_SHEET_FEEDER_REGISTRATION = WIA_DPS_FIRST + 4; WIA_DPS_HORIZONTAL_BED_REGISTRATION = WIA_DPS_FIRST + 5; WIA_DPS_VERTICAL_BED_REGISTRATION = WIA_DPS_FIRST + 6; WIA_DPS_PLATEN_COLOR = WIA_DPS_FIRST + 7; WIA_DPS_PAD_COLOR = WIA_DPS_FIRST + 8; WIA_DPS_FILTER_SELECT = WIA_DPS_FIRST + 9; WIA_DPS_DITHER_SELECT = WIA_DPS_FIRST + 10; WIA_DPS_DITHER_PATTERN_DATA = WIA_DPS_FIRST + 11; WIA_DPS_DOCUMENT_HANDLING_CAPABILITIES = WIA_DPS_FIRST + 12; WIA_DPS_DOCUMENT_HANDLING_STATUS = WIA_DPS_FIRST + 13; WIA_DPS_DOCUMENT_HANDLING_SELECT = WIA_DPS_FIRST + 14; WIA_DPS_DOCUMENT_HANDLING_CAPACITY = WIA_DPS_FIRST + 15; WIA_DPS_OPTICAL_XRES = WIA_DPS_FIRST + 16; WIA_DPS_OPTICAL_YRES = WIA_DPS_FIRST + 17; WIA_DPS_ENDORSER_CHARACTERS = WIA_DPS_FIRST + 18; WIA_DPS_ENDORSER_STRING = WIA_DPS_FIRST + 19; WIA_DPS_SCAN_AHEAD_PAGES = WIA_DPS_FIRST + 20; WIA_DPS_MAX_SCAN_TIME = WIA_DPS_FIRST + 21; WIA_DPS_PAGES = WIA_DPS_FIRST + 22; WIA_DPS_PAGE_SIZE = WIA_DPS_FIRST + 23; WIA_DPS_PAGE_WIDTH = WIA_DPS_FIRST + 24; WIA_DPS_PAGE_HEIGHT = WIA_DPS_FIRST + 25; WIA_DPS_PREVIEW = WIA_DPS_FIRST + 26; WIA_DPS_TRANSPARENCY = WIA_DPS_FIRST + 27; WIA_DPS_TRANSPARENCY_SELECT = WIA_DPS_FIRST + 28; WIA_DPS_SHOW_PREVIEW_CONTROL = WIA_DPS_FIRST + 29; WIA_DPS_MIN_HORIZONTAL_SHEET_FEED_SIZE = WIA_DPS_FIRST + 30; WIA_DPS_MIN_VERTICAL_SHEET_FEED_SIZE = WIA_DPS_FIRST + 31; // WIA Common item properties WIA_IPA_ITEM_NAME = WIA_IPA_FIRST + 0; WIA_IPA_FULL_ITEM_NAME = WIA_IPA_FIRST + 1; WIA_IPA_ITEM_TIME = WIA_IPA_FIRST + 2; WIA_IPA_ITEM_FLAGS = WIA_IPA_FIRST + 3; WIA_IPA_ACCESS_RIGHTS = WIA_IPA_FIRST + 4; WIA_IPA_DATATYPE = WIA_IPA_FIRST + 5; WIA_IPA_DEPTH = WIA_IPA_FIRST + 6; WIA_IPA_PREFERRED_FORMAT = WIA_IPA_FIRST + 7; WIA_IPA_FORMAT = WIA_IPA_FIRST + 8; WIA_IPA_COMPRESSION = WIA_IPA_FIRST + 9; WIA_IPA_TYMED = WIA_IPA_FIRST + 10; WIA_IPA_CHANNELS_PER_PIXEL = WIA_IPA_FIRST + 11; WIA_IPA_BITS_PER_CHANNEL = WIA_IPA_FIRST + 12; WIA_IPA_PLANAR = WIA_IPA_FIRST + 13; WIA_IPA_PIXELS_PER_LINE = WIA_IPA_FIRST + 14; WIA_IPA_BYTES_PER_LINE = WIA_IPA_FIRST + 15; WIA_IPA_NUMBER_OF_LINES = WIA_IPA_FIRST + 16; WIA_IPA_GAMMA_CURVES = WIA_IPA_FIRST + 17; WIA_IPA_ITEM_SIZE = WIA_IPA_FIRST + 18; WIA_IPA_COLOR_PROFILE = WIA_IPA_FIRST + 19; WIA_IPA_MIN_BUFFER_SIZE = WIA_IPA_FIRST + 20; WIA_IPA_BUFFER_SIZE = WIA_IPA_FIRST + 20; WIA_IPA_REGION_TYPE = WIA_IPA_FIRST + 21; WIA_IPA_ICM_PROFILE_NAME = WIA_IPA_FIRST + 22; WIA_IPA_APP_COLOR_MAPPING = WIA_IPA_FIRST + 23; WIA_IPA_PROP_STREAM_COMPAT_ID = WIA_IPA_FIRST + 24; WIA_IPA_FILENAME_EXTENSION = WIA_IPA_FIRST + 25; WIA_IPA_SUPPRESS_PROPERTY_PAGE = WIA_IPA_FIRST + 26; WIA_IPA_LAST = WIA_IPA_FIRST + 26; {!! WIA Camera device properties WIA_DPC_PICTURES_TAKEN WIA_DPC_PICTURES_REMAINING WIA_DPC_EXPOSURE_MODE WIA_DPC_EXPOSURE_COMP WIA_DPC_EXPOSURE_TIME WIA_DPC_FNUMBER WIA_DPC_FLASH_MODE WIA_DPC_FOCUS_MODE WIA_DPC_FOCUS_MANUAL_DIST WIA_DPC_ZOOM_POSITION WIA_DPC_PAN_POSITION WIA_DPC_TILT_POSITION WIA_DPC_TIMER_MODE WIA_DPC_TIMER_VALUE WIA_DPC_POWER_MODE WIA_DPC_BATTERY_STATUS WIA_DPC_THUMB_WIDTH WIA_DPC_THUMB_HEIGHT WIA_DPC_PICT_WIDTH WIA_DPC_PICT_HEIGHT WIA_DPC_DIMENSION WIA_DPC_COMPRESSION_SETTING WIA_DPC_FOCUS_METERING WIA_DPC_TIMELAPSE_INTERVAL WIA_DPC_TIMELAPSE_NUMBER WIA_DPC_BURST_INTERVAL WIA_DPC_BURST_NUMBER WIA_DPC_EFFECT_MODE WIA_DPC_DIGITAL_ZOOM WIA_DPC_SHARPNESS WIA_DPC_CONTRAST WIA_DPC_CAPTURE_MODE WIA_DPC_CAPTURE_DELAY WIA_DPC_EXPOSURE_INDEX WIA_DPC_EXPOSURE_METERING_MODE WIA_DPC_FOCUS_METERING_MODE WIA_DPC_FOCUS_DISTANCE WIA_DPC_FOCAL_LENGTH WIA_DPC_RGB_GAIN WIA_DPC_WHITE_BALANCE WIA_DPC_UPLOAD_URL WIA_DPC_ARTIST WIA_DPC_COPYRIGHT_INFO !!} // WIA Camera device properties WIA_DPC_PICTURES_TAKEN = WIA_DPC_FIRST + 0; WIA_DPC_PICTURES_REMAINING = WIA_DPC_FIRST + 1; WIA_DPC_EXPOSURE_MODE = WIA_DPC_FIRST + 2; WIA_DPC_EXPOSURE_COMP = WIA_DPC_FIRST + 3; WIA_DPC_EXPOSURE_TIME = WIA_DPC_FIRST + 4; WIA_DPC_FNUMBER = WIA_DPC_FIRST + 5; WIA_DPC_FLASH_MODE = WIA_DPC_FIRST + 6; WIA_DPC_FOCUS_MODE = WIA_DPC_FIRST + 7; WIA_DPC_FOCUS_MANUAL_DIST = WIA_DPC_FIRST + 8; WIA_DPC_ZOOM_POSITION = WIA_DPC_FIRST + 9; WIA_DPC_PAN_POSITION = WIA_DPC_FIRST + 10; WIA_DPC_TILT_POSITION = WIA_DPC_FIRST + 11; WIA_DPC_TIMER_MODE = WIA_DPC_FIRST + 12; WIA_DPC_TIMER_VALUE = WIA_DPC_FIRST + 13; WIA_DPC_POWER_MODE = WIA_DPC_FIRST + 14; WIA_DPC_BATTERY_STATUS = WIA_DPC_FIRST + 15; WIA_DPC_THUMB_WIDTH = WIA_DPC_FIRST + 16; WIA_DPC_THUMB_HEIGHT = WIA_DPC_FIRST + 17; WIA_DPC_PICT_WIDTH = WIA_DPC_FIRST + 18; WIA_DPC_PICT_HEIGHT = WIA_DPC_FIRST + 19; WIA_DPC_DIMENSION = WIA_DPC_FIRST + 20; WIA_DPC_COMPRESSION_SETTING = WIA_DPC_FIRST + 21; WIA_DPC_FOCUS_METERING = WIA_DPC_FIRST + 22; WIA_DPC_TIMELAPSE_INTERVAL = WIA_DPC_FIRST + 23; WIA_DPC_TIMELAPSE_NUMBER = WIA_DPC_FIRST + 24; WIA_DPC_BURST_INTERVAL = WIA_DPC_FIRST + 25; WIA_DPC_BURST_NUMBER = WIA_DPC_FIRST + 26; WIA_DPC_EFFECT_MODE = WIA_DPC_FIRST + 27; WIA_DPC_DIGITAL_ZOOM = WIA_DPC_FIRST + 28; WIA_DPC_SHARPNESS = WIA_DPC_FIRST + 29; WIA_DPC_CONTRAST = WIA_DPC_FIRST + 30; WIA_DPC_CAPTURE_MODE = WIA_DPC_FIRST + 31; WIA_DPC_CAPTURE_DELAY = WIA_DPC_FIRST + 32; WIA_DPC_EXPOSURE_INDEX = WIA_DPC_FIRST + 33; WIA_DPC_EXPOSURE_METERING_MODE = WIA_DPC_FIRST + 34; WIA_DPC_FOCUS_METERING_MODE = WIA_DPC_FIRST + 35; WIA_DPC_FOCUS_DISTANCE = WIA_DPC_FIRST + 36; WIA_DPC_FOCAL_LENGTH = WIA_DPC_FIRST + 37; WIA_DPC_RGB_GAIN = WIA_DPC_FIRST + 38; WIA_DPC_WHITE_BALANCE = WIA_DPC_FIRST + 39; WIA_DPC_UPLOAD_URL = WIA_DPC_FIRST + 40; WIA_DPC_ARTIST = WIA_DPC_FIRST + 41; WIA_DPC_COPYRIGHT_INFO = WIA_DPC_FIRST + 42; // WIA Camera item properties WIA_IPC_THUMBNAIL = WIA_IPC_FIRST + 0; WIA_IPC_THUMB_WIDTH = WIA_IPC_FIRST + 1; WIA_IPC_THUMB_HEIGHT = WIA_IPC_FIRST + 2; WIA_IPC_AUDIO_AVAILABLE = WIA_IPC_FIRST + 3; WIA_IPC_AUDIO_DATA_FORMAT = WIA_IPC_FIRST + 4; WIA_IPC_AUDIO_DATA = WIA_IPC_FIRST + 5; WIA_IPC_NUM_PICT_PER_ROW = WIA_IPC_FIRST + 6; WIA_IPC_SEQUENCE = WIA_IPC_FIRST + 7; WIA_IPC_TIMEDELAY = WIA_IPC_FIRST + 8; // WIA_DPC_WHITE_BALANCE constants WIA_WHITEBALANCE_MANUAL = 1; WIA_WHITEBALANCE_AUTO = 2; WIA_WHITEBALANCE_ONEPUSH_AUTO = 3; WIA_WHITEBALANCE_DAYLIGHT = 4; WIA_WHITEBALANCE_FLORESCENT = 5; WIA_WHITEBALANCE_TUNGSTEN = 6; WIA_WHITEBALANCE_FLASH = 7; // WIA_DPC_FOCUS_MODE constants WIA_FOCUSMODE_MANUAL = 1; WIA_FOCUSMODE_AUTO = 2; WIA_FOCUSMODE_MACROAUTO = 3; // WIA_DPC_EXPOSURE_METERING_MODE constants WIA_EXPOSUREMETERING_AVERAGE = 1; WIA_EXPOSUREMETERING_CENTERWEIGHT = 2; WIA_EXPOSUREMETERING_MULTISPOT = 3; WIA_EXPOSUREMETERING_CENTERSPOT = 4; // WIA_DPC_FLASH_MODE constants WIA_FLASHMODE_AUTO = 1; WIA_FLASHMODE_OFF = 2; WIA_FLASHMODE_FILL = 3; WIA_FLASHMODE_REDEYE_AUTO = 4; WIA_FLASHMODE_REDEYE_FILL = 5; WIA_FLASHMODE_EXTERNALSYNC = 6; // WIA_DPC_EXPOSURE_MODE constants WIA_EXPOSUREMODE_MANUAL = 1; WIA_EXPOSUREMODE_AUTO = 2; WIA_EXPOSUREMODE_APERTURE_PRIORITY = 3; WIA_EXPOSUREMODE_SHUTTER_PRIORITY = 4; WIA_EXPOSUREMODE_PROGRAM_CREATIVE = 5; WIA_EXPOSUREMODE_PROGRAM_ACTION = 6; WIA_EXPOSUREMODE_PORTRAIT = 7; // WIA_DPC_CAPTURE_MODE constants WIA_CAPTUREMODE_NORMAL = 1; WIA_CAPTUREMODE_BURST = 2; WIA_CAPTUREMODE_TIMELAPSE = 3; // WIA_DPC_EFFECT_MODE constants WIA_EFFECTMODE_STANDARD = 1; WIA_EFFECTMODE_BW = 2; WIA_EFFECTMODE_SEPIA = 3; // WIA_DPC_FOCUS_METERING_MODE constants WIA_FOCUSMETERING_CENTERSPOT = 1; WIA_FOCUSMETERING_MULTISPOT = 2; // WIA_DPC_POWER_MODE constants WIA_POWERMODE_LINE = 1; WIA_POWERMODE_BATTERY = 2; // WIA_DPS_SHEET_FEEDER_REGISTRATION and // WIA_DPS_HORIZONTAL_BED_REGISTRATION constants WIA_LEFT_JUSTIFIED = 0; WIA_CENTERED = 1; WIA_RIGHT_JUSTIFIED = 2; // WIA_DPS_VERTICAL_BED_REGISTRATION constants WIA_TOP_JUSTIFIED = 0; //WIA_CENTERED =1; WIA_BOTTOM_JUSTIFIED = 2; // WIA_DPS_ORIENTATION and WIA_DPS_ROTATION constants WIA_PORTRAIT = 0; WIA_LANDSCAPE = 1; WIA_ROT180 = 2; WIA_ROT270 = 3; // WIA_DPS_MIRROR flags WIA_MIRRORED = $01; // WIA_DPS_DOCUMENT_HANDLING_SELECT flags WIA_FEEDER = $001; WIA_FLATBED = $002; WIA_DUPLEX = $004; WIA_FRONT_FIRST = $008; WIA_BACK_FIRST = $010; WIA_FRONT_ONLY = $020; WIA_BACK_ONLY = $040; WIA_NEXT_PAGE = $080; WIA_PREFEED = $100; WIA_AUTO_ADVANCE = $200; // WIA_DPS_TRANSPARENCY flags WIA_LIGHT_SOURCE_PRESENT_DETECT = $01; WIA_LIGHT_SOURCE_PRESENT = $02; WIA_LIGHT_SOURCE_DETECT_READY = $04; WIA_LIGHT_SOURCE_READY = $08; // WIA_DPS_TRANSPARENCY_SELECT flags WIA_LIGHT_SOURCE_SELECT = $001; // WIA_DPS_SCAN_AHEAD_PAGES constants WIA_SCAN_AHEAD_ALL = 0; // WIA_DPS_PAGES constants WIA_ALL_PAGES = 0; // WIA_DPS_PREVIEW constants WIA_FINAL_SCAN = 0; WIA_PREVIEW_SCAN = 1; // WIA_DPS_SHOW_PREVIEW_CONTROL constants WIA_SHOW_PREVIEW_CONTROL = 0; WIA_DONT_SHOW_PREVIEW_CONTROL = 1; // Predefined strings for WIA_DPS_ENDORSER_STRING WIA_ENDORSER_TOK_DATE: AnsiString = '$DATE$'; WIA_ENDORSER_TOK_TIME: AnsiString = '$TIME$'; WIA_ENDORSER_TOK_PAGE_COUNT: AnsiString = '$PAGE_COUNT$'; WIA_ENDORSER_TOK_DAY: AnsiString = '$DAY$'; WIA_ENDORSER_TOK_MONTH: AnsiString = '$MONTH$'; WIA_ENDORSER_TOK_YEAR: AnsiString = '$YEAR$'; // WIA_DPS_PAGE_SIZE constants WIA_PAGE_A4 = 0; WIA_PAGE_LETTER = 1; WIA_PAGE_CUSTOM = 2; // WIA_IPA_COMPRESSION constants WIA_COMPRESSION_NONE = 0; WIA_COMPRESSION_BI_RLE4 = 1; WIA_COMPRESSION_BI_RLE8 = 2; WIA_COMPRESSION_G3 = 3; WIA_COMPRESSION_G4 = 4; WIA_COMPRESSION_JPEG = 5; // WIA_IPA_PLANAR constants WIA_PACKED_PIXEL = 0; WIA_PLANAR = 1; // WIA_IPA_DATATYPE constants WIA_DATA_THRESHOLD = 0; WIA_DATA_DITHER = 1; WIA_DATA_GRAYSCALE = 2; WIA_DATA_COLOR = 3; WIA_DATA_COLOR_THRESHOLD = 4; WIA_DATA_COLOR_DITHER = 5; // WIA_IPA_SUPPRESS_PROPERTY_PAGE flags WIA_PROPPAGE_SCANNER_ITEM_GENERAL = $00000001; WIA_PROPPAGE_CAMERA_ITEM_GENERAL = $00000002; // WIA_IPS_CUR_INTENT flags //WIA_INTENT_NONE =$00000000; WIA_INTENT_IMAGE_TYPE_COLOR = $00000001; WIA_INTENT_IMAGE_TYPE_GRAYSCALE = $00000002; WIA_INTENT_IMAGE_TYPE_TEXT = $00000004; WIA_INTENT_IMAGE_TYPE_MASK = $0000000F; WIA_INTENT_MINIMIZE_SIZE = $00010000; WIA_INTENT_MAXIMIZE_QUALITY = $00020000; WIA_INTENT_BEST_PREVIEW = $00040000; WIA_INTENT_SIZE_MASK = $000F0000; // WIA_IPS_PHOTOMETRIC_INTERP constants WIA_PHOTO_WHITE_1 = 0; // default, white is 1, black is 0 WIA_PHOTO_WHITE_0 = 1; // default, white is 0, black is 1 // WIA Extended Property Identifiers WIA_RANGE_MIN = 0; WIA_RANGE_NOM = 1; WIA_RANGE_MAX = 2; WIA_RANGE_STEP = 3; WIA_RANGE_NUM_ELEMS = 4; WIA_LIST_COUNT = 0; WIA_LIST_NOM = 1; WIA_LIST_VALUES = 2; WIA_LIST_NUM_ELEMS = 2; WIA_FLAG_NOM = 0; WIA_FLAG_VALUES = 1; WIA_FLAG_NUM_ELEMS = 2; WIA_PROP_READ = $01; WIA_PROP_WRITE = $02; WIA_PROP_RW = WIA_PROP_READ or WIA_PROP_WRITE; WIA_PROP_SYNC_REQUIRED = $04; WIA_PROP_NONE = $08; WIA_PROP_RANGE = $10; WIA_PROP_LIST = $20; WIA_PROP_FLAG = $40; WIA_PROP_CACHEABLE = $10000; WIA_ITEM_CAN_BE_DELETED = $80; WIA_ITEM_READ = WIA_PROP_READ; WIA_ITEM_WRITE = WIA_PROP_WRITE; WIA_ITEM_RD = WIA_ITEM_READ or WIA_ITEM_CAN_BE_DELETED; WIA_ITEM_RWD = WIA_ITEM_READ or WIA_ITEM_WRITE or WIA_ITEM_CAN_BE_DELETED; // Device connection status WIA_DEVICE_NOT_CONNECTED = 0; WIA_DEVICE_CONNECTED = 1; // WIA_DPS_DOCUMENT_HANDLING_CAPABILITIES flags WIA_FEED = $01; WIA_FLAT = $02; WIA_DUP = $04; WIA_DETECT_FLAT = $08; WIA_DETECT_SCAN = $10; WIA_DETECT_FEED = $20; WIA_DETECT_DUP = $40; WIA_DETECT_FEED_AVAIL = $80; WIA_DETECT_DUP_AVAIL = $100; // WIA_DPS_DOCUMENT_HANDLING_STATUS flags WIA_FEED_READY = $01; WIA_FLAT_READY = $02; WIA_DUP_READY = $04; WIA_FLAT_COVER_UP = $08; WIA_PATH_COVER_UP = $10; WIA_PAPER_JAM = $20; type WIA_DATA_CALLBACK_HEADER = record lSize: integer; guidFormatID: TGUID; lBufferSize: integer; lPageCount: integer; end; PWIA_DATA_CALLBACK_HEADER = ^WIA_DATA_CALLBACK_HEADER; IWiaItem = interface; TIEWGetPage = function(header: PWIA_DATA_CALLBACK_HEADER; data: pointer; datalen: integer): boolean of object; IWiaDataCallback = interface(IUnknown) ['{a558a866-a5b0-11d2-a08f-00c04f72dc3c}'] function BandedDataCallback(lMessage: integer; lStatus: integer; lPercentComplete: integer; lOffset: integer; lLength: integer; lReserved: integer; lResLength: integer; pbBuffer: pbyte): HRESULT; stdcall; end; WIA_DATA_TRANSFER_INFO = record ulSize: dword; ulSection: dword; ulBufferSize: dword; bDoubleBuffer: longbool; ulReserved1: dword; ulReserved2: dword; ulReserved3: dword; end; PWIA_DATA_TRANSFER_INFO = ^WIA_DATA_TRANSFER_INFO; TIEWiaOnProgress = function(percentage: integer): boolean of object; TWiaDataCallBack = class(TInterfacedObject, IWiaDataCallBack) header: WIA_DATA_CALLBACK_HEADER; data: pbyte; datalen: integer; OnGetPage: TIEWGetPage; OnProgress: TIEWiaOnProgress; function BandedDataCallback(lMessage: integer; lStatus: integer; lPercentComplete: integer; lOffset: integer; lLength: integer; lReserved: integer; lResLength: integer; pbBuffer: pbyte): HRESULT; stdcall; constructor Create; destructor Destroy; override; end; PWiaDataCallBAck = ^TWiaDataCallBack; IWiaEventCallback = interface(IUnknown) ['{ae6287b0-0084-11d2-973b-00a0c9068f2e}'] function ImageEventCallback(pEventGUID: pGUID; bstrEventDescription: pwchar; bstrDeviceID: pwchar; bstrDeviceDescription: pwchar; dwDeviceType: dword; bstrFullItemName: pwchar; var pulEventType: DWORD; ulReserved: DWORD): HRESULT; stdcall; end; TWiaEventCallBack = class(TInterfacedObject, IWiaEventCallBack) WIA: TObject; // the TIEWia object function ImageEventCallback(pEventGUID: pGUID; bstrEventDescription: pwchar; bstrDeviceID: pwchar; bstrDeviceDescription: pwchar; dwDeviceType: dword; bstrFullItemName: pwchar; var pulEventType: DWORD; ulReserved: DWORD): HRESULT; stdcall; constructor Create(inWIA: TObject); destructor Destroy; override; end; PWiaEventCallBAck = ^TWiaEventCallBack; IWiaDataTransfer = interface(IUnknown) ['{a6cef998-a5b0-11d2-a08f-00c04f72dc3c}'] function idtGetData: HRESULT; stdcall; // NOT STILL IMPLEMENTED function idtGetBandedData(pWiaDataTransInfo: PWIA_DATA_TRANSFER_INFO; pIWiaDataCallback: IWiaDataCallback): HRESULT; stdcall; function idtQueryGetData: HRESULT; stdcall; // NOT STILL IMPLEMENTED function idtEnumWIA_FORMAT_INFO: HRESULT; stdcall; // NOT STILL IMPLEMENTED function idtGetExtendedTransferInfo: HRESULT; stdcall; // NOT STILL IMPLEMENTED end; IEnumWiaItem = interface(IUnknown) ['{5e8383fc-3391-11d2-9a33-00c04fa36145}'] function Next(celt: integer; out ppIWiaItem: IWiaItem; var pceltFetched: integer): HRESULT; stdcall; function Skip: HRESULT; stdcall; // NOT STILL IMPLEMENTED function Reset: HRESULT; stdcall; // NOT STILL IMPLEMENTED function Clone: HRESULT; stdcall; // NOT STILL IMPLEMENTED function GetCount: HRESULT; stdcall; // NOT STILL IMPLEMENTED end; TIWiaItemArray = array[0..0] of IUnknown; // IUnknown instead IWiaItem because this crashes C++Builder PIWiaItemArray = ^TIWiaItemArray; IWiaItem = interface(IUnknown) ['{4db1ad10-3391-11d2-9a33-00c04fa36145}'] function GetItemType(var pItemType: integer): HRESULT; stdcall; function AnalyzeItem(lFlags: integer): HRESULT; stdcall; function EnumChildItems(out ppIEnumWiaItem: IEnumWiaItem): HRESULT; stdcall; function DeleteItem(lFlags: longint): HRESULT; stdcall; function CreateChildItem: HRESULT; stdcall; // NOT STILL IMPLEMENTED function EnumRegisterEventInfo: HRESULT; stdcall; // NOT STILL IMPLEMENTED function FindItemByName: HRESULT; stdcall; // NOT STILL IMPLEMENTED function DeviceDlg(hwndParent: HWND; lFlags: integer; lIntent: integer; out plItemCount: integer; out ppIWiaItem: PIWiaItemArray): HRESULT; stdcall; function DeviceCommand(lFlags: integer; pCmdGUID: PGUID; var pIWiaItem: IWiaItem): HRESULT; stdcall; function GetRootItem: HRESULT; stdcall; // NOT STILL IMPLEMENTED function EnumDeviceCapabilities: HRESULT; stdcall; // NOT STILL IMPLEMENTED function DumpItemData: HRESULT; stdcall; // NOT STILL IMPLEMENTED function DumpDrvItemData: HRESULT; stdcall; // NOT STILL IMPLEMENTED function DumpTreeItemData: HRESULT; stdcall; // NOT STILL IMPLEMENTED function Diagnostic: HRESULT; stdcall; // NOT STILL IMPLEMENTED end; IWiaPropertyStorage = interface(IUnknown) ['{98B5E8A0-29CC-491a-AAC0-E6DB4FDCCEB6}'] function ReadMultiple(cpspec: integer; rgpspec: pointer; rgpropvar: pointer): HRESULT; stdcall; function WriteMultiple(cpspec: integer; rgpspec: pointer; rgpropvar: pointer; propidNameFirst: integer): HRESULT; stdcall; function DeleteMultiple: HRESULT; stdcall; // NOT STILL IMPLEMENTED function ReadPropertyNames(cpropid: integer; rgpspec: pointer; var name: PWideChar): HRESULT; stdcall; function WritePropertyNames: HRESULT; stdcall; // NOT STILL IMPLEMENTED function DeletePropertyNames: HRESULT; stdcall; // NOT STILL IMPLEMENTED function Commit: HRESULT; stdcall; // NOT STILL IMPLEMENTED function Revert: HRESULT; stdcall; // NOT STILL IMPLEMENTED function Enum: HRESULT; stdcall; // NOT STILL IMPLEMENTED function SetTimes: HRESULT; stdcall; // NOT STILL IMPLEMENTED function SetClass: HRESULT; stdcall; // NOT STILL IMPLEMENTED function Stat: HRESULT; stdcall; // NOT STILL IMPLEMENTED function GetPropertyAttributes(cpspec: integer; rgpspec: pointer; var rgflags: integer; rgpropvar: pointer): HRESULT; stdcall; function GetCount: HRESULT; stdcall; // NOT STILL IMPLEMENTED function GetPropertyStream: HRESULT; stdcall; // NOT STILL IMPLEMENTED function SetPropertyStream: HRESULT; stdcall; // NOT STILL IMPLEMENTED end; IEnumWIA_DEV_INFO = interface(IUnknown) ['{5e38b83c-8cf1-11d1-bf92-0060081ed811}'] function Next(celt: integer; out rgelt: IWiaPropertyStorage; var pceltFetched: integer): HRESULT; stdcall; function Skip: HRESULT; stdcall; // NOT STILL IMPLEMENTED function Reset: HRESULT; stdcall; function Clone: HRESULT; stdcall; // NOT STILL IMPLEMENTED function GetCount(var celt: integer): HRESULT; stdcall; end; PIEnumWIA_DEV_INFO = ^IEnumWIA_DEV_INFO; PPIEnumWIA_DEV_INFO = ^PIEnumWIA_DEV_INFO; IWiaDevMgr = interface(IUnknown) ['{5eb2502a-8cf1-11d1-bf92-0060081ed811}'] function EnumDeviceInfo(lFlag: integer; out ppIEnum: IEnumWIA_DEV_INFO): HRESULT; stdcall; function CreateDevice(bstrDeviceID: WideString; out ppWiaItemRoot: IWiaItem): HRESULT; stdcall; function SelectDeviceDlg: HRESULT; stdcall; // NOT STILL IMPLEMENTED function SelectDeviceDlgID(hwndParent: HWND; lDeviceType: integer; lFlags: integer; var pbstrDeviceID: pwchar): HRESULT; stdcall; function GetImageDlg: HRESULT; stdcall; // NOT STILL IMPLEMENTED function RegisterEventCallbackProgram: HRESULT; stdcall; // NOT STILL IMPLEMENTED function RegisterEventCallbackInterface(lFlags: longint; bstrDeviceID: pwchar; pEventGUID: pGUID; pIWiaEventCallback: IWiaEventCallback; var pEventObject: IUnknown): HRESULT; stdcall; function RegisterEventCallbackCLSID: HRESULT; stdcall; // NOT STILL IMPLEMENTED function AddDeviceDlg: HRESULT; stdcall; // NOT STILL IMPLEMENTED end; IID_IWiaDevMgr = IWiaDevMgr; {!! TIEWiaDeviceInfo Declaration } TIEWiaDeviceInfo = class Name: string; ID: string; DeviceType: (iewScanner, iewDigitalCamera, iewStreamingVideo); DriverVersion: string; PortName: string; ServerName: string; Vendor: string; end; {!!} {!! TIEWiaItemType Declaration } TIEWiaItemType = set of ( witFree, witImage, witFile, witFolder, witRoot, witAnalyze, witAudio, witDevice, witDeleted, witDisconnected, witHPanorama, witVPanorama, witBurst, witStorage, witTransfer, witGenerated, witHasAttachments, witVideo, witTwainCapabilityPassThrough, witRemoved, witMask ); {!!} {!! TIEWiaItem Declaration TIEWiaItem = class This: IWiaItem; Children: TList; ItemType: ; constructor Create; destructor Destroy; override; end; !!} TIEWiaItem = class This: IWiaItem; Children: TList; ItemType: TIEWiaItemType; constructor Create; destructor Destroy; override; end; TIEWProcessingInfo = record DPIX: integer; DPIY: integer; end; {!! TIEWiaAttrib Declaration } TIEWiaAttrib = set of (iewaRead, iewaWrite, iewaSyncRequired, iewaNone, iewaRange, iewaList, iewaFlag, iewaCacheable); {!!} variantarray = array[0..MaxInt div 32] of variant; pvariantarray = ^variantarray; {!! TIEWiaValues Declaration TIEWiaValues = class max: variant; min: variant; count: integer; normal: variant; step: variant; property values[idx: integer]: variant; end; !!} TIEWiaValues = class private fValues: pvariantarray; function GetValues(idx: integer): variant; public max: variant; min: variant; count: integer; normal: variant; step: variant; constructor Create; destructor Destroy; override; property values[idx: integer]: variant read GetValues; end; {!! TIETransferFormat Declaration } TIETransferFormat = (ietfDefault, ietfBitmap, ietfJpeg, ietfRawBitmap); {!!} TIEWiaEvent=(ieeNone, ieeTreeUpdated, ieeItemCreated, ieeItemDeleted); {!! TIEWia Description TIEWia class (TImageEnIO. and TImageEnMIO. properties) allows you to set/get parameters, show dialogs and control WIA devices. Methods and Properties !!} TIEWia = class private fOLEInitialized: boolean; fIWiaDevMgr: IWiaDevMgr; fDevicesInfo: TList; // list of TIEWiaDeviceInfo objects fRoot: TIEWiaItem; // the root IWiaItem (encapsulated in TIEWiaItem) fOwner: TComponent; fMultiCallBack: TIEMultiCallBack; fEventCallBack1: IUnknown; // for WIA_EVENT_ITEM_CREATED event fEventCallBack2: IUnknown; // for WIA_EVENT_ITEM_DELETED event fEventCallBack3: IUnknown; // for WIA_EVENT_TREE_UPDATED event fOnProgress: TIEWiaOnProgress; fTakePicture: boolean; fDeleteTakenPicture: boolean; // delete the item got from fTakePicture (only for cameras) fSaveTransferBufferAs: string; fTransferFormat: TIETransferFormat; fCurrentIndex: integer; // index of current connected device fItemsTreeUpdated: TNotifyEvent; fLastEvent: TIEWiaEvent; procedure FillDevices; procedure FillItemChildren(parent: TIEWiaItem); function GetDevicesInfo(idx: integer): TIEWiaDeviceInfo; function GetDevicesInfoCount: integer; procedure EmptyDeviceInfo; function GetRoot: TIEWiaItem; function GetPage(header: PWIA_DATA_CALLBACK_HEADER; data: pointer; datalen: integer): boolean; procedure CheckConnectToDefault; function ConnectToEx(idx: integer; bMakeWiaDefault : Boolean): boolean; function GetDefaultItem(var item: TIEWiaItem; LastItem: boolean): boolean; procedure DoItemsTreeUpdated; procedure ClearRootItems; public ProcessingBitmap: TIEBitmap; ProcessingInfo: TIEWProcessingInfo; constructor Create(Owner: TComponent); destructor Destroy; override; property DevicesInfo[idx: integer]: TIEWiaDeviceInfo read GetDevicesInfo; property DevicesInfoCount: integer read GetDevicesInfoCount; function ConnectToUsingDialog: boolean; {!! TIEWia.ConnectedDeviceIndex Declaration property ConnectedDeviceIndex: integer; Description Returns the currently connected device index. This property is useful when you connect to a device using Windows dialog, to know which device has been connected, so next time it can be connected directly. !!} property ConnectedDeviceIndex: integer read fCurrentIndex; property Device: TIEWiaItem read GetRoot; procedure UpdateItems; // updates from Device (the root) function ConnectTo(Idx: integer = 0) : boolean; overload; function ConnectTo(const sName : string) : boolean; overload; function ShowAcquireDialog(SystemDialog: boolean = false): boolean; function Transfer(item: TIEWiaItem = nil; MultiPage: boolean = false): boolean; {!! TIEWia.TakePicture Declaration property TakePicture: boolean; Description If true, the next acquire will take a new picture from the camera. Demo Demos\ImageAcquisition\CameraGetImages\CameraGetImages.dpr !!} property TakePicture: boolean read fTakePicture write fTakePicture; {!! TIEWia.DeleteTakenPicture Declaration property DeleteTakenPicture: boolean; Description If true, the photographed image (using ) will be not saved in the camera memory. Demo Demos\ImageAcquisition\CameraGetImages\CameraGetImages.dpr !!} property DeleteTakenPicture: boolean read fDeleteTakenPicture write fDeleteTakenPicture; property OnProgress: TIEWiaOnProgress read fOnProgress write fOnProgress; property OnGetPage: TIEMultiCallBack read fMultiCallBack write fMultiCallBack; property OnItemsTreeUpdated: TNotifyEvent read fItemsTreeUpdated write fItemsTreeUpdated; property LastEvent: TIEWiaEvent read fLastEvent; // raw properties read/write function GetDeviceProperty(PropId: dword): Variant; function SetDeviceProperty(PropId: dword; val: integer): boolean; function SetItemProperty(PropId: dword; val: integer; item: TIEWiaItem = nil): boolean; function SetDevicePropertyVariant(PropId: dword; val: Variant): boolean; function SetItemPropertyVariant(PropId: dword; val: Variant; item: TIEWiaItem = nil): boolean; function GetItemProperty(PropId: dword; item: TIEWiaItem = nil): Variant; procedure GetItemPropertyAttrib(PropId: dword; item: TIEWiaItem; var attrib: TIEWiaAttrib; var values: TIEWiaValues); procedure FillTreeView(Items: TTreeNodes; IncludeDescription: boolean); {!! TIEWia.SaveTransferBufferAs Declaration property SaveTransferBufferAs: string Description Specifies a filename where to transfer the raw data received from the WIA device. This is useful when you want jpegs from a Camera, without losing quality by resaving. The file may be changed to raw, bmp or jpeg according to the actual image type received from the device. Demo Demos\ImageAcquisition\CameraGetImages\CameraGetImages.dpr !!} property SaveTransferBufferAs: string read fSaveTransferBufferAs write fSaveTransferBufferAs; {!! TIEWia.TransferFormat Declaration property TransferFormat: ; Description Specifies the desired format for transfer of raw data from the WIA device. This is useful when you want jpegs from a Camera, without losing quality or a BMP from a scanner for maximum quality. TransferFormat is also filled with the actual used format at the end of image transfer. Demo Demos\ImageAcquisition\CameraGetImages\CameraGetImages.dpr !!} property TransferFormat: TIETransferFormat read fTransferFormat write fTransferFormat; function GetItemThumbnail(item: TIEWiaItem; destBitmap: TIEBitmap): boolean; procedure DeleteItem(item: TIEWiaItem); function IsItemDeleted(item: TIEWiaItem): boolean; function SourceNameToIndex(const sName : string) : Integer; end; implementation uses imageenproc, bmpfilt, imageenio, jpegfilt, iemio, iexAcquire, hyieutils {$ifdef IENEWVARIANTS} , variants {$endif} ; const CLSID_WiaDevMgr: TGUID = '{A1F4E726-8CF1-11D1-BF92-0060081ED811}'; // commands WIA_CMD_TAKE_PICTURE: TGUID = '{af933cac-acad-11d2-a093-00c04f72dc3c}'; WIA_CMD_SYNCHRONIZE: TGUID = '{9b26b7b2-acad-11d2-a093-00c04f72dc3c}'; WIA_CMD_DELETE_ALL_ITEMS: TGUID = '{e208c170-acad-11d2-a093-00c04f72dc3c}'; WIA_CMD_CHANGE_DOCUMENT: TGUID = '{04e725b0-acae-11d2-a093-00c04f72dc3c}'; WIA_CMD_UNLOAD_DOCUMENT: TGUID = '{1f3b3d8e-acae-11d2-a093-00c04f72dc3c}'; // events WIA_EVENT_DEVICE_DISCONNECTED: TGUID='{143e4e83-6497-11d2-a231-00c04fa31809}'; WIA_EVENT_DEVICE_CONNECTED: TGUID= '{a28bbade-64b6-11d2-a231-00c04fa31809}'; WIA_EVENT_ITEM_DELETED: TGUID= '{1d22a559-e14f-11d2-b326-00c04f68ce61}'; WIA_EVENT_ITEM_CREATED: TGUID= '{4c8f4ef5-e14f-11d2-b326-00c04f68ce61}'; WIA_EVENT_TREE_UPDATED: TGUID= '{c9859b91-4ab2-4cd6-a1fc-582eec55e585}'; WIA_EVENT_VOLUME_INSERT: TGUID= '{9638bbfd-d1bd-11d2-b31f-00c04f68ce61}'; WIA_EVENT_SCAN_IMAGE: TGUID= '{a6c5a715-8c6e-11d2-977a-0000f87a926f}'; WIA_EVENT_SCAN_PRINT_IMAGE: TGUID= '{b441f425-8c6e-11d2-977a-0000f87a926f}'; WIA_EVENT_SCAN_FAX_IMAGE: TGUID= '{c00eb793-8c6e-11d2-977a-0000f87a926f}'; WIA_EVENT_SCAN_OCR_IMAGE: TGUID= '{9d095b89-37d6-4877-afed-62a297dc6dbe}'; WIA_EVENT_SCAN_EMAIL_IMAGE: TGUID= '{c686dcee-54f2-419e-9a27-2fc7f2e98f9e}'; WIA_EVENT_SCAN_FILM_IMAGE: TGUID= '{9b2b662c-6185-438c-b68b-e39ee25e71cb}'; WIA_EVENT_SCAN_IMAGE2: TGUID= '{fc4767c1-c8b3-48a2-9cfa-2e90cb3d3590}'; WIA_EVENT_SCAN_IMAGE3: TGUID= '{154e27be-b617-4653-acc5-0fd7bd4c65ce}'; WIA_EVENT_SCAN_IMAGE4: TGUID= '{a65b704a-7f3c-4447-a75d-8a26dfca1fdf}'; WIA_EVENT_STORAGE_CREATED: TGUID= '{353308b2-fe73-46c8-895e-fa4551ccc85a}'; WIA_EVENT_STORAGE_DELETED: TGUID= '{5e41e75e-9390-44c5-9a51-e47019e390cf}'; WIA_EVENT_STI_PROXY: TGUID= '{d711f81f-1f0d-422d-8641-927d1b93e5e5}'; WIA_EVENT_CANCEL_IO: TGUID= '{c860f7b8-9ccd-41ea-bbbf-4dd09c5b1795}'; NULLGUID: TGUID = '{00000000-0000-0000-0000-000000000000}'; CLSCTX_LOCAL_SERVER = 4; CLSCTX_REMOTE_SERVER = $10; CLSCTX_INPROC_HANDLER = 2; CLSCTX_INPROC_SERVER = 1; WIA_DEVINFO_ENUM_LOCAL = $00000010; PRSPEC_LPWSTR = 0; PRSPEC_PROPID = 1; WIA_SELECT_DEVICE_NODEFAULT = $00000001; WIA_INTENT_NONE = $00000000; WIA_DEVICE_DIALOG_USE_COMMON_UI = $00000004; type TVarType = Word; TOleBool = WordBool; PShortInt = ^ShortInt; TShortIntArray = array[0..Maxint div 16] of ShortInt; PShortIntArray = ^TShortIntArray; POleBool = ^TOleBool; TOleBoolArray = array[0..Maxint div 16] of TOleBool; POleBoolArray = ^TOleBoolArray; TLongIntArray = array[0..Maxint div 16] of LongInt; PLongIntArray = ^TLongIntArray; TULongArray = array[0..MaxInt div 16] of ULong; PULongArray = ^TULongArray; TLargeIntegerArray = array[0..Maxint div 16] of TLargeInteger; PLargeIntegerArray = ^TLargeIntegerArray; TOleDate = Double; POleDate = ^TOleDate; TOleDateArray = array[0..maxint div 16] of TOleDate; POleDateArray = ^TOleDateArray; PCLSID = PGUID; PBStr = ^TBStr; PLPSTR = ^LPSTR; PLPWSTR = ^LPWSTR; LPWSTRArray = array[0..maxint div 16] of LPWSTR; PLPWSTRArray = ^LPWSTRArray; LPSTRArray = array[0..maxint div 16] of LPSTR; PLPSTRArray = ^LPSTRArray; TBStr = PWideChar; TBStrArray = array[0..maxint div 16] of TBStr; PBStrArray = ^TBStrArray; PROPSPEC = record ulKind: ULONG; case Integer of 0: (propid: dword); 1: (lpwstr: PWideChar); end; LARGE_INTEGER = packed record LowPart: DWORD; HighPart: Longint; end; ULARGE_INTEGER = packed record LowPart: DWORD; HighPart: DWORD; end; TULargeInteger = ULARGE_INTEGER; PULargeInteger = ^TULargeInteger; TULargeIntegerArray = array[0..maxint div 16] of TULargeInteger; PULargeIntegerArray = ^TULargeIntegerArray; PPropVariant = ^TPropVariant; TCurrencyArray = array[0..maxint div 16] of Currency; PCurrencyArray = ^TCurrencyArray; TFileTimeArray = array[0..maxint div 16] of TFileTime; PFileTimeArray = ^TFileTimeArray; TBLOB = record cbSize: Longint; pBlobData: Pointer; end; PClipData = ^TClipData; TCLIPDATA = record cbSize: Longint; ulClipFmt: Longint; pClipData: Pointer; end; TClipDataArray = array[0..maxint div 32] of TClipData; PClipDataArray = ^TClipDataArray; TGUIDArray = array[0..maxint div 32] of TGUID; PGUIDArray = ^TGUIDArray; TCAUB = record cElems: ULONG; pElems: PBytearray; end; TCAI = record cElems: ULONG; pElems: PShortIntarray; end; TCAUI = record cElems: ULONG; pElems: PWordarray; end; TCABOOL = record cElems: ULONG; pElems: POleBoolarray; end; TCAL = record cElems: ULONG; pElems: PLongintarray; end; TCAUL = record cElems: ULONG; pElems: PULONGArray; end; TCAFLT = record cElems: ULONG; pElems: PSinglearray; end; TCASCODE = record cElems: ULONG; pElems: pintegerarray; end; TCAH = record cElems: ULONG; pElems: PLargeIntegerArray; end; TCAUH = record cElems: ULONG; pElems: PULargeIntegerArray; end; TCADBL = record cElems: ULONG; pElems: PDoubleArray; end; TCACY = record cElems: ULONG; pElems: PCurrencyArray; end; TCADATE = record cElems: ULONG; pElems: POleDateArray; end; TCAFILETIME = record cElems: ULONG; pElems: PFileTimeArray; end; TCACLSID = record cElems: ULONG; pElems: PGUIDArray; end; TCACLIPDATA = record cElems: ULONG; pElems: PClipDataArray; end; TCABSTR = record cElems: ULONG; pElems: PBSTRArray; end; TCALPSTR = record cElems: ULONG; pElems: PLPSTRArray; end; TCALPWSTR = record cElems: ULONG; pElems: PLPWSTRArray; end; TCAPROPVARIANT = record cElems: ULONG; pElems: PPropVariant; end; PROPVARIANT = record vt: TVarType; wReserved1: Word; wReserved2: Word; wReserved3: Word; case Integer of 0: (bVal: Byte); 1: (iVal: SmallInt); 2: (uiVal: Word); 3: (boolVal: TOleBool); 4: (obool: TOleBool); // obool instead of bool, because C++Builder uses bool as keyword 5: (lVal: Longint); 6: (ulVal: Cardinal); 7: (fltVal: Single); 8: (scode: integer); 9: (hVal: LARGE_INTEGER); 10: (uhVal: ULARGE_INTEGER); 11: (dblVal: Double); 12: (cyVal: Currency); 13: (date: TOleDate); 14: (filetime: TFileTime); 15: (puuid: PGUID); 16: (blob: TBlob); 17: (pclipdata: PClipData); 18: (pStream: Pointer); 19: (pStorage: Pointer); 20: (bstrVal: TBStr); 21: (pszVal: PAnsiChar); 22: (pwszVal: PWideChar); 23: (caub: TCAUB); 24: (cai: TCAI); 25: (caui: TCAUI); 26: (cabool: TCABOOL); 27: (cal: TCAL); 28: (caul: TCAUL); 29: (caflt: TCAFLT); 30: (cascode: TCASCODE); 31: (cah: TCAH); 32: (cauh: TCAUH); 33: (cadbl: TCADBL); 34: (cacy: TCACY); 35: (cadate: TCADATE); 36: (cafiletime: TCAFILETIME); 37: (cauuid: TCACLSID); 38: (caclipdata: TCACLIPDATA); 39: (cabstr: TCABSTR); 40: (calpstr: TCALPSTR); 41: (calpwstr: TCALPWSTR); 42: (capropvar: TCAPROPVARIANT); end; TPropVariant = PROPVARIANT; STGMEDIUM = record tymed: Longint; case Integer of 0: (hBitmap: HBitmap; unkForRelease: pointer); 1: (hMetaFilePict: THandle); 2: (hEnhMetaFile: THandle); 3: (hGlobal: HGlobal); 4: (lpszFileName: PWideChar); 5: (stm: pointer); 6: (stg: pointer); end; PSTGMEDIUM = ^STGMEDIUM; const VT_EMPTY = 0; { [V] [P] nothing } VT_NULL = 1; { [V] SQL style Null } VT_I2 = 2; { [V][T][P] 2 byte signed int } VT_I4 = 3; { [V][T][P] 4 byte signed int } VT_R4 = 4; { [V][T][P] 4 byte real } VT_R8 = 5; { [V][T][P] 8 byte real } VT_CY = 6; { [V][T][P] currency } VT_DATE = 7; { [V][T][P] date } VT_BSTR = 8; { [V][T][P] binary string } VT_DISPATCH = 9; { [V][T] IDispatch FAR* } VT_ERROR = 10; { [V][T] SCODE } VT_BOOL = 11; { [V][T][P] True=-1, False=0 } VT_VARIANT = 12; { [V][T][P] VARIANT FAR* } VT_UNKNOWN = 13; { [V][T] IUnknown FAR* } VT_DECIMAL = 14; { [V][T] [S] 16 byte fixed point } VT_I1 = 16; { [T] signed char } VT_UI1 = 17; { [T] unsigned char } VT_UI2 = 18; { [T] unsigned short } VT_UI4 = 19; { [T] unsigned long } VT_I8 = 20; { [T][P] signed 64-bit int } VT_UI8 = 21; { [T] unsigned 64-bit int } VT_INT = 22; { [T] signed machine int } VT_UINT = 23; { [T] unsigned machine int } VT_VOID = 24; { [T] C style void } VT_HRESULT = 25; { [T] } VT_PTR = 26; { [T] pointer type } VT_SAFEARRAY = 27; { [T] (use VT_ARRAY in VARIANT) } VT_CARRAY = 28; { [T] C style array } VT_USERDEFINED = 29; { [T] user defined type } VT_LPSTR = 30; { [T][P] null terminated string } VT_LPWSTR = 31; { [T][P] wide null terminated string } VT_FILETIME = 64; { [P] FILETIME } VT_BLOB = 65; { [P] Length prefixed bytes } VT_STREAM = 66; { [P] Name of the stream follows } VT_STORAGE = 67; { [P] Name of the storage follows } VT_STREAMED_OBJECT = 68; { [P] Stream contains an object } VT_STORED_OBJECT = 69; { [P] Storage contains an object } VT_BLOB_OBJECT = 70; { [P] Blob contains an object } VT_CF = 71; { [P] Clipboard format } VT_CLSID = 72; { [P] A Class ID } VT_VECTOR = $1000; { [P] simple counted array } VT_ARRAY = $2000; { [V] SAFEARRAY* } VT_BYREF = $4000; { [V] } VT_RESERVED = $8000; VT_ILLEGAL = $FFFF; VT_ILLEGALMASKED = $0FFF; VT_TYPEMASK = $0FFF; const ieole32 = 'ole32.dll'; function CoCreateInstance(const clsid: TGUID; unkOuter: IUnknown; dwClsContext: Longint; const iid: TGUID; out pv): HResult; stdcall; external ieole32 name 'CoCreateInstance'; function OleInitialize(pwReserved: Pointer): HResult; stdcall; external ieole32 name 'OleInitialize'; procedure OleUninitialize; stdcall; external ieole32 name 'OleUninitialize'; procedure CoTaskMemFree(pv: pointer); stdcall; external ieole32 name 'CoTaskMemFree'; //procedure ReleaseStgMedium(pmedium: pointer); stdcall; external ieole32 name 'ReleaseStgMedium'; function FreePropVariantArray(cVariants: ULONG; rgvars: PPROPVARIANT): HRESULT; stdcall; external ieole32 name 'FreePropVariantArray'; constructor TIEWia.Create(Owner: TComponent); var callback: TWiaEventCallBack; begin inherited Create; fOLEInitialized := Succeeded(OleInitialize(nil)); fItemsTreeUpdated := nil; fOwner := Owner; fMultiCallBack := nil; fOnProgress := nil; ProcessingBitmap := nil; fDevicesInfo := TList.Create(); fRoot := nil; fIWiaDevMgr := nil; fTakePicture := true; fDeleteTakenPicture := false; fSaveTransferBufferAs := ''; fTransferFormat := ietfDefault; fCurrentIndex := 0; CoCreateInstance(CLSID_WiaDevMgr, nil, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, fIWiaDevMgr); fEventCallBack1 := nil; fEventCallBack2 := nil; fEventCallBack3 := nil; if fIWIADevMgr <> nil then begin callback := TWiaEventCallBack.Create(self); // this object will become fEventCallBack1 fIWiaDevMgr.RegisterEventCallbackInterface(0, nil, @WIA_EVENT_ITEM_CREATED, callback, fEventCallBack1); callback := TWiaEventCallBack.Create(self); // this object will become fEventCallBack2 fIWiaDevMgr.RegisterEventCallbackInterface(0, nil, @WIA_EVENT_ITEM_DELETED, callback, fEventCallBack2); callback := TWiaEventCallBack.Create(self); // this object will become fEventCallBack3 fIWiaDevMgr.RegisterEventCallbackInterface(0, nil, @WIA_EVENT_TREE_UPDATED, callback, fEventCallBack3); end; end; destructor TIEWia.Destroy; begin // unregister events fEventCallBack1 := nil; fEventCallBack2 := nil; fEventCallBack3 := nil; // fIWiaDevMgr := nil; EmptyDeviceInfo; FreeAndNil(fDevicesInfo); if assigned(fRoot) then FreeAndNil(fRoot); if fOLEInitialized then OleUninitialize; inherited; end; procedure TIEWia.EmptyDeviceInfo; var i: integer; begin for i := 0 to fDevicesInfo.Count - 1 do TIEWiaDeviceInfo(fDevicesInfo[i]).free; fDevicesInfo.Clear; end; function GET_STIDEVICE_TYPE(dwDevType: dword): integer; begin result := HIWORD(dwDevType); end; function GET_STIDEVICE_SUBTYPE(dwDevType: dword): integer; begin result := LOWORD(dwDevType); end; procedure TIEWia.FillDevices; const PN = 7; var pIEnumWIA_DEV_INFO: IEnumWIA_DEV_INFO; pIWiaPropStg: IWiaPropertyStorage; hr: HRESULT; ulFetched: integer; vPropSpec: array[0..PN - 1] of PROPSPEC; vPropVar: array[0..PN - 1] of PROPVARIANT; inf: TIEWiaDeviceInfo; begin if fIWiaDevMgr = nil then exit; hr := fIWiaDevMgr.EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, pIEnumWIA_DEV_INFO); if hr <> 0 then exit; hr := pIEnumWIA_DEV_INFO.Reset; if hr <> 0 then exit; EmptyDeviceInfo; while true do begin hr := pIEnumWIA_DEV_INFO.Next(1, pIWiaPropStg, ulFetched); if (hr = 0) and (ulFetched = 1) then begin FillChar(vPropVar[0], sizeof(PROPVARIANT) * PN, 0); vPropSpec[0].ulKind := PRSPEC_PROPID; vPropSpec[0].propid := WIA_DIP_DEV_ID; vPropSpec[1].ulKind := PRSPEC_PROPID; vPropSpec[1].propid := WIA_DIP_DEV_NAME; vPropSpec[2].ulKind := PRSPEC_PROPID; vPropSpec[2].propid := WIA_DIP_DEV_TYPE; vPropSpec[3].ulKind := PRSPEC_PROPID; vPropSpec[3].propid := WIA_DIP_DRIVER_VERSION; vPropSpec[4].ulKind := PRSPEC_PROPID; vPropSpec[4].propid := WIA_DIP_PORT_NAME; vPropSpec[5].ulKind := PRSPEC_PROPID; vPropSpec[5].propid := WIA_DIP_SERVER_NAME; vPropSpec[6].ulKind := PRSPEC_PROPID; vPropSpec[6].propid := WIA_DIP_VEND_DESC; hr := pIWiaPropStg.ReadMultiple(PN, @vPropSpec[0], @vPropVar[0]); if hr = S_OK then begin inf := TIEWiaDeviceInfo.Create(); inf.Name := vPropVar[1].bstrVal; inf.ID := vPropVar[0].bstrVal; case (vPropVar[2].lVal shr 16) and $FFFF of StiDeviceTypeScanner: inf.DeviceType := iewScanner; StiDeviceTypeDigitalCamera: inf.DeviceType := iewDigitalCamera; StiDeviceTypeStreamingVideo: inf.DeviceType := iewStreamingVideo; end; inf.DriverVersion := vPropVar[3].bstrVal; inf.PortName := vPropVar[4].bstrVal; inf.ServerName := vPropVar[5].bstrVal; inf.Vendor := vPropVar[6].bstrVal; fDevicesInfo.Add(inf); end; FreePropVariantArray(PN, @vPropVar[0]); pIWiaPropStg := nil; end else break; end; end; {!! TIEWia.GetDeviceProperty Declaration function GetDeviceProperty(PropId: TPropID): Variant; Description Gets a device property value as Variant. . Example // returns the horizontal bed size HorizBedSize := ImageEnView.IO.WiaParams.GetDeviceProperty(WIA_DPS_HORIZONTAL_BED_SIZE); !!} // if not connected, connect to first device function TIEWia.GetDeviceProperty(PropId: dword): Variant; begin CheckConnectToDefault; result := GetItemProperty(PropId, fRoot); end; {!! TIEWia.SetDeviceProperty Declaration function SetDeviceProperty(PropId: dword; val: integer): boolean; Description Sets a device property value as integer. . !!} // This is important starting at Delphi 6 because it requires typed constants otherwise the variant in invalid! function TIEWia.SetDeviceProperty(PropId: dword; val: integer): boolean; begin result := SetDevicePropertyVariant(PropId, Variant(val)); end; {!! TIEWia.SetDevicePropertyVariant Declaration function SetDevicePropertyVariant(PropId: dword; val: Variant): boolean; Description Sets a device property value as Variant. . Example // sets the string to print (when the scanner supports the endorser) ImageEnView.IO.WiaParams.SetDeviceProperty(WIA_DPS_ENDORSER_STRING, 'Hello World!'); !!} // if not connected, connect to first device function TIEWia.SetDevicePropertyVariant(PropId: dword; val: Variant): boolean; begin CheckConnectToDefault; result := SetItemProperty(PropId, val, fRoot); end; {!! TIEWia.DevicesInfo Declaration property DevicesInfo[idx: integer]: ; Description Returns info about the specified WIA device. Example // this fills a combobox with all installed devices with ImageEnView.IO.WIAParams do for i := 0 to DevicesInfoCount-1 do ComboBox1.Items.Add( DevicesInfo[I].Name ); end; !!} function TIEWia.GetDevicesInfo(idx: integer): TIEWiaDeviceInfo; begin if fDevicesInfo.Count = 0 then FillDevices; if idx < fDevicesInfo.Count then result := fDevicesInfo[idx] else result := nil; end; // if not connected, connect to first device procedure TIEWia.CheckConnectToDefault; begin if fRoot = nil then ConnectToEx(0, False); end; {!! TIEWia.DevicesInfoCount Declaration property DevicesInfoCount: integer; Description Returns the number of WIA devices available. !!} function TIEWia.GetDevicesInfoCount: integer; begin CheckConnectToDefault; if fDevicesInfo.Count = 0 then FillDevices; result := fDevicesInfo.Count; end; {!! TIEWia.ConnectTo Declaration function ConnectTo(idx : integer) : boolean;overload; function ConnectTo(const sName : string) : boolean; overload; Description Connect to the specified device. Returns True if successful. Example // Connect to the second device ImageEnView.IO.WiaParams.ConnectTo( 1 ); // Connect to a named scanner ImageEnView.IO.WiaParams.ConnectTo('CanoScan FB620'); !!} function TIEWia.ConnectTo(idx: integer): boolean; begin Result := ConnectToEx(idx, True); end; function TIEWia.ConnectToEx(idx: integer; bMakeWiaDefault : Boolean): boolean; var hr: HRESULT; pw: WideString; dinfo: TIEWiaDeviceInfo; begin result := false; if fIWiaDevMgr = nil then exit; if assigned(fRoot) then FreeAndNil(fRoot); fRoot := nil; fCurrentIndex := idx; dinfo := DevicesInfo[idx]; if dinfo <> nil then begin fRoot := TIEWiaItem.Create; pw := dinfo.ID; hr := fIWiaDevMgr.CreateDevice(pw, fRoot.this); if hr = S_OK then begin if dinfo.DeviceType=iewDigitalCamera then fTakePicture := false else fTakePicture := true; result := true; FillItemChildren(fRoot); end else begin FreeAndNil(fRoot); end; end; if Result and bMakeWiaDefault then begin // Make WIA the API for subsequent calls to Acquire {$IFDEF IEINCLUDEMULTIVIEW} if fOwner is TImageEnMIO then (fOwner as TImageEnMIO).AcquireParams.fSelectedSourceAPI := ieaWIA else {$ENDIF} If fOwner is TImageEnIO then (fOwner as TImageEnIO).AcquireParams.fSelectedSourceAPI := ieaWIA; end; end; function TIEWia.ConnectTo(const sName : string) : boolean; // NPC: 11/11/11 var i: Integer; begin Result := False; if sName = '' then exit; for i := 0 to DevicesInfoCount - 1 do if SameText(DevicesInfo[I].Name, sName) then begin Result := ConnectToEx(i, True); exit; end; end; procedure TIEWia.ClearRootItems; var i: integer; begin if fRoot<>nil then begin for i := 0 to fRoot.Children.Count - 1 do TIEWiaItem(fRoot.Children[i]).Free; fRoot.Children.Clear; end; end; {!! TIEWia.UpdateItems Declaration procedure UpdateItems; Description Reload items tree. !!} procedure TIEWia.UpdateItems; begin if fRoot<>nil then begin ClearRootItems; FillItemChildren(fRoot); end; end; {!! TIEWia.ConnectToUsingDialog Declaration function ConnectToUsingDialog: boolean; Description Shows a system dialog that allows users to select a WIA device. Returns True if user presses OK. Example If ImageEnView.IO.WiaParams.ConnectToUsingDialog then ImageEnView.IO.Acquire(ieaWIA); !!} function TIEWia.ConnectToUsingDialog: boolean; var hr: HRESULT; pw: pwchar; i: integer; dinfo: TIEWiaDeviceInfo; ss: string; begin result := false; if fIWiaDevMgr = nil then exit; if assigned(fRoot) then FreeAndNil(fRoot); hr := fIWiaDevMgr.SelectDeviceDlgID(IEFindHandle(fOwner), StiDeviceTypeDefault, WIA_SELECT_DEVICE_NODEFAULT, pw); if hr <> S_OK then exit; // search device index ss := WideCharToString(pw); GetDevicesInfo(0); // this will fill fDevicesInfo list, if needed for i := 0 to fDevicesInfo.Count-1 do begin dinfo := DevicesInfo[i]; if dinfo.ID = ss then begin result := ConnectToEx(i, True); break; end; end; end; function BuildWiaItemType(lType: integer): TIEWiaItemType; begin result := []; if (lType and WiaItemTypeFree) <> 0 then result := result + [witFree]; if (lType and WiaItemTypeImage) <> 0 then result := result + [witImage]; if (lType and WiaItemTypeFile) <> 0 then result := result + [witFile]; if (lType and WiaItemTypeFolder) <> 0 then result := result + [witFolder]; if (lType and WiaItemTypeRoot) <> 0 then result := result + [witRoot]; if (lType and WiaItemTypeAnalyze) <> 0 then result := result + [witAnalyze]; if (lType and WiaItemTypeAudio) <> 0 then result := result + [witAudio]; if (lType and WiaItemTypeDevice) <> 0 then result := result + [witDevice]; if (lType and WiaItemTypeDeleted) <> 0 then result := result + [witDeleted]; if (lType and WiaItemTypeDisconnected) <> 0 then result := result + [witDisconnected]; if (lType and WiaItemTypeHPanorama) <> 0 then result := result + [witHPanorama]; if (lType and WiaItemTypeVPanorama) <> 0 then result := result + [witVPanorama]; if (lType and WiaItemTypeBurst) <> 0 then result := result + [witBurst]; if (lType and WiaItemTypeStorage) <> 0 then result := result + [witStorage]; if (lType and WiaItemTypeTransfer) <> 0 then result := result + [witTransfer]; if (lType and WiaItemTypeGenerated) <> 0 then result := result + [witGenerated]; if (lType and WiaItemTypeHasAttachments) <> 0 then result := result + [witHasAttachments]; if (lType and WiaItemTypeVideo) <> 0 then result := result + [witVideo]; if (lType and WiaItemTypeTwainCapabilityPassThrough) <> 0 then result := result + [witTwainCapabilityPassThrough]; if (lType and WiaItemTypeRemoved) <> 0 then result := result + [witRemoved]; if (lType and WiaItemTypeMask) <> 0 then result := result + [witMask]; end; {!! TIEWia.ShowAcquireDialog Declaration function ShowAcquireDialog(SystemDialog: boolean): boolean; Description Shows a system dialog that allows user to set parameters and display a preview of the image. You still need to call to get the image. Returns True if user presses OK (or Acquire). Example If ImageEnView.IO.WiaParams.ShowAcquireDialog(true) then ImageEnView.IO.Acquire(ieaWIA); !!} // if not connected, connect to first device // this free and refill al children of fRoot function TIEWia.ShowAcquireDialog(SystemDialog: boolean): boolean; var hr: HRESULT; items: PIWiaItemArray; itemsCount: integer; i, flags: integer; iewi: TIEWiaItem; lType: integer; begin result := false; if fIWiaDevMgr = nil then exit; CheckConnectToDefault; if fRoot = nil then exit; // free fRoot children ClearRootItems; flags := 0; if SystemDialog then flags := flags or WIA_DEVICE_DIALOG_USE_COMMON_UI; hr := fRoot.This.DeviceDlg(IEFindHandle(fOwner), flags, WIA_INTENT_NONE, itemsCount, items); if hr <> S_OK then begin // Add items back to fRoot UpdateItems; exit; end; for i := 0 to itemsCount - 1 do begin iewi := TIEWiaItem.Create; items[i].QueryInterface(IWiaItem, iewi.This); fRoot.Children.Add(iewi); iewi.This.GetItemType(lType); iewi.ItemType := BuildWiaItemType(lType); if (lType and WiaItemTypeFolder) <> 0 then // this is a folder FillItemChildren(iewi); end; CoTaskMemFree(items); result := true; end; constructor TIEWiaItem.Create; begin inherited; This := nil; Children := TList.Create; ItemType := []; end; destructor TIEWiaItem.Destroy; var i: integer; begin This := nil; // free the old object for i := 0 to Children.Count-1 do TIEWiaItem(Children[i]).Free; FreeAndNil(Children); inherited; end; procedure TIEWia.FillItemChildren(parent: TIEWiaItem); var hr: HRESULT; enum: IEnumWiaItem; iewi: TIEWiaItem; wi: IWiaItem; fetched, lType: integer; begin if assigned(parent.This) then begin // get item type of the parent (useful only if the parent is the root) parent.This.GetItemType(lType); parent.ItemType := BuildWiaItemType(lType); // hr := parent.This.EnumChildItems(enum); if hr <> S_OK then exit; while enum.Next(1, wi, fetched) = S_OK do begin iewi := TIEWiaItem.Create; iewi.This := wi; parent.Children.Add(iewi); wi.GetItemType(lType); iewi.ItemType := BuildWiaItemType(lType); if (lType and WiaItemTypeFolder) <> 0 then // this is a folder FillItemChildren(iewi); end; enum := nil; end; end; {!! TIEWia.Device Declaration property Device: ; Description Returns the currently connected (selected) device. This is the 'root' item. !!} function TIEWia.GetRoot: TIEWiaItem; begin result := fRoot; end; function GetFirstImageItem(Current: TIEWiaItem): TIEWiaItem; var i: integer; begin result := nil; if Current = nil then exit; if witImage in Current.ItemType then result := Current else if witFolder in Current.ItemType then for i := 0 to Current.Children.Count - 1 do begin result := GetFirstImageItem(TIEWiaItem(Current.Children[i])); if result <> nil then exit; // found one end; end; function GetLastImageItem(Current: TIEWiaItem): TIEWiaItem; var i: integer; begin result := nil; if Current = nil then exit; if witImage in Current.ItemType then result := Current else if witFolder in Current.ItemType then for i := Current.Children.Count - 1 downto 0 do begin result := GetLastImageItem(TIEWiaItem(Current.Children[i])); if result <> nil then exit; // found one end; end; (* procedure ConvertGUIDToPROPVARIANT(gg: TGUID; outvar: PPROPVARIANT); begin zeromemory(outvar, sizeof(PROPVARIANT)); outvar.vt := VT_CLSID; outvar.puuid := end; *) function ConvertPROPVARIANTGUID_ToString(invar: PPROPVARIANT): AnsiString; begin result := IEConvertGUIDToString(invar^.puuid); end; function ConvertPROPVARIANT_ToSmallIntArray(invar: PPROPVARIANT): variant; var i: integer; begin result := VarArrayCreate([0, invar^.caui.cElems-1], varSmallInt); for i := 0 to invar^.caui.cElems-1 do result[i] := invar^.caui.pElems[i]; end; function ConvertPROPVARIANT_ToByteArray(invar: PPROPVARIANT): variant; var i: integer; begin result := VarArrayCreate([0, invar^.caub.cElems-1], varByte); for i := 0 to invar^.caub.cElems-1 do result[i] := invar^.caub.pElems[i]; end; {$OPTIMIZATION OFF} // this allows you to get unsupported values by Variant (as GUID) function PropVariantToVariant(vv: PPROPVARIANT): Variant; var xv: variant; begin case vv^.vt of VT_CLSID: result := ConvertPROPVARIANTGUID_ToString(vv); VT_UI2 or VT_VECTOR: // array of words result := ConvertPROPVARIANT_ToSmallIntArray(vv); VT_UI1 or VT_VECTOR: // array of bytes result := ConvertPROPVARIANT_ToByteArray(vv); else begin try copymemory(@TVarData(xv), vv, sizeof(PROPVARIANT)); result := xv; zeromemory(@TVarData(xv), sizeof(PROPVARIANT)); except end; end; end; end; // this allows you to get unsupported values by Variant (as GUID) procedure VariantToPropVariant(invar: Variant; outvar: PPROPVARIANT); var xv: variant; IsString: boolean; IsStringGuid: boolean; ss: string; gg: PGUID; begin IsString := (TVarData(invar).VType and varString) <> 0; IsStringGuid := false; if IsString then begin // check if it is a string guid ss := invar; IsStringGuid := (length(ss) >= 38) and (ss[10] = '-') and (ss[15] = '-') and (ss[20] = '-') and (ss[25] = '-') and (ss[1] = '{') and (ss[38] = '}'); end; if IsStringGuid then begin getmem(gg, sizeof(TGUID)); IEConvertAStringToGUID(AnsiString(invar), gg); zeromemory(outvar, sizeof(PROPVARIANT)); outvar^.vt := VT_CLSID; outvar^.puuid := gg; end else begin xv := invar; copymemory(outvar, @TVarData(xv), sizeof(PROPVARIANT)); zeromemory(@TVarData(xv), sizeof(PROPVARIANT)); end; end; // use this only with PROPVARIANTs created using VariantTopropVariant procedure FreeCreatedPropVariant(invar: PPROPVARIANT); var xv: variant; begin if invar^.vt=VT_CLSID then begin freemem(invar^.puuid); zeromemory(invar, sizeof(PROPVARIANT)); end else begin copymemory(@TVarData(xv), invar, sizeof(PROPVARIANT)); xv := 0; // this frees allocated data zeromemory(invar, sizeof(PROPVARIANT)); zeromemory(@TVarData(xv), sizeof(PROPVARIANT)); end; end; {$OPTIMIZATION ON} {!! TIEWia.GetItemProperty Declaration function GetItemProperty( PropId: TPropID; item: =nil ): Variant; Description Gets an item (image) property as Variant. Example // get the horizontal resolution Xres := ImageEnView1.IO.WiaParams.GetItemProperty(WIA_IPS_XRES) ); !!} // if not connected, connect to first device // if item is nil, search one automatically function TIEWia.GetItemProperty(PropId: dword; item: TIEWiaItem): Variant; var hr: HRESULT; pIWiaPropStg: IWiaPropertyStorage; vPropSpec: PROPSPEC; vPropVar: PROPVARIANT; begin pIWiaPropStg := nil; CheckConnectToDefault; if not GetDefaultItem(item, false) then exit; hr := item.This.QueryInterface(IWiaPropertyStorage, pIWiaPropStg); if hr <> S_OK then exit; fillchar(vPropVar, sizeof(PROPVARIANT), 0); vPropSpec.ulKind := PRSPEC_PROPID; vPropSpec.propid := PropID; pIWiaPropStg.ReadMultiple(1, @vPropSpec, @vPropVar); result := PropVariantToVariant(@vPropVar); FreePropVariantArray(1, @vPropVar); end; constructor TIEWiaValues.Create; begin inherited Create; max := 0; min := 0; count := 0; normal := 0; step := 0; fValues := nil; end; destructor TIEWiaValues.Destroy; var i: integer; begin if fValues <> nil then begin for i := 0 to count - 1 do fValues[i] := 0; freemem(fValues); end; inherited Destroy; end; function TIEWiaValues.GetValues(idx: integer): variant; begin result := fValues[idx]; end; {!! TIEWia.GetItemPropertyAttrib Declaration procedure GetItemPropertyAttrib( PropId: TPropID; item: ; var attrib: ; var values: ); Description Fills attrib and values parameters. They allow knowing a property range and access rights. Example // this gets the minimum and maximum values allowed for horizontal resolution var attrib: TIEWiaAttrib; values: TIEWiaValues; begin ImageEnView1.IO.WIAParams.GetItemPropertyAttrib(WIA_IPS_XRES, nil, attrib, values); Edit.Hint := 'Min='+inttostr(values.min)+' Max='+inttostr(values.max); values.free; end; !!} procedure TIEWia.GetItemPropertyAttrib(PropId: dword; item: TIEWiaItem; var attrib: TIEWiaAttrib; var values: TIEWiaValues); var hr: HRESULT; pIWiaPropStg: IWiaPropertyStorage; vPropSpec: PROPSPEC; vPropVar: PROPVARIANT; i, flags: integer; begin values := TIEWiaValues.Create; pIWiaPropStg := nil; CheckConnectToDefault; if not GetDefaultItem(item, false) then exit; hr := item.This.QueryInterface(IWiaPropertyStorage, pIWiaPropStg); if hr <> S_OK then exit; fillchar(vPropVar, sizeof(PROPVARIANT), 0); vPropSpec.ulKind := PRSPEC_PROPID; vPropSpec.propid := PropID; try pIWiaPropStg.GetPropertyAttributes(1, @vPropSpec, flags, @vPropVar); attrib := []; if (flags and WIA_PROP_CACHEABLE) <> 0 then attrib := attrib + [iewaCacheable]; if (flags and WIA_PROP_FLAG) <> 0 then attrib := attrib + [iewaFlag]; if (flags and WIA_PROP_LIST) <> 0 then attrib := attrib + [iewaList]; if (flags and WIA_PROP_NONE) <> 0 then attrib := attrib + [iewaNone]; if (flags and WIA_PROP_RANGE) <> 0 then attrib := attrib + [iewaRange]; if (flags and WIA_PROP_READ) <> 0 then attrib := attrib + [iewaRead]; if (flags and WIA_PROP_SYNC_REQUIRED) <> 0 then attrib := attrib + [iewaSyncRequired]; if (flags and WIA_PROP_WRITE) <> 0 then attrib := attrib + [iewaWrite]; if (iewaRange in attrib) and ((vPropVar.vt and VT_VECTOR) <> 0) and ((vPropVar.vt and VT_UI4) <> 0) then begin // range (integers) if vPropVar.caul.pElems <> nil then begin if WIA_RANGE_MAX < vPropVar.caul.cElems then values.max := integer(vPropVar.caul.pElems[WIA_RANGE_MAX]); if WIA_RANGE_MIN < vPropVar.caul.cElems then values.min := integer(vPropVar.caul.pElems[WIA_RANGE_MIN]); if WIA_RANGE_NOM < vPropVar.caul.cElems then values.normal := integer(vPropVar.caul.pElems[WIA_RANGE_NOM]); if WIA_RANGE_STEP < vPropVar.caul.cElems then values.step := integer(vPropVar.caul.pElems[WIA_RANGE_STEP]); end; end else if (iewaList in attrib) and ((vPropVar.vt and VT_VECTOR) <> 0) and ((vPropVar.vt and VT_UI4) <> 0) then begin // list (integers) if vPropVar.caul.pElems <> nil then begin values.count := integer(vPropVar.caul.pElems[WIA_LIST_COUNT]); values.normal := integer(vPropVar.caul.pElems[WIA_LIST_NOM]); values.fValues := AllocMem(sizeof(variant) * values.count); // AllocMem fill allocated memory with zeros for i := WIA_LIST_VALUES to WIA_LIST_VALUES + values.count - 1 do values.fValues[i - WIA_LIST_VALUES] := integer(vPropVar.caul.pElems[i]); end; end else if (iewaList in attrib) and ((vPropVar.vt and VT_VECTOR) <> 0) and ((vPropVar.vt and VT_CLSID) <> 0) then begin // list (GUIDs) if vPropVar.cauuid.pElems <> nil then begin values.count := vPropVar.cauuid.cElems; values.normal := 0; getmem(values.fValues, sizeof(variant) * values.count); for i := 0 to values.count - 1 do values.fValues[i] := IEConvertGUIDToString(@vPropVar.cauuid.pElems[i]); end; end else if (iewaFlag in attrib) and ((vPropVar.vt and VT_VECTOR) <> 0) and ((vPropVar.vt and VT_UI4) <> 0) then begin // flag (integers), supported only nominal value if vPropVar.caul.pElems <> nil then values.normal := integer(vPropVar.caul.pElems[WIA_FLAG_NOM]); end; except end; end; function SetItemPropertyEx(PropId: dword; val: Variant; item: IWiaItem): boolean; var hr: HRESULT; pIWiaPropStg: IWiaPropertyStorage; vPropSpec: PROPSPEC; vPropVar: PROPVARIANT; begin result := false; pIWiaPropStg := nil; hr := item.QueryInterface(IWiaPropertyStorage, pIWiaPropStg); if hr <> S_OK then exit; fillchar(vPropVar, sizeof(PROPVARIANT), 0); vPropSpec.ulKind := PRSPEC_PROPID; vPropSpec.propid := PropID; VariantToPropVariant(val, @vPropVar); hr := pIWiaPropStg.WriteMultiple(1, @vPropSpec, @vPropVar, 0); FreeCreatedPropVariant(@vPropVar); result := hr = S_OK; end; {!! TIEWia.SetItemProperty Declaration function TIEWia.SetItemProperty(PropId: dword; val: integer; item: =nil): boolean; Description Sets an item (image) property as integer. Example // sets horizontal resolution to 150 dpi ImageEnView1.IO.WiaParams.SetItemProperty(WIA_IPS_XRES, 150); !!} // This is important starting at Delphi 6 because it requires typed constants otherwise the variant in invalid! function TIEWia.SetItemProperty(PropId: dword; val: integer; item: TIEWiaItem): boolean; begin result := SetItemPropertyVariant(PropId, Variant(val), item); end; {!! TIEWia.SetItemPropertyVariant Declaration function SetItemPropertyVariant(PropId: dword; val: Variant; item: =nil): boolean; Description Sets an item (image) property as Variant. Example // sets horizontal resolution to 150 dpi ImageEnView1.IO.WiaParams.SetItemProperty(WIA_IPS_XRES, 150); !!} // if not connected, connect to first device // if item is nil, search one automatically function TIEWia.SetItemPropertyVariant(PropId: dword; val: Variant; item: TIEWiaItem): boolean; begin result := false; CheckConnectToDefault; if not GetDefaultItem(item, false) then exit; result := SetItemPropertyEx(PropId, val, item.This); end; // return a valid item on if item=nil, otherwise return item // return false if no items are available function TIEWia.GetDefaultItem(var item: TIEWiaItem; LastItem: boolean): boolean; begin result := true; if item = nil then begin // search for an image item if LastItem then item := GetLastImageItem(fRoot) else item := GetFirstImageItem(fRoot); if item = nil then result := false; end; end; // if not connected, connect to first device // if item is nil, search one automatically function TIEWia.Transfer(item: TIEWiaItem; MultiPage: boolean): boolean; var transf: IWiaDataTransfer; hr: HRESULT; callback: TWiaDataCallBack; trinfo: WIA_DATA_TRANSFER_INFO; xitem, witem: IWiaItem; i: integer; begin result := false; if fIWiaDevMgr = nil then exit; CheckConnectToDefault; if (not GetDefaultItem(item, false)) and ((fTakePicture=false) or (fRoot=nil)) then exit; if MultiPage then begin if not SetItemProperty(WIA_IPA_TYMED, WIA_TYMED_MULTIPAGE_CALLBACK, item) then SetItemProperty(WIA_IPA_TYMED, WIA_TYMED_CALLBACK, item); end else SetItemProperty(WIA_IPA_TYMED, WIA_TYMED_CALLBACK, item); if assigned(item) then begin witem := item.This; xitem := nil; end; if fTakePicture then begin fLastEvent := ieeNone; fRoot.This.DeviceCommand(0, @WIA_CMD_TAKE_PICTURE, xitem); // if a new item is requested put it in witem, otherwise witem is unassigned (tehn =item.This) if DevicesInfo[fCurrentIndex].DeviceType=iewDigitalCamera then begin // wait up to 5 seconds waiting for ImageEventCallback for i := 1 to 50 do begin fRoot.This.DeviceCommand(0, @WIA_CMD_SYNCHRONIZE, xitem); // inside this command will execute the callback if fLastEvent<>ieeNone then break; sleep(100); end; // select last item UpdateItems; item := nil; GetDefaultItem(item, true); if assigned(item) then witem := item.This; end; end; if xitem <> nil then begin witem := xitem; xitem := nil; end; case fTransferFormat of ietfBitmap: SetItemPropertyEx(WIA_IPA_FORMAT, IEConvertGUIDToString(@WiaImgFmt_MEMORYBMP), witem); ietfJpeg: SetItemPropertyEx(WIA_IPA_FORMAT, IEConvertGUIDToString(@WiaImgFmt_JPEG), witem); else SetItemPropertyEx(WIA_IPA_FORMAT, IEConvertGUIDToString(@WiaImgFmt_MEMORYBMP), witem); end; hr := witem.QueryInterface(IWiaDataTransfer, transf); if hr <> S_OK then exit; callback := TWiaDataCallBack.Create; callback.OnGetPage := GetPage; callback.OnProgress := fOnProgress; fillchar(trinfo, sizeof(trinfo), 0); trinfo.ulSize := sizeof(WIA_DATA_TRANSFER_INFO); hr := transf.idtGetBandedData(@trinfo, callback); // callback.Destroy is called by idtGetBandedData if fTakePicture and fDeleteTakenPicture and (DevicesInfo[fCurrentIndex].DeviceType=iewDigitalCamera) then begin // delete the taken item witem.DeleteItem(0); end; if item.This <> witem then witem := nil; result := hr = S_OK; end; function TIEWia.GetPage(header: PWIA_DATA_CALLBACK_HEADER; data: pointer; datalen: integer): boolean; var iemem: TIEMemStream; NullProgress: TProgressRec; aborting: boolean; tmpparams: TIOParams; callbackParams: TIOParams; FullParamsAssign: boolean; tempAlphaChannel: TIEMask; ext: string; procedure AssignIO(dest, source: TIOParams); begin if FullParamsAssign then dest.Assign(source) else begin dest.DpiX := source.DpiX; dest.DpiY := source.DpiY; dest.BitsPerSample := source.BitsPerSample; dest.SamplesPerPixel := source.SamplesPerPixel; dest.Width := source.Width; dest.Height := source.Height; end; end; begin iemem := TIEMemStream.Create(data, datalen); tmpparams := TIOParams.Create( nil ); try FullParamsAssign := false; NullProgress := NullProgressRec ( Aborting ); tempAlphaChannel := nil; if CompareMem(@header.guidFormatID, @WiaImgFmt_MEMORYBMP, sizeof(TGuid)) then begin // memory BMP BMPReadStream(iemem, ProcessingBitmap, 0, tmpparams, NullProgress, false, true, tempAlphaChannel, true); fTransferFormat := ietfRawBitmap; end else if comparemem(@header.guidFormatID, @WiaImgFmt_BMP, sizeof(TGuid)) then begin // BMP BMPReadStream(iemem, ProcessingBitmap, 0, tmpparams, NullProgress, false, false, tempAlphaChannel, true); fTransferFormat := ietfBitmap; end else if comparemem(@header.guidFormatID, @WiaImgFmt_JPEG, sizeof(TGuid)) then begin // JPEG ReadJpegStream(iemem, nil, ProcessingBitmap, tmpparams, NullProgress, false, false, true, false, true, true, -1, tmpparams.IsNativePixelFormat); FullParamsAssign := true; // this allows you to load IPTC and EXIF fTransferFormat := ietfJpeg; end; if fSaveTransferBufferAs <> '' then begin case fTransferFormat of ietfDefault, ietfRawBitmap: ext := '.raw'; ietfBitmap: ext := '.bmp'; ietfJpeg: ext := '.jpg'; end; iemem.SaveToFile(ChangeFileExt(fSaveTransferBufferAs, ext)); end; if assigned(fMultiCallBack) then begin fMultiCallBack(ProcessingBitmap, TObject(callbackParams), tmpparams.DpiX, tmpparams.DpiY); AssignIO(callbackParams, tmpparams); end; ProcessingInfo.DPIX := tmpparams.DpiX; ProcessingInfo.DPIY := tmpparams.DpiY; if fOwner is TImageEnIO then AssignIO((fOwner as TImageEnIO).Params, tmpparams); finally tmpparams.Free(); iemem.Free(); end; result := true; end; constructor TWiaDataCallBack.Create; begin inherited Create; data := nil; datalen := 0; OnProgress := nil; OnGetPage := nil; end; destructor TWiaDataCallBack.Destroy; begin if data <> nil then freemem(data); inherited; end; function TWiaDataCallBack.BandedDataCallback(lMessage: integer; lStatus: integer; lPercentComplete: integer; lOffset: integer; lLength: integer; lReserved: integer; lResLength: integer; pbBuffer: pbyte): HRESULT; var ptr: pbyte; // procedure GetPage(); begin if (datalen > 0) and assigned(OnGetPage) then if not OnGetPage(@header, data, datalen) then result := S_FALSE; end; // begin result := S_OK; case lMessage of IT_MSG_DATA: begin ReallocMem(data, datalen + lLength); ptr := data; inc(ptr, datalen); CopyMemory(ptr, pbBuffer, lLength); inc(datalen, lLength); end; IT_MSG_DATA_HEADER: begin CopyMemory(@header, pbBuffer, sizeof(WIA_DATA_CALLBACK_HEADER)); end; IT_MSG_FILE_PREVIEW_DATA: ; IT_MSG_FILE_PREVIEW_DATA_HEADER: ; IT_MSG_NEW_PAGE: begin GetPage(); ReallocMem(data, 0); datalen := 0; end; IT_MSG_STATUS: ; IT_MSG_TERMINATION: begin GetPage(); ReallocMem(data, 0); datalen := 0; end; end; if assigned(OnProgress) then if OnProgress(lPercentComplete) then result := S_OK else result := S_FALSE; end; function BuildItemName(WIA: TIEWIA; item: TIEWiaItem; IncludeDescription: boolean): string; begin if IncludeDescription then begin result := WIA.GetItemProperty(WIA_IPA_ITEM_NAME, item) + ' ( '; if witFree in item.ItemType then result := result + ' Free'; if witImage in item.ItemType then result := result + ' Image'; if witFile in item.ItemType then result := result + ' File'; if witFolder in item.ItemType then result := result + ' Folder'; if witRoot in item.ItemType then result := result + ' Root'; if witAnalyze in item.ItemType then result := result + ' Analyze'; if witAudio in item.ItemType then result := result + ' Audio'; if witDevice in item.ItemType then result := result + ' Device'; if witDeleted in item.ItemType then result := result + ' Deleted'; if witDisconnected in item.ItemType then result := result + ' Disconnected'; if witHPanorama in item.ItemType then result := result + ' HPanorama'; if witVPanorama in item.ItemType then result := result + ' VPanorama'; if witBurst in item.ItemType then result := result + ' Burst'; if witStorage in item.ItemType then result := result + ' Storage'; if witTransfer in item.ItemType then result := result + ' Transfer'; if witGenerated in item.ItemType then result := result + ' Generated'; if witHasAttachments in item.ItemType then result := result + ' HasAttachments'; if witVideo in item.ItemType then result := result + ' Video'; if witRemoved in item.ItemType then result := result + ' Removed'; result := result + ' )'; end else result := WIA.GetItemProperty(WIA_IPA_ITEM_NAME, item); end; procedure AddChildrenOf(WIA: TIEWIA; Items: TTreeNodes; ItemsParent: TIEWiaItem; TreeParent: TTreeNode; IncludeDescription: boolean); var i: integer; node: TTreeNode; begin if assigned(ItemsParent) then for i := 0 to ItemsParent.Children.Count - 1 do begin if not WIA.IsItemDeleted(ItemsParent.Children[i]) then begin node := Items.AddChild(TreeParent, BuildItemName(WIA, ItemsParent.Children[i], IncludeDescription)); node.Data := ItemsParent.Children[i]; AddChildrenOf(WIA, Items, ItemsParent.Children[i], node, IncludeDescription); end; end; end; {!! TIEWia.FillTreeView Declaration procedure FillTreeView(Items: TTreeNodes; IncludeDescription: boolean); Description Fills a TTreeView component with the content of WIA device. Example TreeView1.Items.Clear; ImageEnView1.IO.WIAParams.FillTreeView(TreeView1.Items, false); TreeView1.FullExpand; Demo Demos\ImageAcquisition\CameraGetImages\CameraGetImages.dpr !!} procedure TIEWia.FillTreeView(Items: TTreeNodes; IncludeDescription: boolean); var node: TTreeNode; begin if not assigned(Device) then ConnectToEx(0, False); if assigned(Device) then begin node := Items.Add(TTreeNode.Create(Items), BuildItemName(self, Device, IncludeDescription)); node.Data := Device; AddChildrenOf(self, Items, Device, node, IncludeDescription); end; end; {!! TIEWia.GetItemThumbnail Declaration function GetItemThumbnail(item: ; destBitmap: ): boolean; Description Downloads the thumbnail of specified item in destBitmap . Return true on success. Demo Demos\ImageAcquisition\CameraGetImages\CameraGetImages.dpr !!} function TIEWia.GetItemThumbnail(item: TIEWiaItem; destBitmap: TIEBitmap): boolean; var image: variant; width, height: integer; rl, i: integer; data: pbyte; begin result := false; image := GetItemProperty(WIA_IPC_THUMBNAIL, item); width := GetItemProperty(WIA_IPC_THUMB_WIDTH, item); height := GetItemProperty(WIA_IPC_THUMB_HEIGHT, item); if VarIsArray(image) and (width<>0) and (height<>0) then begin destBitmap.Allocate(width, height, ie24RGB); data := VarArrayLock(image); rl := IEBitmapRowLen(width, 24, 32); for i := height-1 downto 0 do begin CopyMemory( destBitmap.Scanline[i], data, width*3 ); inc(data, rl); end; VarArrayUnLock(image); end; end; {!! TIEWia.DeleteItem Declaration procedure DeleteItem(item: ); Description Deletes the specified item. At the end of session the item should be actually removed. Demo Demos\ImageAcquisition\CameraGetImages\CameraGetImages.dpr !!} procedure TIEWia.DeleteItem(item: TIEWiaItem); begin item.This.DeleteItem(0); end; {!! TIEWia.IsItemDeleted Declaration function IsItemDeleted(item: ): boolean; Description Returns true when the item is marked as deleted. Demo Demos\ImageAcquisition\CameraGetImages\CameraGetImages.dpr !!} function TIEWia.IsItemDeleted(item: TIEWiaItem): boolean; var lType: integer; begin item.This.GetItemType(lType); result := witDeleted in BuildWiaItemType(lType); end; constructor TWiaEventCallBack.Create(inWIA: TObject); begin inherited Create; WIA := inWIA; end; destructor TWiaEventCallBack.Destroy; begin inherited Destroy; end; function TWiaEventCallBack.ImageEventCallback(pEventGUID: pGUID; bstrEventDescription: pwchar; bstrDeviceID: pwchar; bstrDeviceDescription: pwchar; dwDeviceType: dword; bstrFullItemName: pwchar; var pulEventType: DWORD; ulReserved: DWORD): HRESULT; begin if assigned(WIA) then begin if comparemem(pEventGUID, @WIA_EVENT_TREE_UPDATED, sizeof(TGuid)) then begin (WIA as TIEWia).fLastEvent := ieeTreeUpdated; (WIA as TIEWia).DoItemsTreeUpdated; end else if comparemem(pEventGUID, @WIA_EVENT_ITEM_CREATED, sizeof(TGuid)) then begin (WIA as TIEWia).fLastEvent := ieeItemCreated; (WIA as TIEWia).DoItemsTreeUpdated; end else if comparemem(pEventGUID, @WIA_EVENT_ITEM_DELETED, sizeof(TGuid)) then begin (WIA as TIEWia).fLastEvent := ieeItemDeleted; (WIA as TIEWia).DoItemsTreeUpdated; end; end; result := S_OK; end; procedure TIEWia.DoItemsTreeUpdated; begin if assigned(fItemsTreeUpdated) then fItemsTreeUpdated(self); end; function TIEWia.SourceNameToIndex(const sName : string) : Integer; var i: Integer; begin Result := -1; for i := 0 to DevicesInfoCount - 1 do if SameText(sName, DevicesInfo[i].Name) then begin Result := i; exit; end; end; {$ELSE} // IEINCLUDEIEXACQUIRE implementation {$ENDIF} end.