Comport 라는 통신 컴포넌트가 있을때,
메세지를 받았을때 다음과 같은 이벤트가 발생합니다.
procedure Tform1.ComportRxChar();
그런데 이걸 dll로 만들었을때(즉 폼이 없을때)
이벤트가 발생했을때 프로시져로 대입을 해야 하는데 어떻게
해야 하나요?
즉...
아래 소스에서 Read라는 프로시져에서 메세지를 받는
OnRxChar이벤트가 발생했을때 ComportRxChar프로시져로
대입을 해주었는데...
Incompatible Type 에러가 발생하네요...
어렵지 않는 문제인거 같은데 좀 도와주세요...
procedure ComportRxChar(Sender: TObject; Count: Integer);
var
Str: String;
begin
ComPort.ReadStr(Str, Count);
end;
procedure Read(Sender: TObject);
begin
Comport.OnRxChar:=ComportRxChar;
end;
꼭 그 프로시져를 넘길려고 하지마시구요. 특정 사용자 함수를 만듭니다. 이렇게 하는것이 마음대로 콘트롤할 수 있어서 더 좋습니다.
DLL에 포함되는 선언부 유닛에 아래와 같이 선언하구요.
unit XXXX;
type
TCTIDetectEvent = procedure(RingCount: Integer; DTMFNumber, CallerID: PChar; AStopPlay: Boolean); stdcall;
function SetCTIDetect(ACTIDetect: TCTIDetectEvent): Integer; stdcall;
begin
Result := 1;
try
with FrmDVRServer do
begin
FOnCTIDetectEvent := ACTIDetect;
Result := 0;
end;
except
end;
end;
DLL에 포함되는 메인유닛에 아래와 같이 코딩하구요.
public
{ Public declarations }
FOnCTIDetectEvent: TCTIDetectEvent;
procedure TfrmDVRServer.CTIEventHandlerRingDetect(Sender: TObject;
RingCount: Integer);
begin
try
if Assigned(FOnCTIDetectEvent) then
FOnCTIDetectEvent(RingCount, '', '', False);
except
end;
end;
실행프로그램(exe)에 포함되는 Unit에는 아래와 같이 가져가면 됩니다.
unit EEEE;
type
TCTIDetectEvent = procedure(RingCount: Integer; DTMFNumber, CallerID: PChar; AStopPlay: Boolean); stdcall;
function SetCTIDetect(ACTIDetect: TCTIDetectEvent): Integer; stdcall; external DLLNAME;
그리고, 메인에서는 이렇게 이벤트를 받아올 함수를 선언해두고 아래와 같이 부르면 되죠.
implementation
{$R *.DFM}
procedure CTIDetect(RingCount: Integer; DTMFNumber, CallerID: PChar; AStopPlay: Boolean); stdcall;
begin
end;
if SetCTIDetect(@CTIDetect) <> 0 then
...;
소스를 다 올릴수는 없고 추린다고 추렸는데 복잡하다면 죄송합니다.
참고적으로 DLL를 만들때는 String을 사용하지 마시구요. API의 표준인 PChar를 사용하세요. 그래야만 다른 언어(VB, C++, PB 등등)에서 무리없이 사용할 수 있습니다.
감사합니다.
최용일씨가 심플한 소스를 가지고 있는데 자료실에 올리라니까 아직 안 올렸네여. ㅎㅎㅎㅎ