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

📄 msgsimulator.pas

📁 灰鸽子VIP1.2经典源代码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit MsgSimulator;

{
   June 23, 1998   by Ben Ziegler

   6/30/98 - Added a Record Macro function
}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
   TWMMessage = (mmMouseDown, mmMouseUp, mmMouseMove, mmKeyDown, mmKeyUp);

   TMessageItem = class(TCollectionItem)
   protected
      em          : TEventMsg;      // Structure required by JournalPlayback Proc
      FMsg        : TWMMessage;
      FDelay      : DWORD;          // Delay in msec before next message is played
      FX          : integer;        // This means nothing for keystrokes
      FY          : integer;        // This means nothing for keystrokes
      FKey        : integer;        // This means nothing for mouse clicks
      FHWND       : integer;        // Window Handle (not used for keystrokes)
      FButton     : TMouseButton;   // This means nothing for keystrokes
      procedure   Fill_EM_From_Props;
      procedure   Fill_Props_From_EM;
   public
      constructor Create(Collection: TCollection); override;
      property    HWND        : integer read FHWND write FHWND; // No need to save it - it will be different after each run
   published
      property    Msg         : TWMMessage read FMsg write FMsg;
      property    PosX        : integer read FX write FX;
      property    PosY        : integer read FY write FY;
      property    VkKey       : integer read FKey write FKey;
      property    Delay       : DWORD read FDelay write FDelay;
      property    Button      : TMouseButton read FButton write FButton;
   end;

   TMsgSimulator = class;

   TMessageCollection = class(TCollection)
   private
     FOwner       : TMsgSimulator;
     function     GetItem(Index: Integer): TMessageItem;
     procedure    SetItem(Index: Integer; Value: TMessageItem);
   protected
     function     GetOwner: TPersistent; override;
     procedure    Update(Item: TCollectionItem); override;
   public
     constructor  Create(AOwner: TMsgSimulator);
     function     Add: TMessageItem;
     property     Owner: TMsgSimulator read FOwner;
     property     Items[Index: Integer]: TMessageItem read GetItem write SetItem; default;
   end;

   TMsgSimulator = class(TComponent)
   protected
      FRunning    : boolean;     // Simulation is currently running
      play_hk     : THandle;     // JournalPlayback Hook handle
      rec_hk      : THandle;     // RecordPlayback Hook handle
      PlayDone    : boolean;     // Flag to signal that all messages have been simulated
      AbortSim    : boolean;     // Flag to signal aborting the playback of messages
      StartTime   : DWORD;       // Time simulation started (msec)
      StopTime    : DWORD;       // Time simulation stoped (msec)
      FDelay      : integer;     // Default delay between messages
      FMsgList    : TMessageCollection; // Messages to playback
      FTopWin     : string;
      FindText    : string;
      FindHandle  : THandle;
      StopRec     : integer;
      FRecording  : boolean;
      FOnStopRec  : TNotifyEvent;
      function    GetElapTime: integer;
      procedure   SetMsgList(MsgList: TMessageCollection);
      function    Add_Raw_Message(Msg: TWMMessage; x, y, VkKey, Delay, HWND: integer; Button: TMouseButton): TMessageItem;
      procedure   Add_Shift(hwnd: THandle; Shift: TShiftState; UpDown: TWMMessage; Delay: integer);
      procedure   SimClientToScreen(hwnd: THandle; var x, y: integer);
      procedure   FixUp_Playback_Delays;
      procedure   FixUp_Record_Delays;
   public
      constructor Create(AOwner: TComponent); override;
      destructor  Destroy; override;
      // Low-level Message Creation Functions
      procedure   Add_ClickEx(hwnd: THandle; Button: TMouseButton; Shift: TShiftState;
                     x, y, Delay: integer);
      procedure   Add_DragEx(hwnd: THandle; Button: TMouseButton; Shift: TShiftState;
                     StartX, StartY, StopX, StopY, NumMoves, Delay: integer);
      procedure   Add_VirtualKey(hwnd: THandle; VkKey, Delay: integer; UpDown: TWMMessage);
      // High-level Message Creation Functions
      procedure   Add_Window_Click(hwnd: THandle; x, y: integer);
      procedure   Add_Window_Drag(hwnd: THandle; StartX, StartY, StopX, StopY: integer);
      procedure   Add_Screen_Click(x, y: integer);
      procedure   Add_Screen_Drag(StartX, StartY, StopX, StopY: integer);
      procedure   Add_ASCII_Keys(const Keystrokes: string);
   public
      // Playback & Cancel Functions
      procedure   Play;                      // Plays messages, then returns
      procedure   Play_Async;                // Returns immediately
      procedure   Abort;
      procedure   Record_Input;
      procedure   Stop_Record;
      property    Running: boolean read FRunning;
      property    Recording: boolean read FRecording;
      property    ElapTime: integer read GetElapTime; // Elapsed running time in msec
      // Helper Functions
      procedure   FocusWin(hwnd: THandle);
      function    FindTopLevelWin(const FindText: string): THandle;
   published
      property    Messages: TMessageCollection read FMsgList write SetMsgList;
      property    DefaultDelay: integer read FDelay write FDelay default 50;
      property    OnStopRecord: TNotifyEvent read FOnStopRec write FOnStopRec;
   end;

procedure Register;


implementation

var
   CurSim   : TMsgSimulator;  // Only one TMsgSimulator can play at a time
   Cur      : integer;        // Current Message to play in the MsgList
   NumCur   : integer;        // Number of times current message has been played


procedure Register;
begin
  RegisterComponents('Samples', [TMsgSimulator]);
end;


// *********************************************************************
// TMessageItem

constructor TMessageItem.Create(Collection: TCollection);
begin
   inherited;
   Delay := TMessageCollection(Collection).Owner.DefaultDelay;
end;

procedure TMessageItem.Fill_EM_From_Props;
begin
   em.hwnd  := hwnd;

   if (Msg = mmMouseDown) and (Button = mbLeft)   then em.message := WM_LBUTTONDOWN;
   if (Msg = mmMouseUp)   and (Button = mbLeft)   then em.message := WM_LBUTTONUP;
   if (Msg = mmMouseDown) and (Button = mbRight)  then em.message := WM_RBUTTONDOWN;
   if (Msg = mmMouseUp)   and (Button = mbRight)  then em.message := WM_RBUTTONUP;
   if (Msg = mmMouseDown) and (Button = mbMiddle) then em.message := WM_MBUTTONDOWN;
   if (Msg = mmMouseUp)   and (Button = mbMiddle) then em.message := WM_MBUTTONUP;

   case Msg of
      mmMouseMove : em.message := WM_MOUSEMOVE;
      mmKeyDown   : em.message := WM_KEYDOWN;
      mmKeyUp     : em.message := WM_KEYUP;
   end;

   if (Msg = mmKeyDown) or (Msg = mmKeyUp) then begin
      // Keystroke Message
      em.paramL := VkKey;
      em.paramH := MapVirtualKey(VkKey, 0);
   end else begin
      // Mouse Message
      em.paramL := PosX;
      em.paramH := PosY;
   end;
end;

procedure TMessageItem.Fill_Props_From_EM;
begin
   hwnd := em.hwnd;

   case em.message of
      WM_LBUTTONDOWN : begin Msg := mmMouseDown; Button := mbLeft;   end;
      WM_LBUTTONUP   : begin Msg := mmMouseUp;   Button := mbLeft;   end;
      WM_RBUTTONDOWN : begin Msg := mmMouseDown; Button := mbRight;  end;
      WM_RBUTTONUP   : begin Msg := mmMouseUp;   Button := mbRight;  end;
      WM_MBUTTONDOWN : begin Msg := mmMouseDown; Button := mbMiddle; end;
      WM_MBUTTONUP   : begin Msg := mmMouseUp;   Button := mbMiddle; end;
      WM_MOUSEMOVE   : Msg := mmMouseMove;
      WM_KEYDOWN     : Msg := mmKeyDown;
      WM_KEYUP       : Msg := mmKeyUp;
   end;

   if (Msg = mmKeyDown) or (Msg = mmKeyUp) then begin
      // Keystroke Message
      VkKey := em.paramL;
   end else begin
      // Mouse Message
      PosX := em.paramL;
      PosY := em.paramH;
   end;
end;


// *********************************************************************
// TMessageCollection

constructor TMessageCollection.Create(AOwner: TMsgSimulator);
begin
  inherited Create(TMessageItem);
  FOwner := AOwner;
end;

function TMessageCollection.Add: TMessageItem;
begin
  Result := TMessageItem(inherited Add);
end;

function TMessageCollection.GetItem(Index: Integer): TMessageItem;
begin
  Result := TMessageItem(inherited GetItem(Index));
end;

function TMessageCollection.GetOwner: TPersistent;
begin
  Result := FOwner;
end;

procedure TMessageCollection.SetItem(Index: Integer; Value: TMessageItem);
begin
  inherited SetItem(Index, Value);
end;

procedure TMessageCollection.Update(Item: TCollectionItem);
begin
   Assert(not FOwner.Running);
end;


// *********************************************************************
// TMsgSimulator

constructor TMsgSimulator.Create(AOwner: TComponent);
begin
   inherited;
   FDelay   := 50;
   FMsgList := TMessageCollection.Create(Self);
end;

destructor TMsgSimulator.Destroy;
begin
   if Running then Abort;
   FMsgList.Free;
   FMsgList := nil;
   inherited;
end;

procedure TMsgSimulator.SetMsgList(MsgList: TMessageCollection);
begin
   FMsgList.Assign(MsgList);
end;

function TMsgSimulator.Add_Raw_Message(Msg: TWMMessage; x, y, VkKey, Delay, HWND: integer; Button: TMouseButton): TMessageItem;
begin
   Result := Messages.Add;
   Result.Msg    := Msg;
   Result.PosX   := x;
   Result.PosY   := y;
   Result.VkKey  := VkKey;
   Result.Delay  := Delay;
   Result.HWND   := HWND;
   Result.Button := Button;
end;

procedure TMsgSimulator.Add_Shift(hwnd: THandle; Shift: TShiftState; UpDown: TWMMessage; Delay: integer);
begin
   // NOTE:  Keystrokes do not require an hwnd, so use 0
   if Shift = [] then exit;
   if ssShift in Shift then Add_Raw_Message(UpDown, 0, 0, VK_SHIFT, Delay, 0, mbLeft);
   if ssCtrl  in Shift then Add_Raw_Message(UpDown, 0, 0, VK_CONTROL, Delay, 0, mbLeft);
   if ssAlt   in Shift then Add_Raw_Message(UpDown, 0, 0, VK_MENU, Delay, 0, mbLeft);
end;

// x, y are in Screen coordinates
procedure TMsgSimulator.Add_ClickEx(hwnd: THandle; Button: TMouseButton; Shift: TShiftState;
               x, y, Delay: integer);
begin
   Add_Shift(hwnd, Shift, mmKeyDown, Delay);
   Add_Raw_Message(mmMouseDown, x, y, 0, Delay, hwnd, Button);
   Add_Raw_Message(mmMouseUp, x, y, 0, Delay, hwnd, Button);
   Add_Raw_Message(mmMouseMove, x, y, 0, Delay, hwnd, Button);
   Add_Shift(hwnd, Shift, mmKeyUp, Delay);
end;

// x, y are in Screen coordinates
procedure TMsgSimulator.Add_DragEx(hwnd: THandle; Button: TMouseButton; Shift: TShiftState;
               StartX, StartY, StopX, StopY, NumMoves, Delay: integer);

⌨️ 快捷键说明

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