#!perl -w use strict; use warnings; use Win32::GUI(); use Win32::API; use Win32::API::Prototype; use Carp qw(croak); use Data::Dumper; # Preloaded methods go here. ########################################################################### # Supported C types ########################################################################### # ATOM s HWINSTA L # BOOL L HWND L # BOOLEAN c INT i # BYTE C INT32 i # CHAR c INT64 q # COLORREF L LANGID s # DWORD L LCID L # DWORD32 L LCSCSTYPE L # DWORD64 Q LCSGAMUTMATCH L # FLOAT f LCTYPE L # HACCEL L LONG l # HANDLE L LONG32 l # HBITMAP L LONG64 q # HBRUSH L LONGLONG q # HCOLORSPACE L LPARAM L # HCONV L LRESULT L # HCONVLIST L REGSAM L # HCURSOR L SC_HANDLE L # HDC L SC_LOCK L # HDDEDATA L SERVICE_STATUS_HANDLE L # HDESK L SHORT s # HDROP L SIZE_T L # HDWP L SSIZE_T L # HENHMETAFILE L TBYTE c # HFILE L TCHAR C # HFONT L UCHAR C # HGDIOBJ L UINT I # HGLOBAL L UINT_PTR L # HHOOK L UINT32 I # HICON L UINT64 Q # HIMC L ULONG L # HINSTANCE L ULONG32 L # HKEY L ULONG64 Q # HKL L ULONGLONG Q # HLOCAL L USHORT S # HMENU L WCHAR S # HMETAFILE L WORD S # HMODULE L WPARAM L # HPALETTE L VOID c # HPEN L int i # HRGN L long l # HRSRC L float f # HSZ L double d # char c ########################################################################### # DLL Function call setup ########################################################################### my $ScanInit = Win32::API->new('ScanAPI.dll','long ScanInit(HWND hWnd, long wminseriton, long wmRemoval)'); # my $ScanErrToText = Win32::API->new('ScanAPI.dll','long ScanErrToText(int Err, TCHAR lpBuff, int BuffSize)'); my $ScanOpenDevice = Win32::API->new('ScanAPI.dll','long ScanOpenDevice(HANDLE hScanner)'); my $ScanCloseDevice = Win32::API->new('ScanAPI.dll','long ScanCloseDevice(HANDLE hScanner)'); my $ScanRequestDataEvents = Win32::API->new('ScanAPI.dll','long ScanRequestDataEvents(HANDLE hScanner, HWND hWnd, long wmScannerData)'); my $ScanTrigger = Win32::API->new('ScanAPI.dll','long ScanTrigger(HANDLE hScanner)'); my $ScanGetData = Win32::API->new('ScanAPI.dll','long ScanGetData(HANDLE hScanner, LPSTR lpBuff, LPINT BufSize)'); # my $ScanGetData = Win32::API->new('ScanAPI.dll','ScanGetData',['N','P','N'],'N'); # sub hWnd(){0}; # tell the ScanAPI function that no call back is needed sub WM_USER() {1024}; sub WM_INSERTION(){WM_USER + 1}; # the message we want on device insertions sub WM_REMOVAL(){WM_USER + 2}; # the message we want on device removals sub WM_SCANNERDATA(){WM_USER + 3}; # the message we want when data is available sub WM_CHS_STATUS(){WM_USER + 4}; # the message we want when CHS status changes sub NOCALLBACK(){1}; # SCANAPI retunr values use constant SR_SUCCESS => 0; use constant SR_INVALID_WMINSERTION => 1; use constant SR_INVALID_WMREMOVAL => 2; use constant SR_PLUG_THREAD_FAILURE => 3; use constant SR_DEVICE_THREAD_FAILURE => 4; use constant SR_INVALID_SCANNER_HANDLE => 5; use constant SR_OPEN_FAILURE => 6; use constant SR_INVALID_WMSCANNERDATA => 7; use constant SR_NO_DATA => 8; use constant SR_BUFFER_TOO_SMALL => 9; use constant SR_SCANNER_NOT_OPEN => 10; use constant SR_INVALID_SOUND_TYPE => 11; use constant SR_WAVFILE_NOT_FOUND => 12; use constant SR_MEMORY_FAILURE => 13; use constant SR_INVALID_ERR => 14; use constant SR_TOO_MANY_USERS => 15; use constant SR_NOT_INITIALIZED => 16; use constant SR_DEVICE_FAILURE => 17; use constant SR_INTERNAL_FAILURE => 18; use constant SR_INVALID_STRUCTURE => 19; use constant SR_HOTSWAP_ERROR => 20; use constant SR_SCANNER_REMOVED => 21; use constant SR_INVALID_WMCHSSTATUS => 22; our $ret; our $ScannerHandle; sub Buffersize(){1024}; # Create a window, saving it in variable $main my $main = Win32::GUI::Window->new( -name => 'Main', -width => 100, -height => 100, ); # Add a label to the window (by default a label # has size big enough for its text and is positioned # in the top left of its containing window) $main->AddLabel( -text => $main->{-handle}, ); $main->AddButton( -name => 'button1', -text => "click", ); $main->AddButton( -name => 'button2', -text => "scan", -left => 50, ); $main->Hook(WM_INSERTION, \&WMINSERTION); $main->Hook(WM_REMOVAL, \&WMREMOVAL); $main->Hook(WM_SCANNERDATA, \&WMSCANNERDATA); # Show our main window $main->Show(); # Enter the windows message loop, often referred # to as the "dialog phase". Win32::GUI::Dialog(); # When the message loopreturns control to our # perl program, then the interaction with the # GUI is complete, so we exit. exit(0); ###################### ###################### # The Terminate event handler for a window # named 'Main'. Returning -1 causes the # windows message loop to exit and return # control to our perl program. sub Main_Terminate { return -1; } sub button1_Click { $ret=$ScanInit->Call($main->{-handle},WM_INSERTION,WM_REMOVAL); if ($ret != SR_SUCCESS) { &DisplayScanError($ret); exit; } print "Scanner Interface Started\n"; } 1; sub button2_Click { $ret=$ScanTrigger->Call($ScannerHandle); if ($ret != SR_SUCCESS) { &DisplayScanError($ret); exit; } print "Scanner Triggered\n"; } 1; sub WMINSERTION { my ($object, $wParam, $lParam, $type, $msgcode) = @_; return unless $type == 0; return unless $msgcode == WM_INSERTION; $ScannerHandle=$lParam; print "Scanner inserted\n\nscanner handle: $lParam\n"; my $ret=$ScanOpenDevice->Call($lParam); # Inform scanApi.dll this application does nor handle call backs print "Return code: $ret\n"; if ($ret != SR_SUCCESS) { &DisplayScanError($ret); return -1; } print "Scanner opened\n"; $ret=$ScanRequestDataEvents->Call($lParam, $main->{-handle}, WM_SCANNERDATA); if ($ret != SR_SUCCESS) { &DisplayScanError($ret); return -1; } print "Scanner Events Monitoring started\n"; return; } sub WMREMOVAL { my ($object, $wParam, $lParam, $type, $msgcode) = @_; return unless $type == 0; return unless $msgcode == WM_REMOVAL; print "Scanner Removed\n\nscanner handle: $lParam\n"; my $ret=$ScanCloseDevice->Call($lParam); print "Return code: $ret\n"; if ($ret != SR_SUCCESS) { &DisplayScanError($ret); exit; } print "Scanner Closed\n"; return; } sub WMSCANNERDATA { print "Scanner Has data waiting\n"; my ($object, $wParam, $lParam, $type, $msgcode) = @_; return unless $type == 0; return unless $msgcode == WM_SCANNERDATA; print "Data size: $wParam\n"; my $buffer= 0 x $wParam; my $buffersize= \$wParam; my $ret=$ScanGetData->Call($ScannerHandle, $buffer, $buffersize); # Inform scanApi.dll this application does nor handle call backs print "Return code: $ret"; if ($ret != SR_SUCCESS) { &DisplayScanError($ret); exit; } print $buffer."\n\n"; # undef @_; # undef $object; # undef $wParam; # undef $lParam; # undef $type; # undef $msgcode; return 1; } sub DisplayScanError() { my $ErrorCode=$_[0]; my $ErrorText=''; if ($ErrorCode == SR_INVALID_WMINSERTION) { $ErrorText= "ScanAPI Error: Invalid WM_INSERTION Value"; } if ($ErrorCode == SR_INVALID_WMREMOVAL) { $ErrorText= "ScanAPI Error: Invalid WM_REMOVAL Value"; } if ($ErrorCode == SR_PLUG_THREAD_FAILURE) { $ErrorText= "ScanAPI Error: SR_PLUG_THREAD_FAILURE"; } if ($ErrorCode == SR_DEVICE_THREAD_FAILURE) { $ErrorText= "ScanAPI Error: SR_DEVICE_THREAD_FAILURE"; } if ($ErrorCode == SR_INVALID_SCANNER_HANDLE) { $ErrorText= "ScanAPI Error: SR_INVALID_SCANNER_HANDLE"; } if ($ErrorCode == SR_OPEN_FAILURE) { $ErrorText= "ScanAPI Error: SR_OPEN_FAILURE"; } if ($ErrorCode == SR_INVALID_WMSCANNERDATA) { $ErrorText= "ScanAPI Error: SR_INVALID_WMSCANNERDATA"; } if ($ErrorCode == SR_NO_DATA) { $ErrorText= "ScanAPI Error: SR_NO_DATA"; } if ($ErrorCode == SR_BUFFER_TOO_SMALL) { $ErrorText= "ScanAPI Error: SR_BUFFER_TOO_SMALL"; } if ($ErrorCode == SR_SCANNER_NOT_OPEN) { $ErrorText= "ScanAPI Error: SR_SCANNER_NOT_OPEN"; } if ($ErrorCode == SR_INVALID_SOUND_TYPE) { $ErrorText= "ScanAPI Error: SR_INVALID_SOUND_TYPE"; } if ($ErrorCode == SR_WAVFILE_NOT_FOUND) { $ErrorText= "ScanAPI Error: SR_WAVFILE_NOT_FOUND"; } if ($ErrorCode == SR_MEMORY_FAILURE) { $ErrorText= "ScanAPI Error: SR_MEMORY_FAILURE"; } if ($ErrorCode == SR_INVALID_ERR) { $ErrorText= "ScanAPI Error: SR_INVALID_ERR"; } if ($ErrorCode == SR_TOO_MANY_USERS) { $ErrorText= "ScanAPI Error: SR_TOO_MANY_USERS"; } if ($ErrorCode == SR_NOT_INITIALIZED) { $ErrorText= "ScanAPI Error: SR_NOT_INITIALIZED"; } if ($ErrorCode == SR_DEVICE_FAILURE) { $ErrorText= "ScanAPI Error: SR_DEVICE_FAILURE"; } if ($ErrorCode == SR_INTERNAL_FAILURE) { $ErrorText= "ScanAPI Error: SR_INTERNAL_FAILURE"; } if ($ErrorCode == SR_INVALID_STRUCTURE) { $ErrorText= "ScanAPI Error: SR_INVALID_STRUCTURE"; } if ($ErrorCode == SR_HOTSWAP_ERROR) { $ErrorText= "ScanAPI Error: SR_HOTSWAP_ERROR"; } if ($ErrorCode == SR_SCANNER_REMOVED) { $ErrorText= "ScanAPI Error: SR_SCANNER_REMOVED"; } if ($ErrorCode == SR_INVALID_WMCHSSTATUS) { $ErrorText= "ScanAPI Error: SR_INVALID_WMCHSSTATUS"; } print "Error Message: $ErrorText\n"; return 1; }