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 $ret=$ScanGetData->Call($ScannerHandle, $buffer, \$buffersize);
print "Return code: $ret";
if ($ret != SR_SUCCESS)
{
&DisplayScanError($ret);
exit;
}
print $buffer."\n\n";
return 1;
}
####
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;
# added this line to make function call work
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";
return 1;
}
####
SCANGETDATA()
Prototype:
SCAN_RESULT ScanGetData(HANDLE hScanner, TCHAR * lpBuff, LPINT BufSize);
Purpose:
Returns scanned data after a successful read operation on the scanner device.
Arguments:
[in] hScanner is the value received by the client application in lParam of the WM_INSERTION message specified when ScanInit() was called.
If the application program doesn’t support callbacks, use 1 for the HANDLE (if multi-scanner disabled) .
[out] lpBuff points to the buffer to receive the scanned data.
[in/out] BufSize points to the size of the buffer in bytes (not characters). Upon return, BufSize will be set to the number of bytes written into lpBuff. This can be converted to a character count by dividing BufSize by sizeof(TCHAR). Typically the buffer size will be equal to the character count on Win32 Desktop systems.
####
#!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;
}