ServerDlg.pas
上传用户:llfxmlw
上传日期:2009-09-14
资源大小:335k
文件大小:20k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit ServerDlg;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  5.   ExtCtrls, StdCtrls, WinSock, ScktComp, Menus, TrayIcon, FormSettings,
  6.   RemConMessages, ZLib, MsgSimulator, ComCtrls, ShellAPI;
  7. type
  8.   TServerForm = class(TForm)
  9.     PageControl1: TPageControl;
  10.     TabSheet1: TTabSheet;
  11.     TabSheet2: TTabSheet;
  12.     LogList: TListBox;
  13.     ServerPanel: TPanel;
  14.     Label5: TLabel;
  15.     StartLab: TLabel;
  16.     Label9: TLabel;
  17.     ConLab: TLabel;
  18.     Label11: TLabel;
  19.     NumRecLab: TLabel;
  20.     Label13: TLabel;
  21.     NumSendLab: TLabel;
  22.     Label3: TLabel;
  23.     LastRecLab: TLabel;
  24.     Label4: TLabel;
  25.     NumErrLab: TLabel;
  26.     Panel1: TPanel;
  27.     Label1: TLabel;
  28.     NameLabel: TLabel;
  29.     Label2: TLabel;
  30.     PortEdit: TEdit;
  31.     Panel2: TPanel;
  32.     StartBut: TButton;
  33.     DisconBut: TButton;
  34.     MinimizeBut: TButton;
  35.     ClientBut: TButton;
  36.     ServerSocket1: TServerSocket;
  37.     TrayIcon1: TTrayIcon;
  38.     TrayMenu: TPopupMenu;
  39.     RemoteControl1: TMenuItem;
  40.     N1: TMenuItem;
  41.     Client1: TMenuItem;
  42.     N2: TMenuItem;
  43.     Shutdown1: TMenuItem;
  44.     FormSettings1: TFormSettings;
  45.     MsgSimulator1: TMsgSimulator;
  46.     Label6: TLabel;
  47.     PassEdit: TEdit;
  48.     procedure StartButClick(Sender: TObject);
  49.     procedure DisconButClick(Sender: TObject);
  50.     procedure FormShow(Sender: TObject);
  51.     procedure MinimizeButClick(Sender: TObject);
  52.     procedure RemoteControl1Click(Sender: TObject);
  53.     procedure Shutdown1Click(Sender: TObject);
  54.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  55.     procedure ServerSocket1Listen(Sender: TObject;
  56.       Socket: TCustomWinSocket);
  57.     procedure ServerSocket1ClientRead(Sender: TObject;
  58.       Socket: TCustomWinSocket);
  59.     procedure ServerSocket1ClientConnect(Sender: TObject;
  60.       Socket: TCustomWinSocket);
  61.     procedure ServerSocket1ClientDisconnect(Sender: TObject;
  62.       Socket: TCustomWinSocket);
  63.     procedure ServerSocket1ClientError(Sender: TObject;
  64.       Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  65.       var ErrorCode: Integer);
  66.     procedure FormCreate(Sender: TObject);
  67.     procedure FormDestroy(Sender: TObject);
  68.     procedure Client1Click(Sender: TObject);
  69.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  70.     procedure ClientButClick(Sender: TObject);
  71.   protected
  72.     NumRec     : double;
  73.     NumSend    : double;
  74.     NumError   : integer;
  75.     CurMsg     : string;
  76.     LoggedOn   : boolean;
  77.     CurBmp     : TBitmap;
  78.     CurSocket  : TCustomWinSocket;
  79.     CurHandle  : THandle;
  80.     SleepTime  : integer;
  81.     ViewMode   : TViewMode;
  82.     CompMode   : TCompressionLevel;
  83.     procedure  UpdateStats;
  84.     procedure  Log(const s: string);
  85.     procedure  ProcessClick(const Data: string);
  86.     procedure  ProcessDrag(const Data: string);
  87.     procedure  Send_Screen_Update(Socket: TCustomWinSocket);
  88.     procedure  SleepDone(Sender: TObject);
  89.     procedure  ProcessKeys(const Data: string);
  90.     procedure  CreateSleepThread;
  91.     procedure  GetHostNameAddr;
  92.     procedure  ParseComLine;
  93.     function   Get_Process_List: string;
  94.     procedure  CloseWindow(const Data: string);
  95.     procedure  KillWindow(const Data: string);
  96.     function   Get_Drive_List: string;
  97.     function   GetDirectory(const PathName: string): string;
  98.     function   GetFile(const PathName: string): string;
  99.   public
  100.     procedure  EnableButs;
  101.     procedure  ProcessMessage(const Msg: string; Socket: TCustomWinSocket);
  102.     procedure  SendMsg(MsgNum: integer; const MsgData: string; Socket: TCustomWinSocket);
  103.   end;
  104. var
  105.   ServerForm: TServerForm;
  106. implementation
  107. uses ClientFrm;
  108. {$R *.DFM}
  109. procedure TServerForm.StartButClick(Sender: TObject);
  110. begin
  111.    with ServerSocket1 do begin
  112.       Port := StrToInt(PortEdit.Text);
  113.       Active := True;
  114.    end;
  115.    EnableButs;
  116. end;
  117. procedure TServerForm.DisconButClick(Sender: TObject);
  118. begin
  119.    ServerSocket1.Active := False;
  120.    EnableButs;
  121. end;
  122. procedure TServerForm.EnableButs;
  123. var
  124.    b : boolean;
  125. begin
  126.    b := ServerSocket1.Active;
  127.    StartBut.Enabled := not b;
  128.    PortEdit.Enabled := not b;
  129.    DisconBut.Enabled := b;
  130.    // MinimizeBut.Enabled := b;
  131. end;
  132. procedure TServerForm.GetHostNameAddr;
  133. var
  134.    buf   : array[0..MAX_PATH] of char;
  135.    he    : PHostEnt;
  136.    buf2  : PChar;
  137.    rc    : integer;
  138. begin
  139.    rc := GetHostName(buf, sizeof(buf));
  140.    if rc<>SOCKET_ERROR then begin
  141.       he := GetHostByName(buf);
  142.       if he = nil then begin
  143.          rc := WSAGetLastError;
  144.          NameLabel.Caption := Format('Socket Error %d = %s', [rc, SysErrorMessage(rc)]);
  145.       end else begin
  146.          buf2 := inet_ntoa(PInAddr(he.h_addr^)^);
  147.          NameLabel.Caption := Format('%s  (%s)', [buf, buf2]);
  148.       end;
  149.    end else begin
  150.       NameLabel.Caption := 'Unknown Host';
  151.    end;
  152. end;
  153. procedure TServerForm.FormShow(Sender: TObject);
  154. begin
  155.    EnableButs;
  156.    GetHostNameAddr;
  157. end;
  158. procedure TServerForm.MinimizeButClick(Sender: TObject);
  159. begin
  160.    if ServerSocket1.Active then begin
  161.       TrayIcon1.ToolTip := Application.Title + ' - Port: ' + PortEdit.Text;
  162.    end else begin
  163.       TrayIcon1.ToolTip := Application.Title + ' - Inactive';
  164.    end;
  165.    TrayIcon1.Active := True;
  166.    ShowWindow(Application.Handle, SW_HIDE);
  167.    Hide;
  168. end;
  169. procedure TServerForm.RemoteControl1Click(Sender: TObject);
  170. begin
  171.    TrayIcon1.Active := False;
  172.    ShowWindow(Application.Handle, SW_SHOW);
  173.    Application.Restore;
  174.    Show;
  175.    SetForegroundWindow(Handle);
  176. end;
  177. procedure TServerForm.Shutdown1Click(Sender: TObject);
  178. begin
  179.    RemoteControl1Click(nil);
  180.    Close;
  181. end;
  182. procedure TServerForm.FormClose(Sender: TObject; var Action: TCloseAction);
  183. begin
  184.    FormSettings1.SaveSettings;
  185. end;
  186. procedure TServerForm.ServerSocket1Listen(Sender: TObject;
  187.   Socket: TCustomWinSocket);
  188. begin
  189.    StartLab.Caption := CurTime;
  190.    NumRec   := 0;
  191.    NumSend  := 0;
  192.    CurMsg   := '';
  193.    LoggedOn := False;
  194.    UpdateStats;
  195.    Log('Startup at ' + CurTime);
  196. end;
  197. procedure TServerForm.UpdateStats;
  198. begin
  199.    ConLab.Caption := IntToStr(ServerSocket1.Socket.ActiveConnections);
  200.    NumRecLab.Caption := Format('%1.0n', [NumRec]);
  201.    NumSendLab.Caption := Format('%1.0n', [NumSend]);
  202.    NumErrLab.Caption := IntToStr(NumError);
  203. end;
  204. procedure TServerForm.ServerSocket1ClientRead(Sender: TObject;
  205.   Socket: TCustomWinSocket);
  206. var
  207.    s : string;
  208. begin
  209.    Log(Format('%-20s %s', ['Recv Data', Socket.RemoteAddress]));
  210.    LastRecLab.Caption := CurTime;
  211.    s := Socket.ReceiveText;
  212.    NumRec := NumRec + Length(s);
  213.    UpdateStats;
  214.    CurMsg := CurMsg + s;
  215.    while IsValidMessage(CurMsg) do begin
  216.       s := TrimFirstMsg(CurMsg);
  217.       ProcessMessage(s, Socket);
  218.    end;
  219. end;
  220. procedure TServerForm.ServerSocket1ClientConnect(Sender: TObject;
  221.   Socket: TCustomWinSocket);
  222. begin
  223.    Log(Format('%-20s %s', ['Connect', Socket.RemoteAddress]));
  224.    ViewMode := vmColor4;
  225.    CompMode := clDefault;
  226.    SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_NORMAL);
  227.    UpdateStats;
  228. end;
  229. procedure TServerForm.ServerSocket1ClientDisconnect(Sender: TObject;
  230.   Socket: TCustomWinSocket);
  231. begin
  232.    Log(Format('%-20s %s', ['Disconnect', Socket.RemoteAddress]));
  233.    UpdateStats;
  234. end;
  235. procedure TServerForm.ServerSocket1ClientError(Sender: TObject;
  236.   Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  237.   var ErrorCode: Integer);
  238. begin
  239.    Log(Format('%-20s %d', ['Error', ErrorCode]));
  240.    ErrorCode := 0;
  241.    Inc(NumError);
  242.    UpdateStats;
  243. end;
  244. procedure TServerForm.Log(const s: string);
  245. begin
  246.    LogList.ItemIndex := LogList.Items.Add(s);
  247. end;
  248. procedure TServerForm.ProcessMessage(const Msg: string; Socket: TCustomWinSocket);
  249. var
  250.    MsgNum, x: integer;
  251.    rc       : integer;
  252.    Data     : string;
  253.    bmp      : TBitmap;
  254.    tmp      : string;
  255. begin
  256.    CurSocket := Socket;
  257.    Move(Msg[1], MsgNum, sizeof(integer));
  258.    Data := Copy(Msg, 9, Length(Msg));
  259.    Log(Format('%-20s %d', ['Message', MsgNum]));
  260.    if MsgNum = MSG_LOGON then begin
  261.       LoggedOn := (AnsiCompareText(Data, PassEdit.Text) = 0);
  262.       if LoggedOn then begin
  263.          SendMsg(MSG_LOGON, '1', Socket)
  264.       end else begin
  265.          SendMsg(MSG_LOGON, '0', Socket);
  266.       end;
  267.       exit;
  268.    end;
  269.    if not LoggedOn then begin
  270.       Log('Denied Access!');
  271.       SendMsg(MSG_STAT_MSG, 'Invalid Password', Socket);
  272.       Socket.Close;
  273.       exit;
  274.    end;
  275.    if MsgNum = MSG_REFRESH then begin
  276.       Log('Screen Capture');
  277.       SendMsg(MSG_STAT_MSG, 'Screen Capture', Socket);
  278.       GetScreen(bmp, ViewMode);
  279.       Log('Compressing Bitmap');
  280.       SendMsg(MSG_STAT_MSG, 'Screen Compression', Socket);
  281.       CompressBitmap(bmp, tmp);
  282.       SaveString(tmp, 'Temp1.txt');
  283.       SendMsg(MSG_REFRESH, tmp, Socket);
  284.       CurBmp.Assign(bmp);
  285.       bmp.Free;
  286.    end;
  287.    if MsgNum = MSG_SCREEN_UPDATE then begin
  288.       Send_Screen_Update(Socket);
  289.    end;
  290.    if MsgNum = MSG_CLICK then begin
  291.       SendMsg(MSG_STAT_MSG, 'Simulating Input', Socket);
  292.       ProcessClick(Data);
  293.       // SleepDone will be called when it is finished
  294.    end;
  295.    if MsgNum = MSG_DRAG then begin
  296.       SendMsg(MSG_STAT_MSG, 'Simulating Input', Socket);
  297.       ProcessDrag(Data);
  298.       // SleepDone will be called when it is finished
  299.    end;
  300.    if MsgNum = MSG_KEYS then begin
  301.       SendMsg(MSG_STAT_MSG, 'Simulating Input', Socket);
  302.       ProcessKeys(Data);
  303.       // SleepDone will be called when it is finished
  304.    end;
  305.    if MsgNum = MSG_SEVER_DELAY then begin
  306.       Move(Data[1], SleepTime, sizeof(integer));
  307.       SendMsg(MSG_SEVER_DELAY, '', Socket);
  308.    end;
  309.    if MsgNum = MSG_VIEW_MODE then begin
  310.       Move(Data[1], x, sizeof(integer));
  311.       ViewMode := TViewMode(x);
  312.       SendMsg(MSG_VIEW_MODE, '', Socket);
  313.    end;
  314.    if MsgNum = MSG_FOCUS_SERVER then begin
  315.       if TrayIcon1.Active then RemoteControl1Click(nil);
  316.       SetFocus;
  317.       CreateSleepThread;
  318.       // SleepDone will be called when it is finished
  319.    end;
  320.    if MsgNum = MSG_COMP_MODE then begin
  321.       Move(Data[1], x, sizeof(integer));
  322.       CompMode := TCompressionLevel(x);
  323.       SendMsg(MSG_COMP_MODE, '', Socket);
  324.    end;
  325.    if MsgNum = MSG_PRIORITY_MODE then begin
  326.       Move(Data[1], x, sizeof(integer));
  327.       SetThreadPriority(GetCurrentThread, x);
  328.       SendMsg(MSG_PRIORITY_MODE, '', Socket);
  329.    end;
  330.    if MsgNum = MSG_PROCESS_LIST then begin
  331.       SendMsg(MSG_PROCESS_LIST, Get_Process_List, Socket);
  332.    end;
  333.    if MsgNum = MSG_CLOSE_WIN then begin
  334.       CloseWindow(Data);
  335.    end;
  336.    if MsgNum = MSG_KILL_WIN then begin
  337.       KillWindow(Data);
  338.    end;
  339.    if MsgNum = MSG_DRIVE_LIST then begin
  340.       SendMsg(MSG_DRIVE_LIST, Get_Drive_List, Socket);
  341.    end;
  342.    if MsgNum = MSG_DIRECTORY then begin
  343.       SendMsg(MSG_DIRECTORY, GetDirectory(Data), Socket);
  344.    end;
  345.    if MsgNum = MSG_FILE then begin
  346.       SendMsg(MSG_FILE, GetFile(Data), Socket);
  347.    end;
  348.    if MsgNum = MSG_REMOTE_LAUNCH then begin
  349.       SendMsg(MSG_STAT_MSG, 'Launching File: ' + Data, Socket);
  350.       rc := ShellExecute(Handle, 'open', PChar(Data), nil, nil, SW_SHOWNORMAL);
  351.       if rc <= 32 then begin
  352.          Data := Format('ShellExecute Error #%d Launching %s', [rc, Data]);
  353.          SendMsg(MSG_REMOTE_LAUNCH, Data, Socket);
  354.       end else begin
  355.          SendMsg(MSG_REMOTE_LAUNCH, Data, Socket);
  356.       end;
  357.    end;
  358. end;
  359. function EnumWinProc(hw: THandle; lp: LParam): boolean; stdcall;
  360. var
  361.    sl    : TStringList;
  362.    buf   : array[0..MAX_PATH] of char;
  363.    s, iv : string;
  364. begin
  365.    sl := TStringList(lp);
  366.    GetWindowText(hw, buf, sizeof(buf));
  367.    if buf<>'' then begin
  368.       if IsWindowVisible(hw) then iv := '' else iv := '(Invisible)';
  369.       s := Format('%8.8x - %-32s  %s', [hw, buf, iv]);
  370.       sl.AddObject(s, TObject(hw));
  371.    end;
  372.    Result := True;
  373. end;
  374. function TServerForm.Get_Process_List: string;
  375. var
  376.    sl : TStringList;
  377. begin
  378.    sl := TStringList.Create;
  379.    EnumWindows(@EnumWinProc, integer(sl));
  380.    Result := sl.Text;
  381.    sl.Free;
  382. end;
  383. function TServerForm.Get_Drive_List: string;
  384. var
  385.    DriveBits : integer;
  386.    i         : integer;
  387. begin
  388.    Result := '';
  389.    DriveBits := GetLogicalDrives;
  390.    for i := 0 to 25 do begin
  391.       if (DriveBits and (1 shl i)) <> 0 then
  392.          Result := Result + Chr(Ord('A') + i) + ':' + #13#10;
  393.    end;
  394. end;
  395. function TServerForm.GetDirectory(const PathName: string): string;
  396. var
  397.    DirList   : TStringList;
  398.    CommaList : TStringList;
  399.    sr        : TSearchRec;
  400.    s         : string;
  401.    dt        : TDateTime;
  402. begin
  403.    DirList := TStringList.Create;
  404.    CommaList := TStringList.Create;
  405.    if FindFirst(PathName, faAnyFile, sr) = 0 then repeat
  406.       CommaList.Clear;
  407.       s := sr.Name;
  408.       if (s = '.') or (s = '..') then continue;
  409.       if (sr.Attr and faDirectory) <> 0 then s := s + '';
  410.       CommaList.Add(s);
  411.       s := Format('%1.0n', [sr.Size+0.0]);
  412.       CommaList.Add(s);
  413.       dt := FileDateToDateTime(sr.Time);
  414.       s := FormatDateTime('yyyy-mm-dd  hh:nn ampm', dt);
  415.       CommaList.Add(s);
  416.       DirList.Add(CommaList.CommaText);
  417.    until FindNext(sr) <> 0;
  418.    FindClose(sr);
  419.    Result := DirList.Text;
  420.    CommaList.Free;
  421.    DirList.Free;
  422. end;
  423. function TServerForm.GetFile(const PathName: string): string;
  424. var
  425.    fs : TFileStream;
  426. begin
  427.    fs := TFileStream.Create(PathName, fmOpenRead or fmShareDenyWrite);
  428.    SetLength(Result, fs.Size);
  429.    fs.Read(Result[1], fs.Size);
  430.    fs.Free;
  431. end;
  432. procedure TServerForm.CloseWindow(const Data: string);
  433. var
  434.    sl : TStringList;
  435.    i  : integer;
  436.    hw : THandle;
  437. begin
  438.    sl := TStringList.Create;
  439.    EnumWindows(@EnumWinProc, integer(sl));
  440.    i := sl.IndexOf(Data);
  441.    if i<>-1 then begin
  442.       hw := THandle(sl.Objects[i]);
  443.       SendMessage(hw, WM_CLOSE, 0, 0);
  444.       Sleep(SleepTime);
  445.       SendMsg(MSG_PROCESS_LIST, Get_Process_List, CurSocket);
  446.    end;
  447.    sl.Free;
  448. end;
  449. procedure TServerForm.KillWindow(const Data: string);
  450. var
  451.    sl     : TStringList;
  452.    i      : integer;
  453.    hw     : THandle;
  454.    ProcID : integer;
  455.    hProc  : THandle;
  456. begin
  457.    sl := TStringList.Create;
  458.    EnumWindows(@EnumWinProc, integer(sl));
  459.    i := sl.IndexOf(Data);
  460.    if i<>-1 then begin
  461.       hw := THandle(sl.Objects[i]);
  462.       GetWindowThreadProcessId(hw, @ProcID);
  463.       hProc := OpenProcess(PROCESS_ALL_ACCESS, False, ProcID);
  464.       TerminateProcess(hProc, DWORD(-1));
  465.       CloseHandle(hProc);
  466.       Sleep(SleepTime);
  467.       SendMsg(MSG_PROCESS_LIST, Get_Process_List, CurSocket);
  468.    end;
  469.    sl.Free;
  470. end;
  471. procedure TServerForm.SleepDone(Sender: TObject);
  472. begin
  473.    Send_Screen_Update(CurSocket);
  474. end;
  475. procedure TServerForm.Send_Screen_Update(Socket: TCustomWinSocket);
  476. var
  477.    bmp, dif : TBitmap;
  478.    R        : TRect;
  479.    tmp      : string;
  480. begin
  481.    Log('Screen Capture');
  482.    SendMsg(MSG_STAT_MSG, 'Screen Capture', Socket);
  483.    GetScreen(bmp, ViewMode);
  484.    Log('Creating Diff Image');
  485.    dif := TBitmap.Create;
  486.    dif.Assign(bmp);
  487.    R := Rect(0, 0, dif.Width, dif.Height);
  488.    SendMsg(MSG_STAT_MSG, 'Screen Difference', Socket);
  489.    dif.Canvas.CopyMode := cmSrcInvert;
  490.    dif.Canvas.CopyRect(R, CurBmp.Canvas, R);
  491.    Log('Compressing Bitmap');
  492.    SendMsg(MSG_STAT_MSG, 'Screen Compression', Socket);
  493.    CompressBitmap(dif, tmp);
  494.    SendMsg(MSG_SCREEN_UPDATE, tmp, Socket);
  495.    CurBmp.Assign(bmp);
  496.    dif.Free;
  497.    bmp.Free;
  498. end;
  499. function GetMB(but: integer): TMouseButton;
  500. begin
  501.    case but of
  502.       1 : Result := mbLeft;
  503.       2 : Result := mbRight;
  504.       else Result := mbLeft;
  505.    end;
  506. end;
  507. procedure TServerForm.ProcessClick(const Data: string);
  508. var
  509.    x, y, i  : integer;
  510.    num, but : integer;
  511.    p        : TPoint;
  512. begin
  513.    Move(Data[1], x, sizeof(integer));
  514.    Move(Data[1+4], y, sizeof(integer));
  515.    Move(Data[1+8], num, sizeof(integer));
  516.    Move(Data[1+12], but, sizeof(integer));
  517.    // Find the Window Handle
  518.    p := Point(x, y);
  519.    CurHandle := WindowFromPoint(p);
  520.    Assert(CurHandle<>0);
  521.    SetCursorPos(x, y);
  522.    // Create the Messages to send in the Hook procedure
  523.    with MsgSimulator1 do begin
  524.       Messages.Clear;
  525.       for i := 1 to num do
  526.          Add_ClickEx(0, GetMB(but), [], x, y, 1);
  527.       Play;
  528.    end;
  529.    CreateSleepThread;
  530. end;
  531. procedure TServerForm.ProcessDrag(const Data: string);
  532. var
  533.    x, y       : integer;
  534.    time       : integer;
  535.    num, but   : integer;
  536.    p          : TPoint;
  537.    StartPt    : TPoint;
  538.    StopPt     : TPoint;
  539. begin
  540.    Move(Data[1], but, sizeof(integer));
  541.    Move(Data[1+4], num, sizeof(integer));
  542.    Assert(num > 2);
  543.    // Create the Messages to send in the Hook procedure
  544.    // Mouse Down
  545.    Move(Data[(1-1)*12 + 9], x, sizeof(integer));
  546.    Move(Data[(1-1)*12 + 13], y, sizeof(integer));
  547.    Move(Data[(1-1)*12 + 17], time, sizeof(integer));
  548.    SetCursorPos(x, y);
  549.    // Find the Window Handle
  550.    p := Point(x, y);
  551.    CurHandle := WindowFromPoint(p);
  552.    Assert(CurHandle<>0);
  553.    with MsgSimulator1 do begin
  554.       Messages.Clear;
  555.       StartPt.X := x;
  556.       StartPt.Y := y;
  557.       Windows.ScreenToClient(CurHandle, StartPt);
  558.       Move(Data[(num-1)*12 + 9], x, sizeof(integer));
  559.       Move(Data[(num-1)*12 + 13], y, sizeof(integer));
  560.       StopPt.X := x;
  561.       StopPt.Y := y;
  562.       Windows.ScreenToClient(CurHandle, StopPt);
  563.       Add_Window_Drag(CurHandle, StartPt.X, StartPt.Y, StopPt.X, StopPt.Y);
  564.       Play;
  565.    end;
  566.    CreateSleepThread;
  567. end;
  568. procedure TServerForm.ProcessKeys(const Data: string);
  569. begin
  570.    with MsgSimulator1 do begin
  571.       Messages.Clear;
  572.       Add_ASCII_Keys(Data);
  573.       Play;
  574.    end;
  575.    CreateSleepThread;
  576. end;
  577. procedure TServerForm.SendMsg(MsgNum: integer; const MsgData: string; Socket: TCustomWinSocket);
  578. var
  579.    s : string;
  580. begin
  581.    s := IntToByteStr(MsgNum) + IntToByteStr(Length(MsgData)) + MsgData;
  582.    Log(Format('%-20s %-4d %1.0n', ['Send', MsgNum, Length(s)+0.0]));
  583.    Socket.SendText(s);
  584.    NumSend := NumSend + Length(s);
  585.    UpdateStats;
  586. end;
  587. procedure TServerForm.FormCreate(Sender: TObject);
  588. begin
  589.    CurBmp    := TBitmap.Create;
  590.    SleepTime := 50;
  591.    ParseComLine;
  592. end;
  593. procedure TServerForm.FormDestroy(Sender: TObject);
  594. begin
  595.    CurBmp.Free;
  596. end;
  597. type
  598.    TSleepThread = class(TThread)
  599.    public
  600.       SleepTime   : integer;
  601.       procedure   Execute; override;
  602.    end;
  603. procedure TSleepThread.Execute;
  604. begin
  605.    Sleep(SleepTime);
  606. end;
  607. procedure TServerForm.CreateSleepThread;
  608. var
  609.    st : TSleepThread;
  610. begin
  611.    st := TSleepThread.Create(True);
  612.    st.SleepTime := SleepTime;
  613.    st.OnTerminate := SleepDone;
  614.    st.Resume;
  615. end;
  616. procedure TServerForm.Client1Click(Sender: TObject);
  617. begin
  618.    ClientForm.Show;
  619. end;
  620. procedure TServerForm.FormCloseQuery(Sender: TObject;
  621.   var CanClose: Boolean);
  622. var
  623.    rc : integer;
  624. begin
  625.    if ServerSocket1.Socket.ActiveConnections > 0 then begin
  626.       rc := MessageDlg('Clients are still connected, do you want to close?',
  627.          mtWarning, mbYesNoCancel, 0);
  628.       CanClose := (rc = mrYes);
  629.    end;
  630. end;
  631. procedure TServerForm.ParseComLine;
  632. var
  633.    i           : integer;
  634.    s           : string;
  635.    AutoStart   : boolean;
  636. begin
  637.    AutoStart := False;
  638.    for i := 1 to ParamCount do begin
  639.       s := UpperCase(ParamStr(i));
  640.       if Copy(s, 1, 6) = '/PORT:' then begin
  641.          PortEdit.Text := Copy(s, 7, Length(s));
  642.          AutoStart := True;
  643.          StartButClick(nil);
  644.          MinimizeButClick(nil);
  645.       end;
  646.       if s = '/CLIENT' then begin
  647.          MinimizeButClick(nil);
  648.          AutoStart := True;
  649.       end;
  650.    end;
  651.    if not AutoStart then
  652.       Visible := True;
  653. end;
  654. procedure TServerForm.ClientButClick(Sender: TObject);
  655. begin
  656.    ClientForm.Show;
  657. end;
  658. end.