مشكلة عند تنفيذ البرنامج يتخاطب مع ملف dll
#1
لدي برنامج يقوم بالاتصال مع قارئ تصويري وعند التصوير نحصل على صورة من البفر بعد الحصول على رسائل من ملف ال DLL هنا الوصف لكيفية ارسال الرسائل من مكتبة ال DLL:
كود :
Data Returned by DLL The host application should allocate a destination data buffer for use by the DLL. When the scanner sends data to the DLL, the destination buffer is filled with the scanner's data. Once the destination buffer is filled by the DLL (if a buffer was set), the application is sent a WM_xxx message with the number of bytes of data that were stored indicated in the WPARAM. If the buffer was not large enough to hold all the data, the last two bits of WPARAM are set to zero. If no buffer was given to the DLL for the data to be stored in, the last two bits of WPARAM are 01. If the data was stored correctly, the last two bits of WPARAM are 11. The following #defines are provided for this purpose: • BUFFERSIZE_MASK – 0x0003 • BUFFERSIZE_GOOD – 0x0003 • BUFFERSIZE_ERROR – 0x0000 • NOBUFFER_ERROR – 0x0001 After the message is sent, the DLL marks the buffer as NULL indicating no user buffer is available for storage. The host application should reset the buffer after a WM_xxx message occurs. A second call to set the data buffer causes the new buffer to be used for incoming data. For example, after a WM_DECODE message is sent to the application, the application should handle the message and process the data in the destination buffer, then call SNAPI_SetDecodeBuffer again.
وهنا وصف للرسائل التي نتلقاها من المكتبة:
كود :
Message WM_XFERSTATUS Description Image data is transferring from the scanner. Value WM_APP+7 Parameters • wParam – Pointer to DWPARAM structure (cast to DWPARAM *). • LODWORD (wparam) – The total number of bytes received so far. • HIDWORD (wparam) – The total number of bytes expected. • lParam – Handle to the device for which the message was posted
.

وهنا وصف الرسالة التي تعطي الصورة:

كود :
Message WM_IMAGE Description Image data is available from the scanner and is stored in the buffer provided by a previous call to SNAPI_SetImageBuffer. Value WM_APP+2 Parameters • wParam – Pointer to DWPARAM structure (cast to DWPARAM *) • LODWORD (wparam) – The buffer status of the data stored • HIDWORD (wparam) – The length of the data in bytes • lParam – Handle to the device for which the message was posted Data Format Actual image data.

وهذا الكود الذي استخدمه:

PHP كود :
unit Unit2;

interface

uses
  Windows
, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  
Dialogs, StdCtrls;

type TObjectList = class(TList)
  
end;

type
  TScanner 
= class
  public
    
Device: THandle;
    
Connected: Boolean;
    
ImageData: array of Byte;
    
Pending: Boolean;

    
procedure Connect;
    
procedure Disconnect;
    
procedure RequestSnapshot;
    
procedure SetImageBuffer(Size: Integer);
  
end;


const
  
SNAPI_DLL = 'snapi.dll';

function 
SNAPI_Init(wnd: HWND; var DeviceHandles: THandle; var NumDevices: Integer): Integer; stdcall; external SNAPI_DLL;
function 
SNAPI_Connect(DeviceHandle: THandle): Integer; stdcall; external SNAPI_DLL;
function 
SNAPI_Disconnect(DeviceHandle: THandle): Integer; stdcall; external SNAPI_DLL;
function 
SNAPI_SetImageBuffer(DeviceHandle: THandle; Data: Pointer; MaxLength: Longint): Integer; stdcall; external SNAPI_DLL;
function 
SNAPI_SnapShot(DeviceHandle: THandle): Integer; stdcall; external SNAPI_DLL;

const
  
MAX_SCANNER = 10; // you will have to look this up

  
BUFFERSIZE_ERROR = $0000;
  
NOBUFFER_ERROR = $0001;
  
BUFFERSIZE_GOOD = $0003;
  
BUFFERSIZE_MASK = $0003;

  
WM_IMAGE = WM_APP+2;
  
WM_ERROR = WM_APP+4;
  
WM_TIMEOUT = WM_APP+5;
  
WM_XFERSTATUS = WM_APP+7;
  
WM_DEVICENOTIFICATION = WM_APP + 12;

  
IMAGE_DATA_TIMEOUT = $B1;

type
  ESNAPIError 
= class(Exception)
  public
    
Status: Integer;
    
constructor CreateErr(AStatus: Integer);
  
end;


type
  TMyform 
= class(TForm)
    
Button1: TButton;
    
Edit1: TEdit;
    
procedure Button1Click(Sender: TObject);
    
procedure FormCreate(Sender: TObject);
    
procedure FormDestroy(Sender: TObject);
  private
    
ScannerWnd: HWND;
    
Scanners: TObjectList;
    function  
FindScanner(Device: THandle): TScanner;
    
procedure ConnectScanner(Index:integer);
    
procedure DisconnectScanner(Index:integer);
    
procedure RequestSnapshot(Index:integer);
    
procedure ScannerWndProc(var Message: TMessage);
  
end;



var
  
Myform: TMyform;
  
scanner : TScanner;
implementation

{$R *.dfm}

constructor ESNAPIError.CreateErr(AStatus: Integer);
begin
  inherited CreateFmt
('SNAPI Error %d', [AStatus]);
  
Status := AStatus;
end;

procedure CheckSNAPIStatus(AStatus: Integer);
begin
  
if AStatus <> 0 then
    raise ESNAPIError
.CreateErr(AStatus);
end;

procedure TScanner.Connect;
begin
  
if not Connected then
  begin
    CheckSNAPIStatus
(SNAPI_Connect(Device));
    
Connected := True;
  
end;
end;

procedure TScanner.Disconnect;
begin
  
if Connected then
  begin
    SNAPI_Disconnect
(Device);
    
Connected := False;
  
end;
end;

procedure TScanner.RequestSnapshot;
begin
  Connect
;

  if 
Pending then
    raise Exception
.Create('Scanner is busy, try again later');

  
SetLength(ImageData, 0);
  
CheckSNAPIStatus(SNAPI_SnapShot(Device));

  
Pending := True;
end;

procedure TScanner.SetImageBuffer(Size: Integer);
begin
  SetLength
(ImageData, Size);
  
CheckSNAPIStatus(SNAPI_SetImageBuffer(Device, Pointer(ImageData), Length(ImageData)));
end;




procedure TMyform.FormCreate(Sender: TObject);
var
  
Devices: array[0..MAX_SCANNER-1] of THandle;
  
NumScanners, I: Integer;
  
Scanner: TScanner;
begin
  Scanners 
:= TObjectList.Create;
  
ScannerWnd := AllocateHWnd(ScannerWndProc);

  
CheckSNAPIStatus(SNAPI_Init(ScannerWnd, Devices[0], NumScanners));
  for 
I := 0 to NumScanners-1 do
  
begin
    Scanner 
:= TScanner.Create;
    
Scanner.Device := Devices[I];
    
Scanners.Add(Scanner);
    
// add it to the UI somewhere...
  
end;
end;

procedure TMyform.FormDestroy(Sender: TObject);
begin
  DeallocateHWnd
(ScannerWnd);
  
Scanners.Free;
end;

function 
TMyform.FindScanner(Device: THandle): TScanner;
var
  
I: Integer;
begin
  
for I := 0 to Scanners.Count-1 do
  
begin
    Result 
:= TScanner(Scanners[I]);
    if 
Scanner.Device = Device then
      
Exit;
  
end;
  
Result := nil;
end;

procedure TMyform.Button1Click(Sender: TObject);
begin
RequestSnapshot
(0);
end;

procedure TMyform.ConnectScanner(Index:integer);
begin
  TScanner
(Scanners[Index]).Connect;
end;

procedure TMyform.DisconnectScanner(Index:integer);
begin
  TScanner
(Scanners[Index]).Disconnect;
end;

procedure TMyform.RequestSnapshot(Index:integer);
begin
  TScanner
(Scanners[Index]).RequestSnapshot;
end;

procedure TMyform.ScannerWndProc(var Message: TMessage);
var
  
Scanner: TScanner;
begin
  
case Message.Msg of

    WM_XFERSTATUS
:
    
begin
      Scanner 
:= FindScanner(THandle(Message.LParam));
      if 
Scanner = nil then Exit;

      
//BytesRecv := LODWORD(Message.WParam)
      //BytesTotal := HIDWORD(Message.WParam)

      
if Scanner.ImageData = nil then
       Scanner
.SetImageBuffer( Message.WParamHi);
    
end;

    
WM_IMAGE:
    
begin
      Scanner 
:= FindScanner(THandle(Message.LParam));
      if 
Scanner = nil then Exit;

      
Scanner.Pending := False;

      if (
LO(Message.WParam) and BUFFERSIZE_MASK) <> BUFFERSIZE_GOOD then
        raise Exception
.Create('Image buffer error');

      
// use Scanner.ImageData up to HIDWORD(Message.WParam) bytes as needed...

      
SetLength(Scanner.ImageData, 0);
    
end;


    
WM_TIMEOUT:
    
begin
      Scanner 
:= FindScanner(THandle(Message.LParam));
      if 
Scanner = nil then Exit;

      
Scanner.Pending := False;

      case 
HI(Message.WParam) of

        IMAGE_DATA_TIMEOUT
:
        
begin
          raise Exception
.Create('Image timeout');
        
end;

      
end;
    
end;

    
WM_ERROR:
    
begin
      Scanner 
:= FindScanner(THandle(Message.LParam));
      if 
Scanner = nil then Exit;

      
Scanner.Pending := False;

      
CheckSNAPIStatus(Integer(LO(Message.WParam)));
    
end;

  else
    
Message.Result := DefWindowProc(ScannerWnd, Message.Msg, Message.WParam, Message.LParam);
end;
end;

end. 

المشكلة عند القيام بالتصوير والوصول إلى الرسالة WM_XFERSTATUS يعطي خطأ ويغلق البرنامج
الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم