13-09-2013, 04:09 PM
لدي برنامج يقوم بالاتصال مع قارئ تصويري وعند التصوير نحصل على صورة من البفر بعد الحصول على رسائل من ملف ال DLL هنا الوصف لكيفية ارسال الرسائل من مكتبة ال DLL:
وهنا وصف للرسائل التي نتلقاها من المكتبة:
.
وهنا وصف الرسالة التي تعطي الصورة:
وهذا الكود الذي استخدمه:
المشكلة عند القيام بالتصوير والوصول إلى الرسالة WM_XFERSTATUS يعطي خطأ ويغلق البرنامج
كود :
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 يعطي خطأ ويغلق البرنامج

