Eigene Messages erstellen ...



  • Das meinte ich!

    Dann drück dich doch das nächste mal besser aus.

    Beide Programme server und client rufen RegisterWindowMessage() mit dem gleichen String auf.

    hört sich nämlich an wie ein Beobachtung im Code von DarkMight1. Was solls... wir haben das Problem ja jetzt gelöst.



  • Wenn ich das nun so ändere wie flenders das beschrieben hat kann ich die beiden oben genannten Variablen nun auch lokal in der WndProc behandeln !!!

    Ich habe vor dem Server einen String (oder vielleicht die Startadresse des Strings) zu übermitteln geht das irgendwie oder gibt es da andere Möglichkeiten ??



  • @DarkMight1: WM_COPYDATA

    @WebFritzi: Mitdenken!



  • Ok in dem Client-Programm habe ich nun WM_COPYDATA eingebunden, mir ist nur nicht klar wofür copydatastruct.dwData da ist.

    Hier mal das listing wie es jetzt aus sieht.

    #include <windows.h>
    #include <string.h>
    
    #define WM_MYMSG WM_USER
    
    HWND    hwnd;
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
    {
        char        szAppName[] = "DX-Client";
        MSG         msg;
        WNDCLASSEX  wndclass;
    
        wndclass.cbSize         = sizeof (wndclass);
        wndclass.style          = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc    = WndProc;
        wndclass.cbClsExtra     = 0;
        wndclass.cbWndExtra     = 0;
        wndclass.hInstance      = hInstance;
        wndclass.hIcon          = LoadIcon (NULL, IDI_APPLICATION);
        wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
        wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
        wndclass.lpszMenuName   = NULL;
        wndclass.lpszClassName  = szAppName;
        wndclass.hIconSm        = LoadIcon (NULL, IDI_APPLICATION);
    
        RegisterClassEx (&wndclass);
    
        hwnd = CreateWindow (szAppName, "DX-Client", WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                             NULL, NULL, hInstance, NULL);
    
        ShowWindow (hwnd, iCmdShow);
        UpdateWindow (hwnd);
    
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
    
        return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
        HWND                hwnd_Server;
        COPYDATASTRUCT      copydatastruct;
        char                String[] = "Test-String";
        STARTUPINFO         StartupInfo;
        PROCESS_INFORMATION ProcessInformation;
    
        switch (iMsg)
        {
            case WM_CREATE:
    
                ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
                StartupInfo.cb = sizeof(STARTUPINFO);
                ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
    
                CreateProcess ("DX-Server.exe", NULL, NULL, NULL, false, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartupInfo, &ProcessInformation);
    
                CloseHandle(ProcessInformation.hProcess);
                CloseHandle(ProcessInformation.hThread);
                return 0;
            case WM_PAINT:
    
                hwnd_Server = FindWindow("DX-Server","DX-Server");
                copydatastruct.cbData = sizeof (String);
                copydatastruct.lpData = String;
    
                SendMessage(hwnd_Server, WM_COPYDATA, (WPARAM) hwnd, (LPARAM) ©datastruct);
    
                return 0;
            case WM_DESTROY:
                hwnd_Server = FindWindow("DX-Server","DX-Server");
                SendMessage(hwnd_Server, WM_CLOSE, NULL ,NULL);
                PostQuitMessage (0);
                return 0;
        }
    
        return DefWindowProc (hwnd, iMsg, wParam, lParam);
    }
    

    Ich müste jetzt nur noch wissen wie ich den String wieder aus der Nachricht rausbekomme, hier mein erster Versuch:

    LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
        COPYDATASTRUCT copydatastruct;
    
        switch (iMsg)
        {
            case WM_CREATE:
                return 0;
            case WM_PAINT:
                return 0;
            case WM_DESTROY:
                PostQuitMessage (0);
                return 0;
            case WM_COPYDATA:
                copydatastruct = (COPYDATASTRUCT) lParam;
                MessageBox(NULL,"WM_COPYDATA", "Message", MB_OK);
                return 0;
        }
    
        return DefWindowProc (hwnd, iMsg, wParam, lParam);
    }
    

    Das sagt der Compiler dazu:
    I:\Projects\DX_Server\DX-Server.cpp(59) : error C2440: 'type cast' : 'long' kann nicht in 'struct tagCOPYDATASTRUCT' konvertiert werden
    Quelltyp konnte von keinem Konstruktor angenommen werden, oder die Ueberladungsaufloesung des Konstruktors ist mehrdeutig



  • @John: Ne, wer hier mitdenken muss, das bist du! Du solltest deine Beiträge so schreiben, dass sie jeder versteht. Das war hier nicht der Fall! Beiträge sind nicht zum Interpretieren da, sondern zum Helfen. Und mit Beiträgen, in denen du dich nicht eindeutig ausdrückst, hilfst du keinem!



  • ...und du hälst UINT MY_MSG für 'ne Konstante :o

    Mein Gott bist du kleinlich...oder peinlich! :p



  • Bist du fertig?

    [ Dieser Beitrag wurde am 14.04.2003 um 01:07 Uhr von WebFritzi editiert. ]



  • Eine einfachere alternative Lösung wäre die Verwendung von PostThreadMessage. Kann von jedem Prozess oder Thread zu einem Thread gesendet werden. Die Empfänger-Thread-ID muß aber bekannt. Entweder über die Registry (eintragen vom Thread und ausleses vom Message-Sender) oder über einen gemeinsam bekannten Klassennamen. Vor- und Nachteile muß jeder selber abwägen.
    Ich wollte nur zeigen, dass es noch mindestens eine Lösung mehr gibt.

    Blackbird



  • hi,
    ich glaube jemand hat bei WM_PAINT : BeginPaint () und EndPaint () vergessen



  • Also ich habe das mit WM_COPYDATA jetzt hinbekommen. Der String kommt an das blöde ist nur das ab und zu mal so komisches Zeugs mit auftaucht wo ich mir nicht reklären wo jetzt der Fehler liegen soll.

    Hier noch mal die beiden Listings:

    Client:

    #include <windows.h>
    #include <string.h>
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    void    SendCmd (HWND, HWND, char*);
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
    {
        char        szAppName[] = "DX-Client";
        MSG         msg;
        WNDCLASSEX  wndclass;
        HWND        hwnd;
    
        wndclass.cbSize         = sizeof (wndclass);
        wndclass.style          = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc    = WndProc;
        wndclass.cbClsExtra     = 0;
        wndclass.cbWndExtra     = 0;
        wndclass.hInstance      = hInstance;
        wndclass.hIcon          = LoadIcon (NULL, IDI_APPLICATION);
        wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
        wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
        wndclass.lpszMenuName   = NULL;
        wndclass.lpszClassName  = szAppName;
        wndclass.hIconSm        = LoadIcon (NULL, IDI_APPLICATION);
    
        RegisterClassEx (&wndclass);
    
        hwnd = CreateWindow (szAppName, "DX-Client", WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                             NULL, NULL, hInstance, NULL);
    
        ShowWindow (hwnd, iCmdShow);
        UpdateWindow (hwnd);
    
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
    
        return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
        HWND                hwnd_Server;
        STARTUPINFO         StartupInfo;
        PROCESS_INFORMATION ProcessInformation;
    
        switch (iMsg)
        {
            case WM_CREATE:
                ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
                ZeroMemory(&ProcessInformation, sizeof(PROCESS_INFORMATION));
    
                CreateProcess ("DX-Server.exe", NULL, NULL, NULL, false, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartupInfo, &ProcessInformation);
    
                CloseHandle(ProcessInformation.hProcess);
                CloseHandle(ProcessInformation.hThread);
                return 0;
            case WM_PAINT:
                SendCmd (NULL, FindWindow("DX-Server",NULL),"Test-String\0");
                return 0;
            case WM_DESTROY:
                hwnd_Server = FindWindow("DX-Server","DX-Server");
                SendMessage(hwnd_Server, WM_CLOSE, NULL ,NULL);
                PostQuitMessage (0);
                return 0;
        }
    
        return DefWindowProc (hwnd, iMsg, wParam, lParam);
    }
    
    void SendCmd (HWND Sender, HWND Empfaenger, char* Commando)
    {
        COPYDATASTRUCT *    cds;
        cds = new COPYDATASTRUCT;
        cds->cbData = sizeof(char) * strlen(Commando);
        cds->lpData = Commando;
        cds->dwData  = NULL;
        SendMessage(Empfaenger, WM_COPYDATA, (WPARAM) Sender, (LPARAM) cds);
    
        free(cds);
    }
    

    Server:

    #include <windows.h>
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
    {
        char        szAppName[] = "DX-Server";
        HWND        hwnd;
        MSG         msg;
        WNDCLASSEX  wndclass;
    
        wndclass.cbSize         = sizeof (wndclass);
        wndclass.style          = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc    = WndProc;
        wndclass.cbClsExtra     = 0;
        wndclass.cbWndExtra     = 0;
        wndclass.hInstance      = hInstance;
        wndclass.hIcon          = LoadIcon (NULL, IDI_APPLICATION);
        wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
        wndclass.hbrBackground  = (HBRUSH) GetStockObject (WHITE_BRUSH);
        wndclass.lpszMenuName   = NULL;
        wndclass.lpszClassName  = szAppName;
        wndclass.hIconSm        = LoadIcon (NULL, IDI_APPLICATION);
    
        RegisterClassEx (&wndclass);
    
        hwnd = CreateWindow (szAppName, "DX-Server", WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                             NULL, NULL, hInstance, NULL);
    
        ShowWindow (hwnd, iCmdShow);
        UpdateWindow (hwnd);
    
        while (GetMessage (&msg, NULL, 0, 0))
        {
            TranslateMessage (&msg);
            DispatchMessage (&msg);
        }
    
        return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
        switch (iMsg)
        {
            case WM_DESTROY:
                PostQuitMessage (0);
                return 0;
            case WM_COPYDATA:
                COPYDATASTRUCT * cds;
                cds = (COPYDATASTRUCT *)lParam;
                MessageBox(NULL,(char *) cds->lpData, "Message", MB_OK);
                return 0;
        }
    
        return DefWindowProc (hwnd, iMsg, wParam, lParam);
    }
    

    und hier mal das komische Zeugs was ab und zu mal in der MessageBox auftaucht:

    http://marco.kaminski.bei.t-online.de/files/gedoens.JPG

    [ Dieser Beitrag wurde am 14.04.2003 um 11:46 Uhr von DarkMight1 editiert. ]



  • Ein Tip ins Blaue: Du hast das abschließende Nullbyte vergessen, oder?
    [cpp]
    cds->cbData = sizeof(char) * strlen(Commando) + 1;[/cpp]



  • Deshalb habe ich ja an den übertragenen String \0 mit drangehangen.

    SendCmd (NULL, FindWindow("DX-Server",NULL),"Test-String\0");
    

    Aber das hilft wohl nichts, jetzt funktioniert es jedenfalls !!!

    [ Dieser Beitrag wurde am 14.04.2003 um 14:51 Uhr von DarkMight1 editiert. ]



  • Also... entweder schickst du den String mit 0 rüber, oder du hängst sie serverseitig an die empfangene Zeichenfolge.

    SendCmd (NULL, FindWindow("DX-Server",NULL),"Test-String\0");
    

    hilft natürlich nix!
    [cpp]
    cds->cbData = sizeof(char) * strlen(Commando); // Länge des Strings ohne 0 Zeichen![/cpp]
    ergibt 11, weil strlen das abschließende 0-Zeichen nicht mitzählt. Deshalb sollst du ja noch 1 dazu addieren.
    sizeof(char) * strlen("Test-String\0") == 1 * strlen("Test-String\0") == 11

    Klar?



  • Lass das '\0' in der Definition des Test-Strings weg!
    Und:

    COPYDATASTRUCT cds;
        cds.cbData = sizeof(char) * lstrlen(Commando) + 1;
        cds.lpData = (LPVOID)Commando;
        cds.dwData  = 0;
        SendMessage(Empfaenger, WM_COPYDATA, (WPARAM)Sender, (LPARAM)cds);
    

    Und wenn du schon unbedingt new benutzen willst, dann lösche den Speicher mit delete.

    [ Dieser Beitrag wurde am 14.04.2003 um 16:41 Uhr von WebFritzi editiert. ]



  • Ha da hat der Fritz! ja doch noch nen Fehler gemacht 😃

    Rate doch mal welchen Fehler ich bei folgender Zeile bekomme:

    SendMessage(Empfaenger, WM_COPYDATA, (WPARAM)Sender, (LPARAM)cds);
    

    Mal gespannt ob du den Fehler findest !!



  • Man darf doch mal ein '&' vergessen, oder? 😉 Läuft's denn jetzt?

    [EDIT]
    Um mal deine Homepage aufzupolieren, kannst ja mal das "seid" in "seit" umändern neben dem Counter. 😉
    [/EDIT]

    [ Dieser Beitrag wurde am 15.04.2003 um 01:12 Uhr von WebFritzi editiert. ]



  • Hey richtig, ja jetzt läuft es.

    Ja meine HP könnte mal wieder nen Update vertragen mal schauen die nächsten Tage habe ja jetzt URLAUB und damit ein wenig Zeit 🙂

    Hat mich diese blöde M$ Frontpage nicht auf diesen Fehler hingewissen na warte das gibt ne fette Klage 😃


Anmelden zum Antworten