2009-04-06 12 views
1

Verwenden Sie die DelphiTwain-Dateien von http://delphitwain.sourceforge.net/ und bekomme ein seltsames Verhalten.Delphi Twain Problem Hilfe

  1. Nach jedem Scan wird etwas mehr Speicher gehalten.
  2. Nach etwa einer Stunde wiederholter Scans wird das gescannte Bild ungefähr zehnmal gezoomt und nur der obere linke Quadratzoll wird gespeichert.

Hat jemand ähnliche Probleme gehabt oder einige Vorschläge?

Code unten ...

try 
    try 
    Twain := TDelphiTwain.Create(self); 

    Twain.OnTwainAcquire := TwainAcquireHandler; //manually set the event handler 
    Twain.OnSourceFileTransfer := TwainSourceFileTransfer; 
    Twain.OnSourceSetupFileXfer := TwainSourceSetupFileXfer; 

    Twain.LoadLibrary; 
    Twain.LoadSourceManager; 
    Twain.Source[0].Loaded := TRUE; 
    Twain.Source[0].TransferMode := ttmFile; 
    Twain.Source[0].EnableSource(false, false); 
    except on e : exception do 
    showmessage('Error loading Scanner.'); 
    end; 

    try 
    while Twain.Source[0].Enabled do 
     Application.ProcessMessages; 
    except on e : exception do 
    showmessage('Error Scanning Packing List.'); 
    end; 
finally 
    Twain.Source[0].Loaded := FALSE; 
    Twain.UnloadSourceManager(true); 
    Twain.UnloadLibrary; 
    Twain.Destroy; 
end; 
+0

Erlaubt "Aktivieren" einer Quelle implizit, ein Bild von dieser Quelle zu erhalten? Was soll dieser Code tun und was tut er stattdessen? Können Sie die Scan-Koordinaten überwachen? An welchem ​​Punkt ändern sie sich? Welche Nachrichten möchten Sie verarbeiten und warum ignorieren Sie alle Ausnahmen? –

Antwort

0

Ich kann das Problem nicht adressieren Sie berichten aber Sie haben eine beschäftigt Schleife gibt, die CPU-Zeit verschlingen wird.

2

Untersuchen Sie den Code innerhalb dieser Anrufe fruchtbar sein kann:

TwainAcquireHandler; 
TwainSourceFileTransfer; 
TwainSourceSetupFileXfer; 

Führen Sie einen von denen, erstellen Sie alle Objekte, ohne sie zu befreien?

Wenn Sie mit Delphi 2006 oder höher, dann können Sie diese Zeile in .dpr Datei hinzufügen:

ReportMemoryLeaksOnShutdown := True; 

Dann den Speicherverlust reproduzieren, schließen Sie die App ... und es wird die Lecks beschreiben im Detail. Ein wenig mehr Infos dazu can be found here.

Auf einer anderen Anmerkung, ich

ersetzen würde vorschlagen
Twain.Destroy; 

mit

FreeAndNil(Twain); 

.Destroy die destructor direkt anrufen, während FreeAndNil eine sicherere Alternative ist, dass auch die "Twain" verhindert Variable vom Zeigen überall gefährlich. (Siehe die akzeptierte answer to this question).

+0

Sie wissen nicht, was FreeAndNil wirklich tut, sonst hätten Sie es nicht als Lösung für ein Speicherleck vorgeschlagen. –

+0

Überarbeitet in Reaktion auf Ihren Kommentar. Es ist jedoch noch sicherer. – JosephStyons

0

Was machst du, wenn du das Bild bekommst, hast du es im Gedächtnis behalten? Oder die Bibliothek kann einige Speicherlecks haben, Sie können überprüfen, ob es mit FastMM4 wahr ist.

3

Da TDelphiTwain eine Komponente zu sein scheint, die Sie in Code erstellen, würde ich empfehlen, nil für den Konstruktor zu übergeben und die .Free-Methode oder (wie von Joseph vorgeschlagen) FreeAndNil aufzurufen.

Twain := TDelphiTwain.Create(nil); 
try 
    try 
    Twain.OnTwainAcquire := TwainAcquireHandler; //manually set the event handler 
    Twain.OnSourceFileTransfer := TwainSourceFileTransfer; 
    Twain.OnSourceSetupFileXfer := TwainSourceSetupFileXfer; 

    Twain.LoadLibrary(); 
    Twain.LoadSourceManager(); 
    Twain.Source[0].Loaded := True; 
    Twain.Source[0].TransferMode := ttmFile; 
    Twain.Source[0].EnableSource(False, False); 
    except on e : exception do 
    showmessage('Error loading Scanner.'); 
    end; 

    try 
    while Twain.Source[0].Enabled do 
     Application.ProcessMessages; 
    except on e : exception do 
    showmessage('Error Scanning Packing List.'); 
    end; 
    Twain.Source[0].Loaded := False; 
    Twain.UnloadSourceManager(True); 
    Twain.UnloadLibrary(); 
finally 
    FreeAndNil(Twain); 
end; 

Ich würde auch bessere Ausnahmebehandlung empfehlen, aber nicht im Zusammenhang mit der Frage, die Sie gestellt haben. Das einzige, was Benutzer sehen und berichten Sie (oder noch schlimmer, die ruhige Mann in der Ecke verantwortlich für Ihre IT-Support, der liebt nicht-deskriptiven Fehler von den Benutzern zu bekommen) ist ‚Fehler, etwas zu tun‘

Viel Glück

Ein weiterer Bereich zu sehen ist, wenn der Scanner WIA (Windows Image Acquisition)

var 
    DevMgr: IDeviceManager; 
    Scanner: Idevice; 
    Picture: IItem; 
    Image: OleVariant; 
    AImage: IImageFile; 
begin 
    DevMgr := CreateOleObject('WIA.DeviceManager') as IDeviceManager; 

    // Figure out which device is the scanner 
    Scanner:= DevMgr.DeviceInfos.Item[1].Connect; 

    //Command: Figure out which command scans.. 
    Picture := Scanner.ExecuteCommand(Scanner.Commands.Item[1].CommandID); 

    //Transfer as JPG 
    Image := Picture.Transfer(Picture.Formats.Item[1]); 

    //Save the image 
    AImage := IImageFile(Image); 
    AImage.SaveFile('c:\wia_viaScanner\image.' + AImage.FileExtension); 
end; 

Weitere Informationen über die Bibliothek WIA unterstützt, kann hier gefunden werden .. http://msdn.microsoft.com/en-us/library/ms629859(VS.85).aspx

0

zu KevinRF:
Ich brauche WIA Automatisierung in Delphi 7-Projekt zu verwenden. Ich registrierte WIAAut.dll in meinem System importieren diese Bibliothek in Delphi und vorbei an Ihrem Programm-Code in meinem Projekt und bekam einige Fehler:

Scanner:= DevMgr.DeviceInfos.Item[1].Connect; 

Typen der tatsächlichen und formalen var Parameter müssen identisch sein
in „Item "muss Item [var Index: OleVariant] sein, aber" 1 "ist eine ganze Zahl

Was ist los, was muss ich machen, damit es funktioniert?

+0

Renat, sollte dies eine separate Frage gestellt werden. – Spike0xff