![]() |
Unknown Directive Message
(Delphi 7 Enterprise)
Hallo bezüglich des threads ![]() habe ich das problem mit WSAAsyncSelect mittels eines unsichtbaren Fenster gelöst. Allerdings bekomme ich ein Problem mit meiner Message Methode
Delphi-Quellcode:
ich programmiere nonVCL und wenn ich ihm das hinsetze meckert er beim message WM_mySocket.uses WinSock, Messages, system, Windows; type WM_mySocket = WM_APP +1 ; procedure SocketMessage(var msg: TMessage); message WM_mySocket; forward; hab schon einiges dazu gesucht, aber nichts brauchbares gefunden |
Re: Unknown Directive Message
Das geht nur für Methoden (einer Klasse) nicht für Funktionen/Prozeduren.
|
Re: Unknown Directive Message
okay, kann ich das also komplett vergessen und muss auf threads umsteigen ?
Edit: ich könnte ja auch über
Delphi-Quellcode:
if not GetMessage(Msg,0,0,0) then Break;
DispatchMessage(Msg); gehen :gruebel: |
Re: Unknown Directive Message
Hallo jokerfacehro, anbei Template Vorlage, für Verwendung einer eigenen WndProc.
Delphi-Quellcode:
lg. Astatuses windows, sysutils, messages, classes; const WM_MY_SOCKET_DATA = WM_USER + 1; WM_MY_SOCKET_ERROR = WM_USER + 2; WM_MY_SOCKET_LOGON = WM_USER + 3; WM_MY_SOCKET_CLIENT_DISCONNECT = WM_USER + 4; function MainWndProc(wnd: HWND; Msg: Integer; wp: WPARAM; lp: LPARAM): Integer; stdcall; forward; var _Terminated : Boolean; _hWndMain : HWND; MySocketMainWindowClass : TWndClass = (style: 0; lpfnWndProc: @MainWndProc; cbClsExtra: 0; cbWndExtra: 0; hInstance: 0; hIcon: 0; hCursor: 0; hbrBackground: 0; lpszMenuName: nil; lpszClassName: 'MySocketWindowClass' ); function MainWndProc(wnd: HWND; Msg: Integer; wp: WPARAM; lp: LPARAM): Integer; stdcall; begin Result := 0; case Msg of WM_MY_SOCKET_DATA: begin //-- WMOnAsyncServerData(wp, lp); end; WM_MY_SOCKET_ERROR: begin //-- WMOnAsyncServerError(wp, lp); end; WM_MY_SOCKET_LOGON: begin //-- WMOnAsyncServerLogon(wp, lp); end; WM_MY_SOCKET_CLIENT_DISCONNECT: begin //-- WMOnAsyncServerDisconnect(wp, lp); end; WM_CLOSE: begin DestroyWindow(wnd); end; WM_DESTROY: begin end; else Result := DefWindowProc(wnd, Msg, wp, lp) end; end; function InitAplication : Boolean; begin Result := FALSE; MySocketMainWindowClass.hInstance := hInstance; if Windows.RegisterClass(MySocketMainWindowClass) = 0 then raise exception.Create('InitAplication: RegisterClass FAILED'); _hWndMain := CreateWindowEx(WS_EX_TRANSPARENT , MySocketMainWindowClass.lpszClassName, '', WS_DISABLED, 0, 0, 0, 0, 0, 0, hInstance, nil); if _hWndMain = 0 then raise exception.Create('InitAplication: CreateWindowEx FAILED'); //-- Hier Socketverbindung aufbauen //-- result := InitConnections(_hWndMain); //-- if not result then //-- raise exception.Create('InitAplication: InitConnections FAILED') end; procedure CleanupAplication; begin if _hWndMain <> 0 then begin DestroyWindow(_hWndMain); _hWndMain := 0; end; end; procedure RunAplication; var MsgRec : TMsg; begin while GetMessage(MsgRec, 0, 0, 0) do begin DispatchMessage(MsgRec) end; _Terminated := TRUE; end; begin InitAplication; try RunAplication; finally CleanupAplication; end; end. |
Re: Unknown Directive Message
@Astat: Fehlt bei dir nicht noch ein PostQuitMessage?
Aber die Frage ist nach wie vor, wozu überhaupt Messages in dem Programm? Wenn man außer für die Sockets keine Messages braucht, ist das sowieso überdimensioniert. (genauso auch mit den Events) |
Re: Unknown Directive Message
ich will dann 2 sockets laufen lassen und die sollen sich dann nicht in die quere kommen, deshalb fand ich events als eleganteste lösung
|
Re: Unknown Directive Message
Zitat:
Yupp fehlt! :wall: Danke für Hinweis. :thumb: lg. Astat |
Re: Unknown Directive Message
eine frage wofür brauchst du die unit classes ?
|
Re: Unknown Directive Message
Beispiel für Event (ist leider nicht so chic wie bei Astat)
Delphi-Quellcode:
Die Funktionen aus der WinSock2 musste ich reinschreiben, da in D7 diese Unit nicht existiert. In neueren Delphis muss man Imho nur Winsock2 einbauen und kann sich die Deklaration der WSAxxx-funktionen sparen.
uses
Windows, Winsock; // aus WinSock2 type WSAevent=THandle; function WSACreateEvent:WSAEvent;stdcall; external 'ws2_32.dll' name 'WSACreateEvent'; function WSACloseEvent(hEvent:WSAevent):bool;stdcall; external 'ws2_32.dll' name 'WSACloseEvent'; function WSAResetEvent(hEvent: WSAEvent):bool;stdcall; external 'ws2_32.dll' name 'WSAResetEvent'; function WSAEventSelect(s:TSocket;hEventObject:WSAevent;lNetworkEvents:LongInt):Integer; stdcall; external 'ws2_32.dll' name 'WSAEventSelect'; function WSAWaitForMultipleEvents(cEvents:DWord; lphEvents:Pointer; fWaitAll:bool; dwTimeOUT:DWord; fAlertable:bool):DWord;stdcall; external 'ws2_32.dll' name 'WSAWaitForMultipleEvents'; var SockAddr1:TSockAddr= (sin_family:af_Inet; sin_port:$0020; //=8192 sin_addr:(S_addr:$0100007F)); //home SockAddr2:TSockAddr= (sin_family:af_Inet; sin_port:$0120; //=8193 sin_addr:(S_addr:$0100007F)); const WSA_WAIT_EVENT_0 = WAIT_OBJECT_0; procedure main; var wsaData:TwsaData; SockEvent:array[1..2] of WSAEvent; Socket1,Socket2:TSocket; WSAresult:Integer; buf:array[0..511] of char; begin WSAStartUp(MakeWord(2,0),WSAData); Socket1:=Socket(af_Inet,Sock_Stream,IPProto_TCP); SockAddr1.sin_addr.S_addr:=inet_addr('127.0.0.1'); Connect(Socket1,SockAddr1,sizeof(TSockAddr)); SockEvent[1]:=WSACreateEvent; WSAEventSelect(Socket1,SockEvent[1],FD_Read); Socket2:=Socket(af_Inet,Sock_Stream,IPProto_TCP); Connect(Socket2,SockAddr2,sizeof(TSockAddr)); SockEvent[2]:=WSACreateEvent; WSAEventSelect(Socket2,SockEvent[2],FD_Read); repeat WSAResult:=WSAWaitForMultipleEvents(2,@SockEvent,false,infinite,false); case WSAResult of WSA_WAIT_EVENT_0 : begin recv(Socket1,buf,512,0); if buf='exit' then break; end; WSA_WAIT_EVENT_0+1:begin recv(Socket2,buf,512,0); end; else break; end; WSAresetEvent(SockEvent[WSAResult-WSA_Wait_Event_0+1]); until false; WSACloseEvent(SockEvent[1]); WSACloseEvent(SockEvent[2]); WSACleanUp; end; begin main; end. Edit: Natürlich fehlt die komplette Fehlerbehandlung. Soll ja auch nur ein Beispiel sein. |
Re: Unknown Directive Message
:chat: mal eine lösung mit WSAEventSelect.
ich muss mir dat erstmal injezieren, hab mal rübergeschaut und einigermaßen das prinzip verstanden, bei paar befehlen hakst aber noch. |
Re: Unknown Directive Message
Hallo sirius, ich glaub mal @jokerfacehro vermischt da Windows Messages mit Socket Callbacks. :gruebel:
@jokerfacehro, sollen es nun Callbacks oder Windows Messages sein? lg. Astat |
Re: Unknown Directive Message
da mein quellcode sehr ähnlich zu deinem ist astat und ich eh mit messages arbeiten wollte, probier ich das erstmal ^^
mit callbacks bin ich jetz noch nicht so beleckt und werd mir dazu erstma was durchlesen |
Re: Unknown Directive Message
hab grad mal geschaut,
das Handle von CreateWindowEx ist 0. hab keine erklärung dafür :shock:
Delphi-Quellcode:
WC:TWndClassEX=(cbSize:SizeOf(WC);
lpfnWndProc:@WndProc; lpszClassName:'0'); ... RegisterClassEx(wc); winhwnd:=CreateWindowEx(0,'0','',0,0,0,0,0,0,0,hInstance,NIL); |
Re: Unknown Directive Message
Na dann schau mal was getlasterror bzw. syserrormessage(getlasterror) mit sysutils sagt.
|
Re: Unknown Directive Message
1400: Ungültiges Fensterhandle
|
Re: Unknown Directive Message
jemand ne idee warum das nicht hinhaut ?
|
Re: Unknown Directive Message
Kann es sein, dass dein Name zu kurz ist, und deswegen der Wert als Atom und nicht als String angesehen wird?
Versuche es doch mal mit mindestens 4 Zeichen. |
Re: Unknown Directive Message
du meinst den WindowName ? oder den ClassNAme ?
Edit, hab beides geändert und keine auswirkung auf das handle muss ich vielleicht noch en parent handle angeben ? von der anwendung oder so ? |
Re: Unknown Directive Message
Kannst du mal bitte den kompletten Codeteil zur Erstellung des Fensters reinstellen.
|
Re: Unknown Directive Message
jop :)
Delphi-Quellcode:
function WndProc(hWnd: HWND; Msg: UINT; wp: WPARAM; lp: LPARAM): integer; stdcall; forward; var WC:TWndClassEX=(cbSize:SizeOf(TWndClassEX); lpfnWndProc:@WndProc; lpszClassName:'ATestWndClassEx'); function WndProc(hWnd: HWND; Msg: UINT; wp: WPARAM; lp: LPARAM): integer; stdcall; var str:string; begin Result := 0; case Msg of WM_MY_SOCKET_DATA: begin setLength(str,1024); FillChar(str,Length(str),#0); recv(FSocket,str,Length(str),0); Showmessage(str); //-- WMOnAsyncServerData(wp, lp); end; WM_MY_SOCKET_ERROR: begin //-- WMOnAsyncServerError(wp, lp); end; WM_MY_SOCKET_LOGON: begin //-- WMOnAsyncServerLogon(wp, lp); end; WM_MY_SOCKET_CLIENT_DISCONNECT: begin //-- WMOnAsyncServerDisconnect(wp, lp); end; WM_CLOSE: begin DestroyWindow(winhwnd); end; WM_DESTROY: begin end; else Result := DefWindowProc(winhwnd, Msg, wp, lp); end; end; procedure connectSock(Socket:TSocket;IP:string;Port:Integer); var SockAddr: TSockAddrIn; AddrLen: Integer; begin RegisterClassEx(wc); {winhwnd:=CreateWindowEx(WS_EX_TRANSPARENT , wc.lpszClassName, '', WS_DISABLED, 0, 0, 0, 0, 0, 0, hInstance, nil);// } winhwnd:=CreateWindowEx(WS_EX_TRANSPARENT,wc.lpszClassName,'12345',0,0,0,0,0,0,0,hInstance,NIL); Showmessage(syserrormessage(getlasterror)); AddrLen := SizeOf(SockAddr); SockAddr.sin_family := AF_Inet; SockAddr.sin_port := htons(Port); SockAddr.sin_addr.S_addr := inet_addr(PChar(IP)); if Connect(Socket, SockAddr, AddrLen) = Socket_Error then HandleError; { if WSAAsyncSelect(FSocket, winhwnd, WM_mySocket, FD_READ or FD_CLOSE or FD_WRITE)= SOCKET_ERROR then HandleError; } end; begin ... connectSock(FSocket,'127.0.0.1',12345); ... end; Edit: ich habe für classname mal wc.lpszClassName eingetragen,w as ich vorhin auch schon versucht hatte. aber irgendwie funktioniert es jetzt |
Re: Unknown Directive Message
Ähm, und warum sind die ClassNAmes bei registerClass und CreateWindow unterschiedlich? Das geht so natürlich nicht. Du willst/musst doch ein Fenster aus Basis einer registrierten Fensterklasse erstellen.
|
Re: Unknown Directive Message
ich hab jetz en problem mitm speicher beim empfangen der daten
Delphi-Quellcode:
function WndProc(hWnd: HWND; Msg: UINT; wp: WPARAM;
lp: LPARAM): integer; stdcall; var str,str1:string; begin Result := 0; case lp of FD_READ: begin str:=''; setLength(str,1024); //FillChar(str,Length(str),#0); recv(FSocket,str[1],1024,0); Showmessage(str); //in str steht der empfangene text und ein teil vom showmessage vom syserrormessage PostQuitmessage(Msg); //-- WMOnAsyncServerData(wp, lp); end; WM_MY_SOCKET_ERROR: begin //-- WMOnAsyncServerError(wp, lp); end; WM_MY_SOCKET_LOGON: begin //-- WMOnAsyncServerLogon(wp, lp); end; WM_MY_SOCKET_CLIENT_DISCONNECT: begin //-- WMOnAsyncServerDisconnect(wp, lp); end; WM_CLOSE: begin DestroyWindow(winhwnd); end; WM_DESTROY: begin end; else Result := DefWindowProc(hwnd, Msg, wp, lp); end; end; anscheinend überschreibt der einfach den speicher. bei str wenn z.B. "Vorgang erfolgreich beendet" im syserrormessage stand, steht beim empfangen der daten in der variable str --> datenng erfolgreich abgeschlossen |
Re: Unknown Directive Message
recv liefert als Rückgabewerte, die Länge des übertragenen Strings. Merk die diese und setze damit die Länge:
Delphi-Quellcode:
str:=''; //brauchst du nicht
setLength(str,1024); len:=recv(FSocket,str[1],1024,0); setlength(str,len); Showmessage(str); //in str steht der empfangene text und ein teil vom showmessage vom syserrormessage Edit: Hat aber nix mehr mit dem ursprünglichen Thema zu tun. |
Re: Unknown Directive Message
ok danke dir.
jop bei weiteren fragen mach ich neuen thread auf danke dir sirius hast mir echt geholfen ^^ |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz