⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 remconmessages.pas

📁 能够监视另一台机子的屏幕
💻 PAS
字号:
unit RemConMessages;

interface

uses SysUtils, Classes, Windows, Graphics, Forms;


const
   // Messages
   // All numbers are 4-byte integers
   // Strings include a null terminating zero

   MSG_LOGON            = 1;     // Client logs on to the server
                                 // Data = password

   MSG_REFRESH          = 2;     // Client wants the entire screen
                                 // Data = Compressed BMP

   MSG_SCREEN_UPDATE    = 3;     // Server sends client a screen update
                                 // Data = Compressed BMP (to XOR)

   MSG_CLICK            = 4;     // Mouse click (single or double, left or right)
                                 // Data = X, Y, Single (1) / Double (2), Left (1) / Right (2)

   MSG_DRAG             = 5;     // Mouse drag
                                 // Data = Left (1) / Right (2), Num Pts, X/Y/time sets

   MSG_KEYS             = 6;     // Send keystrokes
                                 // Data = KeyCode(s)

   MSG_DIRECTORY        = 7;     // Request a directory
                                 // Data = directory (client -> server)
                                 // Data = File StringList (dirs end in "\"), Size StringList, Date/Time StringList (server -> client)

   MSG_FILE             = 8;     // Request a file
                                 // Data = Filename (client -> server)
                                 // Data = File Contents

   MSG_SEVER_DELAY      = 9;     // Set the amount of time the server should wait before sending back the screen image
                                 // Data = Delay in milliseconds

   MSG_FOCUS_SERVER     = 10;    // To restore & focus the Server Window

   MSG_VIEW_MODE        = 11;    // Set the view mode for the graphics
                                 // Data = View Mode (TViewMode as integer)

   MSG_STAT_MSG         = 12;    // Generic Status Msg
                                 // Data = Status Message (string)

   MSG_COMP_MODE        = 13;    // Screen Compression Mode
                                 // Data = CompMode (TCompressionLevel as integer)

   MSG_PRIORITY_MODE    = 14;    // Server Thread Priority
                                 // Data = Priority (integer)

   MSG_PROCESS_LIST     = 15;    // List of running processes
                                 // Data = Process StringList

   MSG_CLOSE_WIN        = 16;    // Close one of the running processes (gracefully)
                                 // Data = Process Name (actually Window Name)

   MSG_KILL_WIN         = 17;    // Kill one of the running processes (NOT graceful)
                                 // Data = Process Name (actually Window Name)

   MSG_DRIVE_LIST       = 18;    // Get a list of all the Logical Drives
                                 // Data = Drives StringList

   MSG_REMOTE_LAUNCH    = 19;    // Launch (ShellExecute) a remote file (of any type)
                                 // Data = Filename

type
   TViewMode = (vmColor4, vmGray4, vmGray8, vmColor24, vmDefault);

   procedure GetScreen(var bmp: TBitmap; ViewMode: TViewMode);
   procedure CompressBitmap(bmp: TBitmap; var Data: string);
   procedure UnCompressBitmap(const Data: string; bmp: TBitmap);
   function  IntToByteStr(Value: integer): string;
   function  IsValidMessage(const Msg: string): boolean;
   function  CurTime: string;
   function  MsgLen(const Msg: string): integer;
   function  TrimFirstMsg(var Msg: string): string;

   // Debugging
   procedure SaveString(const s, FileName: string);


implementation

uses ZLib;

type
   TRGBCol = record
      Blu, Grn, Red : byte;
   end;
   TRGBArray   = array[0..0] of TRGBCol;
   PRGBArray   = ^TRGBArray;

   TByteArray = array[0..0] of byte;
   PByteArray = ^TByteArray;


procedure SaveString(const s, FileName: string);
var
   fs : TFileStream;
begin
   fs := TFileStream.Create(FileName, fmCreate);
   fs.Write(s[1], Length(s));
   fs.Free;
end;

function GammaConv(Value: double; Gamma: double): double;
begin
   if Value <> 0 then Result := Exp(Ln(Value) / Gamma)
      else Result := 0;
end;

function CreateGrayPalette(Num: integer; Gamma: double): HPalette;
var
   lPal  : PLogPalette;
   i     : integer;
begin
   // Add the Grayscale palette
   lPal := AllocMem(sizeof(TLogPalette) + Num * sizeof(TPaletteEntry));
   lPal.palVersion   := $300;
   lPal.palNumEntries := Num;
   for i := 0 to Num-1 do with lPal.palPalEntry[i] do begin
      peRed    := Round(255 * GammaConv(i / (Num-1), Gamma));
      peGreen  := Round(255 * GammaConv(i / (Num-1), Gamma));
      peBlue   := Round(255 * GammaConv(i / (Num-1), Gamma));
      peFlags  := 0;
   end;
   Result := CreatePalette(lPal^);
   FreeMem(lPal);
   Win32Check(longbool(Result));
end;

procedure ConvertToGray_256(bmp: TBitmap);
var
   gm       : TBitmap;  // Destination grayscale bitmap
   x, y     : integer;
   p1       : PRGBArray;
   p2       : PByteArray;
begin
   bmp.PixelFormat := pf24bit;

   // Convert to Grayscale
   gm := TBitmap.Create;
   gm.PixelFormat := pf8bit;
   gm.Width  := bmp.Width;
   gm.Height := bmp.Height;

   gm.Palette := CreateGrayPalette(256, 1.4);

   for y := 0 to bmp.Height-1 do begin
      p1 := bmp.ScanLine[y];
      p2 := gm.ScanLine[y];
      for x := 0 to bmp.Width-1 do with p1^[x] do begin
         p2^[x] := (Red * 3 + Grn * 4 + Blu) div 8;
      end;
   end;

   bmp.Assign(gm);
   gm.Free;
end;

procedure ConvertToGray_16(bmp: TBitmap);
var
   gm       : TBitmap;  // Destination grayscale bitmap
   x, y     : integer;
   p1       : PRGBArray;
   p2       : PByteArray;
   c        : integer;
begin
   bmp.PixelFormat := pf24bit;

   // Convert to Grayscale
   gm := TBitmap.Create;
   gm.PixelFormat := pf4bit;
   gm.Width  := bmp.Width;
   gm.Height := bmp.Height;

   gm.Palette := CreateGrayPalette(16, 1.4);

   for y := 0 to bmp.Height-1 do begin
      p1 := bmp.ScanLine[y];
      p2 := gm.ScanLine[y];
      for x := 0 to bmp.Width-1 do with p1^[x] do begin
         c := (Red * 3 + Grn * 4 + Blu) div (8 * 16);
         if (x and 1) = 1 then begin
            p2^[x div 2] := p2^[x div 2] and (not 15) or c;
         end else begin
            p2^[x div 2] := p2^[x div 2] and (15) or (c shl 4);
         end;
      end;
   end;

   bmp.Assign(gm);
   gm.Free;
end;


procedure GetScreen(var bmp: TBitmap; ViewMode: TViewMode);
var
   dc : integer;
   c  : TCanvas;
   R  : TRect;
begin
   bmp := TBitmap.Create;

   dc := GetWindowDC(0);
   try
      c := TCanvas.Create;
      c.Handle := dc;
      R := Rect(0, 0, Screen.Width, Screen.Height);
      bmp.Width := R.Right;
      bmp.Height := R.Bottom;
      bmp.Canvas.CopyRect(R, c, R);
      c.Handle := 0;
      c.Free;
   finally
      ReleaseDC(0, dc);
   end;

   case ViewMode of
      vmColor4    : bmp.PixelFormat := pf4bit;
      vmGray4     : ConvertToGray_16(bmp);
      vmGray8     : ConvertToGray_256(bmp);
      vmColor24   : bmp.PixelFormat := pf24bit;
      vmDefault   : bmp.HandleType := bmDIB;
   end;
end;

procedure CompressBitmap_Slow(bmp: TBitmap; var Data: string);
var
   ms    : TMemoryStream;
   buf   : pointer;
   size  : integer;
begin
   ms := TMemoryStream.Create;

   bmp.SaveToStream(ms);
   CompressBuf(ms.Memory, ms.Size, buf, size);

   SetLength(Data, size);
   Move(buf^, Data[1], size);
   FreeMem(buf);

   ms.Free;
end;

procedure CompressBitmap(bmp: TBitmap; var Data: string);
var
   cs      : TCompressionStream;
   ms      : TMemoryStream;
begin
   ms := TMemoryStream.Create;
   cs := TCompressionStream.Create(clDefault, ms); // clDefault is a LOT faster than clMax

   bmp.SaveToStream(cs);
   cs.Free;

   SetLength(Data, ms.Size);
   Move(ms.Memory^, Data[1], ms.Size);

   ms.Free; 
end;

procedure UnCompressBitmap(const Data: string; bmp: TBitmap);
var
   ms    : TMemoryStream;
   buf   : pointer;
   size  : integer;
begin
   try
      DecompressBuf(@Data[1], Length(Data), Length(Data) * 3, buf, size);
   except
      on E: Exception do begin
         E.Message := Format('Error Decompressing Buffer (Len = %d):'#13#10'%s', [Length(Data), e.Message]);
         raise;
      end;
   end;

   ms := TMemoryStream.Create;
   ms.Write(buf^, size);
   FreeMem(buf);
   ms.Position := 0;
   Assert(bmp<>nil);
   bmp.LoadFromStream(ms);

   ms.Free;
end;

function IntToByteStr(Value: integer): string;
begin
   SetLength(Result, 4);
   Move(Value, Result[1], sizeof(integer));
end;

function IsValidMessage(const Msg: string): boolean;
var
   len : integer;
begin
   Result := False;

   len := Length(Msg);
   if len < 8 then exit;

   if MsgLen(Msg) > len then exit;

   Result := True;
end;

function MsgLen(const Msg: string): integer;
var
   len, mlen : integer;
begin
   len := Length(Msg);
   Assert(len >= 8);

   Move(Msg[5], mlen, sizeof(integer));

   Result := mlen + 8;
end;

function TrimFirstMsg(var Msg: string): string;
begin
   Result := Copy(Msg, 1, MsgLen(Msg));
   Msg := Copy(Msg, MsgLen(Msg)+1, Length(Msg));
end;

function CurTime: string;
begin
   Result := FormatDateTime('mmm d, yyyy  hh:nn:ss ampm', Now);
end;


end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -