mehrere childwindows mit einer callback funktion



  • Nabend.
    Wollt mir hier gerade sowas kleines schreiben auf einma merk ich, dass es da ja die totalen komplikationen gibt 😕
    Es geht darum, ich will eine bestimmte (dynamische)Anzahl von childs bekommen.
    Und ich rate mal, dass man da auf die gleiche callback funktion zugreift weil das ja sonst witzlos wäre. Der komplette Inhalt der childs verwischt sich ineinander ... schrecklich sieht das aus. Das ist der code (könnt es ja dann selbst probiern :D):

    #include <windows.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK ChildProc(HWND, UINT, WPARAM, LPARAM);
    
    WNDCLASS wc;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, int) {
        MSG      msg;
        HWND     hWnd;
    
        wc.style             = CS_HREDRAW | CS_VREDRAW;
        wc.lpfnWndProc       = WndProc;
        wc.cbClsExtra        = 0;
        wc.cbWndExtra        = 0;
        wc.hInstance         = hInstance;
        wc.hIcon             = NULL;
        wc.hCursor           = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground     = (HBRUSH)COLOR_BACKGROUND;
        wc.lpszMenuName      = NULL;
        wc.lpszClassName     = "Parent";
    
        RegisterClass(&wc);
    
        wc.lpszClassName = "Child";
        wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
        wc.lpfnWndProc   = ChildProc;
    
        RegisterClass(&wc);
    
        hWnd = CreateWindow("Parent", "Parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, &wc);
    
        if(!hWnd)
            return 0;
    
        while(GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        return 0;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
        switch(msg) {
            case WM_CREATE: {
                for(int i = 0; i < 5; i++) {
                    CreateWindow("Child", NULL, WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW, i*15, i*15, 300, 200, hwnd, NULL, ((LPCREATESTRUCT)lparam)->hInstance, NULL);
                }
    
                return 0;
            }
            case WM_DESTROY: {
                PostQuitMessage(0);
                return 0;
            }
        }
    
        return DefWindowProc(hwnd, msg, wparam, lparam);
    }
    
    LRESULT CALLBACK ChildProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
        switch(msg) {
            case WM_PAINT: {
                /* something to do? */
            }
        }
    
        return DefWindowProc(hwnd, msg, wparam, lparam);
    }
    

    danke schonma im voraus



  • Dir ist aber bewust das CreateWindow ein HWND zurückgiebt und du somit zu jedem Child ein Handle hast (HWND HChild[5]; HChild[i] = CreateWindow...)
    Und dir ist auch bewust das jedem Child eine eigene WndProc zugewisen werden kann und wenn nicht und alle die gleiche haben das man über das Handle identifizieren kann welches Child die message versand hat. Das weißt du doch oder? Doch das weißt du.



  • Dass sich die Childs überlappen ist ja klar, wenn du sie jeweils nur um 15 px weiterschiebst, aber sie 200x300 px groß sind.
    Das was du mit Verschmieren meinst, kommt sicher daher, dass du in deiner ChildProc WM_PAINT abfängst, dann aber dort nichts machst. Zumindest ein Begin-/EndPaint musst du aber dann schon reinsetzen 😉



  • das hab ich alles schon probiert. dass sich die childs überlappen is schon klar ... aber das es schmiert versteh ich halt nich



  • Hast du jetzt WM_PAINT rausgenommen oder Begin-/EndPaint und dann return 0 in ChildProc aufgerufen?



  • case WM_PAINT: {
    PAINTSTRUCT ps;
    ps.hdc = BeginPaint(hwnd, &ps);
    EndPaint(hwnd, &ps);
    return 0;
    }



  • MiC++ha schrieb:

    Dir ist aber bewust das CreateWindow ein HWND zurückgiebt und du somit zu jedem Child ein Handle hast (HWND HChild[5]; HChild[i] = CreateWindow...)

    ist mir bewusst, ja. Mein posting ist jetzt die komplett abgespeckte version weil ich denke ich brauch euch nich mit mehr code belasten als nötig is ... habs inner liste un nich innem array

    MiC++ha schrieb:

    Und dir ist auch bewust das jedem Child eine eigene WndProc zugewisen werden kann und wenn nicht und alle die gleiche haben das man über das Handle identifizieren kann welches Child die message versand hat.

    Ich weiß dass ich jedem child eine eigene funktion zuweisen kann, aber wie ich in meiner frage schon erwähnt habe weiß ich ja nicht wie viele childs von dieser klasse geöffnet werden sollen und mal schnell im voraus 1000 verschiedene wndclasses mit gleichem inhalt machen halte ich für schwachsinn.

    Und ich denke für den test jetzt in dem ich noch nichts richtiges mache bringts mir doch auch wenig die handles zu identifizieren, mitgeschickt wird er ja.



  • hmmm...was ich jetzt aber gemerkt habe, kanns eigtl garnich an der gemeinsamen wndproc liegen ... hab jetzt testweise einfach ma ne neue für ein 2. child genommen, ...das gleiche phänomen wie davor 😕
    woran kann das liegen?



  • LOL

    ja genau, hast ja recht 🙂
    Ich habe deine frage bissel falsch interpretiert.

    So ich habe das jetzt mal kopiert und bei mir schmierd nichts, vieleicht hilft es auch mit einem feuchten Tuch den Monitorschirm zu streicheln 😃
    Nein im ernst, bei mir zeigt er alles normnal an, ohne schmieren.
    Ich mache meine Childs (meißt eigene Controls) in einer Klasse, für die Klasse giebt es eine WndProc und per SetWindowLong übergebe ich jeder Instance bzw. jedem Child in GWL_USERDATA den Zeiger mit, so das ich die Instance bzw. Childwindow direkt ansprechen kann, infos abrufen etc., aber am wichtigsten ist dabei Klasse->WProcedure(Message, wParam, lParam); in ihr werden dann die Funktion für zB OnMouseOver etc. aufgerufen.

    Warum und in wie weit es bei dir "schmiert" kann ich nicht nachvollziehen.



  • was? du hast das mit meinem code probiert und das hat funktioniert?!

    das mit den zeigern & setwindowlong etc. is ja im mom noch nich aufregend weil ich ja erstma nur will dass die childs gescheit da sind ohne inhalt.
    mit dem schmieren kannstes dir so vorstellen: ich tu ein child z.T über ein anderes, dann verschiebe ich dieses andere, aber das fenster, das auf ihm drauf WAR ist dort zu diesem teil immernoch abgebildet, bis ich ein anderes nehme und drüber"wische" ... also WM_PAINT aufrufe indirekt



  • also was ich jetzt gemerkt habe, sobald ich im createwindowstyle das WS_CHILD weglasse, sinds zwar keine childs aber es funzt perfekt .... hab ich da irgendwas definiert was nicht mit childwindow kann? das find ich ma sehr komisch ..



  • Nimm MDI



  • MDI? Nochnie gehört ... was ist das?





  • Ahhh, jetzt verstehe ich erst, du hast vor dies auch als Fenster zu benutzen, sprich wie Dialoge etc. Oder?
    Ne ne, dazu ist WS_CHILD nicht geeignet, das dient mehr zum benutzen von eigene Controls, z.B. ein anklickbares Image, in WM_PAINT wird dann das Bild gezeichnet (beginPaint,EndPaint), also praktisch eigene Controls.
    Ist dir nicht aufgefallen das keins der Childs Aktiv wird wenn man es anklickt, sondern stehts das Parent.
    Für Multifenster Anwendungen niemmt man MDI, ist auch relativ einfach.


Log in to reply