Klikacz - błąd podczas działania

0

Witam

Napisałem klikacza, który klika seriami w wyznaczone miejsca. Wszystko byłoby ok gdyby nie to, że po przeskoczeniu do kolejnej serii kliknięć, program "jakby" się zawiesza. Pojawia się informacja o braku dostępu, niemniej wszystko dalej działa, a po skończeniu serii kliknięć program jest ponownie dostępny.
Opis problemu, jest pewnie ciężki do zrozumienia, dlatego zamieszczam paczkę całego projektu (wraz z plikiem .exe):
tu był link

Problem zapewne tkwi w mojej niewiedzy w zwalnianiu pamięci itp. niestety na chwilę obecną nie jestem sobie w stanie z nim poradzić.
Gdyby, ktoś mógł mi coś podpowiedzieć, byłbym bardzo wdzięczny.

Pozdrawiam

0
  1. Nie dodałeś kodu formy, to co dałeś jest nam nie potrzebne.
  2. Spróbuj dodać Application.ProcessMessages
0

jeśli mimo błędu, działa prawidłowo spróbuj dodać try i except aby nic nie robiło przy błędzie

0
Patryk27 napisał(a)
  1. Nie dodałeś kodu formy, to co dałeś jest nam nie potrzebne.
  2. Spróbuj dodać Application.ProcessMessages

Wrzuciłem wszystkie pliki projektu, łącznie z kodem źródłowym, dlatego nie widziałem potrzeby ponownego wrzucania go w post.
Niemniej:

unit Klikacz;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Spin, Menus;

type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    Label2: TLabel;
    Label3: TLabel;
    GroupBox2: TGroupBox;
    ListBox1: TListBox;
    GroupBox3: TGroupBox;
    SpinEdit1: TSpinEdit;
    SpinEdit2: TSpinEdit;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Button1: TButton;
    Button2: TButton;
    ListBox2: TListBox;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    SpinEdit3: TSpinEdit;
    Label12: TLabel;
    MainMenu1: TMainMenu;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Klikaj;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    Foreground : HWND;  // zmienna przechowuje uchwyt okna
    procedure WMHOTKEY(var Msg : TMessage); message WM_HOTKEY; // przechwytuje skrot klawiaturowy

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterHotKey(Handle, $0001, MOD_CONTROL,  90);
RegisterHotKey(Handle, $0002, 0,  VK_F1);
Caption := 'Klikacz v1.1';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
{ zwolnienie skrotu w systemi }
  UnregisterHotKey(Handle, $0001);
  UnregisterHotKey(Handle, $0002);
end;

procedure TForm1.WMHOTKEY(var Msg: TMessage);
var
  MousePos : TPoint;
  Buffer : array[0..255] of char;
   i:Integer;
begin

  if Msg.WParam = $0001 then
    begin
      GetCursorPos(MousePos);  // pobierz pozycje kursora
      ListBox1.Items.Add(IntToStr(MousePos.X));
      ListBox2.Items.Add(IntToStr(MousePos.Y));
      Edit1.Text := IntToStr(MousePos.X); // przypisz do kontrolek
      Edit2.Text := IntToStr(MousePos.Y);
      Foreground := GetForegroundwindow;  // pobierz uchwyt okna

      // pobierz tytul aktywnego okna
      GetWindowText(Foreground, Buffer, SizeOf(Buffer));
    end;
  if Msg.WParam = $0002 then
    begin
    for i:=0 to SpinEdit3.Value-1 do
      begin
      Klikaj;
      end;
    end;
end;

procedure TForm1.Klikaj;
var i:Integer;
    CurrentPos : TPoint;
    CurrentWindow : HWND;
begin

for i:=0 to ListBox1.Items.Count-1 do
  begin
  CurrentWindow := GetForegroundWindow; // pobierz uchwyt aktywnego okna
  GetCursorPos(CurrentPos); // pobierz tymczasowa pozycje ekranu
  ShowWindow(Foreground, SW_SHOWNA);  // pokaż okno
  BringWindowToTop(Foreground); // dla pewnosci - wysun na wierzch
  SetForegroundwindow(Foreground);  // ustaw aktywne okno

  SetCursorPos(StrToInt(ListBox1.Items[i]), StrToInt(ListBox2.Items[i]));  // ustaw w wybranej pozycji
  { kliknij na pozycje }
  mouse_event(MOUSEEVENTF_LEFTDOWN, StrToInt(ListBox1.Items[i]), StrToInt(ListBox2.Items[i]), 0, 0);
  mouse_event(MOUSEEVENTF_LEFTUP, StrToInt(ListBox1.Items[i]), StrToInt(ListBox2.Items[i]), 0, 0);

  ShowWindow(Currentwindow, SW_SHOWNA);  // pokaż okno
  SetForegroundWindow(Currentwindow);  // ustaw aktywne okno
  SetCursorPos(CurrentPos.X, CurrentPos.Y); // ustaw ponownie na poprzedniej pozycji
  ListBox1.Selected[i]:=True;
  ListBox2.Selected[i]:=True;
  Sleep(SpinEdit1.Value);
end;
Sleep(SpinEdit2.Value);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ListBox1.Clear;
ListBox2.Clear;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ListBox1.Items.Delete(ListBox1.Items.Count-1);
ListBox2.Items.Delete(ListBox2.Items.Count-1);
end;

end.

A co do wskazówek, to możecie tak pokrótce wyjaśnić co to zmieni?

0

Nie wrzuciłeś żadnego kodu modułu oraz odpowiadającemu mu plikowi z wyglądem formatek.
Dlatego też nie wiem po co Tobie aż dwa ListBoxy. Jak chcesz przechowywać w wierszu więcej
niż jedną wartość tekstową to używaj ListView. A ujęcie instrukcji w bloki try ... except, zaś po
except nie dają nic, powinno spowodować, że po uruchomieniu z poza IDE nie pokażą się Tobie
żadne komunikaty o wyjątkach. Natomiast Application.ProcessMessages masz opisane w helpie:

Interrupts the execution of an application so that it can process the message queue.

Delphi syntax:

procedure ProcessMessages;

C++ syntax:

void __fastcall ProcessMessages(void);

Description

Call ProcessMessages to permit the application to process messages that are currently in the message queue. ProcessMessages cycles the Windows message loop until it is empty, and then returns control to the application.

Note: Neglecting message processing affects only the application calling ProcessMessages, not other applications. In lengthy operations, calling ProcessMessages periodically allows the application to respond to paint and other messages.
Note: ProcessMessages does not allow the application to go idle, whereas HandleMessage does.

0

Dawno nie pisałem nic w delphi, więc się pogubiłem z tymi plikami.
2 ListBox'ów użyłem do przechowywania współrzędnych X oraz Y. Dlaczego tak? Bo nie wiedziałem jak inaczej :)

Co do try...except, to raczej dodanie tego nic nie pomoże bo mnie nie pojawia się, żaden komunikat, tylko w Caption programu wyświetla się "brak dostępu" (program dalej działa prawidłowo).

A co do ProcessMessages, to nie mam helpa w Delphi, niemniej poczytam w sieci.

Dziękuję za pomoc. W razie wątpliwości zgłoszę się jeszcze w tym temacie.

EDIT:
Poczytałem i dodałem ProcessMessages i program pięknie śmiga. Jeszcze raz dzięki panowie, naprawdę bardzo mi pomogliście.

1 użytkowników online, w tym zalogowanych: 0, gości: 1