Optymalizacja załączonego kodu

0

Witam,

chciałbym w tym wątku zamieszczać po kolei kilka procedur na które patrząc - mówię sobie "na pewno można to skrócić o połowę - tylko jak?".

Proszę Was o wskazówki dotyczące optymalizacji poniższej procedury. Na pierwszy odstrzał procedurka, która odpowiada za 'odgrywanie' schematu który zawiera instrukcje typu 'przenieś kursor na kontrolkę', 'wyślij tekst do aktywnego okna', 'wyślij klawisz specjalny', itp.

Jeżeli chcecie zobaczyć co kryje się w którejś z procedury wywoływanej wewnątrz - to piszcie w komentarzu, a załączę kod.

procedure TfrmMenu.PlaySchema;
var
  kmbControl_Pos_x, kmbControl_Pos_y: integer;
  On_Control_Click_x, On_Control_Click_y: integer;
  On_Window_Click_x, On_Window_Click_y: integer;
  Window_Pos_x, Window_Pos_y: integer;
  ControlFound: boolean;
  Comment, Loop: string;
  sciezkaPliku: string;
  id_action: integer;

  CursorPos: TPoint;
  Target: HWND;

  lpPowtorzen: integer;
  label Petla;
begin
  Action_Stopped := False;
  AllowPlay(False);
  ControlFound := False;

  lpPowtorzen := 0;
  Application.ProcessMessages;
  IBDataSet_Instructions.First;

  Petla:
  while not IBDataSet_Instructions.Eof do
  begin
    if IBDataSet_InstructionsCHECKED.Value = 0 then
    begin
      IBDataSet_Instructions.Next;
      Continue;
    end;

    if IBDataSet_InstructionsID_ACTION.Value = Action_MouseMove then
    begin
      // Mouse move loop - animate recorded mouse movements
      while not IBDataSet_MousePath.Eof do
      begin
        Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, (IBDataSet_MousePathX.Value) * 65535 div Screen.Width, (IBDataSet_MousePathY.Value) * 65535 div Screen.Height, 0, GetMessageExtraInfo);
        Application.ProcessMessages;
        Sleep(_playing_MouseCursorSpeed);
        if Action_Stopped then
          break;

        IBDataSet_MousePath.Next;
      end;
      IBDataSet_Instructions.Next;
      Continue; // Step to next instruction
    end;

    if Action_Stopped then
      break;

    id_action := IBDataSet_InstructionsID_ACTION.Value;
    Window_ClassName := IBDataSet_InstructionsWINDOW_NAME.Value;
    Control_ClassName := IBDataSet_InstructionsCONTROL_NAME.Value;
    Control_Caption := IBDataSet_InstructionsCONTROL_CAPTION.Value;
    sciezkaPliku := IBDataSet_InstructionsAPP_PATH.Value;

    WaitTime := IBDataSet_InstructionsWAITTIME.Value;
    Comment := IBDataSet_InstructionsCOMMENT.Value;


    On_Control_Click_x := IBDataSet_InstructionsON_CONTROL_CLICK_LEFT.Value;
    On_Control_Click_y := IBDataSet_InstructionsON_CONTROL_CLICK_TOP.Value;
    On_Window_Click_x := IBDataSet_InstructionsON_WINDOW_CLICK_LEFT.Value;
    On_Window_Click_y := IBDataSet_InstructionsON_WINDOW_CLICK_TOP.Value;
    Window_Pos_x := GetWindowPos(Window_ClassName, Control_Caption).X;
    Window_Pos_y := GetWindowPos(Window_ClassName, Control_Caption).Y;

    if id_action = Action_SetCursorPos then
    begin
      Tray.BalloonHint(AppName, 'Ustawiam pozycję kursora', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, (On_Window_Click_X * 65535) div Screen.Width, (On_Window_Click_Y * 65535) div Screen.Height, 0, GetMessageExtraInfo);

      IBDataSet_Instructions.Next;
      Continue; // Step to next instruction
    end;

    if id_action = Action_WaitTime then
    begin
      Sleep(WaitTime);
      IBDataSet_Instructions.Next;
      Continue;
    end;

    if (id_action <> Action_RunFile) and (id_action <> Action_Condition) then
    begin

      if edtPowtorzen.Text = '0' then
        Loop := 'Nieskończenie wiele / ' + IntToStr(lpPowtorzen)
      else
        Loop := IntToStr(lpPowtorzen) + '/' + edtPowtorzen.Text;

      Tray.BalloonHint(AppName, 'Szukam okna...', btInfo, 5000, True);
      Foreground := FindWindow(PChar(Window_ClassName), nil);

      frmdm.Debug(Window_ClassName + ' - ' + IntToStr(Foreground));

      if (Foreground = 0) then
      begin
        Tray.BalloonHint(AppName, 'Nie znaleziono okna [' + Window_ClassName + ']!', btWarning, 5000, True);
        StopSchema;
        Application.MessageBox(PChar('Nie znaleziono okna [' + Window_ClassName + ']!'), 'Błąd', MB_ICONWARNING);
        Break;
      end;

      if IsIconic(Foreground) and (Foreground <> 0) then
      begin
        Tray.BalloonHint(AppName, 'Przywracam okno...', btInfo, 5000, True);
        ShowWindow(Foreground, SW_SHOW);
        ShowWindow(Foreground, SW_RESTORE);
        frmdm.Debug(Window_ClassName + ' - pokaż okno');
      end;

      if Pos('#', Window_ClassName) = 0 then
      begin
        BringWindowToTop(Foreground); // dla pewnosci - wysun na wierzch
        SetForegroundwindow(Foreground); // ustaw aktywne okno
      end;

      // Send Special Key to window
      if IBDataSet_InstructionsID_ACTION.Value = Action_SpecialKey then
      begin
        if IBDataSet_InstructionsCOMMENT.Value = '[ENTER]' then
        begin
          keybd_event(Ord(VK_RETURN),0,0,0);
          keybd_event(Ord(VK_RETURN),0,KEYEVENTF_KEYUP,0);
        end;

        if IBDataSet_InstructionsCOMMENT.Value = '[TAB]' then
        begin
          keybd_event(Ord(VK_TAB),0,0,0);
          keybd_event(Ord(VK_TAB),0,KEYEVENTF_KEYUP,0);
        end;

        if IBDataSet_InstructionsCOMMENT.Value = '[ESC]' then
        begin
          keybd_event(Ord(VK_ESCAPE),0,0,0);
          keybd_event(Ord(VK_ESCAPE),0,KEYEVENTF_KEYUP,0);
        end;

        if IBDataSet_InstructionsCOMMENT.Value = '[BACKSPACE]' then
        begin
          keybd_event(Ord(VK_BACK),0,0,0);
          keybd_event(Ord(VK_BACK),0,KEYEVENTF_KEYUP,0);
        end;

        Sleep(WaitTime);
        IBDataSet_Instructions.Next;
        Continue;
       end;

      kbmControlInfo.Close;
      kbmControlInfo.Open;

      frmdm.Debug(Window_ClassName + ' - Pobierz uchwyty okien');


      Tray.BalloonHint(AppName, 'Pobieram listę obiektów...', btInfo, 5000, True);
      EnumChildWindows(ForeGround, @EnumChildWinProc, 0);

      frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + '): X = ' + IntToStr(kbmControlInfoControlPos_Left.Value));
      frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + '): Y = ' + IntToStr(kbmControlInfoControlPos_Top.Value));
      Application.ProcessMessages;

      if Foreground <> 0 then
      begin
        Tray.BalloonHint(AppName, 'Szukam obiektu...', btInfo, 5000, True);

        ControlFound := False;
        // 1. Ma klasę i ma nie zmieniony caption
        if (Control_ClassName <> '') and (Control_Caption <> '') then
          ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName;ControlCaption', VarArrayOf([Window_ClassName, Control_ClassName, Control_Caption]), []);

        // 1. ma klasę ale nie ma captiona
        if not ControlFound then
          if (Control_ClassName <> '') and (Control_Caption = '') then
            ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName', VarArrayOf([Window_ClassName, Control_ClassName]), []);

        // ma klasę i inny caption
        if not ControlFound then
          if (Control_ClassName <> '') then
            ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName', VarArrayOf([Window_ClassName, Control_ClassName]), []);

        // znaleziono ale caption jest inny to oznacz jako nie znaleziony
        if ControlFound then
          if Control_Caption <> kbmControlInfoControlCaption.Value then
            ControlFound := False
          else
            if Control_Name <> kbmControlInfoControlName.Value then
              ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlClass;ControlName;ControlCaption', VarArrayOf([Window_ClassName, Control_ClassName, Control_Name, Control_Caption]), []);

        kmbControl_Pos_x := kbmControlInfoControlPos_Left.Value; // pozycja X kontrolki
        kmbControl_Pos_y := kbmControlInfoControlPos_Top.Value;  // pozycja Y kontrolki

        if ControlFound then
          frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + ') - znaleziono!')
        else
          frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + ') - nie znaleziono!');
        Application.ProcessMessages;

        if ControlFound then
          Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, (kmbControl_Pos_X + On_Control_Click_X) * 65535 div Screen.Width, (On_Control_Click_Y + kmbControl_Pos_Y) * 65535 div Screen.Height, 0, GetMessageExtraInfo)
        else
          Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, (Window_Pos_X + On_Window_Click_X) * 65535 div Screen.Width, (Window_Pos_Y + On_Window_Click_Y) * 65535 div Screen.Height, 0, GetMessageExtraInfo);

        Application.ProcessMessages;
      end;
    end;

    if id_action = Action_MouseLeftClick then
    begin
      Tray.BalloonHint(AppName, 'LPM', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
      Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    end;

    if id_action = Action_MouseRightClick then
    begin
      Tray.BalloonHint(AppName, 'PPM', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
      Mouse_Event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
    end;

    if id_action = Action_MouseMiddleClick then
    begin
      Tray.BalloonHint(AppName, 'ŚPM', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);
      Mouse_Event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);
    end;

    if id_action = Action_RunFile then // Run
    begin
      // if process exists then kill process
      if IBDataSet_InstructionsAPP_RESTART.Value = 1 then
        if processExists(ExtractFileName(sciezkaPliku)) then
          KillTask(ExtractFileName(sciezkaPliku));
      Application.ProcessMessages;
      Sleep(50);

      if IBDataSet_InstructionsMULTIPLE_INSTANCES.Value = 0 then
        // if process exists then do not run another copy
        if processExists(ExtractFileName(sciezkaPliku)) then
        begin
          IBDataSet_Instructions.Next;
          Continue;
        end;

      Tray.BalloonHint(AppName, 'Uruchamiam plik...', btInfo, 5000, True);
      if not RunFile(sciezkaPliku) then
      begin
        Tray.BalloonHint(AppName, 'Nie znaleziono pliku źródłowego!', btWarning, 5000, True);
        StopSchema;
        Break;
      end;
    end;

    if id_action = Action_Condition then
    begin
      Tray.BalloonHint(AppName, 'Sprawdzam warunek...', btInfo, 5000, True);

      if Check_Condition(IBDataSet_InstructionsID_C.Value) then
      begin
        if not IBDataSet_Instructions.Locate('CONDITION_IDENTIFICATOR', IBDataSet_InstructionsID_TRUE.Value, []) then
        begin
          Tray.BalloonHint(AppName, 'Nie znaleziono warunku!', btWarning, 5000, True);
          Application.MessageBox(PChar('Nie znaleziono identyfikatora warunku PRAWDA [' + frmdm.IBDataSet_CheckConditionID_TRUE.Value + ']!'), 'Nie znaleziono identyfikatora warunku', MB_ICONWARNING);
          StopSchema;
          Break;
        end else
        begin
          Tray.BalloonHint(AppName, 'Warunek spełniony', btInfo, 5000, True);
          Application.ProcessMessages;
          Sleep(WaitTime);
          IBDataSet_Instructions.Prior;
          IBDataSet_Instructions.Next;
          Continue;
        end;
      end else
      begin
        if not IBDataSet_Instructions.Locate('CONDITION_IDENTIFICATOR', IBDataSet_InstructionsID_FALSE.Value, []) then
        begin
          Tray.BalloonHint(AppName, 'Nie znaleziono warunku!', btWarning, 5000, True);
          Application.MessageBox(PChar('Nie znaleziono identyfikatora warunku FAŁSZ [' + frmdm.IBDataSet_CheckConditionID_FALSE.Value + ']!'), 'Nie znaleziono identyfikatora warunku', MB_ICONWARNING);
          StopSchema;
          IBDataSet_Instructions.Next;
          Continue;
        end else
        begin
          Tray.BalloonHint(AppName, 'Warunek nie spełniony', btInfo, 5000, True);
          Application.ProcessMessages;
          Sleep(WaitTime);
          IBDataSet_Instructions.Prior;
          Continue;
        end;
      end;
    end;

    if id_action = Action_MouseDBClick then
    begin
      Tray.BalloonHint(AppName, 'Otwieram...', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
      Sleep(5); 
      Application.ProcessMessages;
      Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
      Sleep(5);
      Application.ProcessMessages;
      Mouse_Event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
      Sleep(5);
      Application.ProcessMessages;
      Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
      Application.ProcessMessages;
    end;

    if id_action = Action_TypeText then
    begin
      if ControlFound then
      begin
        if IBDataSet_InstructionsINPUTTEXT_MODE.Value = 1 then
          Keyboard_SendText(Comment) // Keyboard
        else begin // Cursor
          SendMessage(kbmControlInfoHandle.Value, WM_SETTEXT, 0, integer(PChar(Comment)));
          SendMessage(kbmControlInfoHandle.Value, EM_SETSEL, length(Comment), length(Comment));
        end;
        Tray.BalloonHint(AppName, 'Wysłano tekst', btInfo, 5000, True);
      end else
      begin
        GetCursorPos(CursorPos);
        Target := WindowFromPoint(CursorPos);
        if Target <> 0 then
        begin
          if IBDataSet_InstructionsINPUTTEXT_MODE.Value = 1 then
            Keyboard_SendText(Comment) // Keyboard
          else begin // Cursor
            SendMessage(Target, WM_SETTEXT, ord(True), LPARAM(PChar(Comment)));
            SendMessage(Target, EM_SETSEL, length(Comment), length(Comment));
          end;
          Tray.BalloonHint(AppName, 'Wysłano tekst', btInfo, 5000, True);
        end else
        begin
          Application.MessageBox('Nie wysłano tekstu [Nie można odwołać się do obiektu]', 'Błąd wysyłania tekstu', MB_ICONWARNING);
          StopSchema;
          Tray.BalloonHint(AppName, 'Nie wysłano tekstu [Nie można odwołać się do obiektu]', btWarning, 5000, True);
          Break;
        end;
      end;
    end;

    Application.ProcessMessages;
    Sleep(WaitTime);

    {end else
    begin
      Application.MessageBox(PChar('Nie znaleziono kontrolki [' + nazwaKontrolki + '] !'), 'Błąd', MB_ICONWARNING);
      StopSchema;
      Break;
    end;    }

    IBDataSet_Instructions.Next;
  end;

  if not Action_Stopped and not (edtPowtorzen.Text = '1')  then
    repeat
      Inc(lpPowtorzen);
      if StrToInt(edtPowtorzen.Text) = 0 then
        lpPowtorzen := -1; // nieskończenie wiele

      if lpPowtorzen < StrToInt(edtPowtorzen.Text) + 1 then
        goto Petla;
    until (lpPowtorzen = StrToInt(edtPowtorzen.Text) + 1) or Action_Stopped;

  StopSchema;

  AllowPlay(True);
  Beep;
  Tray.BalloonHint(AppName, 'Zakończono odtwarzanie.', btInfo, 5000, True);
end;
0

Przede wszystkim podziel ten kod na mniejsze części, bo jest obrzydliwie długi i nieczytelny :]


Kod jest ładnie sformatowany, ale jest zbyt długi, przez co ciężko się go analizuje;

W ostatnim czasie na forum pojawiło się wiele wątków dotyczących formatowania kodu, dzielenia go i ogólnie organizacji - sporo ludzi twierdzi (w tym także ja), że każda procedura/funkcja powinna w całości mieścić się na jednym ekranie; Jeśli jest dłuższa niż jeden ekran - należy ją podzielić na mniejsze części;

Twoja procedura nie mieści się na dziesięciu ekranach, więc trzeba ją podzielić; Poza tym jeden blok instrukcji odpowiada za wiele funkcji - przenoszenie kursora, wysyłanie tekstu do okna, wysyłanie klawiszy itd.; Podziel sobie ten kod na mniejsze procedury/funkcje odpowiadające za jedną czynność, a jeśli instrukcje tej "jednej czynności" nie mieszczą się na ekranie - podziel jeszcze raz; W ten sposób uzyskasz mniejsze bloki, które łatwiej jest analizować;

Poza tym - jeśli już podzielisz kod to nie używaj globalnych zmiennych (jeśli to robisz), tylko przekazuj odpowiednie informacje w argumentach;

@user322 - jeśli nie będziesz chciał podzielić tej procedury na 5 - 10 mniejszych, to chociaż wstaw sobie w nim komentarze, które pozwolą na lepszą orientację w kodzie;

I wyrzuć to pierońskie GoTo! :]

0

Część 1

procedure TfrmMenu.PlaySchema;
var
  kmbControl_Pos_x, kmbControl_Pos_y: integer;
  On_Control_Click_x, On_Control_Click_y: integer;
  On_Window_Click_x, On_Window_Click_y: integer;
  Window_Pos_x, Window_Pos_y: integer;
  ControlFound: boolean;
  Comment, Loop: string;
  sciezkaPliku: string;
  id_action: integer;
 
  CursorPos: TPoint;
  Target: HWND;
 
  lpPowtorzen: integer;
  label Petla;
begin
  Action_Stopped := False;
  AllowPlay(False);
  ControlFound := False;
 
  lpPowtorzen := 0;
  Application.ProcessMessages;
  IBDataSet_Instructions.First;
 
  Petla:
  while not IBDataSet_Instructions.Eof do
  begin
    if IBDataSet_InstructionsCHECKED.Value = 0 then
    begin
      IBDataSet_Instructions.Next;
      Continue;
    end;
 
    if IBDataSet_InstructionsID_ACTION.Value = Action_MouseMove then
    begin
      // Mouse move loop - animate recorded mouse movements
      while not IBDataSet_MousePath.Eof do
      begin
        Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, 
                          (IBDataSet_MousePathX.Value) * 65535 div Screen.Width, 
                          (IBDataSet_MousePathY.Value) * 65535 div Screen.Height, 0, GetMessageExtraInfo);
        Application.ProcessMessages;
        Sleep(_playing_MouseCursorSpeed);
        if Action_Stopped then
          break;
 
        IBDataSet_MousePath.Next;
      end;
      
      IBDataSet_Instructions.Next;
      Continue; // Step to next instruction
    end;
 
    if Action_Stopped then
      break;
 
    id_action := IBDataSet_InstructionsID_ACTION.Value;
    Window_ClassName := IBDataSet_InstructionsWINDOW_NAME.Value;
    Control_ClassName := IBDataSet_InstructionsCONTROL_NAME.Value;
    Control_Caption := IBDataSet_InstructionsCONTROL_CAPTION.Value;
    sciezkaPliku := IBDataSet_InstructionsAPP_PATH.Value;
 
    WaitTime := IBDataSet_InstructionsWAITTIME.Value;
    Comment := IBDataSet_InstructionsCOMMENT.Value;
 
 
    On_Control_Click_x := IBDataSet_InstructionsON_CONTROL_CLICK_LEFT.Value;
    On_Control_Click_y := IBDataSet_InstructionsON_CONTROL_CLICK_TOP.Value;
    On_Window_Click_x := IBDataSet_InstructionsON_WINDOW_CLICK_LEFT.Value;
    On_Window_Click_y := IBDataSet_InstructionsON_WINDOW_CLICK_TOP.Value;
    Window_Pos_x := GetWindowPos(Window_ClassName, Control_Caption).X;
    Window_Pos_y := GetWindowPos(Window_ClassName, Control_Caption).Y;
 
    if id_action = Action_SetCursorPos then
    begin
      Tray.BalloonHint(AppName, 'Ustawiam pozycję kursora', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, 
                       (On_Window_Click_X * 65535) div Screen.Width, 
                       (On_Window_Click_Y * 65535) div Screen.Height, 0, GetMessageExtraInfo);
 
      IBDataSet_Instructions.Next;
      Continue; // Step to next instruction
    end;
 
    if id_action = Action_WaitTime then
    begin
      Sleep(WaitTime);
      IBDataSet_Instructions.Next;
      Continue;
    end;
 
    if (id_action <> Action_RunFile) and (id_action <> Action_Condition) then
    begin
 
      if edtPowtorzen.Text = '0' then
        Loop := 'Nieskończenie wiele / ' + IntToStr(lpPowtorzen)
      else
        Loop := IntToStr(lpPowtorzen) + '/' + edtPowtorzen.Text;
 
      Tray.BalloonHint(AppName, 'Szukam okna...', btInfo, 5000, True);
      Foreground := FindWindow(PChar(Window_ClassName), nil);
 
      frmdm.Debug(Window_ClassName + ' - ' + IntToStr(Foreground));
 
      if (Foreground = 0) then
      begin
        Tray.BalloonHint(AppName, 'Nie znaleziono okna [' + Window_ClassName + ']!', btWarning, 5000, True);
        StopSchema;
        Application.MessageBox(PChar('Nie znaleziono okna [' + Window_ClassName + ']!'), 'Błąd', MB_ICONWARNING);
        Break;
      end;

Część 2

     
if IsIconic(Foreground) and (Foreground <> 0) then
begin
   Tray.BalloonHint(AppName, 'Przywracam okno...', btInfo, 5000, True);
   ShowWindow(Foreground, SW_SHOW);
   ShowWindow(Foreground, SW_RESTORE);
   frmdm.Debug(Window_ClassName + ' - pokaż okno');
end;
 
if Pos('#', Window_ClassName) = 0 then
begin
  BringWindowToTop(Foreground); // dla pewnosci - wysun na wierzch
  SetForegroundwindow(Foreground); // ustaw aktywne okno
end;
 
// Send Special Key to window
if IBDataSet_InstructionsID_ACTION.Value = Action_SpecialKey then
begin
   if IBDataSet_InstructionsCOMMENT.Value = '[ENTER]' then
   begin
     keybd_event(Ord(VK_RETURN),0,0,0);
     keybd_event(Ord(VK_RETURN),0,KEYEVENTF_KEYUP,0);
   end;
 
   if IBDataSet_InstructionsCOMMENT.Value = '[TAB]' then
   begin
     keybd_event(Ord(VK_TAB),0,0,0);
     keybd_event(Ord(VK_TAB),0,KEYEVENTF_KEYUP,0);
   end;
 
   if IBDataSet_InstructionsCOMMENT.Value = '[ESC]' then
   begin
     keybd_event(Ord(VK_ESCAPE),0,0,0);
     keybd_event(Ord(VK_ESCAPE),0,KEYEVENTF_KEYUP,0);
   end;
 
   if IBDataSet_InstructionsCOMMENT.Value = '[BACKSPACE]' then
   begin
      keybd_event(Ord(VK_BACK),0,0,0);
      keybd_event(Ord(VK_BACK),0,KEYEVENTF_KEYUP,0);
   end;
 
   Sleep(WaitTime);
   IBDataSet_Instructions.Next;
   Continue;
end;
 
kbmControlInfo.Close;
kbmControlInfo.Open;
 
frmdm.Debug(Window_ClassName + ' - Pobierz uchwyty okien');
 
 
Tray.BalloonHint(AppName, 'Pobieram listę obiektów...', btInfo, 5000, True);
EnumChildWindows(ForeGround, @EnumChildWinProc, 0);
 
frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + '): X = ' + IntToStr(kbmControlInfoControlPos_Left.Value));
frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + '): Y = ' + IntToStr(kbmControlInfoControlPos_Top.Value));
Application.ProcessMessages;

Część 3

      
      if Foreground <> 0 then
      begin
        Tray.BalloonHint(AppName, 'Szukam obiektu...', btInfo, 5000, True);
 
        ControlFound := False;
        // 1. Ma klasę i ma nie zmieniony caption
        if (Control_ClassName <> '') and (Control_Caption <> '') then
          ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName;ControlCaption', VarArrayOf([Window_ClassName, Control_ClassName, Control_Caption]), []);
 
        // 1. ma klasę ale nie ma captiona
        if not ControlFound then
          if (Control_ClassName <> '') and (Control_Caption = '') then
            ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName', VarArrayOf([Window_ClassName, Control_ClassName]), []);
 
        // ma klasę i inny caption
        if not ControlFound then
          if (Control_ClassName <> '') then
            ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName', VarArrayOf([Window_ClassName, Control_ClassName]), []);
 
        // znaleziono ale caption jest inny to oznacz jako nie znaleziony
        if ControlFound then
          if Control_Caption <> kbmControlInfoControlCaption.Value then
            ControlFound := False
          else
            if Control_Name <> kbmControlInfoControlName.Value then
              ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlClass;ControlName;ControlCaption', 
                                                    VarArrayOf([Window_ClassName, Control_ClassName, Control_Name, Control_Caption]), []);
 
        kmbControl_Pos_x := kbmControlInfoControlPos_Left.Value; // pozycja X kontrolki
        kmbControl_Pos_y := kbmControlInfoControlPos_Top.Value;  // pozycja Y kontrolki
 
        if ControlFound then
          frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + ') - znaleziono!')
        else
          frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + ') - nie znaleziono!');
        Application.ProcessMessages;
 
        if ControlFound then
          Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, 
                           (kmbControl_Pos_X + On_Control_Click_X) * 65535 div Screen.Width,
                          (On_Control_Click_Y + kmbControl_Pos_Y) * 65535 div Screen.Height, 0, GetMessageExtraInfo)
        else
          Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE, 
                           (Window_Pos_X + On_Window_Click_X) * 65535 div Screen.Width, 
                           (Window_Pos_Y + On_Window_Click_Y) * 65535 div Screen.Height, 0, GetMessageExtraInfo);
 
        Application.ProcessMessages;
      end;
    end;
 
    if id_action = Action_MouseLeftClick then
    begin
      Tray.BalloonHint(AppName, 'LPM', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
      Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
    end;
 
    if id_action = Action_MouseRightClick then
    begin
      Tray.BalloonHint(AppName, 'PPM', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
      Mouse_Event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
    end;
 
    if id_action = Action_MouseMiddleClick then
    begin
      Tray.BalloonHint(AppName, 'ŚPM', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);
      Mouse_Event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);
    end;
 
    if id_action = Action_RunFile then // Run
    begin
      // if process exists then kill process
      if IBDataSet_InstructionsAPP_RESTART.Value = 1 then
        if processExists(ExtractFileName(sciezkaPliku)) then
          KillTask(ExtractFileName(sciezkaPliku));
      Application.ProcessMessages;
      Sleep(50);
 
      if IBDataSet_InstructionsMULTIPLE_INSTANCES.Value = 0 then
        // if process exists then do not run another copy
        if processExists(ExtractFileName(sciezkaPliku)) then
        begin
          IBDataSet_Instructions.Next;
          Continue;
        end;
 
      Tray.BalloonHint(AppName, 'Uruchamiam plik...', btInfo, 5000, True);
      if not RunFile(sciezkaPliku) then
      begin
        Tray.BalloonHint(AppName, 'Nie znaleziono pliku źródłowego!', btWarning, 5000, True);
        StopSchema;
        Break;
      end;
    end;
 
    if id_action = Action_Condition then
    begin
      Tray.BalloonHint(AppName, 'Sprawdzam warunek...', btInfo, 5000, True);
 
      if Check_Condition(IBDataSet_InstructionsID_C.Value) then
      begin
        if not IBDataSet_Instructions.Locate('CONDITION_IDENTIFICATOR', IBDataSet_InstructionsID_TRUE.Value, []) then
        begin
          Tray.BalloonHint(AppName, 'Nie znaleziono warunku!', btWarning, 5000, True);
          Application.MessageBox(PChar('Nie znaleziono identyfikatora warunku PRAWDA [' + frmdm.IBDataSet_CheckConditionID_TRUE.Value + ']!'), 
                                                   'Nie znaleziono identyfikatora warunku', MB_ICONWARNING);
          StopSchema;
          Break;
        end else
        begin
          Tray.BalloonHint(AppName, 'Warunek spełniony', btInfo, 5000, True);
          Application.ProcessMessages;
          Sleep(WaitTime);
          IBDataSet_Instructions.Prior;
          IBDataSet_Instructions.Next;
          Continue;
        end;
      end else
      begin
        if not IBDataSet_Instructions.Locate('CONDITION_IDENTIFICATOR', IBDataSet_InstructionsID_FALSE.Value, []) then
        begin
          Tray.BalloonHint(AppName, 'Nie znaleziono warunku!', btWarning, 5000, True);
          Application.MessageBox(PChar('Nie znaleziono identyfikatora warunku FAŁSZ [' + frmdm.IBDataSet_CheckConditionID_FALSE.Value + ']!'), 
                                                   'Nie znaleziono identyfikatora warunku', MB_ICONWARNING);
          StopSchema;
          IBDataSet_Instructions.Next;
          Continue;
        end else
        begin
          Tray.BalloonHint(AppName, 'Warunek nie spełniony', btInfo, 5000, True);
          Application.ProcessMessages;
          Sleep(WaitTime);
          IBDataSet_Instructions.Prior;
          Continue;
        end;
      end;
    end;
 
    if id_action = Action_MouseDBClick then
    begin
      Tray.BalloonHint(AppName, 'Otwieram...', btInfo, 5000, True);
      Mouse_Event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
      Sleep(5); 
      Application.ProcessMessages;
      Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
      Sleep(5);
      Application.ProcessMessages;
      Mouse_Event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
      Sleep(5);
      Application.ProcessMessages;
      Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
      Application.ProcessMessages;
    end;
 
    if id_action = Action_TypeText then
    begin
      if ControlFound then
      begin
        if IBDataSet_InstructionsINPUTTEXT_MODE.Value = 1 then
          Keyboard_SendText(Comment) // Keyboard
        else begin // Cursor
          SendMessage(kbmControlInfoHandle.Value, WM_SETTEXT, 0, integer(PChar(Comment)));
          SendMessage(kbmControlInfoHandle.Value, EM_SETSEL, length(Comment), length(Comment));
        end;
        Tray.BalloonHint(AppName, 'Wysłano tekst', btInfo, 5000, True);
      end else
      begin
        GetCursorPos(CursorPos);
        Target := WindowFromPoint(CursorPos);
        if Target <> 0 then
        begin
          if IBDataSet_InstructionsINPUTTEXT_MODE.Value = 1 then
            Keyboard_SendText(Comment) // Keyboard
          else begin // Cursor
            SendMessage(Target, WM_SETTEXT, ord(True), LPARAM(PChar(Comment)));
            SendMessage(Target, EM_SETSEL, length(Comment), length(Comment));
          end;
          Tray.BalloonHint(AppName, 'Wysłano tekst', btInfo, 5000, True);
        end else
        begin
          Application.MessageBox('Nie wysłano tekstu [Nie można odwołać się do obiektu]', 'Błąd wysyłania tekstu', MB_ICONWARNING);
          StopSchema;
          Tray.BalloonHint(AppName, 'Nie wysłano tekstu [Nie można odwołać się do obiektu]', btWarning, 5000, True);
          Break;
        end;
      end;
    end;
 
    Application.ProcessMessages;
    Sleep(WaitTime);
 
    {end else
    begin
      Application.MessageBox(PChar('Nie znaleziono kontrolki [' + nazwaKontrolki + '] !'), 'Błąd', MB_ICONWARNING);
      StopSchema;
      Break;
    end;    }
 
    IBDataSet_Instructions.Next;
  end;
 
  if not Action_Stopped and not (edtPowtorzen.Text = '1')  then
    repeat
      Inc(lpPowtorzen);
      if StrToInt(edtPowtorzen.Text) = 0 then
        lpPowtorzen := -1; // nieskończenie wiele
 
      if lpPowtorzen < StrToInt(edtPowtorzen.Text) + 1 then
        goto Petla;
    until (lpPowtorzen = StrToInt(edtPowtorzen.Text) + 1) or Action_Stopped;
 
  StopSchema;
 
  AllowPlay(True);
  Beep;
  Tray.BalloonHint(AppName, 'Zakończono odtwarzanie.', btInfo, 5000, True);
end;
0

Na sam początek na pewno wypadałoby to porozdzielać w takim schemacie:

Case id_action of
 Action_Condition: ParseCondition();
 Action_MouseDBClick: ParseMouseDoubleClick();
End;

Ewentualnie:

Const Actions: Array[foo..bar] of Procedure = (@ParseCondition, @ParseMouseDoubleClick, ...);
Begin
 Actions[id_action]();
End;

W swoim kompilatorze korzystam z tej pierwszej metody (patrz: https://github.com/Piterolex/SScript-Compiler/blob/master/compiler/Compile1.pas#L572) i jest ok ;P

Btw, wnioskuję, że robisz coś na wzór parsera i robisz to dosyć... źle. Ale nie widzę reszty kodu, więc ciężko mi coś powiedzieć.
Btw2, mieszasz polskie nazwy identyfikatorów z angielskimi: zdecyduj się na angielski i tylko w nim pisz kod :P

0

Kod po konwersji:
Muszę sprawdzić jeszcze czy w ogóle działa :)
Działa :)

procedure TfrmMenu.PlaySchema;
var
  kmbControl_Pos_x, kmbControl_Pos_y: integer;
  On_Control_Click_x, On_Control_Click_y: integer;
  On_Window_Click_x, On_Window_Click_y: integer;
  Window_Pos_x, Window_Pos_y: integer;
  ControlFound: boolean;
  Comment: string;
  sciezkaPliku: string;
  id_action: integer;

  CursorPos: TPoint;
  Target: HWND;
begin
  Action_Stopped := False;
  AllowPlay(False);
  ControlFound := False;

  Application.ProcessMessages;
  IBDataSet_Instructions.First;

  // Pętla tylko po zaznaczonych, jesli nie jest zaznaczony
  // to następny przebieg
  while not IBDataSet_Instructions.Eof do
  begin
    if Action_Stopped then // jeśli przerwano
      Break;

    if IBDataSet_InstructionsCHECKED.Value = 0 then
    begin
      IBDataSet_Instructions.Next;
      Continue; // idź do następnego przebiegu pętli
    end;

    ////////////////////////////////
    // Przypisz wartości z Dataset
    // do globalnych zmiennych
    ////////////////////////////////
    id_action         := IBDataSet_InstructionsID_ACTION.Value;
    Window_ClassName  := IBDataSet_InstructionsWINDOW_NAME.Value;
    Control_ClassName := IBDataSet_InstructionsCONTROL_NAME.Value;
    Control_Caption   := IBDataSet_InstructionsCONTROL_CAPTION.Value;
    sciezkaPliku      := IBDataSet_InstructionsAPP_PATH.Value;
    WaitTime  := IBDataSet_InstructionsWAITTIME.Value;
    Comment   := IBDataSet_InstructionsCOMMENT.Value;

    On_Control_Click_x := IBDataSet_InstructionsON_CONTROL_CLICK_LEFT.Value;
    On_Control_Click_y := IBDataSet_InstructionsON_CONTROL_CLICK_TOP.Value;
    On_Window_Click_x  := IBDataSet_InstructionsON_WINDOW_CLICK_LEFT.Value;
    On_Window_Click_y  := IBDataSet_InstructionsON_WINDOW_CLICK_TOP.Value;
    Window_Pos_x       := GetWindowPos(Window_ClassName, Control_Caption).X;
    Window_Pos_y       := GetWindowPos(Window_ClassName, Control_Caption).Y;

    // Znajdź okno o podanej klasie
    Foreground := FindWindow(PChar(Window_ClassName), nil);
    frmdm.Debug(Window_ClassName + ' - ' + IntToStr(Foreground));

    if Foreground <> 0 then // znalezione okno
    begin
      if IsIconic(Foreground) then
      begin // Jeśli okno zminimalizowane to przywróć
        ShowWindow(Foreground, SW_SHOW);
        ShowWindow(Foreground, SW_RESTORE);
        frmdm.Debug(Window_ClassName + ' - przywróć okno');
      end;

      // jeśli # to nie pokazuj
      if Pos('#', Window_ClassName) = 0 then
      begin
        BringWindowToTop(Foreground); // wysun na wierzch
        SetForegroundwindow(Foreground); // ustaw aktywne okno
      end;
    end;


    ////////////////////////////////////////////////
    // Poniższy kod dotyczy operacji, które muszą
    // zostać wykonane na danym oknie
    ////////////////////////////////////////////////

    // ten warunek eliminuje instrukcje,
    // które nie wymagają operowania na oknie
    if (id_action <> Action_RunFile) and (id_action <> Action_Condition) then
    begin
      if (Foreground = 0) then // Nie znaleziono okna
      begin
        Tray.BalloonHint(AppName, 'Nie znaleziono okna [' + Window_ClassName + ']!', btWarning, 5000, True);
        Application.MessageBox(PChar('Nie znaleziono okna [' + Window_ClassName + ']!'), 'Błąd', MB_ICONWARNING);
        Break; // koniec
      end;

      kbmControlInfo.Close;
      kbmControlInfo.Open;

      frmdm.Debug(Window_ClassName + ' - Pobierz uchwyty obiektów');
      Tray.BalloonHint(AppName, 'Pobieram listę obiektów...', btInfo, 5000, True);
      EnumChildWindows(ForeGround, @EnumChildWinProc, 0);

      frmdm.Debug(Window_ClassName + ' (' + Control_ClassName +'): X = ' + IntToStr(kbmControlInfoControlPos_Left.Value));
      frmdm.Debug(Window_ClassName + ' (' + Control_ClassName +'): Y = ' + IntToStr(kbmControlInfoControlPos_Top.Value));
      Application.ProcessMessages;

      Tray.BalloonHint(AppName, 'Szukam obiektu...', btInfo, 5000, True);

      ControlFound := False;
      // 1. Ma klasę i ma nie zmieniony caption
      if (Control_ClassName <> '') and (Control_Caption <> '') then
        ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName;ControlCaption',
        VarArrayOf([Window_ClassName, Control_ClassName, Control_Caption]), []);

      // 2. ma klasę ale nie ma captiona
      if not ControlFound then
        if (Control_ClassName <> '') and (Control_Caption = '') then
          ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName', VarArrayOf([Window_ClassName, Control_ClassName]), []);

      // 3. ma klasę i inny caption
      if not ControlFound then
        if (Control_ClassName <> '') then
          ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName', VarArrayOf([Window_ClassName, Control_ClassName]), []);

      // znaleziono ale caption jest inny to oznacz jako nie znaleziony
      if ControlFound then
        if Control_Caption <> kbmControlInfoControlCaption.Value then
          ControlFound := False
        else
          if Control_Name <> kbmControlInfoControlName.Value then
            ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlClass;ControlName;ControlCaption', VarArrayOf([Window_ClassName, Control_ClassName, Control_Name, Control_Caption]), []);

      kmbControl_Pos_x := kbmControlInfoControlPos_Left.Value; // pozycja X kontrolki
      kmbControl_Pos_y := kbmControlInfoControlPos_Top.Value;  // pozycja Y kontrolki

      if ControlFound then
        frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + ') - znaleziono!')
      else
        frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + ') - nie znaleziono!');

      Application.ProcessMessages;

      if ControlFound then
        Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE,
                   (kmbControl_Pos_X + On_Control_Click_X) * 65535 div Screen.Width,
                   (On_Control_Click_Y + kmbControl_Pos_Y) * 65535 div Screen.Height,
                   0, GetMessageExtraInfo)
      else
        Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE,
                   (Window_Pos_X + On_Window_Click_X) * 65535 div Screen.Width,
                   (Window_Pos_Y + On_Window_Click_Y) * 65535 div Screen.Height,
                   0, GetMessageExtraInfo);
    end;
    ////////////////////////////////
    ///  KONIEC KODU 'OKIENKOWEGO'
    ////////////////////////////////


    case ID_ACTION of

      Action_MouseMove: // Animacja ruchów myszki
        begin
          if not Animate_MouseMovement then
            break
          else
            IBDataSet_Instructions.Next;
        end;

      Action_SetCursorPos: // Ustaw pozycję kursora
        begin
          Tray.BalloonHint(AppName, 'Ustawiam pozycję kursora', btInfo, 5000, True);

          Mouse_Event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE,
                     (On_Window_Click_X * 65535) div Screen.Width,
                     (On_Window_Click_Y * 65535) div Screen.Height, 0, GetMessageExtraInfo);

          IBDataSet_Instructions.Next;
        end;

      Action_WaitTime: // Czekaj
        begin
          Sleep(WaitTime);
          IBDataSet_Instructions.Next;
        end;

      Action_MouseLeftClick: // Lewy przycisk myszy
        begin
          Tray.BalloonHint(AppName, 'LPM', btInfo, 5000, True);
          Mouse_Event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
          Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
        end;

      Action_MouseRightClick: // Prawy przycisk myszy
        begin
          Tray.BalloonHint(AppName, 'PPM', btInfo, 5000, True);
          Mouse_Event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
          Mouse_Event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
        end;

      Action_MouseMiddleClick: // Środkowy przycisk myszy
        begin
          Tray.BalloonHint(AppName, 'ŚPM', btInfo, 5000, True);
          Mouse_Event(MOUSEEVENTF_MIDDLEDOWN, 0, 0, 0, 0);
          Mouse_Event(MOUSEEVENTF_MIDDLEUP, 0, 0, 0, 0);
        end;

      Action_MouseDBClick: // Podwójne kliknięcie
        begin
          Tray.BalloonHint(AppName, 'Otwieram...', btInfo, 5000, True);

          Mouse_Event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
          Sleep(5);
          Application.ProcessMessages;
          Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
          Sleep(5);
          Application.ProcessMessages;
          Mouse_Event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
          Sleep(5);
          Application.ProcessMessages;
          Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
          Application.ProcessMessages;
        end;

      Action_RunFile: // Uruchom plik
        begin
          // Jeśli włączona opcja jednej instancji programu
          // a 1 proces jest już uruchomiony
          if (IBDataSet_InstructionsAPP_RESTART.Value = 1)
          and processExists(ExtractFileName(sciezkaPliku)) then
            KillTask(ExtractFileName(sciezkaPliku)); // Zakończ proces

          Application.ProcessMessages;
          Sleep(50);

          // Jeśli wyłączona opcja wielu instancji
          // a proces jest już uruchomiony to idz do nast. instrukcji
          if (IBDataSet_InstructionsMULTIPLE_INSTANCES.Value <> 0)
          and not processExists(ExtractFileName(sciezkaPliku)) then
          begin // uruchom plik
            Tray.BalloonHint(AppName, 'Uruchamiam plik...', btInfo, 5000, True);
            if not RunFile(sciezkaPliku) then
            begin
              Tray.BalloonHint(AppName, 'Nie znaleziono pliku źródłowego!', btWarning, 5000, True);
              Break;
            end;
          end;
        end;

      Action_Condition: // Sprawdzanie warunku
        begin
          Tray.BalloonHint(AppName, 'Sprawdzam warunek...', btInfo, 5000, True);

          if Check_Condition(IBDataSet_InstructionsID_C.Value) then
          begin
            if not IBDataSet_Instructions.Locate('CONDITION_IDENTIFICATOR', IBDataSet_InstructionsID_TRUE.Value, []) then
            begin
              Tray.BalloonHint(AppName, 'Nie znaleziono warunku!', btWarning, 5000, True);
              Application.MessageBox(PChar('Nie znaleziono identyfikatora warunku PRAWDA [' + frmdm.IBDataSet_CheckConditionID_TRUE.Value + ']!'), 'Nie znaleziono identyfikatora warunku', MB_ICONWARNING);
              Break;
            end else
            begin
              Tray.BalloonHint(AppName, 'Warunek spełniony', btInfo, 5000, True);
              IBDataSet_Instructions.Prior;
            end;
          end else
          begin
            if not IBDataSet_Instructions.Locate('CONDITION_IDENTIFICATOR', IBDataSet_InstructionsID_FALSE.Value, []) then
            begin
              Tray.BalloonHint(AppName, 'Nie znaleziono warunku!', btWarning, 5000, True);
              Application.MessageBox(PChar('Nie znaleziono identyfikatora warunku FAŁSZ [' + frmdm.IBDataSet_CheckConditionID_FALSE.Value + ']!'), 'Nie znaleziono identyfikatora warunku', MB_ICONWARNING);
              Break;
            end else
            begin
              Tray.BalloonHint(AppName, 'Warunek nie spełniony', btInfo, 5000, True);
              IBDataSet_Instructions.Prior;
            end;
          end;
        end;

      Action_SpecialKey: // Klawisze specjalne
        begin
          if IBDataSet_InstructionsCOMMENT.Value = '[ENTER]' then
          begin
            keybd_event(Ord(VK_RETURN),0,0,0);
            keybd_event(Ord(VK_RETURN),0,KEYEVENTF_KEYUP,0);
          end;

          if IBDataSet_InstructionsCOMMENT.Value = '[TAB]' then
          begin
            keybd_event(Ord(VK_TAB),0,0,0);
            keybd_event(Ord(VK_TAB),0,KEYEVENTF_KEYUP,0);
          end;

          if IBDataSet_InstructionsCOMMENT.Value = '[ESC]' then
          begin
            keybd_event(Ord(VK_ESCAPE),0,0,0);
            keybd_event(Ord(VK_ESCAPE),0,KEYEVENTF_KEYUP,0);
          end;

          if IBDataSet_InstructionsCOMMENT.Value = '[BACKSPACE]' then
          begin
            keybd_event(Ord(VK_BACK),0,0,0);
            keybd_event(Ord(VK_BACK),0,KEYEVENTF_KEYUP,0);
          end;
        end;

      Action_TypeText: // Emulowanie wpisywanego tekstu
        begin
          if ControlFound then // Jeśli kontrolka znaleziona
          begin
            if IBDataSet_InstructionsINPUTTEXT_MODE.Value = 1 then
              Keyboard_SendText(Comment) // Wpisz tekst
            else begin // Wyślij do kursora
              SendMessage(kbmControlInfoHandle.Value, WM_SETTEXT, 0, integer(PChar(Comment)));
              SendMessage(kbmControlInfoHandle.Value, EM_SETSEL, length(Comment), length(Comment));
            end;
            Tray.BalloonHint(AppName, 'Wysłano tekst', btInfo, 5000, True);
          end else
          begin
            GetCursorPos(CursorPos);
            Target := WindowFromPoint(CursorPos);
            if Target <> 0 then
            begin
              if IBDataSet_InstructionsINPUTTEXT_MODE.Value = 1 then
                Keyboard_SendText(Comment) // Wpisz tekst
              else begin // Wyślij do kursora
                SendMessage(Target, WM_SETTEXT, ord(True), LPARAM(PChar(Comment)));
                SendMessage(Target, EM_SETSEL, length(Comment), length(Comment));
              end;
              Tray.BalloonHint(AppName, 'Wysłano tekst', btInfo, 5000, True);
            end else
            begin
              Application.MessageBox('Nie wysłano tekstu [Nie można odwołać się do obiektu]', 'Błąd wysyłania tekstu', MB_ICONWARNING);
              Tray.BalloonHint(AppName, 'Nie wysłano tekstu [Nie można odwołać się do obiektu]', btWarning, 5000, True);
            end;
          end;

        end;
    end;

    Sleep(WaitTime);
    IBDataSet_Instructions.Next;
  end;

  StopSchema; // Koniec schematu
  AllowPlay(True);
  Beep;
  Tray.BalloonHint(AppName, 'Zakończono odtwarzanie.', btInfo, 5000, True);
end;
0

Nic tak nie mierzy wydajności jak ludzki mózg ^^

Dzięki @Patryk27 i @furious programming bardzo pomogliście. Aż się chce patrzeć teraz na ten kod.

Proszę o ewentualne zastrzeżenia co do powyższego kodu i zapodam kolejną porcję.

0
user322 napisał(a)

Ale jak mogę jeszcze skrócić go? Chodzi o to, aby nie wykonywać wielu tych samych czynności pod sobą tylko przekazywać do funkcji?

Nie, chodzi o to, by podzielić jedną dużą procedurę na wiele mniejszych, mających po 30-40 linii lub mniej; Oczywiście każda z tych mniejszych procedur musi służyć do jednego zadania.

0

Tyle udało mi się zdziałać.

obecna wersja: 287 linijek
pierwotna wersja: 379 linijek

czyli ponad 100 linijek mniej.

procedure TfrmMenu.PlaySchema;
var
  kmbControl_Pos_x, kmbControl_Pos_y: integer;
  On_Control_Click_x, On_Control_Click_y: integer;
  On_Window_Click_x, On_Window_Click_y: integer;
  Window_Pos_x, Window_Pos_y: integer;
  ControlFound: boolean;
  Comment: string;
  FilePath: string;
  id_action: integer;

  CursorPos: TPoint;
  Target: HWND;
begin
  Action_Stopped := False;
  AllowPlay(False);
  ControlFound := False;

  Application.ProcessMessages;
  IBDataSet_Instructions.First;

  // Pętla tylko po zaznaczonych, jesli nie jest zaznaczony
  // to następny przebieg
  while not IBDataSet_Instructions.Eof do
  begin
    if Action_Stopped then // jeśli przerwano
      Break;

    if IBDataSet_InstructionsCHECKED.Value = 0 then
    begin
      IBDataSet_Instructions.Next;
      Continue; // idź do następnego przebiegu pętli
    end;

    ////////////////////////////////
    // Przypisz wartości z Dataset
    // do globalnych zmiennych
    ////////////////////////////////
    id_action         := IBDataSet_InstructionsID_ACTION.Value;
    Window_ClassName  := IBDataSet_InstructionsWINDOW_NAME.Value;
    Control_ClassName := IBDataSet_InstructionsCONTROL_NAME.Value;
    Control_Caption   := IBDataSet_InstructionsCONTROL_CAPTION.Value;
    FilePath          := IBDataSet_InstructionsAPP_PATH.Value;
    WaitTime          := IBDataSet_InstructionsWAITTIME.Value;
    Comment           := IBDataSet_InstructionsCOMMENT.Value;

    On_Control_Click_x := IBDataSet_InstructionsON_CONTROL_CLICK_LEFT.Value;
    On_Control_Click_y := IBDataSet_InstructionsON_CONTROL_CLICK_TOP.Value;
    On_Window_Click_x  := IBDataSet_InstructionsON_WINDOW_CLICK_LEFT.Value;
    On_Window_Click_y  := IBDataSet_InstructionsON_WINDOW_CLICK_TOP.Value;
    Window_Pos_x       := GetWindowPos(Window_ClassName, Control_Caption).X;
    Window_Pos_y       := GetWindowPos(Window_ClassName, Control_Caption).Y;

    // Znajdź okno o podanej klasie
    Foreground := FindWindow(PChar(Window_ClassName), nil);
    frmdm.Debug(Window_ClassName + ' - ' + IntToStr(Foreground));

    if Foreground <> 0 then // znalezione okno
      if Pos('#', Window_ClassName) = 0 then // jeśli okno to nie popup
        ActivateWindow(Foreground); // Wysuń na wierzch / przywróc


    ////////////////////////////////////////////////
    // Poniższy kod dotyczy operacji, które muszą
    // zostać wykonane na danym oknie
    ////////////////////////////////////////////////

    // ten warunek eliminuje instrukcje,
    // które nie wymagają operowania na oknie
    if (id_action <> Action_RunFile) and (id_action <> Action_Condition)
    and (id_action <> Action_WaitTime) and (id_action <> Action_MouseMove)
    and (id_action <> Action_TypeText) and (id_action <> Action_SpecialKey) then
    begin
      if (Foreground = 0) then // Nie znaleziono okna
      begin
        Tray.BalloonHint(AppName, 'Nie znaleziono okna [' + Window_ClassName + ']!', btWarning, 5000, True);
        Application.MessageBox(PChar('Nie znaleziono okna [' + Window_ClassName + ']!'), 'Błąd', MB_ICONWARNING);
        Break; // koniec
      end;

      kbmControlInfo.Close;
      kbmControlInfo.Open;

      frmdm.Debug(Window_ClassName + ' - Pobranie uchwytów obiektów');
      Tray.BalloonHint(AppName, 'Pobieram listę obiektów...', btInfo, 5000, True);
      EnumChildWindows(ForeGround, @EnumChildWinProc, 0);
      frmdm.Debug(Window_ClassName + ' - Pobrano uchwyty obiektów');


      frmdm.Debug(Window_ClassName + ' (' + Control_ClassName +'): X = ' + IntToStr(kbmControlInfoControlPos_Left.Value));
      frmdm.Debug(Window_ClassName + ' (' + Control_ClassName +'): Y = ' + IntToStr(kbmControlInfoControlPos_Top.Value));
      Application.ProcessMessages;

      Tray.BalloonHint(AppName, 'Szukam obiektu...', btInfo, 5000, True);

      ControlFound := False;
      // 1. Ma klasę i ma nie zmieniony caption
      if (Control_ClassName <> '') and (Control_Caption <> '') then
        ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName;ControlCaption',
        VarArrayOf([Window_ClassName, Control_ClassName, Control_Caption]), []);

      // 2. ma klasę ale nie ma captiona
      if not ControlFound then
        if (Control_ClassName <> '') and (Control_Caption = '') then
          ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName', VarArrayOf([Window_ClassName, Control_ClassName]), []);

      // 3. ma klasę i inny caption
      if not ControlFound then
        if (Control_ClassName <> '') then
          ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlName', VarArrayOf([Window_ClassName, Control_ClassName]), []);

      // znaleziono ale caption jest inny to oznacz jako nie znaleziony
      if ControlFound then
        if Control_Caption <> kbmControlInfoControlCaption.Value then
          ControlFound := False
        else
          if Control_Name <> kbmControlInfoControlName.Value then
            ControlFound := kbmControlInfo.Locate('WindowClass_Name;ControlClass;ControlName;ControlCaption', VarArrayOf([Window_ClassName, Control_ClassName, Control_Name, Control_Caption]), []);

      kmbControl_Pos_x := kbmControlInfoControlPos_Left.Value; // pozycja X kontrolki
      kmbControl_Pos_y := kbmControlInfoControlPos_Top.Value;  // pozycja Y kontrolki

      if ControlFound then
        frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + ') - obiekt znaleziony')
      else
        frmdm.Debug(Window_ClassName + ' (' + Control_ClassName + ') - obiekt nie znaleziony');

      Application.ProcessMessages;

      if ControlFound then
        MouseAction('Move', kmbControl_Pos_X + On_Control_Click_X, On_Control_Click_Y + kmbControl_Pos_Y)
      else
        MouseAction('Move', Window_Pos_X + On_Window_Click_X, Window_Pos_Y + On_Window_Click_Y);
    end;
    ////////////////////////////////
    ///  KONIEC KODU 'OKIENKOWEGO'
    ////////////////////////////////


    case ID_ACTION of

      Action_MouseMove: // Animacja ruchów myszki
        begin
          if not Animate_MouseMovement then
            break;
        end;

      Action_SetCursorPos: // Ustaw pozycję kursora
        begin
          Tray.BalloonHint(AppName, 'Ustawiam pozycję kursora', btInfo, 5000, True);
          MouseAction('SetPos', On_Window_Click_X, On_Window_Click_Y);
        end;

      Action_WaitTime: // Czekaj
        begin
          Sleep(WaitTime);
        end;

      Action_MouseLeftClick: // Lewy przycisk myszy
        begin
          Tray.BalloonHint(AppName, 'LPM', btInfo, 5000, True);
          MouseAction('LeftClick', 0, 0);
        end;

      Action_MouseRightClick: // Prawy przycisk myszy
        begin
          Tray.BalloonHint(AppName, 'PPM', btInfo, 5000, True);
          MouseAction('RightClick', 0, 0);
        end;

      Action_MouseMiddleClick: // Środkowy przycisk myszy
        begin
          Tray.BalloonHint(AppName, 'ŚPM', btInfo, 5000, True);
          MouseAction('MiddleClick', 0, 0);
        end;

      Action_MouseDBClick: // Podwójne kliknięcie
        begin
          Tray.BalloonHint(AppName, 'Otwieram...', btInfo, 5000, True);
          MouseAction('DBClick', 0, 0);
        end;

      Action_RunFile: // Uruchom plik
        begin
          // Jeśli włączona opcja jednej instancji programu
          // a 1 proces jest już uruchomiony
          if (IBDataSet_InstructionsAPP_RESTART.Value = 1)
          and processExists(ExtractFileName(FilePath)) then
            KillTask(ExtractFileName(FilePath)); // Zakończ proces

          Application.ProcessMessages;
          Sleep(50);

          // Jeśli wyłączona opcja wielu instancji
          // a proces jest już uruchomiony to idz do nast. instrukcji
          if (IBDataSet_InstructionsMULTIPLE_INSTANCES.Value <> 0)
          and not processExists(ExtractFileName(FilePath)) then
          begin // uruchom plik
            Tray.BalloonHint(AppName, 'Uruchamiam plik...', btInfo, 5000, True);
            if not RunFile(FilePath) then
            begin
              Tray.BalloonHint(AppName, 'Nie znaleziono pliku źródłowego!', btWarning, 5000, True);
              Break;
            end;
          end;
        end;

      Action_Condition: // Sprawdzanie warunku
        begin
          Tray.BalloonHint(AppName, 'Sprawdzam warunek...', btInfo, 5000, True);

          if Check_Condition(IBDataSet_InstructionsID_C.Value) then
          begin
            if not IBDataSet_Instructions.Locate('CONDITION_IDENTIFICATOR', IBDataSet_InstructionsID_TRUE.Value, []) then
            begin
              Tray.BalloonHint(AppName, 'Nie znaleziono warunku!', btWarning, 5000, True);
              Application.MessageBox(PChar('Nie znaleziono identyfikatora warunku PRAWDA [' + frmdm.IBDataSet_CheckConditionID_TRUE.Value + ']!'), 'Nie znaleziono identyfikatora warunku', MB_ICONWARNING);
              Break;
            end else
            begin
              Tray.BalloonHint(AppName, 'Warunek spełniony', btInfo, 5000, True);
              IBDataSet_Instructions.Prior;
            end;
          end else
          begin
            if not IBDataSet_Instructions.Locate('CONDITION_IDENTIFICATOR', IBDataSet_InstructionsID_FALSE.Value, []) then
            begin
              Tray.BalloonHint(AppName, 'Nie znaleziono warunku!', btWarning, 5000, True);
              Application.MessageBox(PChar('Nie znaleziono identyfikatora warunku FAŁSZ [' + frmdm.IBDataSet_CheckConditionID_FALSE.Value + ']!'), 'Nie znaleziono identyfikatora warunku', MB_ICONWARNING);
              Break;
            end else
            begin
              Tray.BalloonHint(AppName, 'Warunek nie spełniony', btInfo, 5000, True);
              IBDataSet_Instructions.Prior;
            end;
          end;
        end;

      Action_SpecialKey: // Klawisze specjalne
        begin
          SendSpecialKey(IBDataSet_InstructionsCOMMENT.Value); // wyślij klawisz
        end;

      Action_TypeText: // Emulowanie wpisywanego tekstu
        begin
          if ControlFound then // Jeśli kontrolka znaleziona
          begin
            if IBDataSet_InstructionsINPUTTEXT_MODE.Value = 1 then
              Keyboard_SendText(Comment) // Wpisz tekst
            else begin // Wyślij do kursora
              SendMessage(kbmControlInfoHandle.Value, WM_SETTEXT, 0, integer(PChar(Comment)));
              SendMessage(kbmControlInfoHandle.Value, EM_SETSEL, length(Comment), length(Comment));
            end;
            Tray.BalloonHint(AppName, 'Wysłano tekst', btInfo, 5000, True);
          end else
          begin
            GetCursorPos(CursorPos);
            Target := WindowFromPoint(CursorPos);
            if Target <> 0 then
            begin
              if IBDataSet_InstructionsINPUTTEXT_MODE.Value = 1 then
                Keyboard_SendText(Comment) // Wpisz tekst
              else begin // Wyślij do kursora
                SendMessage(Target, WM_SETTEXT, ord(True), LPARAM(PChar(Comment)));
                SendMessage(Target, EM_SETSEL, length(Comment), length(Comment));
              end;
              Tray.BalloonHint(AppName, 'Wysłano tekst', btInfo, 5000, True);
            end else
            begin
              Application.MessageBox('Nie wysłano tekstu [Nie można odwołać się do obiektu]', 'Błąd wysyłania tekstu', MB_ICONWARNING);
              Tray.BalloonHint(AppName, 'Nie wysłano tekstu [Nie można odwołać się do obiektu]', btWarning, 5000, True);
            end;
          end;

        end;
    end;

    if id_action <> Action_WaitTime then
      Sleep(WaitTime);
    IBDataSet_Instructions.Next;
  end;

  StopSchema; // Koniec schematu
  AllowPlay(True);
  Beep;
  Tray.BalloonHint(AppName, 'Zakończono odtwarzanie.', btInfo, 5000, True);
end;
1
    if (id_action <> Action_RunFile) and (id_action <> Action_Condition)
    and (id_action <> Action_WaitTime) and (id_action <> Action_MouseMove)
    and (id_action <> Action_TypeText) and (id_action <> Action_SpecialKey) then

Lepiej:

if (not (id_action in [Action_RunFile, Action_Condition, ...])) Then

```delphi Window_Pos_x, Window_Pos_y: integer; ``` Lepiej: ```delphi Var WindowPos: TPoint; ```
```delphi frmdm.Debug(Window_ClassName + ' (' + Control_ClassName +'): X = ' + IntToStr(kbmControlInfoControlPos_Left.Value)); ``` Lepiej: ```delphi frmdm.Debug(Format('%s (%s): X = %d', [Window_ClassName, Control_ClassName, kbmControlInfo...])); ``` Jeszcze lepiej: ```delphi frmdm.Debug('%s (%s): X = %d', [Window_ClassName...]); ``` Z deklaracją `Debug` jako: ```delphi Procedure TSomething.Debug(const Format: String; Args: Array of Const); ```
0

Wielkie dzięki za wszelkie wskazów dot. powyższego kodu, na pewno zapamiętam te rady i wykorzystam w przyszłych projektach.

Mam pytanie, w jaki sposób najlepiej będzie 'zaczytywać' kliknięcia myszki w ten sposób, aby pobrać osobno każde ze zdarzeń czyli:

Event Delay
LeftButtonDown
1000ms - czas trzymania wciśnietego przycisku
LeftButtonUp

Ale wziąć również pod uwagę możliwość wykrycia dwukrotnego kliknięcia na przykładzie poniższego kodu:

function MouseHookProc(Code : integer; WParam : WPARAM; LParam : LPARAM) : LRESULT; stdcall;
var
  HookStruct : PMOUSEHOOKSTRUCT;
begin
  HookStruct := Pointer(LParam);
  case Code of
    HC_ACTION :
      begin

        if vars.Hook_Active and not HookPaused then
        begin
          Case wParam of
            WM_LBUTTONDOWN: begin
                               frmMenu.Timer_RecordMousePath.Enabled := False;
                               GetDataFromCursor;
                            end;

            WM_LBUTTONUP:
              If frmMenu.TimerMouse.Enabled then
              Begin //jeśli w limicie czasu na podwójny klik wystąpiło drugie lewo-kliknięcie, to uznanie kliku jako podwójnego
                frmMenu.TimerMouse.Enabled:=false;

                frmMenu.AddAction(Action_MouseDBClick, '', 0, 0, _def_go_next_instruction_deelay, 'Otwórz'); // dbclick
              end else
                frmMenu.TimerMouse.Enabled:=true; //interwał timera określa limit czasu na podwójny klik. Gdy limit czasu minie, to w zdarzeniu TimerMouseClickTimer uznanie kliku jako pojedynczego

             WM_RBUTTONDOWN: begin
                                GetDataFromCursor;
                                frmMenu.AddAction(Action_MouseRightClick, '', 0, 0, _def_go_next_instruction_deelay, 'PPM');
                             end;

             WM_MBUTTONDOWN: begin
                                GetDataFromCursor;
                                frmMenu.AddAction(Action_MouseMiddleClick, '', 0, 0, _def_go_next_instruction_deelay, 'ŚPM');

                             end;
          End;
        end;
      end
  end;
  Result := CallNextHookEx(MouseHookHandle, Code, WParam, LParam);
end;

Kod timera:

procedure TfrmMenu.TimerMouseTimer(Sender: TObject);
begin
  TimerMouse.Enabled:=false; //minął limit czasu na podwójny lewo-klik

  AddAction(Action_MouseLeftClick, '', 0, 0, _def_go_next_instruction_deelay, 'LPM');
end;

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