caused
2009-08-02 00:32:31
I needed a small chat thingy, which i could use to stay in contact with my brother :'D…
This is basicly a chat client and server, but its intended to only connect 2 pc's…
It Runs in the Systray and is designed to not annoy the user too much :).
Usage:
Start 2chat.
Put in a Name.
@ CLient Ip, there comes the ip of the PC you want to chat with.
Do that for both pc's and you're set.
I' suggest to put a shortcut to the programme in the startup folder.
The advantage of this kind of chat is:
1. It works even if your internet is down.
2. Its simple
3. Its not annoying.. like … uhm… msn…
x. It also has an auto AFK feature, so you can see if your client is currently on their pc.
~caused
// sauce for anyone interested :3…
This is basicly a chat client and server, but its intended to only connect 2 pc's…
It Runs in the Systray and is designed to not annoy the user too much :).
Usage:
Start 2chat.
Put in a Name.
@ CLient Ip, there comes the ip of the PC you want to chat with.
Do that for both pc's and you're set.
I' suggest to put a shortcut to the programme in the startup folder.
The advantage of this kind of chat is:
1. It works even if your internet is down.
2. Its simple
3. Its not annoying.. like … uhm… msn…
x. It also has an auto AFK feature, so you can see if your client is currently on their pc.
~caused
// sauce for anyone interested :3…
unit sauce;
//{$APPTYPE CONSOLE}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdTCPConnection, IdTCPClient, IdBaseComponent, IdComponent,
IdTCPServer, StdCtrls, ExtCtrls,IniFiles, ShellApi, ToolWin, ComCtrls,CoolTrayIcon,
TextTrayIcon, Menus, ImgList, MPlayer,MMSystem ;
const
WM_NOTIFYICON = WM_USER+333;
type
TForm1 = class(TForm)
IdTCPServer1: TIdTCPServer;
Button1: TButton;
IdTCPClient1: TIdTCPClient;
Memo1: TMemo;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Button3: TButton;
CoolTrayIcon1: TCoolTrayIcon;
PopupMenu1: TPopupMenu;
Exit1: TMenuItem;
ResetUsernameIP1: TMenuItem;
Timer2: TTimer;
Timer3: TTimer;
ProgressBar1: TProgressBar;
Label3: TLabel;
Label4: TLabel;
Timer4: TTimer;
ImageList1: TImageList;
RichEdit1: TRichEdit;
Timer5: TTimer;
Timer1: TTimer;
Label5: TLabel;
Timer6: TTimer;
Timer7: TTimer;
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Exit1Click(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
procedure Timer3Timer(Sender: TObject);
procedure CoolTrayIcon1Click(Sender: TObject);
procedure Memo1Click(Sender: TObject);
procedure RichEdit1Click(Sender: TObject);
procedure RichEdit1Change(Sender: TObject);
procedure Edit1Change(Sender: TObject);
procedure Edit2Change(Sender: TObject);
procedure ResetUsernameIP1Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Timer4Timer(Sender: TObject);
procedure RichEdit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure RichEdit1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormShow(Sender: TObject);
procedure Timer5Timer(Sender: TObject);
procedure Label5Click(Sender: TObject);
procedure Timer6Timer(Sender: TObject);
procedure Timer7Timer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
private
public
end;
var
Form1: TForm1;
Username,ClientIp : String;
ini: TIniFile;
xw,xh : Integer;
pro : Integer;
rdy2go : Boolean;
sendit : Boolean;
countit : Integer;
FirstRun: Boolean;
TrayBlink : Boolean;
CurPos : TPOINT;
implementation
{$R *.dfm}
function DeleteLineBreaks(const S: string): string;
var
Source, SourceEnd: PChar;
begin
Source := Pointer(S) ;
SourceEnd := Source + Length(S) ;
while Source < SourceEnd do
begin
case Source^ of
#10: Source^ := #32;
#13: Source^ := #32;
end;
Inc(Source) ;
end;
Result := S;
End;
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
Command : String;
WinPath: array[0..MAX_PATH + 1] of char;
winpatch2 : String;
testxx : PAnsiChar;
begin
Command := AThread.Connection.ReadLn;
If not(length(command) < 1) then
begin
Timer1.Enabled := TRUE;
pro := 0;
Memo1.Text := Memo1.Text+#13+#10+Command;
SendMessage(Memo1.Handle,WM_VSCROLL,SB_BOTTOM,0);
GetWindowsDirectory(WinPath,MAX_PATH);
winpatch2 := StrPas(WinPath);
winpatch2 := winpatch2+'/Media/NOTIFY.WAV';
testxx := PAnsiChar(winpatch2);
sndPlaySound(testxx,SND_SYNC);
//MessageBeep(1);
Form1.Visible := True;
end;
end;
function GetTaskbarHeight: integer;
var
SysTray: Windows.HWND;
Rect: TRect;
begin
Result := -1;
SysTray := FindWindow('Shell_TrayWnd', nil);
If SysTray <> INVALID_HANDLE_VALUE then begin
If GetWindowRect(SysTray, Rect) then begin
Result := Screen.Height - Rect.Top;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CoolTrayIcon1.IconVisible:= True;
FirstRun := True;
CoolTrayIcon1.MinimizeToTray := True;
CoolTrayIcon1.IconIndex := 1;
xw:=screen.Monitors[0].Width;
xh:=screen.Monitors[0].Height;
Label4.Caption := 'Init/Connect';
IdTCPServer1.Active := True;
ini:=TIniFile.create(ExtractFilePath(ParamStr(0))+'startup.ini');
Username := ini.ReadString('User','Name','0');
ClientIp := ini.ReadString('ConnectTo','IP','0');
ini.free;
rdy2go := False;
GetCursorPos(CurPos); // FÜR AFK MODUS
Button1.Enabled:=False;
If (ClientIP <> '0') AND (Username <> '0') then
begin
Memo1.Visible:= True;
RichEdit1.Visible := True;
Button1.Visible := True;
Button3.Visible:=False;
Edit1.Visible:=False;
Edit2.Visible:=False;
Label1.Visible :=False;
Label2.Visible:=False;
Form1.Left := xw-Form1.ClientWidth;
Form1.Top := xh-Form1.ClientHeight-GetTaskbarHeight;
rdy2go := True;
end else
begin
Memo1.Visible:= False;
RichEdit1.Visible := False;
Button1.Visible := False;
Button3.Visible:=True;
Edit1.Visible:=True;
Edit2.Visible:=True;
Label1.Visible :=True;
Label2.Visible:=True;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
buff : String;
begin
IF IdTCPClient1.Connected then
begin
buff := DeleteLineBreaks(RichEdit1.Text);
Memo1.Text := Memo1.Text+#13+#10+username+'> '+buff;
try
IdTCPClient1.WriteLn(username+'> '+buff);
except
label4.caption := 'NOT SENT';
end;
RichEdit1.Clear;
RichEdit1.SetFocus;
RichEdit1.SelStart := 0;
RichEdit1.Lines.Delete(0);
If FirstRun then
begin
Memo1.Lines.Delete(0);
FirstRun := FALSE;
end;
Button1.Enabled := FALSE;
Timer5.Enabled:= TRUE;
SendMessage(Memo1.Handle,WM_VSCROLL,SB_BOTTOM,0);
end else
begin
Button1.enabled := False;
Label4.Caption := 'Connecting';
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
If rdy2go then
begin
IF TrayBlink then
begin
CoolTrayIcon1.IconIndex := 3;
TrayBlink := FALSE;
end else
begin
CoolTrayIcon1.IconIndex := 2;
TrayBlink := TRUE;
end;
end;
end;
function IsWrongIP(ip: string): Boolean;
var
z, i: byte;
st: array[1..3] of byte;
const
ziff = ['0'..'9'];
begin
st[1] := 0;
st[2] := 0;
st[3] := 0;
z := 0;
Result := False;
for i := 1 to Length(ip) do if ip[i] in ziff then
else
begin
if ip[i] = '.' then
begin
Inc(z);
if z < 4 then st[z] := i
else
begin
IsWrongIP := True;
Exit;
end;
end
else
begin
IsWrongIP := True;
Exit;
end;
end;
if (z <> 3) or (st[1] < 2) or (st[3] = Length(ip)) or (st[1] + 2 > st[2]) or
(st[2] + 2 > st[3]) or (st[1] > 4) or (st[2] > st[1] + 4) or (st[3] > st[2] + 4) then
begin
IsWrongIP := True;
Exit;
end;
z := StrToInt(Copy(ip, 1, st[1] - 1));
if (z > 255) or (ip[1] = '0') then
begin
IsWrongIP := True;
Exit;
end;
z := StrToInt(Copy(ip, st[1] + 1, st[2] - st[1] - 1));
if (z > 255) or ((z <> 0) and (ip[st[1] + 1] = '0')) then
begin
IsWrongIP := True;
Exit;
end;
z := StrToInt(Copy(ip, st[2] + 1, st[3] - st[2] - 1));
if (z > 255) or ((z <> 0) and (ip[st[2] + 1] = '0')) then
begin
IsWrongIP := True;
Exit;
end;
z := StrToInt(Copy(ip, st[3] + 1, Length(ip) - st[3]));
if (z > 255) or ((z <> 0) and (ip[st[3] + 1] = '0')) then
begin
IsWrongIP := True;
Exit;
end;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
ini:=TIniFile.create(ExtractFilePath(ParamStr(0))+'startup.ini');
// If Username = '0' then
// begin
ini.WriteString('User','Name',Edit1.Text);
// end;
If not IsWrongIP(Edit2.Text) then
ini.WriteString('ConnectTo','IP',Edit2.Text)
else
Edit2.Text := 'INVALID IP!!';
Username := ini.ReadString('User','Name','0');
ClientIp := ini.ReadString('ConnectTo','IP','0');
If not((ClientIP = '0')AND not(Username='0')) then
begin
Memo1.Visible:= True;
RichEdit1.Visible := True;
Button1.Visible := True;
Button3.Visible:=False;
Edit1.Visible:=False;
Edit2.Visible:=False;
Label1.Visible :=False;
Label2.Visible:=False;
Form1.Left := xw-Form1.ClientWidth;
Form1.Top := xh-Form1.ClientHeight-GetTaskbarHeight;
rdy2go := True;
end;
ini.free;
end;
procedure TForm1.Exit1Click(Sender: TObject);
begin
Application.Terminate;
end;
procedure TForm1.Timer2Timer(Sender: TObject);
begin
If rdy2go then
begin
pro := pro +1;
ProgressBar1.Position := pro;
If pro >= 10 then
begin
Form1.Visible := False;
Timer2.Enabled := False;
pro := 0;
end;
end;
end;
procedure TForm1.Timer3Timer(Sender: TObject);
begin
If rdy2go then
begin
Timer2.Enabled := True;
end;
end;
procedure TForm1.CoolTrayIcon1Click(Sender: TObject);
begin
Form1.Visible := True;
Timer1.Enabled := FALSE;
If not CoolTrayIcon1.IconIndex = 0 then
CoolTrayIcon1.IconIndex := 2;
end;
procedure TForm1.Memo1Click(Sender: TObject);
begin
Timer2.Enabled := False;
ProgressBar1.Position := pro;
pro := 0;
Timer1.Enabled := FALSE;
If not CoolTrayIcon1.IconIndex = 0 then
CoolTrayIcon1.IconIndex := 2;
end;
procedure TForm1.RichEdit1Click(Sender: TObject);
begin
Timer2.Enabled := False;
ProgressBar1.Position := pro;
pro := 0;
If not CoolTrayIcon1.IconIndex = 0 then
CoolTrayIcon1.IconIndex := 2;
end;
procedure TForm1.RichEdit1Change(Sender: TObject);
begin
Timer2.Enabled := False;
ProgressBar1.Position := pro;
pro := 0;
Timer1.Enabled := FALSE;
If not CoolTrayIcon1.IconIndex = 0 then
CoolTrayIcon1.IconIndex := 2;
end;
procedure TForm1.Edit1Change(Sender: TObject);
begin
Timer2.Enabled := False;
end;
procedure TForm1.Edit2Change(Sender: TObject);
begin
Timer2.Enabled := False;
end;
procedure TForm1.ResetUsernameIP1Click(Sender: TObject);
begin
Memo1.Visible:= False;
RichEdit1.Visible := False;
Button1.Visible := False;
Button3.Visible:=True;
Edit1.Visible:=True;
Edit2.Visible:=True;
Label1.Visible :=True;
Label2.Visible:=True;
Form1.Visible := True;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
ProgressBar1.Position := pro;
pro := 0;
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
ProgressBar1.Position := pro;
pro := 0;
Timer1.Enabled := FALSE;
If not CoolTrayIcon1.IconIndex = 0 then
CoolTrayIcon1.IconIndex := 2;
end;
procedure TForm1.Timer4Timer(Sender: TObject);
begin
If rdy2go then
begin
If not IdTCPClient1.Connected then
begin
Button1.Enabled := FALSE;
Label4.Caption := 'Connecting';
IdTCPClient1.Host := ClientIp;
IdTCPClient1.Port := 9535;
CoolTrayIcon1.IconIndex := 0;
try
IdTCPClient1.Connect(700);
except
CoolTrayIcon1.IconIndex := 0;
end;
end;
If IdTCPCLient1.Connected then
begin
Label4.Caption := 'Connected';
CoolTrayIcon1.IconIndex := 2;
Button1.Enabled := TRUE;
end;
end;
end;
procedure TForm1.RichEdit1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Timer1.Enabled := FALSE;
If not CoolTrayIcon1.IconIndex = 0 then
CoolTrayIcon1.IconIndex := 2;
if GetAsyncKeyState(VK_LCONTROL) <> 0 then
begin
sendit := FALSE
// WriteLn('down')
end else
sendit := TRUE;
end;
procedure TForm1.RichEdit1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Timer1.Enabled := FALSE;
If not CoolTrayIcon1.IconIndex = 0 then
CoolTrayIcon1.IconIndex := 2;
If IDtcpclient1.Connected AND Button1.enabled then
begin
If (GetAsyncKeyState(VK_RETURN)<>0) AND sendit then
begin
Button1.Click;
RichEdit1.SelStart := 0;
end;
end;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
pro := 0;
end;
procedure TForm1.Timer5Timer(Sender: TObject);
begin
Button1.Enabled := TRUE;
Timer5.Enabled := FALSE;
end;
procedure TForm1.Label5Click(Sender: TObject);
begin
Form1.Visible := FALSE;
end;
procedure TForm1.Timer6Timer(Sender: TObject);
var
checkitx : TPOINT;
begin
If rdy2go AND IDtcpclient1.Connected then
begin
GetCursorPos(checkitx);
if (CurPos.x = checkitx.x)AND (CurPos.y = checkitx.y) then
begin
Memo1.Text := Memo1.Text+#13+#10+'< '+username+' is AFK';
SendMessage(Memo1.Handle,WM_VSCROLL,SB_BOTTOM,0);
try
IdTCPClient1.WriteLn('< '+username+' is AFK');
except
label4.caption := 'NOT SENT';
end;
Timer6.Enabled := FALSE;
Timer7.Enabled := TRUE;
end;
GetCursorPos(CurPos);
end;
end;
procedure TForm1.Timer7Timer(Sender: TObject);
var
tempcur : TPOINT;
begin
GetCursorPos(tempcur);
If not (tempcur.x = CurPos.x) AND not(tempcur.y = CurPos.y) then
begin
Memo1.Text := Memo1.Text+#13+#10+'< '+username+' is BACK';
SendMessage(Memo1.Handle,WM_VSCROLL,SB_BOTTOM,0);
try
IdTCPClient1.WriteLn('< '+username+' is BACK');
except
label4.caption := 'NOT SENT';
end;
Timer6.Enabled := TRUE;
Timer7.Enabled := FALSE;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
IdTCPCLient1.Disconnect;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
IdTCPCLient1.Disconnect;
end;
end.