5.获取和设置设备性能参数
这一步是可选的。到这一步骤以后,应用程序和Source之间就可以进行消息传递了。获取和设置设备性能参数的操作是:DG_CONTROL / DAT_CAPABILITY / MSG_GET和DG_CONTROL / DAT_CAPABILITY / MSG_SET。使用这两个操作可以查询当前设备是否支持某种功能,如图像获取方式、图像数量等信息。有些参数还必须设备驱动支持才有效,如果支持,还可以按用户的要求设置这些参数。下面的函数用于显示当前设备可以获取的图像数量:
function getinfo:tw_uint16;
var
tc:tw_capability;
p:ptw_onevalue;
begin
result:=0;
tc.Cap := cap_xfercount;
tc.ConType :=twon_dontcare16;
tc.hContainer :=0;
twrc:=dsmentry(app,newds,DG_CONTROL ,DAT_capability,MSG_get,@tc);
if twrc<>TWRC_SUCCESS then exit;
p:=ptw_onevalue(globallock(tc.hContainer ));
result:=p.Item ;
globalfree(tc.hContainer);
end;
6.请求从Source获取数据
Source打开后,应用程序可以允许Source显示它提供的用户界面,准备请求数据传输。当然用户也可以选择不显示它的用户界面。这一步骤使用的Triplets 操作是:DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDS。
function enableds(isshow:boolean=true):boolean;
var
twrc:tw_uint16;
twshowui:TW_USERINTERFACE;
begin
twshowui.hParent :=winhandle; //指定消息传递的父窗体
twshowui.ShowUI :=isshow; //指定是否显示Source提供的用户界面
twrc:=dsmentry(app,newds,DG_CONTROL ,DAT_USERINTERFACE,MSG_ENABLEDS,@twshowui);
result:=(twrc=TWRC_SUCCESS);
end;
不同的TWAIN设备提供的用户界面是不同的。因此,通常情况下,都使用Source自己提供的用户界面。
7.确认为数据传输做准备
要注意的是,这一步骤不是由应用程序发出一个Triplets 操作来触发的,而是由Source发起的。Source准备好了要传输数据时,它会发出一个事件信号给它的父窗体,应用程序需在这个窗体的消息循环中使用 DG_CONTROL /DAT_EVENT / MSG_PROCESSEVENT操作,检测Source是否有事件发生。如果检测到包含MSG_XFERREADY的消息,则表示Source已准备好正等待应用程序请求实际的数据传输。消息处理的代码如下。
procedure tform1.wmset(var msg:tmsg;var b:boolean);
var
twevent:tw_event;
begin
if isdsopen then
begin
twevent.pEvent := TW_MEMREF(@Msg);
if(((Msg.wParam <> 0) and (Msg.lParam = 0)) or((Msg.wParam =0) and (Msg.lParam <> 0))) then
begin
dsmentry(app,newds,DG_CONTROL,DAT_EVENT,MSG_PROCESSEVENT,(@twevent));
if twevent.TWMessage =MSG_XFERREADY then
begin
trans;//开始传输数据
end
else
if twevent.TWMessage = MSG_CLOSEDSREQ then // 关闭 Source 用户界面的申请
begin
dsmentry(app,newds,DG_CONTROL ,DAT_USERINTERFACE,MSG_disableDS,@k);
dsmentry(app,nil,DG_CONTROL,DAT_IDENTITY,MSG_closeds, TW_MEMREF(newds));
dsmentry(app,NiL,DG_CONTROL,DAT_PARENT,MSG_closeDSM,TW_MEMREF(newds) );
isdsmopen:=false;
isdsopen:=false;
dispose(app);
dispose(k);
dispose(newds);
freelibrary(dll);
dsmentry:=nil;
end
else
if twevent.TWMessage =MSG_CLOSEDSOK then
showmessage('界面已经成功关闭。')
else
if twevent.TWMessage =MSG_DEVICEEVENT then
showmessage('驱动消息。');
end;
end;
end;
然后在form1的oncreate()事件中加入语句:
application.OnMessage :=wmset;
8.进行数据传输
在这个步骤中有两个Triplets 操作可以使用:DG_IMAGE / DAT_IMAGEINFO / MSG_GET和DG_IMAGE / DAT_IMAGENATIVEXFER / MSG_GET。
传输前,应用程序可以通过 DG_IMAGE / DAT_IMAGEINFO / MSG_GET 操作,获得将要传输的图像的相关信息,比如位图大小、宽度、长度、传输模式等。再通过 DG_IMAGE / DAT_IMAGENATIVEXFER / MSG_GET 操作,实现使用本地传输模式去传输数据。当所有数据传输完成后,Source 将给它的父窗口发送一个包含PM_XFERDONE 的消息, dsmentry() 函数返回后的pData参数将指向一个包含 DIB 位图格式数据的地址。
9.结束传输
在上一步骤中,当应用程序接收到PM_XFERDONE时,将使用DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER操作通知Source已经接收完所有的数据,到此一次数据传输过程全部完成。同时还可以根据dsmentry()的返回值,去检查是否有其他图像等待传送。
下面的过程trans将实现以本地模式进行数据传输和传输完成后中止传输的操作。
procedure trans;
var
twPx: TW_PENDINGXFERS;
pDib, pbmp :PBITMAPINFOHEADER;
pBits :Pointer;
dwColorTableSize:TW_UINT32;
LogPal :TMaxLogPalette;
twRC, twRC2 :TW_UINT16;
hBitMap :TW_UINT32;
hbmp, hDibPal :THandle;
mDC :HDC;
begin
dwColorTableSize := 0;
twPx.count:= 0;
repeat
twRC:=dsmentry(app,newds,DG_IMAGE,DAT_IMAGENATIVEXFER,MSG_GET,@hBitMap);//发送本地模式传输请求
case twRC of
TWRC_XFERDONE:
begin
hbmp := hBitMap;
twRC2:=dsmentry(app,newds,DG_CONTROL,DAT_PENDINGXFERS,MSG_ENDXFER,@twPx);
if twRC2<>TWRC_SUCCESS then
showMessage('DG_CONTROL/DAT_PENDINGXFERS/MSG_ENDXFER操作失败');
if twPx.Count =0 then
begin
pdib := GlobalLock(hbmp);
if pdib<>NIL then
begin
pBmp := pDib;
case pBmp^.biBitCount of
1 : dwColorTableSize := 8;
4 : dwColorTableSize := 64;
8 : dwColorTableSize := 1024;
24 : dwColorTableSize := 0;
end;
pBits:=Pointer(Longint(pDib)+Longint(pBmp^.biSize)+Longint(dwColorTableSize));
mDC :=GetDC(application.Handle );
LogPal.palVersion :=$0300;
LogPal.palNumEntries :=256;
hDibPal:=CreatePalette(PLogPalette(@LogPal)^);
if hDibPal<>0 then
begin
SelectPalette (mDC, hDibPal, FALSE);
RealizePalette (mDC);
end;
hk:= CreateDIBitmap(mDC, (pDib)^, CBM_INIT, pBits,PBitMapInfo(pDib)^ , DIB_RGB_COLORS);
ReleaseDC(application.Handle , mDC);
form1.image1.Picture.Bitmap.Handle :=hk;
GlobalUnlock(hbmp);
end
else showMessage('锁定内存失败。');
end;
end;
TWRC_CANCEL :showMessage('传输被中止。');
TWRC_FAILURE :showMessage('图像传输失败');
else showMessage('其他未知错误。');
end;
until twPx.count=0;
end;
|