📄 comdll.~dpr
字号:
library COMdll;
{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
Const
Wm_CommNotify=WM_User+12;
var
Hcom,Post_Event:Thandle;
LpolW,LpolR:Poverlapped;
// RXComm:TComm;
{$R *.res}
Procedure Execute;
var
dwEvtmask,dwOvres,bb:Dword;
RXFinish:Bool;
begin
while true do
begin
DwEvtMask:=0;
RXFinish:=WaitCommEvent(hcom,dwevtmask,LpolR); //等待串口事件EV_RXCHAR
if not RXFinish then //如果返回True,已立即完成,否则继续判断
if GetLastError()=ERROR_IO_PENDING then //正在接收数据
begin
bb:=WaitForSingleObject(LpolR^.hEvent,500);//等待500ms
Case bb of
Wait_Object_0: RXFinish:=GetOverLappedResult(hcom,LpolR^,dwOvRes,False);
//返回False,出错
Wait_TimeOut: RXFinish:=False;//定时溢出
else RXFinish:=False; //出错
end;
end else RXFinish:=False;
if RXFinish then
begin
if WaitForsingleobject(Post_Event,infinite)=Wait_Object_0 then //等待同步事件置位
begin
resetEvent(Post_Event); //同步事件复位
// PostMessage(self.handle,WM_CommNotify,0,0); //发送消息
//在这里可以触发串口接收事件
end;
end;
end;
end;
Procedure ComInit(com:PAnsiChar;baudrate,DataBit,stopBit,parity:integer;buf:longint);stdCall;
Var
Lpdcb:TDCB;
begin
hcom:=createFile(com, //串口名,可为com1-com4
generic_read or Generic_write,//访问模式
0, //共享模式,必须为0
nil, //安全属性指针
open_existing, ///找开方式必须为open_existing
File_Flag_Overlapped,//文件属性,本文设为交迭标志
0); //临时文件句柄,必须为0
if hcom<>invalid_Handle_Value then
begin
SetupComm(hcom,buf,buf); //设置缓冲区长度
getCommState(hcom,lpdcb); //设置串口
lpdcb.baudrate:=baudrate;
lpdcb.stopbits:=stopBit;
lpdcb.bytesize:=DataBit;
lpdcb.parity:=parity;
setCommState(hcom,lpdcb);
SetCommMask(Hcom,ev_Rxchar); //设置串口事件屏蔽
end else showMessage('无法打开串口!');
end;
Function WriteStr(const Str:String):Boolean;stdCall; //发送数据
var
DwCharsWritten,DwRes:Dword;
S_DATA:String;
BRes:boolean;
Begin
BRes:=False;
S_Data:=Str;
if hcom<>INVALID_HANDLE_VALUE then
begin
DwCharsWritten:=0;
BRes:=WriteFile(Hcom,PChar(S_Data)^,Length(S_Data),
DwCharsWritten,LpolW); //返回True,数据立即发送完成
if not BRes then
begin
if GetLastError()=Error_IO_Pending then
begin //正在发送数据
DwRes:=WaitForSingleObject(LpolW^.hEvent,Infinite);
if DwRes=Wait_Object_0 then // 如果不相等,出错
BRes:=GetOverLappedResult(hcom,LpolW^,DwCharsWritten,False) //返回False,出错
else BRes:=true; //数据发送完成
end;
end;
end;
Result:=Bres;
end;
Procedure ReadStr(Var Msg:Tmessage);stdCall; //接收数据
var
clear:boolean;
coms:TComStat;
cbNum,Cbread,lpErrors:Dword;
s:string;
begin
clear:=clearCommerror(hcom,lperrors,@Coms);
if clear then
begin
cbnum:=Coms.cbInQue; //获取接收缓冲区待接收字节数
setlength(s,cbnum+1); //分配内存
ReadFile(hcom,PChar(S)^,cbnum,Cbread,LpolR); //读串口
setlength(s,cbread); //分配
SetEvent(Post_Event); //同步事件置位
end;
end;
procedure FreeMemo(Sender: TObject);stdcall //释放内存
begin
CloseHandle(LpolW^.hEvent);
CloseHandle(LpolR^.hEvent);
dispose(lpolW);
dispose(lpolR);
LpolW:=Nil;
LpolR:=Nil;
SetEvent(Post_Event);
CloseHandle(Post_Event);
CloseHandle(hcom);
end;
procedure InitMemo();stdCall; //初始化内存
begin
New(lpolW);
New(lpolR);
LpolW^.Internal:=0;
LpolW^.InternalHigh:=0;
LpolW^.Offset:=0;
LpolW^.OffsetHigh:=0;
LpolW^.hEvent:=Createevent(nil,true,False,nil);
Lpolr^.Internal:=0;
Lpolr^.InternalHigh:=0;
Lpolr^.Offset:=0;
Lpolr^.OffsetHigh:=0;
Lpolr^.hEvent:=Createevent(nil,true,False,nil);
PurgeComm(Hcom,Purge_TxAbort or Purge_RxAbort or Purge_Txclear or Purge_Rxclear);
Post_Event:=Createevent(nil,true,true,nil);
//RXComm:=Tcomm.Create(false);
end;
exports
ComInit,WriteStr,ReadStr,FreeMemo,InitMemo;
begin
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -