Entwickler-Ecke

Windows API - Message Window erstellen (für asnychrone WSA-Aufrufe)


Flamefire - Fr 14.08.09 11:11
Titel: Message Window erstellen (für asnychrone WSA-Aufrufe)
Ich brauche für die WinSock API ein Handle. Oder besser: Ein fenster was meine asynchronen nachrichten behandelt.

Wie kann ich ein "Fenster" erstellen, dass möglichst wenig Ressourcen beansprucht und nur eine MessageSchleife hat?
Habe da CreateWindowEx und AllocateHWND gelesen, weiß aber nicht, wie ich die verwende. Bzw. stand dabei dass AllocateHWND auch nur createWindowEx benutzt.
Was also verwenden und wie?

Hätte z.Zt. Das hier:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
procedure TWS.Execute;
var
  wc: TWndClassEx;
  msg: TMsg;
begin
  with wc do begin
    cbSize:=SizeOf(TWndClassEx);
    Style:=CS_HREDRAW or CS_VREDRAW;
    lpfnWndProc:=@WndProc;
    cbClsExtra:=0;
    cbWndExtra:=0;
    hbrBackground:=GetSysColorBrush(COLOR_3DFACE);
    lpszMenuName:=nil;
    lpszClassName:='WindowClass';
    hIconSm:=0;
    hInstance:=SysInit.hInstance;
    hIcon:=0;
    hCursor:=0;
  end;

  {register Window}
  RegisterClassEx(wc);
  FwndHandle:=CreateWindowEx(0,'WindowClass','',WS_POPUP ,0,0,0,0,0,0,hInstance,nil);
  while getmessage(msg,0,0,0do //MessageSchleife
  begin
    translatemessage(msg);
    dispatchmessage(msg);
  end;
end;

procedure TWS.WndProc(wnd: HWND; uMsg: Cardinal; wp: Integer; lp: Integer):Integer; stdcall;
begin
  //handel Messages
end;


Moderiert von user profile iconNarses: Titel erweitert.


Narses - Fr 14.08.09 11:39

Moin!

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Ich brauche für die WinSock API ein Handle. Oder besser: Ein fenster was meine asynchronen nachrichten behandelt.
Mein Tipp: Lass das bleiben und mach es mit blocking-calls und Threads, das ist die stabilere Variante. :idea:

cu
Narses


Flamefire - Fr 14.08.09 11:48

ok und wie funktioniert das im Blocking mode?
bisher habe ich ne schöne wrapper klasse, die mir ein "event" auslöst, wodurch ich dann mit einer anderen funktion mittels recv die empfangenen Daten bekomme

muss dazu sagen, ich habe bis zu 3 client und 2 server sockets


Narses - Fr 14.08.09 12:04

Moin!

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
ok und wie funktioniert das im Blocking mode?
Nimm die Indy-Kompos IdTCPClient und IdTCPServer, die sind schon so designed (schnell-fertig-werden-Ansatz). Alternativ schau einfach in den Source der Compos, dann kannst du sehen wie die´s konkret machen. Grober Fahrplan: gib dem Socket beim Erstellen nicht das AsyncFlag mit, dann blockieren die Aufrufe, bis ein Ergebnis vorliegt. Das ganze dann in Threads, fertig.

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
muss dazu sagen, ich habe bis zu 3 client und 2 server sockets
Und? Sehe ich keine Probleme mit (genug RAM/CPU-Power der Maschine vorausgesetzt, wenn du fett Datenlast ziehen willst). :nixweiss:

cu
Narses


Flamefire - Fr 14.08.09 12:48

hm...wie verwende ich die Indys (10)?
Ich sehe dort keine Recv ereignisse.
Ich hatte in Delphi 7 mal TServerSocket verwendet und bin damit super klargekommen. Aber die gibts ja nicht mehr :-(


Narses - Fr 14.08.09 13:10

Moin!

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
hm...wie verwende ich die Indys (10)?
Indy-Tuts gibt´s doch wie Sand-am-Meer. :nixweiss:

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Ich sehe dort keine Recv ereignisse.
Ähm, genau davon reden wir gerade? Keine Ereignisse, sondern blocking-calls und Threads? :gruebel:

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Ich hatte in Delphi 7 mal TServerSocket verwendet und bin damit super klargekommen. Aber die gibts ja nicht mehr :-(
Geben tut´s die schon noch, aber durch den Unicode-String funktionieren die Sockets in D2009 nicht mehr ganz korrekt.

cu
Narses


Flamefire - Fr 14.08.09 13:25

hm. finde aber keins, dass zu meinem Problem passt

z.B. verbinde ich zu einem Server:

Delphi-Quelltext
1:
2:
3:
4:
IdClient.Host:=...
IDClient.Port:=...
IDClient.Connect;
IDClient.Socket.ReadBytes(Buffer,9999);


obwohl laut WPEPro Daten da sind, wird der Aufruf nicht zuende geführt
hättest du ein Bsp, wie man den Client und server korrekt verwendet?

Edit: ok. Aufruf würde erst nach 9999 Bytes ausgeführt. gut so weit
fehlt mir trotzdem noch, wie ich die Indy kapsle.
Hat die nicht Intern schon einen Thread, oder muss ich den erst selbst erstellen?

Außerdem fehlt mir die Möglichkeit einen Buffer, der über Pointer und länge gegeben ist zu senden.
Hier brauch ich immer ein TBytes.


Xentar - Fr 14.08.09 13:30

Bei Indy liegen doch Beispiele bei

Für den Client solltest du einen eigenen TThread aufmachen, der zyklisch ein Read aufruft.


Flamefire - Fr 14.08.09 13:49

Ok danke
funktioniert soweit
mein problem jetzt noch: wie kann ich alles, was bisher emfangen wurde lesen?
weil bei read muss ich immer ne zahl mitgeben
da ich die größe der pakete nicht kenne müsste die 1 sein, da sonst der socket blockiert.
das ist aber sehr ineffizient.
also woher bekomme ich die akutelle empfangsbuffergröße?

Hat sich erledigt. Bekomme die größe aus den ersten bytes des pakets