📄 pop3prot.pas
字号:
write FPassWord;
property AuthType : TPop3AuthType read FAuthType
write FAuthType; {HLX}
property ErrorMessage : String read FErrorMessage;
property LastResponse : String read FLastResponse;
property State : TPop3State read FState;
property Connected : Boolean read FConnected;
property ProtocolState : TPop3ProtocolState read FProtocolState;
{:Updated by the Stat method with the number of
messages in the maildrop }
property MsgCount : Integer read FMsgCount;
{:Updated by the Stat method with the total size
in byte for the messages in the maildrop }
property MsgSize : Integer read FMsgSize;
{:This is the number of lines to display in the TOP command
Set to zero if you wants the default value }
property MsgLines : Integer read FMsgLines
write FMsgLines;
{:This is the message number which must be returned by the Retr
method. It is also updated by the Last method }
property MsgNum : Integer read FMsgNum
write FMsgNum;
property MsgUidl : String read FMsgUidl;
{:The following properties are decoded by RETR command }
property HeaderKeyword : String read FHeaderKeyword;
property HeaderData : String read FHeaderData;
property HeaderFrom : String read FHeaderFrom;
property HeaderTo : String read FHeaderTo;
property HeaderSubject : String read FHeaderSubject;
property HeaderReplyTo : String read FHeaderReplyTo;
property HeaderInReplyTo : String read FHeaderInReplyTo;
property HeaderMessageId : String read FHeaderMessageId;
property HeaderDate : String read FHeaderDate;
property HeaderReturnPath : String read FHeaderReturnPath;
{:General purpose property, not used by component }
property Tag : LongInt read FTag
write FTag;
property Handle : HWND read FWindowHandle;
property OnDisplay : TPop3Display read FOnDisplay
write FOnDisplay;
property OnMessageBegin : TNotifyEvent read FOnMessageBegin
write FOnMessageBegin;
property OnMessageEnd : TNotifyEvent read FOnMessageEnd
write FOnMessageEnd;
property OnMessageLine : TNotifyEvent read FOnMessageLine
write FOnMessageLine;
property OnListBegin : TNotifyEvent read FOnListBegin
write FOnListBegin;
property OnListEnd : TNotifyEvent read FOnListEnd
write FOnListEnd;
property OnListLine : TNotifyEvent read FOnListLine
write FOnListLine;
property OnUidlBegin : TNotifyEvent read FOnUidlBegin
write FOnUidlBegin;
property OnUidlEnd : TNotifyEvent read FOnUidlEnd
write FOnUidlEnd;
property OnUidlLine : TNotifyEvent read FOnUidlLine
write FOnUidlLine;
property OnHeaderEnd : TNotifyEvent read FOnHeaderEnd
write FOnHeaderEnd;
property OnStateChange : TNotifyEvent read FOnStateChange
write FOnStateChange;
property OnRequestDone : TPop3RequestDone read FOnRequestDone
write FOnRequestDone;
property OnResponse: TPop3Display read FOnResponse
write FOnResponse;
property OnSessionConnected : TSessionConnected
read FOnSessionConnected
write FOnSessionConnected;
property OnSessionClosed : TSessionClosed
read FOnSessionClosed
write FOnSessionClosed;
end;
TPop3Cli = class(TCustomPop3Cli)
published
property Host;
property LocalAddr; {bb}
property Port;
property UserName;
property PassWord;
property AuthType;
property ErrorMessage;
property LastResponse;
property ProtocolState;
property MsgCount;
property MsgSize;
property MsgLines;
property MsgNum;
property MsgUidl;
property Tag;
property OnDisplay;
property OnMessageBegin;
property OnMessageEnd;
property OnMessageLine;
property OnListBegin;
property OnListEnd;
property OnListLine;
property OnUidlBegin;
property OnUidlEnd;
property OnUidlLine;
property OnHeaderEnd;
property OnStateChange;
property OnRequestDone;
property OnResponse;
property OnSessionConnected;
property OnSessionClosed;
end;
{ TSyncPop3Cli add synchronous functions. You should avoid using this }
{ component because synchronous function, apart from being easy, result }
{ in lower performance programs. }
TSyncPop3Cli = class(TPop3Cli)
protected
FTimeout : Integer; { Given in seconds }
FTimeStop : LongInt; { Milli-seconds }
FMultiThreaded : Boolean;
function WaitUntilReady : Boolean; virtual;
function Synchronize(Proc : TPop3NextProc) : Boolean;
procedure TriggerResponse(Msg : String); override; { Angus }
public
constructor Create(AOwner : TComponent); override;
function ConnectSync : Boolean; virtual;
function OpenSync : Boolean; virtual;
function UserSync : Boolean; virtual;
function PassSync : Boolean; virtual;
function RPopSync : Boolean; virtual;
function APopSync : Boolean; virtual;
function QuitSync : Boolean; virtual;
function StatSync : Boolean; virtual;
function ListSync : Boolean; virtual;
function RetrSync : Boolean; virtual;
function TopSync : Boolean; virtual;
function DeleSync : Boolean; virtual;
function NoopSync : Boolean; virtual;
function LastSync : Boolean; virtual;
function RSetSync : Boolean; virtual;
function UidlSync : Boolean; virtual;
function AbortSync : Boolean; virtual;
published
property Timeout : Integer read FTimeout
write FTimeout;
property MultiThreaded : Boolean read FMultiThreaded
write FMultiThreaded;
end;
procedure Register;
implementation
const
HexDigits : array [0..15] of char = ('0','1','2','3','4','5','6','7','8',
'9','a','b','c','d','e','f');
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{$IFDEF VER80}
procedure SetLength(var S: string; NewLength: Integer);
begin
S[0] := chr(NewLength);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function RTrim(Str : String) : String;
var
i : Integer;
begin
i := Length(Str);
while (i > 0) and (Str[i] = ' ') do
i := i - 1;
Result := Copy(Str, 1, i);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function LTrim(Str : String) : String;
var
I : Integer;
begin
if Str[1] <> ' ' then { Petite optimisation: pas d'espace }
Result := Str
else begin
I := 1;
while (i <= Length(Str)) and (Str[I] = ' ') do
I := I + 1;
Result := Copy(Str, I, Length(Str) - I + 1);
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function Trim(Str : String) : String;
begin
Result := LTrim(Rtrim(Str));
end;
{$ENDIF}
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function stpblk(PValue : PChar) : PChar;
begin
Result := PValue;
while Result^ in [' ', #9, #10, #13] do
Inc(Result);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function atoi(PValue : PChar) : Integer;
begin
Result := 0;
PValue := stpblk(PValue);
while PValue^ in ['0'..'9'] do begin
Result := Result * 10 + ord(PValue^) - ord('0');
Inc(PValue);
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
{$IFDEF NOFORMS}
{ This function is a callback function. It means that it is called by }
{ windows. This is the very low level message handler procedure setup to }
{ handle the message sent by windows (winsock) to handle messages. }
function POP3CliWindowProc(
ahWnd : HWND;
auMsg : Integer;
awParam : WPARAM;
alParam : LPARAM): Integer; stdcall;
var
Obj : TObject;
MsgRec : TMessage;
begin
{ At window creation asked windows to store a pointer to our object }
Obj := TObject(GetWindowLong(ahWnd, 0));
{ If the pointer doesn't represent a TCustomFtpCli, just call the default procedure}
if not (Obj is TPOP3Cli) then
Result := DefWindowProc(ahWnd, auMsg, awParam, alParam)
else begin
{ Delphi use a TMessage type to pass parameter to his own kind of }
{ windows procedure. So we are doing the same... }
MsgRec.Msg := auMsg;
MsgRec.wParam := awParam;
MsgRec.lParam := alParam;
{ May be a try/except around next line is needed. Not sure ! }
TPOP3Cli(Obj).WndProc(MsgRec);
Result := MsgRec.Result;
end;
end;
{$ENDIF}
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
function TCustomPop3Cli.POP3CliAllocateHWnd(Method: TWndMethod) : HWND;
begin
{$IFDEF NOFORMS}
Result := XSocketAllocateHWnd(Self);
SetWindowLong(Result, GWL_WNDPROC, LongInt(@POP3CliWindowProc));
{$ELSE}
Result := WSocket.AllocateHWnd(Method);
{$ENDIF}
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.POP3CliDeallocateHWnd(WHandle : HWND);
begin
{$IFDEF NOFORMS}
XSocketDeallocateHWnd(WHandle);
{$ELSE}
WSocket.DeallocateHWnd(WHandle);
{$ENDIF}
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
constructor TCustomPop3Cli.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
FWindowHandle := POP3CliAllocateHWnd(WndProc);
FWSocket := TWSocket.Create(nil);
FWSocket.OnSessionClosed := WSocketSessionClosed;
FProtocolState := pop3Disconnected;
FState := pop3Ready;
FLocalAddr := '0.0.0.0'; {bb}
FPort := 'pop3';
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
destructor TCustomPop3Cli.Destroy;
begin
if Assigned(FWSocket) then begin
FWSocket.Destroy;
FWSocket := nil;
end;
POP3CliDeallocateHWnd(FWindowHandle);
inherited Destroy;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.WndProc(var MsgRec: TMessage);
begin
with MsgRec do begin
case Msg of
WM_POP3_REQUEST_DONE : WMPop3RequestDone(MsgRec);
else
Result := DefWindowProc(Handle, Msg, wParam, lParam);
end;
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.WMPop3RequestDone(var msg: TMessage);
begin
if Assigned(FOnRequestDone) then
FOnRequestDone(Self, FRequestType, Msg.LParam);
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if Operation = opRemove then begin
if AComponent = FWSocket then
FWSocket := nil;
end;
end;
{* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
procedure TCustomPop3Cli.WSocketDnsLookupDone(Sender: TObject; Error: Word);
begin
if Error <> 0 then begin
FLastResponse := '-ERR ' + WSocketErrorDesc(Error) +
' (Winsock error #' + IntToStr(Error) + ')';
FStatusCode := 500;
FRequestResult := Error; { V2.02 }
SetErrorMessage;
TriggerRequestDone(Error);
end
else begin
FWSocket.Addr := FWSocket.DnsResult;
FWSocket.Proto := 'tcp';
FWSocket.Port := FPort;
FWSocket.LocalAddr := FLocalAddr; {bb}
FWSocket.OnSessionConnected := WSocketSessionConnected;
FWSocket.OnDataAvailable := WSocketDataAvailable;
StateChange(pop3Connecting);
try
FWSocket.Connect;
except
on E:Exception do begin
FLastResponse := '-ERR ' + E.ClassName + ': ' + E.Message;
FStatusCode := 500;
FRequestResult := FStatusCode;
SetErrorMessage;
TriggerRequestDone(FStatusCode);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -