Auf Button-Click UND Windows-Socket-Nachricht reagieren

Onkel Schuppig

Erfahrenes Mitglied
Hallo,
ich habe einen kleines Testprogramm, welches als einzige Funktion einen "Beenden"-Button hat. Desweiteren soll es noch einen Socket eröffnen, der an einem bestimmten Port auf Nachrichten von außen wartet.
Mein Problem ist die Parallelität: Das Programm soll auf Betätigung des Buttons UND auf Eingang einer Nachricht reagieren.
Ich kann bisher nur auf Buttons oder nur auf Nachrichten reagieren, nicht beides.
Die "accept"-Funktion des Sockets blockiert alles.
 
Du kannst die Sockets auf non-blocking setzen (WSAAsyncSelect). Dann bekommst du jedesmal, wenn ein Ereignis am Socket auftritt eine Windows-Nachricht gesendet.
Das erspart dir einen extra Thread aufzumachen.
 
Wo setze ich denn an mit WSAAsyncSelect()? Mein bisheriger Code-Abschnitt sieht so aus:

Code:
void SocketServer::GetMsg() {
  // Call accept() to accept the connection request. 
  // This call will block until a connection request arrives.
  sockaddr_in sa_client;
  int sa_length = sizeof(sa_client);
  ClientSock = accept(ServerSock, (sockaddr*)&sa_client, &sa_length);

  if (ClientSock == INVALID_SOCKET) {
    Error("Verbindung zum Client fehlgeschlagen");
  }

  if (recv(ClientSock, puffer, bufsize, 0) == SOCKET_ERROR)
    Error("Empfang klappt nicht");
}
 
In meinem Server-Code habe ich nur ein WSAAsyncSelect, und zwar direkt nach dem listen-Aufruf. Ich meine, mit accept würde der neu erzeugte Socket die Eigenschaft erben.
(Ich bekomme dann von allen Clients jeweils eine Windows-Nachricht, wenn sich etwas tut).

Ansonsten würde ich das da direkt nach accept einfügen.
 
Nehmen wir mal an, ich schreibe es nun so:
int success = WSAAsyncSelect(my_socket, my_window, my_message, FD_ACCEPT);

Jetzt fehlt mir noch die Verknüpfung zur Applikations-Nachrichtenliste. Was kann ich denn als "my_message" - Argument angeben und mit welcher Zeile muss dann die Message-Map erweitert werden? Message-Maps erweitern kenne ich nur in Verbindung mit "Controls" (rechte Maustaste, Ereignishandler hinzufügen).
 
Der Tipp bringt mich schon gut weiter. Habe es folgendermassen realisiert:

Code:
static UINT NEAR WM_SOCKET_MESSAGE = RegisterWindowMessage("SOCKET_MESSAGE");

BEGIN_MESSAGE_MAP(CSocketTestDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
  ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
  ON_REGISTERED_MESSAGE(WM_SOCKET_MESSAGE, OnSocketMessage)
END_MESSAGE_MAP()

Jetzt kompiliert die Zeile "ON_REGISTERED_MESSAGE..." in der Message-Map nicht. :(
Den Grund kann ich mir denken: Ich befinde mich in einer Message-Map eines Dialoges, verlangt wird aber eine Message-Map eines Windows.
Ich habe aber kein Window, weil es sich um eine dialogbasierte Anwendung handelt. Oder kann ich irgendwie die Tatsache ausnutzen, dass der Dialog ja eine Ableitung eines Windows ist?
 
Hmm, sollte eigentlich. Wie sieht deine OnSocketMessage-Routine aus?
Zeig mal den Fehler mit Beschreibung!
 
error C2440: 'static_cast' : 'LRESULT (__thiscall CSocketTestDlg::* )(void)' kann nicht in 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)' konvertiert werden
 
Ein verbibsch. Ich sollte ja den Code beilegen!
Code:
LRESULT CSocketTestDlg::OnSocketMessage() {
  AfxMessageBox("Socketnachricht empfangen!");
}
 
Zurück