使用CreateOleObject调用COM,关闭子窗口时,父窗口被一起关闭,是否资源释放问题?!(200分)

  • 主题发起人 主题发起人 Neo_leaf
  • 开始时间 开始时间
N

Neo_leaf

Unregistered / Unconfirmed
GUEST, unregistred user!
Project->ImportTypeLibrary->Add"SBSPCOM.DLL"->Create Unit
定义变量:
uses Comobj;// Unit_UIdefined,

var
DeviceID : Smallint; //SBSPCOMLib.SecuBSP
objSecuBsp : variant; // Declaration variable for SecuBSP Object
objDevice : variant; //Store Device ID etc.
objExtraction : variant; //Store & Process FingerPrint Data
objMatching : variant;
objFPData : IFPData; //
szFIRTextData : wideString;//Store The Finger Print Data after Encode.
biFIR1,biFIR2,biFIR_First,biFIR_Second : array of byte; //Store The Finger Print Data Byte.

FirstFIR,SecondFIR : WideString; //objExtraction.TextEncodeFIR 指纹数据
arrFP : array[0..799] of byte;
调用COM:
objSecuBsp := CreateOleObject('SBSPCOM.SecuBSP');
objDevice := objSecuBSP.Device;
objExtraction := objSecuBSP.Extraction;
objMatching := objSecuBSP.Matching;
objFPData := IFPData(IUnknown(objSecuBSP.FPData));
调用取数据:
procedure TFrm_Capture.TimerFirstTimer(Sender: TObject);
var
len : Integer;
begin
try
TimerFirst.Enabled := False;
TimerSec.Enabled := False;
LblCptMsg.Caption := 'Put your finger on the sensor please!';
LblCptMsg.Refresh;
objDevice.Enumerate;
objDevice.Open(2); //
SetInitValue(PicFirst.Handle);
objExtraction.Capture(1);
Len := objExtraction.FIRLength;
biFIR1 := nil;
SetLength(biFIR1, Len); //biFIR
biFIR1 := objExtraction.FIR;
szFIRTextData := objExtraction.TextEncodeFIR;
FirstFIR := objExtraction.TextEncodeFIR;
objFPData.Export(biFIR1,2);
if objFPData.ErrorCode=0 then
begin
biFIR_First := nil;
Len := objFPData.FPDataSize[0];
SetLength(biFIR_First, len);
biFIR_First := objFPData.FPData[0,0];
end;
objDevice.Close(2);
//取完数据,关闭子窗口
  Frm_Capture.Close;
except
end;
end;

//父窗口调用子窗口
procedure TFrm_Main.Button2Click(Sender: TObject);
begin
if not Assigned(Frm_Capture) then
Frm_Capture := TFrm_Capture.Create(nil);
Frm_Capture.Visible := False;
Frm_Capture.ShowModal;
sFPData2 := Frm_Capture.sFPData;//这个变量子窗口有的,
FreeAndNil(Frm_Capture);
end;

请教大家:由于某种原因,需要调用两次子窗口,在第一次调用并关闭时,一切正常(父窗口不会被关闭),
但是第二次关闭子窗口时,出现故障,父窗口被一起关闭,
并有时会出现异常错误:
Access Violation at address '十六进制数' in module 'ntdll.dll'.....
 
oleaut32.dll
还有这个错误,
 
WinXP Professional + Delphi 7
 
会有这两个错误时常弹出,
Access violation at address 77121829 in modulte 'oleaut32.dll'.Write of address 011C3000.

Access violation at address 7C938FEA in module 'ntdll.dll'.Write of address 00000010.
有时出现,有时不出现,很晕,
 
难道没有人愿意回答我的问题,
 
资源释放:
procedure TFrm_Capture.FormDestroy(Sender: TObject);
begin
try
objExtraction := null;
objMatching := null;
objDevice := null;
objSecuBSP := null;
biFIR1 := nil;
biFIR2 := nil;
biFIR_First := nil;
biFIR_Second := nil;
objFPData := nil;
except
on E:Exception do
ShowMessage(E.Message);
end;
end;
 
一个回复都没有,
看来送不出分了,
斑竹别怪我不结帖了,
 
-------Form Main
procedure TFrm_Main.Button1Click(Sender: TObject);
begin
try
if Frm_Capture=nil then
Frm_Capture := TFrm_Capture.Create(Self);
Frm_Capture.Visible := False;
Frm_Capture.iFlag := 0;
Frm_Capture.ShowModal;
finally
FreeAndNil(Frm_Capture);
ShowMessage('FreeAndNil Success!');
end;
end;

procedure TFrm_Main.Button2Click(Sender: TObject);
begin
try
if Frm_Capture=nil then
Frm_Capture := TFrm_Capture.Create(Self);
Frm_Capture.Visible := False;
Frm_Capture.iFlag := 1;
Frm_Capture.ShowModal;
finally
FreeAndNil(Frm_Capture);
ShowMessage('FreeAndNil Success!');
end;
end;

---------Form Child

uses Comobj, Unit_Main;

var
objSecuBsp : ISecuBSP;
objDevice : IDevice;
objExtraction : IExtraction;
objMatching : IMatching;
objFPData : IFPData;
FirstFIR,SecondFIR : WideString;
biFIR1,biFIR2,biFIR_First,biFIR_Second : array of byte;

{$R *.dfm}

procedure TFrm_Capture.AssignStringToTxt(sTxt :WideString);
var
vTxtFile : TextFile;
begin
if(FileExists(ExtractFilePath(ParamStr(0))+'YYQFPData.txt'))
and(IsFileInUse(ExtractFilePath(ParamStr(0))+'YYQFPData.txt'))then
begin
MessageBox(Handle,'The File FPData.txt is in use!','Warning',MB_OK+MB_ICONWARNING);
exit;
end;
AssignFile(vTxtFile,ExtractFilePath(ParamStr(0))+'YYQFPData.txt');
Rewrite(vTxtFile);
try
Writeln(vTxtFile,sTxt);
Reset(vTxtFile);
finally
CloseFile(vTxtFile);
Self.Refresh;
end;
end;

procedure TFrm_Capture.FormCreate(Sender: TObject);
begin
try
objSecuBsp := CreateComObject(CLASS_SecuBSP) as ISecuBSP;
objDevice := IDispatch(objSecuBsp.Device) as IDevice;
objFPData := IDispatch(objSecuBsp.FPData) as IFPData;
objExtraction := IDispatch(objSecuBsp.Extraction) as IExtraction;
objMatching := IDispatch(objSecuBsp.Matching) as IMatching;
except
on E:Exception do
showmessage('FormCreate: '+E.Message);
end;
end;

procedure TFrm_Capture.FormShow(Sender: TObject);
begin
TimerFirst.OnTimer := TimerFirstTimer;
TimerFirst.Enabled := True;
TimerSec.OnTimer := nil;
TimerSec.Enabled := False;
end;

procedure TFrm_Capture.FormDestroy(Sender: TObject);
begin
try
objMatching := nil;
objExtraction := nil;
objFPData := nil;
objDevice := nil;
objSecuBSP := nil;
ShowMessage('FormDestroy Success!');
except
on E:Exception do
ShowMessage('FormDestroy: '+E.Message);
end;
end;

function TFrm_Capture.IsFileInUse(fName : string) : boolean;
var
HFileRes : HFILE;
begin
Result := False;
if not FileExists(fName) then
exit;
HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE,
0 {this is the trick!}, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Result := (HFileRes = INVALID_HANDLE_VALUE);
if not Result then
CloseHandle(HFileRes);
end;

Function TFrm_Capture.GetFPData:WideString;//Get Finger Print Data Length is 800.
var
Arr_Combine : array of byte;
Str_Combine : WideString;
i : Integer;
begin
try
Result := '';
Str_Combine := '';
SetLength(Arr_Combine,800);
for i := 0 to 399 do
begin
Arr_Combine := biFIR_First;
Arr_Combine[400+i] := biFIR_Second;
end;
Str_Combine := '';
Str_Combine := IntToHex(Arr_Combine[0],2);
for i := 1 to 799 do
Str_Combine := Str_Combine+IntToHex(Arr_Combine,2);
Result := Str_Combine;
Arr_Combine := nil;
except
on E:Exception do
ShowMessage('GetFPData: '+E.Message);
end;
end;

procedure TFrm_Capture.SetInitValue(h:HWND);
begin
objExtraction.WindowStyle := 1;//set display style of FP
objExtraction.FPForeColor := '0000FF'; //Set FP Color Blue
objExtraction.FPBackColor := 'FFFFFF'; //Set Back Color White
objExtraction.FingerWnd := h;
end;

procedure TFrm_Capture.TimerFirstTimer(Sender: TObject);
var
len : Integer;
v : Variant;
begin
try
objDevice.Open(2);
if(objDevice.ErrorCode<>0)then //Open Failed
begin
MessageBox(Handle,'Open Device Failed,Check your Device Please!','FingerPrintERROR',MB_OK+MB_ICONERROR);
TimerFirst.OnTimer := nil;
TimerSec.OnTimer := nil;
TimerFirst.Enabled := False;
TimerSec.Enabled := False;
LblCptMsg.Caption := 'Open Device Failed!';
LblCptMsg.Refresh;
exit;
end;

TimerFirst.Enabled := False;
TimerSec.Enabled := False;
LblCptMsg.Caption := 'Put your finger on the sensor please!';
LblCptMsg.Refresh;
SetInitValue(PicFirst.Handle);
objExtraction.Capture(1);
if(objExtraction.ErrorCode<>0)then
begin
MessageBox(Handle,'First Capture Failed!', 'FirstCaptureERROR',MB_OK+MB_ICONERROR);
objDevice.Close(2);
Self.Close;
end;
Len := objExtraction.FIRLength;
//biFIR1 := nil;
SetLength(biFIR1, Len); //biFIR
biFIR1 := objExtraction.FIR;
FirstFIR := objExtraction.TextEncodeFIR;
objFPData.Export(biFIR1,2);
if objFPData.ErrorCode=0 then
begin
//biFIR_First := nil;
Len := objFPData.FPDataSize[0];
SetLength(biFIR_First, len);
biFIR_First := objFPData.FPData[0,0];
varVarrayUnLock(objFPData.FPData[0,0]);
end
else
begin
MessageBox(Handle,'Convert Data Failed!','ERROR',MB_OK+MB_ICONERROR);
exit;
end;
objDevice.Close(2);

LblCptMsg.Caption := 'Remove your finger please!';
LblCptMsg.Refresh;
Sleep(1000);
TimerFirst.OnTimer := nil;
TimerFirst.Enabled := False;
TimerSec.OnTimer := TimerSecTimer;
TimerSec.Enabled := True;
except
on E:Exception do
ShowMessage('First: '+E.Message);
end;
end;

procedure TFrm_Capture.TimerSecTimer(Sender: TObject);
var
len : Integer;
Str_Fp : WideString;
begin
try
objDevice.Open(2);
if(objDevice.ErrorCode<>0)then //Open Failed
begin
MessageBox(Handle,'Open Device Failed,Check your Device Please!','FingerPrintERROR',MB_OK+MB_ICONERROR);
TimerFirst.OnTimer := nil;
TimerSec.OnTimer := nil;
TimerFirst.Enabled := False;
TimerSec.Enabled := False;
LblCptMsg.Caption := 'Open Device Failed!';
exit;
end;
TimerFirst.Enabled := False;
TimerSec.Enabled := False;
LblCptMsg.Caption := 'Put your finger on the sensor again!';
LblCptMsg.Refresh;
SetInitValue(PicSec.Handle);
objExtraction.Capture(1);
if(objExtraction.ErrorCode<>0)then
begin
MessageBox(Handle,'Second Capture Failed!', 'ERROR',MB_OK+MB_ICONERROR);
objDevice.Close(2);
Self.Close;
end;
Len := objExtraction.FIRLength;
//biFIR2 := nil;
SetLength(biFIR2, Len);
biFIR2 := objExtraction.FIR;
SecondFIR := objExtraction.TextEncodeFIR; //得到一个指纹的第一次数据
objFPData.Export(biFIR2,2);
if objFPData.ErrorCode=0 then
begin
//biFIR_Second := nil;
Len := objFPData.FPDataSize[0];
SetLength(biFIR_Second, len);
biFIR_Second := objFPData.FPData[0,0];
end;
TimerSec.Enabled := False;
objMatching.VerifyMatch(SecondFIR,FirstFIR); //Check Two FPData.
if(objMatching.MatchingResult=1)then //Success
begin
Str_Fp := GetFPData;
if iFlag=0 then
Frm_Main.sFPData1 := Str_Fp
else if iFlag=1 then
Frm_Main.sFPData2 := Str_Fp;
AssignStringToTxt(Str_Fp);
LblCptMsg.Caption := 'Enroll Success!';
end
else //Failed
LblCptMsg.Caption := 'Enroll Failed!';
objDevice.Close(2);
if(objDevice.ErrorCode<>0)then
ShowMessage('Second Capture: Device Close Failed!')
else
begin
LblCptMsg.Caption := 'Device Close Success!';
LblCptMsg.Refresh;
end;
Self.Refresh;
Sleep(2000);

Finalize(biFIR1);
Finalize(biFIR2);
Finalize(biFIR_First);
Finalize(biFIR_Second);
PicFirst.FreeOnRelease;
PicSec.FreeOnRelease;
LblCptMsg.Caption := 'Complete!!!';
LblCptMsg.Refresh;
Sleep(2000);
Close;
except
on E:Exception do
ShowMessage('Second: '+E.Message);
end;
end;

end.
 
现在改为这样了,
还是不行,
在Close;时出错,
 
错误依旧,
和原来差不多,
经常提示"variant or safe array is locked"
 
斑竹别怪,
无法揭贴,
 
跟踪查一下呢,看一下CLOSE时做了什么东西
还有TIMER在CLOSE时最好也Enabled:=False;
 
改成这样试试:
procedure TFrm_Main.Button2Click(Sender: TObject);
begin
Frm_Capture := TFrm_Capture.Create(self);
Frm_Capture.ShowModal;
sFPData2 := Frm_Capture.sFPData;//这个变量子窗口有的,
Frm_Capture.Free;
end;
不能肯定你的问题到底出在哪里,只好瞎撞了。
 
多人接受答案了。
 
后退
顶部