Ce petit programme permet d'enregistrer des séquences de points puis de cliquer automatiquement dessus. Il est possible de spécifier le nombre de séquences à "jouer" et de mettre un délai entre chaque click et entre chaque séquence. Ce programme permet par exemple de cliquer à intervalle régulier sur une bannière de pub, de voter automatiquement pour un site ou toute autre utilisation qui implique de cliquer à intervalle régulier à un endroit donné.
Dans le code, pour ceux que ça intéresse, il y a des exemples pour faire les choses suivantes :
- Déplacer automatiquement le curseur
- Cliquer automatiquement à un endroit donné
- Créer une "hotkey" globale qui peut être déclenchée même quand le prog n'a pas le focus
- Créer des timer dynamiquement
- Faire une classe réutilisable et entièrement indépendante de l'interface graphique
Ci-dessous, la classe utilisée par le programme (voir le ZIP pour le programme complet :)
Source / Exemple :
unit pointListClass;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, inifiles;
type TPointList = class (TObject)
private
pPointList: array of TPoint;
pFileName : string;
pPointTimer : TTimer;
pSequenceTimer : TTimer;
pGlobalTimer : TTimer; // Sert juste à mesurer le temps entre chaque click
pForm : TForm;
pCurrentPointID : word;
pClickInterval : LongWord;
pSequenceInterval : LongWord;
pNbSequences : LongWord;
pSequenceCount : LongWord;
procedure pPointOnTimer(Sender : TObject);
procedure pSequenceOnTimer(Sender : TObject);
procedure pGlobalOnTimer(Sender : TObject);
procedure ClickPoint(const point : TPoint);
public
constructor Create(const form : TForm);
function TimeToNextClick : longWord;
procedure add(const point : TPoint);
function get(const i : byte) : TPoint;
procedure deleteLast;
procedure deleteAt(const listIndex : word);
function count : word;
procedure clear;
function print : string;
function getFileName : string;
procedure setFileName(const s : string);
function toStringList : TStringList;
function save(const fileName : string) : boolean; overload;
function load(const fileName : string) : boolean; overload;
function save() : boolean; overload;
function load() : boolean; overload;
procedure run();
procedure stop();
function isRunning : boolean;
property NumberOfSequences : LongWord read pNbSequences write pNbSequences;
property TimeBetweenSequences : LongWord read pSequenceInterval write pSequenceInterval;
property TimeBetweenClicks : LongWord read pClickInterval write pClickInterval;
end;
implementation
uses main;
// Simule un click sur le point passé en paramètre
procedure TPointList.ClickPoint(const point : TPoint);
var saveState : TWindowState;
begin
// Réduit la fiche
saveState := pForm.WindowState;
if pForm.WindowState <> wsMinimized then pForm.WindowState := wsMinimized;
// Déplace le curseur
setCursorPos(point.X, point.Y);
// Clique
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
// Restore la fiche
pForm.WindowState := saveState;
end;
// Procédure appelée par le timer "pointTimer"
procedure TPointList.pPointOnTimer(Sender : TObject);
begin
// Si tous les points n'ont pas encore été cliqués...
if pCurrentPointID < self.count() then begin
// Clique le point
clickPoint(self.get(pCurrentPointID));
pCurrentPointID := pCurrentPointID + 1;
pGlobalTimer.Tag := 0;
end;
// Si tous les points ont été cliqués
if pCurrentPointID = self.count() then begin
// Désactive le timer "pointTimer" ...
pPointTimer.Enabled := FALSE;
// ...et active le timer "sequenceTimer"
pSequenceCount := pSequenceCount + 1;
// Si toutes les séquences n'ont pas été exécutées
if pSequenceCount <= pNbSequences then begin
// Démarre le timer pour que le programme pause pendant "pSequenceInterval" ms
pSequenceTimer.Interval := pSequenceInterval;
pSequenceTimer.Enabled := TRUE;
pGlobalTimer.Tag := 0;
end else begin
// Stop
self.stop();
end;
end;
end;
procedure TPointList.stop();
begin
// Détruit tous les timers
if pSequenceTimer <> nil then begin
pSequenceTimer.Destroy;
pSequenceTimer := nil;
end;
if pPointTimer <> nil then begin
pPointTimer.Destroy;
pPointTimer := nil;
end;
if pGlobalTimer <> nil then begin
pGlobalTimer.Destroy;
pGlobalTimer := nil;
end;
end;
procedure TPointList.pGlobalOnTimer(Sender : TObject);
begin
// Le tag sert à mémoriser le temps écoulé depuis le dernier click
pGlobalTimer.Tag := LongWord(pGlobalTimer.Tag) + pGlobalTimer.Interval;
end;
procedure TPointList.pSequenceOnTimer(Sender : TObject);
begin
// Prépare les données pour une nouvelle séquence
pCurrentPointID := 0;
pPointTimer.Interval := pClickInterval;
pPointTimer.Enabled := TRUE;
pSequenceTimer.Interval := pSequenceInterval;
pSequenceTimer.Enabled := FALSE;
pGlobalTimer.Tag := 0;
self.pPointOnTimer(self);
end;
procedure TPointList.run();
begin
if (pNbSequences > 0) and (self.count > 0) then begin
// Créé les timers
pPointTimer := TTimer.Create(nil);
pPointTimer.OnTimer := self.pPointOnTimer;
pPointTimer.Enabled := FALSE;
pSequenceTimer := TTimer.Create(nil);
pSequenceTimer.OnTimer := self.pSequenceOnTimer;
pSequenceTimer.Enabled := FALSE;
pGlobalTimer := TTimer.Create(nil);
pGlobalTimer.OnTimer := self.pGlobalOnTimer;
pGlobalTimer.Enabled := FALSE;
// Valeur minimum de 1 sinon ça ne marche pas
if pClickInterval = 0 then pClickInterval := 1;
if pSequenceInterval = 0 then pSequenceInterval := 1;
// Initialise les données pour une nouvelle séquence
pCurrentPointID := 0;
pPointTimer.Interval := pClickInterval;
if pPointTimer.Interval = 0 then pPointTimer.Interval := 1;
pSequenceCount := 1;
pPointTimer.Enabled := TRUE;
pGlobalTimer.Enabled := TRUE;
pGlobalTimer.Interval := 1000;
pGlobalTimer.Tag := 0;
self.pPointOnTimer(self);
end;
end;
function TPointList.isRunning : boolean;
begin
Result := (pPointTimer <> nil) and (pSequenceTimer <> nil);
end;
constructor TPointList.Create(const form : TForm);
begin
setLength(pPointList, 0);
pForm := form;
pFileName := '';
pNbSequences := 1;
pClickInterval := 0;
pSequenceInterval := 0;
end;
procedure TPointList.clear;
begin
setLength(pPointList, 0);
end;
function TPointList.getFileName : string;
begin
result := pFileName;
end;
procedure TPointList.setFileName(const s : string);
begin
pFileName := s;
end;
// Ajoute un point
procedure TPointList.add(const point : TPoint);
begin
setLength(pPointList, length(pPointList) + 1);
pPointList[length(pPointList) - 1] := point;
end;
// Retourne un point
function TPointList.get(const i : byte) : TPoint;
begin
Result := pPointList[i];
end;
// Efface le dernier point
procedure TPointList.deleteLast;
begin;
if length(pPointList) > 0 then begin
setLength(pPointList, length(pPointList) - 1);
end;
end;
// Efface un point
procedure TPointList.deleteAt(const listIndex : word);
var i : word;
begin
if listIndex < length(pPointList) then begin
i := listIndex;
while i < length(pPointList) - 1 do begin
pPointList[i] := pPointList[i+1];
i := i + 1;
end;
setLength(pPointList, length(pPointList) - 1);
end;
end;
// Nombre de points dans la liste
function TPointList.count;
begin
Result := length(pPointList);
end;
function TPointList.print : string;
var i : byte;
s : string;
begin
i := 1;
s := '';
while i <= length(pPointList) do begin
if i <> 1 then s := s + chr(13) + chr(10);
if self.isRunning() then begin
if pCurrentPointID = i - 1 then begin
s := s + '->'
end;
end;
s := s + 'Point ' + IntToStr(i) + ' = ';
s := s + '(' + IntToStr(pPointList[i - 1].X) + ', ' + IntToStr(pPointList[i - 1].Y) + ')';
i := i + 1;
end;
Result := s;
end;
function TPointList.toStringList : TStringList;
var i : byte;
begin
i := 0;
Result := TStringList.Create();
while i < length(pPointList) do begin
Result.Add('Point ' + IntToStr(i+1) + ' = ');
Result[i] := Result[i] + '(' + IntToStr(pPointList[i].X) + ', ' + IntToStr(pPointList[i].Y) + ')';
if self.isRunning() then begin
if i < pCurrentPointID then begin
Result[i] := Result[i] + ' <--'
end;
end;
i := i + 1;
end;
end;
function TPointList.TimeToNextClick : longWord;
begin
Result := 0;
if (self.isRunning()) then begin
if pPointTimer.Enabled then begin
if pGlobalTimer.Tag > pPointTimer.Interval then
result := 0
else
Result := (Integer(pPointTimer.Interval) - pGlobalTimer.Tag);
end else begin
if pSequenceTimer.Enabled then begin
if pGlobalTimer.Tag > pSequenceTimer.Interval then
Result := 0
else
Result := (Integer(pSequenceTimer.Interval) - pGlobalTimer.Tag);
end;
end;
end;
Result := Result div 1000;
end;
// Sauvegarde
function TPointList.save(const fileName : string) : boolean;
var iniFile: TIniFile;
i: LongWord;
begin
iniFile := TIniFile.Create(fileName);
iniFile.WriteString('CONFIG', 'ClickInterval', intToStr(pClickInterval));
iniFile.WriteString('CONFIG', 'SequenceInterval', intToStr(pSequenceInterval));
iniFile.WriteString('CONFIG', 'NumberOfSequences', intToStr(pNbSequences));
iniFile.WriteString('CONFIG', 'NumberOfPoints', intToStr(length(pPointList)));
i := 0;
while i < length(pPointList) do begin
iniFile.WriteString('POINTS', 'px' + intToStr(i), intToStr(pPointList[i].x));
iniFile.WriteString('POINTS', 'py' + intToStr(i), intToStr(pPointList[i].y));
i := i + 1;
end;
iniFile.Free;
result := true;
end;
// Charge
function TPointList.load(const fileName : string) : boolean;
var iniFile: TIniFile;
i, numberOfPoints: LongWord;
pointToAdd: TPoint;
begin
iniFile := TIniFile.Create(fileName);
pClickInterval := strToInt(iniFile.ReadString('CONFIG', 'ClickInterval', '1'));
pSequenceInterval := strToInt(iniFile.ReadString('CONFIG', 'SequenceInterval', '1'));
pNbSequences := strToInt(iniFile.ReadString('CONFIG', 'NumberOfSequences', '1'));
numberOfPoints := strToInt(iniFile.ReadString('CONFIG', 'NumberOfPoints', '0'));
i := 0;
while i < numberOfPoints do begin
pointToAdd.X := strToInt(iniFile.ReadString('POINTS', 'px' + intToStr(i), '0'));
pointToAdd.Y := strToInt(iniFile.ReadString('POINTS', 'px' + intToStr(i), '0'));
self.add(pointToAdd);
i := i + 1;
end;
iniFile.Free;
result := true;
end;
function TPointList.save() : boolean;
begin
if pFileName <> '' then
Result := self.save(pFileName)
else
Result := FALSE;
end;
function TPointList.load() : boolean;
begin
if pFileName <> '' then
Result := self.load(pFileName)
else
Result := FALSE;
end;
end.
Conclusion :
L'exécutable est désormais disponible sur :
http://pogopixels.fr/download/AUTOCLICK.zip
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.