Win32::GUI Community,

Thank you for your help in the birth of this sample application. Thanks to
Brian Millham for the MUTEX suggestion and sample code. Also to jez for the
Hook suggestion. To Robert May, Thanks for such a good perl module. I have
posted this sampe so others won't have the same growing pains that I did. I
hope you can use it.

The purpose of this application is to scan barcodes using the Socket Mobile
ScanAPI.dll. You must have the Socket Mobile SDK installed before this
application will run.

The application has two buttons. The first "START" will initilize the
ScanAPI.dll. The second button "Scan" will trigger the scanner and print out
the result.

Based on the SocketScan.exe, it will also trigger the scanner by starting a
second copy of the application. This is useful when you use a Hot button on
a laptop to start the application and trigger the scanner.

Please feel free to suggest improvements.

Richard Noble

___ Code ___

#!perl -w
use strict;
use warnings;

use Win32::GUI qw(MB_OK MB_ICONASTERISK);
use Win32::API;
use Win32::API::Prototype;
use Carp qw(croak);
use Win32::Mutex;


# Preloaded methods go here.

  
###########################################################################
   # DLL Function call setup
  
###########################################################################


   my $ScanInit = Win32::API->new('ScanAPI.dll','long ScanInit(HWND hWnd,
long wminseriton, long wmRemoval)');
   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)');

   # define user messages
   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 WM_SCANBADGE(){WM_USER + 5};    # the message we want when
application starts a 2nd copy to scan a badge
   sub NOCALLBACK(){1};

   # SCANAPI return 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 or open the mutex
# This code checks to see if a copy of the application is running.
# If it detects the first copy it sends it a message to trigger the
# scanner. Then exit after the message has been posted.
my $mutex = Win32::Mutex->new(1, "Mutex Test");
# Die if the mutex exists (183 == ERROR_ALREADY_EXISTS)
if ($^E == 183)
{
   # find first copy of application and get its window handle
   my $hWnd=Win32::GUI::FindWindow("\x00","ScanTest");
   Win32::GUI::SendMessage($hWnd, WM_SCANBADGE, 1, 0);
   exit;
}
   

# Create a window, saving it in variable $main
my $main = Win32::GUI::Window->new(
        -name   => 'Main',
        -width  => 100,
        -height => 100,
        -title  => 'ScanTest',
);

# 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 => "Start",
        
);

$main->AddButton(
        -name => 'button2',
  -text => "Scan",
  -left => 50,
        
);

# set up message hooks
$main->Hook(WM_INSERTION, \&WMINSERTION);
$main->Hook(WM_REMOVAL, \&WMREMOVAL);
$main->Hook(WM_SCANNERDATA, \&WMSCANNERDATA);
$main->Hook(WM_SCANBADGE, \&WMSCANBADGE);


# Show our main window
$main->Show();

# Enter the windows message loop, often referred
# to as the "dialog phase".
Win32::GUI::Dialog();

# When the message loop returns 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
{
   # initilize the ScanAPI.dll
   $ret=$ScanInit->Call($main->{-handle},WM_INSERTION,WM_REMOVAL);
   if ($ret != SR_SUCCESS)
   {
       &DisplayScanError($ret);
       return 0;
   }
}
1;

sub button2_Click
{
   
   # trigger the scanner
   $ret=$ScanTrigger->Call($ScannerHandle);
   if ($ret != SR_SUCCESS)
   {
       &DisplayScanError($ret);
       return 0;
   }
}
1;


sub WMINSERTION
{ 
        # Handle the scanner insertion message
        
        # get data passed from the message queue
        my ($object, $wParam, $lParam, $type, $msgcode) = @_; 
        return unless $type == 0; 
        return unless $msgcode == WM_INSERTION; 

        # Store the scanner handle to a global
        $ScannerHandle=$lParam;

        # call the ScanAPI open device function
        my $ret=$ScanOpenDevice->Call($lParam);    
        if ($ret != SR_SUCCESS)
        {
          &DisplayScanError($ret);
          return 0; 
        }

        # if the ScanAPI opens the scanner, add this application to the
ScanAPI.dll message queue
        $ret=$ScanRequestDataEvents->Call($lParam, $main->{-handle},
WM_SCANNERDATA);
        if ($ret != SR_SUCCESS)
        {
          &DisplayScanError($ret);
          return 0; 
        }
        return 1; 

}



sub WMREMOVAL
{ 
        # Handle the scanner removal message

        # get data passed from the message queue
        my ($object, $wParam, $lParam, $type, $msgcode) = @_; 
        return unless $type == 0; 
        return unless $msgcode == WM_REMOVAL; 

        # Close the ScanAPI
        my $ret=$ScanCloseDevice->Call($lParam);    
        if ($ret != SR_SUCCESS)
        {
          &DisplayScanError($ret);
          return 0;
        }
        return 1; 

}

sub WMSCANNERDATA
{ 
        # Handle the scanner has data waiting message

        # get data passed from the message queue
        my ($object, $wParam, $lParam, $type, $msgcode) = @_; 
        return unless $type == 0; 
        return unless $msgcode == WM_SCANNERDATA; 

        # The $wParam tell us how much data is in the scanner buffer. If
there is
        # a problem in future, multiply the $wParam by the
Win32::API::Type->sizeof() 
        # function using the TCHAR
        
        # define a buffer the size of the data in the scanner buffer
        my $buffer= 0 x $wParam;
        my $buffersize= \$wParam;   # store the reference to $wmParam, why I
don't know. 
        
        # Get the data from the scanner
        my $ret=$ScanGetData->Call($ScannerHandle, $buffer, $buffersize);    
        if ($ret != SR_SUCCESS)
        {
          &DisplayScanError($ret);
          return 0;
        }

        #Process scanner data here
        print $buffer."\n\n";
        return 1; 

}

sub WMSCANBADGE
{ 
        # This message tells the application to trigger the scanner. This
message is sent
        # from a 2nd copy of the application

        # get data passed from the message queue
        print "a second copy of the program has started\n";
        my ($object, $wParam, $lParam, $type, $msgcode) = @_; 
        return unless $type == 0; 
        return unless $msgcode == WM_SCANBADGE; 

        #`trigger the scanner
        button2_Click();
        
        return 1; 

}

sub DisplayScanError()
{

   # process any ScanAPI error messages
   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";
   }

   Win32::GUI::MessageBox(
      $main,
      "ScanAPI.dll Error Message: $ErrorText",
      MB_OK|MB_ICONASTERISK
   );
   
   return 0;
}

___ End Code ___


-- 
View this message in context: 
http://www.nabble.com/Sample-application-to-access-the-ScanAPI.dll-from-Socket-Mobile-tp18062929p18062929.html
Sent from the perl-win32-gui-users mailing list archive at Nabble.com.


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Perl-Win32-GUI-Users mailing list
Perl-Win32-GUI-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users
http://perl-win32-gui.sourceforge.net/

Reply via email to