I'm wondering if I'm doing something wrong. I've implemented scanning using ImageEn and it works great. Then I went back and added a call to AutoCrop after the call to Acquire:
ImageEnMView.MIO.Acquire();
ImageEnMView.Proc.AutoCrop(10, CreateRGB(0, 0, 0));
Now I get an Access Violation when freeing ImageEnMView. Simplified stack:
hyieutils.TIEBitmap.FreeAllMaps
hyieutils.TIEBitmap.FreeImage(True)
hyieutils.TIEBitmap.Destroy
imageenproc.TImageEnProc.Destroy
iemview.TImageEnMView.Destroy
At this point, when FreeAllMaps is called, fScanlinesToUnMapPtr is nil. So accessing fScanlinesToUnMapPtr.Count causes an Access Violation. Best I can tell, the problem is that TImageEnProc.fIEBitmap is being freed twice.
TImageEnMView.GetImageEnProc creates TImageEnProc and attaches itself to fImageEnProc. At that point,
fImageEnProc.FIEBitMapCreated = True
fImageEnProc.fBitMap is not assigned
fImageEnproc.fIEBitmap is assigned
Then fSelectedItem = -1 so SelectedImage is assigned zero. This causes TImageEnProc.OnBitmapChange to be called.
Both fImageEnView and fIEBitmap are assigned, so fIEBitmap is assigned frmImageEnView.IEBitmap.
Now, fImageEnView should own frmImageEnView.Bitmap. But TImageEnProc.fIEBitmapCreated is not set to False.
When I free the ImageEnMView that I created, the embedded TImageEnProc is destroyed as well. The bottom of its constructor is
if fIEBitmapCreated then
FreeAndNil(fIEBitmap);
Since fIEBitmapCreated is still True, the bitmap is freed twice.
I added a line to OnBitmapChange to set fIEBitmapCreated := False. But I'm not sure this is the correct fix:
procedure TImageEnProc.OnBitmapChange(Sender: TObject; destroying: boolean);
begin
if destroying then
begin
fImageEnView := nil;
end
else if assigned(fImageEnView) then
begin
if assigned(fIEBitmap) then
begin
fIEBitmap := fImageEnView.IEBitmap;
fBitmap := nil; // both fBitmap and fIEBitmap aren't allowed if not encapsulated
fIEBitmapCreated := False; // ADDED THIS LINE!
end
else if assigned(fBitmap) then
begin
fBitmap := fImageEnView.Bitmap;
if fIEBitmapCreated then
fIEBitmap.EncapsulateTBitmap(fBitmap, true);
end;
end;
end;