ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Impossible to select Twain-Device

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

View 
UserName:
Password:
Format  Bold Italicized Underline  Align Left Centered Align Right  Horizontal Rule  Insert Hyperlink   Browse for an image to attach to your post Browse for a zip to attach to your post Insert Code  Insert Quote Insert List
   
Message 

 

Emoji
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Black Eye [B)]
Frown [:(] Shocked [:0] Angry [:(!] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
Xylit Posted - Apr 20 2012 : 03:08:14
Hi,

I have two Twain-Devices: "Scanner ABC" and "Scanner" (In that order; The second name is the prefix of the first name). In this constellation it is not possible to select the second Twain-Device. Both functions
TImageEnIO.SelectAcquireSource(ieaTWain)
or
TwainParams.SelectSourceByName('Scanner')
result in the first Twain-Device selected. (Checked with TImageEnIO.TWainParams.SourceName[TestIO.TWainParams.SelectedSource]).

Is this bug fixed in the actual version?

I am using ImageEn 3.0.5 components for Delphi.
9   L A T E S T    R E P L I E S    (Newest First)
fab Posted - Apr 20 2012 : 08:55:05
Previous code allowed to execute partial matches (this is the reason you will always select "Optic Pro S28 Pro", that partially matches with "Optic Pro S28").
To avoid to break old code, I think it is better to execute an exact match first, then a partial patch.
This is the changed code (for 4.x version):

function TIETwainParams.SelectSourceByName(const sn: AnsiString): boolean;
var
  q: integer;
  bestMatch: integer;
  bestMatchLen: integer;
  toFind, current: AnsiString;
  minLen: integer;
begin
  result := false;
  FillSourceListData;

  bestMatch := -1;
  toFind := IEUpperCase(sn);

  // search for exact match
  for q := 0 to fSourceListData.Count - 1 do
    if (IEUpperCase(IETrim(AnsiString(pTW_IDENTITY(fSourceListData[q])^.ProductName))) = toFind) then
    begin
      bestMatch := q;
      break;
    end;

  if bestMatch = -1 then
  begin
    // partial match
    bestMatchLen := 0;
    for q := 0 to fSourceListData.Count - 1 do
    begin
      current := IETrim(AnsiString(pTW_IDENTITY(fSourceListData[q])^.ProductName));
      minLen := imin(length(current), length(toFind));
      if (IEUpperCase(IECopy(current, 1, minLen)) = IECopy(toFind, 1, minLen)) and (minLen > bestMatchLen) then
      begin
        bestMatch := q;
        bestMatchLen := minLen;
      end;
    end;
  end;
  if bestMatch <> -1 then
  begin
    if fSelectedSource <> bestMatch then
      SetSelectedSource(bestMatch);
    result := true;
  end;

  // Make Twain the API for subsequent calls to Acquire
  {$IFDEF IEINCLUDEMULTIVIEW}
  If Result and (fOwner is TImageEnMIO) then
    (fOwner as TImageEnMIO).AcquireParams.fSelectedSourceAPI := ieaTwain
  else
  {$ENDIF}
  If Result and (fOwner is TImageEnIO) then
    (fOwner as TImageEnIO).AcquireParams.fSelectedSourceAPI := ieaTwain;
end;


This is for 3.x versions (not tested!):

function TIETwainParams.SelectSourceByName(const sn: AnsiString): boolean;
var
  q: integer;
  bestMatch: integer;
  bestMatchLen: integer;
  toFind, current: AnsiString;
  minLen: integer;
begin
  result := false;
  FillSourceListData;

  bestMatch := -1;
  toFind := IEUpperCase(sn);

  // search for exact match
  for q := 0 to fSourceListData.Count - 1 do
    if (IEUpperCase(IETrim(AnsiString(pTW_IDENTITY(fSourceListData[q])^.ProductName))) = toFind) then
    begin
      bestMatch := q;
      break;
    end;

  if bestMatch = -1 then
  begin
    // partial match
    bestMatchLen := 0;
    for q := 0 to fSourceListData.Count - 1 do
    begin
      current := IETrim(AnsiString(pTW_IDENTITY(fSourceListData[q])^.ProductName));
      minLen := imin(length(current), length(toFind));
      if (IEUpperCase(IECopy(current, 1, minLen)) = IECopy(toFind, 1, minLen)) and (minLen > bestMatchLen) then
      begin
        bestMatch := q;
        bestMatchLen := minLen;
      end;
    end;
  end;
  if bestMatch <> -1 then
  begin
    if fSelectedSource <> bestMatch then
      SetSelectedSource(bestMatch);
    result := true;
  end;
end;


Xylit Posted - Apr 20 2012 : 08:32:56
Okay, now I get it.

Yes, I have the source code. What do you propose?
fab Posted - Apr 20 2012 : 08:19:25
quote:
Are you kidding?


No, why?

quote:
You don't have the 3.0.5 source code?


My question was: "Do YOU have source code, ...".

I just wanted to propose a fix in "ImageEn" source code (in TIETWainParams.SelectSourceByName, of course...).
Xylit Posted - Apr 20 2012 : 07:47:57
Are you kidding? You don't have the 3.0.5 source code?

Well the fix is quite easy: Remove the "IECopy" or fix the length parameter.
function TIETWainParams.SelectSourceByName(const sn: AnsiString): boolean;
var
  q, ll: integer;
begin
  {$ifdef IEPROFILE} try IEProfileBegin('TIETWainParams.SelectSourceByName'); {$endif}
  result := false;
  FillSourceListData;
  ll := length(sn);
  for q := 0 to fSourceListData.Count - 1 do
    if IEUpperCase(IECopy(pTW_IDENTITY(fSourceListData[q])^.ProductName, 1, ll)) = IEUpperCase(sn) then
    begin
      if fSelectedSource <> q then
        SetSelectedSource(q);
      result := true;
      break;
    end;
  {$ifdef IEPROFILE} finally IEProfileEnd; end; {$endif}
end;
fab Posted - Apr 20 2012 : 07:34:23
I meant ImageEn source code.
Xylit Posted - Apr 20 2012 : 07:29:48
function ShowSelectAcquirSource: AnsiString;
var
  TestIO: TImageEnIO;
begin
  result:='';
  TestIO:=TImageEnIO.Create(NIL);

  Application.BringToFront;
  if TestIO.SelectAcquireSource(ieaTWain) then
  begin
    result:=TestIO.TWainParams.SourceName[TestIO.TWainParams.SelectedSource];
  end;

  TestIO.Free;
end;
fab Posted - Apr 20 2012 : 07:21:41
Yes, it is important for me in order to find the bug!!
Do you have source code, so I can propose a fix?
Xylit Posted - Apr 20 2012 : 05:11:14
I don't think it changes something, but the real TWAIN names are "Optic Pro S28 Pro" and "Optic Pro S28". Both drivers are installed but only the second device was ever connected to the pc. The first device is installed, but was never connected to the pc.
fab Posted - Apr 20 2012 : 05:00:44
Hi,
this is not a known bug (and I cannot replicate in my tests). Please could you clear this: "The second name is the prefix of the first name"? Are both devices connected?