?? scktmain.pas
字號:
{*******************************************************}
{ }
{ Borland Delphi Visual Component Library }
{ Borland Socket Server source code }
{ }
{ Copyright (c) 1997,99 Inprise Corporation }
{ }
{*******************************************************}
unit ScktMain;
interface
uses
SvcMgr, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ShellAPI, ExtCtrls, StdCtrls, ComCtrls, ScktComp, Registry,
ActnList;
const
WM_MIDASICON = WM_USER + 1;
UI_INITIALIZE = WM_MIDASICON + 1;
type
TSocketProc = procedure(Item: TListItem; Socket: TCustomWinSocket) of Object;
TSocketForm = class(TForm)
PopupMenu: TPopupMenu;
miClose: TMenuItem;
N1: TMenuItem;
miProperties: TMenuItem;
UpdateTimer: TTimer;
MainMenu1: TMainMenu;
miPorts: TMenuItem;
miAdd: TMenuItem;
miRemove: TMenuItem;
Pages: TPageControl;
PropPage: TTabSheet;
PortGroup: TGroupBox;
Label1: TLabel;
PortDesc: TLabel;
PortNo: TEdit;
PortUpDown: TUpDown;
ThreadGroup: TGroupBox;
Label4: TLabel;
ThreadDesc: TLabel;
ThreadSize: TEdit;
ThreadUpDown: TUpDown;
InterceptGroup: TGroupBox;
Label5: TLabel;
GUIDDesc: TLabel;
StatPage: TTabSheet;
ConnectionList: TListView;
Connections1: TMenuItem;
miShowHostName: TMenuItem;
miDisconnect: TMenuItem;
N2: TMenuItem;
TimeoutGroup: TGroupBox;
Label7: TLabel;
Timeout: TEdit;
TimeoutUpDown: TUpDown;
TimeoutDesc: TLabel;
InterceptGUID: TEdit;
ApplyButton: TButton;
ActionList1: TActionList;
ApplyAction: TAction;
DisconnectAction: TAction;
ShowHostAction: TAction;
RemovePortAction: TAction;
N3: TMenuItem;
miExit: TMenuItem;
Panel1: TPanel;
PortList: TListBox;
HeaderControl1: THeaderControl;
UserStatus: TStatusBar;
ExportedObjectOnly1: TMenuItem;
RegisteredAction: TAction;
XMLPacket1: TMenuItem;
AllowXML: TAction;
About1: TMenuItem;
About2: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure miCloseClick(Sender: TObject);
procedure miPropertiesClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure miDisconnectClick(Sender: TObject);
procedure miExitClick(Sender: TObject);
procedure ApplyActionExecute(Sender: TObject);
procedure ApplyActionUpdate(Sender: TObject);
procedure DisconnectActionUpdate(Sender: TObject);
procedure ShowHostActionExecute(Sender: TObject);
procedure miAddClick(Sender: TObject);
procedure RemovePortActionUpdate(Sender: TObject);
procedure RemovePortActionExecute(Sender: TObject);
procedure UpDownClick(Sender: TObject; Button: TUDBtnType);
procedure PortListClick(Sender: TObject);
procedure ConnectionListCompare(Sender: TObject; Item1,
Item2: TListItem; Data: Integer; var Compare: Integer);
procedure ConnectionListColumnClick(Sender: TObject;
Column: TListColumn);
procedure IntegerExit(Sender: TObject);
procedure UpdateTimerTimer(Sender: TObject);
procedure RegisteredActionExecute(Sender: TObject);
procedure AllowXMLExecute(Sender: TObject);
procedure About2Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
FTaskMessage: DWord;
FIconData: TNotifyIconData;
FClosing: Boolean;
FProgmanOpen: Boolean;
FFromService: Boolean;
NT351: Boolean;
FCurItem: Integer;
FSortCol: Integer;
procedure UpdateStatus;
function GetSelectedSocket: TServerSocket;
function GetItemIndex: Integer;
procedure SetItemIndex(Value: Integer);
procedure CheckValues;
protected
procedure AddClient(Thread: TServerClientThread);
procedure RemoveClient(Thread: TServerClientThread);
procedure ClearModifications;
procedure UIInitialize(var Message: TMessage); message UI_INITIALIZE;
procedure WMMIDASIcon(var Message: TMessage); message WM_MIDASICON;
procedure AddIcon;
procedure ReadSettings;
procedure WndProc(var Message: TMessage); override;
procedure WriteSettings;
public
procedure Initialize(FromService: Boolean);
property SelectedSocket: TServerSocket read GetSelectedSocket;
property ItemIndex: Integer read GetItemIndex write SetItemIndex;
end;
TSocketService = class(TService)
protected
procedure Start(Sender: TService; var Started: Boolean);
procedure Stop(Sender: TService; var Stopped: Boolean);
public
function GetServiceController: TServiceController; override;
constructor CreateNew(AOwner: TComponent; Dummy: Integer = 0); override;
end;
var
SocketForm: TSocketForm;
SocketService: TSocketService;
implementation
uses ScktCnst, SConnect, ActiveX, MidConst;
{$R *.dfm}
{ TSocketDispatcherThread }
type
TSocketDispatcherThread = class(TServerClientThread, ISendDataBlock)
private
FRefCount: Integer;
FInterpreter: TDataBlockInterpreter;
FTransport: ITransport;
FInterceptGUID: string;
FLastActivity: TDateTime;
FTimeout: TDateTime;
FRegisteredOnly: Boolean;
FAllowXML: Boolean;
protected
function CreateServerTransport: ITransport; virtual;
procedure AddClient;
procedure RemoveClient;
{ IUnknown }
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
{ ISendDataBlock }
function Send(const Data: IDataBlock; WaitForResult: Boolean): IDataBlock; stdcall;
public
constructor Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket;
const InterceptGUID: string; Timeout: Integer; RegisteredOnly, AllowXML: Boolean);
procedure ClientExecute; override;
property LastActivity: TDateTime read FLastActivity;
end;
constructor TSocketDispatcherThread.Create(CreateSuspended: Boolean;
ASocket: TServerClientWinSocket; const InterceptGUID: string; Timeout: Integer;
RegisteredOnly, AllowXML: Boolean);
begin
FInterceptGUID := InterceptGUID;
FTimeout := EncodeTime(Timeout div 60, Timeout mod 60, 0, 0);
FLastActivity := Now;
FRegisteredOnly := RegisteredOnly;
FAllowXML := AllowXML;
inherited Create(CreateSuspended, ASocket);
end;
function TSocketDispatcherThread.CreateServerTransport: ITransport;
var
SocketTransport: TSocketTransport;
begin
SocketTransport := TSocketTransport.Create;
SocketTransport.Socket := ClientSocket;
SocketTransport.InterceptGUID := FInterceptGUID;
Result := SocketTransport as ITransport;
end;
procedure TSocketDispatcherThread.AddClient;
begin
SocketForm.AddClient(Self);
end;
procedure TSocketDispatcherThread.RemoveClient;
begin
SocketForm.RemoveClient(Self);
end;
{ TSocketDispatcherThread.IUnknown }
function TSocketDispatcherThread.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE;
end;
function TSocketDispatcherThread._AddRef: Integer;
begin
Inc(FRefCount);
Result := FRefCount;
end;
function TSocketDispatcherThread._Release: Integer;
begin
Dec(FRefCount);
Result := FRefCount;
end;
{ TSocketDispatcherThread.ISendDataBlock }
function TSocketDispatcherThread.Send(const Data: IDataBlock; WaitForResult: Boolean): IDataBlock;
begin
FTransport.Send(Data);
if WaitForResult then
while True do
begin
Result := FTransport.Receive(True, 0);
if Result = nil then break;
if (Result.Signature and ResultSig) = ResultSig then
break else
FInterpreter.InterpretData(Result);
end;
end;
procedure TSocketDispatcherThread.ClientExecute;
var
Data: IDataBlock;
msg: TMsg;
Obj: ISendDataBlock;
Event: THandle;
WaitTime: DWord;
begin
CoInitialize(nil);
try
Synchronize(AddClient);
FTransport := CreateServerTransport;
try
Event := FTransport.GetWaitEvent;
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
GetInterface(ISendDataBlock, Obj);
if FRegisteredOnly then
FInterpreter := TDataBlockInterpreter.Create(Obj, SSockets) else
FInterpreter := TDataBlockInterpreter.Create(Obj, '');
try
Obj := nil;
if FTimeout = 0 then
WaitTime := INFINITE else
WaitTime := 60000;
while not Terminated and FTransport.Connected do
try
case MsgWaitForMultipleObjects(1, Event, False, WaitTime, QS_ALLEVENTS) of
WAIT_OBJECT_0:
begin
WSAResetEvent(Event);
Data := FTransport.Receive(False, 0);
if Assigned(Data) then
begin
FLastActivity := Now;
FInterpreter.InterpretData(Data);
Data := nil;
FLastActivity := Now;
end;
end;
WAIT_OBJECT_0 + 1:
while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
DispatchMessage(msg);
WAIT_TIMEOUT:
if (FTimeout > 0) and ((Now - FLastActivity) > FTimeout) then
FTransport.Connected := False;
end;
except
FTransport.Connected := False;
end;
finally
FInterpreter.Free;
FInterpreter := nil;
end;
finally
FTransport := nil;
end;
finally
CoUninitialize;
Synchronize(RemoveClient);
end;
end;
{ TSocketDispatcher }
type
TSocketDispatcher = class(TServerSocket)
private
FInterceptGUID: string;
FTimeout: Integer;
procedure GetThread(Sender: TObject; ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
public
constructor Create(AOwner: TComponent); override;
procedure ReadSettings(PortNo: Integer; Reg: TRegINIFile);
procedure WriteSettings(Reg: TRegINIFile);
property InterceptGUID: string read FInterceptGUID write FInterceptGUID;
property Timeout: Integer read FTimeout write FTimeout;
end;
constructor TSocketDispatcher.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ServerType := stThreadBlocking;
OnGetThread := GetThread;
end;
procedure TSocketDispatcher.GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
try {##Fix By Manuel Parma mparma@usa.net}
SocketThread := TSocketDispatcherThread.Create(False, ClientSocket,
InterceptGUID, Timeout, SocketForm.RegisteredAction.Checked, SocketForm.AllowXML.Checked);
except {##Fix By Manuel Parma mparma@usa.net}
Abort; {##Fix By Manuel Parma mparma@usa.net}
end; {##Fix By Manuel Parma mparma@usa.net}
end;
procedure TSocketDispatcher.ReadSettings(PortNo: Integer; Reg: TRegINIFile);
var
Section: string;
begin
if PortNo = -1 then
begin
Section := csSettings;
Port := Reg.ReadInteger(Section, ckPort, 211);
end else
begin
Section := IntToStr(PortNo);
Port := PortNo;
end;
ThreadCacheSize := Reg.ReadInteger(Section, ckThreadCacheSize, 10);
FInterceptGUID := Reg.ReadString(Section, ckInterceptGUID, '');
FTimeout := Reg.ReadInteger(Section, ckTimeout, 0);
end;
procedure TSocketDispatcher.WriteSettings(Reg: TRegINIFile);
var
Section: string;
begin
Section := IntToStr(Port);
Reg.WriteInteger(Section, ckPort, Port);
Reg.WriteInteger(Section, ckThreadCacheSize, ThreadCacheSize);
Reg.WriteString(Section, ckInterceptGUID, InterceptGUID);
Reg.WriteInteger(Section, ckTimeout, Timeout);
end;
{ TSocketService }
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
SocketService.Controller(CtrlCode);
end;
function TSocketService.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
constructor TSocketService.CreateNew(AOwner: TComponent; Dummy: Integer);
begin
inherited CreateNew(AOwner, Dummy);
AllowPause := False;
Interactive := True;
DisplayName := SApplicationName;
Name := SServiceName;
OnStart := Start;
OnStop := Stop;
end;
procedure TSocketService.Start(Sender: TService; var Started: Boolean);
begin
PostMessage(SocketForm.Handle, UI_INITIALIZE, 1, 0);
Started := True;
end;
procedure TSocketService.Stop(Sender: TService; var Stopped: Boolean);
begin
PostMessage(SocketForm.Handle, WM_QUIT, 0, 0);
Stopped := True;
end;
{ TSocketForm }
procedure TSocketForm.FormCreate(Sender: TObject);
begin
if not LoadWinSock2 then
raise Exception.CreateRes(@SNoWinSock2);
FClosing := False;
FCurItem := -1;
FSortCol := -1;
end;
procedure TSocketForm.WndProc(var Message: TMessage);
begin
if Message.Msg = FTaskMessage then
begin
AddIcon;
Refresh;
end;
inherited WndProc(Message);
end;
procedure TSocketForm.UpdateTimerTimer(Sender: TObject);
var
Found: Boolean;
begin
Found := FindWindow('Progman', nil) <> 0;
if Found <> FProgmanOpen then
begin
FProgmanOpen := Found;
if Found then AddIcon;
Refresh;
end;
end;
procedure TSocketForm.CheckValues;
begin
StrToInt(PortNo.Text);
StrToInt(ThreadSize.Text);
StrToInt(Timeout.Text);
end;
function TSocketForm.GetItemIndex: Integer;
begin
Result := FCurItem;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -