Ebenen der Einzelnen ChildWindows definieren



  • Nicht drauf geachtet: muss HWND_TOP oder HWND_TOPMOST lauten.



  • Ich habe mir jetzt deine Frage noch einmal genauer durchgelesen. Was bezweckst du damit? Windows-Controls sollten sich einfach nicht überdecken.

    So wie ich das sehe, gibt es einige bessere Lösungen, wie ein Tab-Control oder eine Listbox, mit denen die Sichtbarkeit von Dialogen geregelt werden kann (die dann ihrerseits die entsprechenden Controls enthalten).



  • Ich habe bis jetzt ein ParentWindow erstellt in dem es 2ChildWindows gibt (in allem wird Text ausgegeben). Nun soll immer das aktive ChildWindow vor dem anderen ChildWindow und NICHT dahinter sein.
    Mein Code (lang aber evtl. hilft das zum Verständnis):

    // main_cpp //
    
    #include <Windows.h>
    #include <iostream>
    
    int width = 640;
    int height = 420;
    
    LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    bool InitWndClassEx ( WNDCLASSEX *WndClassEx, HINSTANCE hInstance, const char szClassName[] = "Hallo"); 
    const char szClassName[] =  "Hallo";
          char szTitle[] = "1.Programm   Grafic3 Silent1297 2011 ©";
    
     		HWND hWndChild;	//Handle to 1.ChildWindow
    		HWND hWndChild2; //Handle to 2. ChildWindow
    		HWND hWndParent;      //legt die Eigenschaften des ParentWindows fest.
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
               LPSTR szCmdLine, int iCmdShow)
    
        {
            WNDCLASSEX WndClassEx;  // legt die Grundeigenschaften für das Fenster fest.
            WNDCLASSEX WndClassExChild; //Grundeigenschaften für ChildWindow
    		WNDCLASSEX WndClassExChild2; //Grundeigenschaften für ChildWindow2
            MSG msg;        //darin werden die Daten gespeichert.
    		HINSTANCE hChildInst = NULL;
    
            //          Registrierung      //
    
    		InitWndClassEx ( &WndClassEx, hInstance, szClassName);
    		InitWndClassEx ( &WndClassExChild, hInstance, "WndClassExChild");
            InitWndClassEx ( &WndClassExChild2, hInstance, "WndClassExChild2");
    
            //          Fenster Erstellen          //
    
            hWndParent = CreateWindowEx (NULL,    // beeinhaltet die Folgenden Eigenschaften und die Eigenschaften aus WndClassEx
                             szClassName,   //hierüber werden die Eigenschaften aus WndClassEx. eingebunden
                             szTitle,
                            WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, //Fenster (Minimierungsbutton.....
                            300, //Abstand-Oben
                            600, //Abstand-Links
                            width, // Breite
                            height, // Höhe
                            NULL,
                            NULL,
                            hInstance,
                            NULL);		
    
            if ( hWndParent == NULL )
                 {MessageBox ( NULL, "Create Window  failed", "Error", MB_OK);
                  return false;
                 }
    
            { 
                int cx = GetSystemMetrics(SM_CXSCREEN); //cx = desktopbreite ermitteln
                int cy = GetSystemMetrics(SM_CYSCREEN);//cx = desktophöhe ermitteln
    
                int px = (cx - width) / 2; //AbstanddesFensters von links errechnen
                int py = (cy - height) / 2; //AbstanddesFensters von oben errechnen
    
                MoveWindow( hWndParent, px, py, width, height, true);
            }
    
    		 ShowWindow( hWndParent, iCmdShow);
    
                    hWndChild =  CreateWindowEx (WS_EX_CLIENTEDGE, "WndClassExChild",
                             "Child Window silent1297", WS_SYSMENU| WS_CAPTION | WS_CHILD| WS_VISIBLE | WS_CLIPSIBLINGS, //WS_CLIPSIBLINGS damit Fenster beim Verziehen nicht "verwischt"
                            70, 30, 250, 300, // LinksAbstand, Obenabstand, Breite, Höhe
                            hWndParent, NULL, hChildInst, NULL );
    
                    hWndChild2 =  CreateWindowEx (WS_EX_CLIENTEDGE, "WndClassExChild2",
                             "Child Window - 2 silent1297",WS_SYSMENU | WS_CAPTION | WS_CHILD| WS_VISIBLE | WS_CLIPSIBLINGS, //WS_CLIPSIBLINGS damit Fenster beim Verziehen nicht "verwischt"
                            320, 30, 250, 300,  // LinksAbstand, Obenabstand, Breite, Höhe
                            hWndParent, NULL, hChildInst, NULL );
    
    				 SetWindowPos(
    					   hWndChild2,
    					   HWND_TOPMOST,
    					  70,
    					  30,
    					  250,
    					  300,
    					  SWP_SHOWWINDOW
    					);
    
                    SetClassLong ( hWndChild2, GCL_HBRBACKGROUND, (LONG) GetStockObject (BLACK_BRUSH)); //ändert die Hintergrundfarbe des Fensters dessen HWND (Handle to Window) angegeben ist 
    
            while( GetMessage ( &msg, hWndParent, NULL, NULL) > NULL) // -1 = Fehler | 0 // > 0
                {
                    TranslateMessage( &msg ); // wird in Character-Message übersetzt
                    DispatchMessage ( &msg ); // wird verschickt an die Callback Funktion
                };
                // WINDOW-PROCEDUR(Einleitungsteil) -> WNDCLASSEX(Registrierung) -> HWND(Fenstereinstellungenfestlegen) -> MESSAGELOOP(Messages übersetzen und an die CALLBACK-Funktion weiterverschicken)
    
            return 0;
        }
    //Variablen zur Textausgabe des ParentWindow
    HDC hDCParent;	// Handle to a Device Context für das ParentWindow
    PAINTSTRUCT psParent; //Paintstruktur für das ParentWindow
    char szTextParent[] = ("Hallo Welt");	// Text der ausgegeben werden soll für das ParentWindow
    
    //Variablen zur Textausgabe des 1.ChildWindow
    HDC hDCChild;	// Handle to a Device Context für das ChildWindow
    PAINTSTRUCT psChild; //Paintstruktur für das ChildWindow
    char szTextChild[] = ("Hallo 1.ChildFenster");	// Text der ausgegeben werden soll für das ChildWindow
    
    //Variablen zur Textausgabe des 2.ChildWindow
    HDC hDCChild2;	// Handle to a Device Context für das ChildWindow
    PAINTSTRUCT psChild2; //Paintstruktur für das ChildWindow
    char szTextChild2[] = ("Hallo 2.ChildFenster");	// Text der ausgegeben werden soll für das ChildWindow
    
    LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)        //Gehirn des eigentlichen Windows, Verarbeitung von Messages...
                {
    
                    //Jede Message hat 2 Informationen ( wParam und lParam)
                    switch (msg)
                        {  
    						case WM_PAINT:		//Text ausgeben
    
    							hDCParent = BeginPaint (hWnd,&psParent);		//ParentWindow neu gestalten :D
    									hDCChild = BeginPaint (hWndChild,&psChild);     //ChildWindow neu gestalten :D
    											hDCChild2 = BeginPaint (hWndChild2, &psChild2);
    
    													//Settings 2.ChildWindow
    											SetBkMode (hDCChild2, TRANSPARENT); //setzt die Hintergrundfarbe des Textes auf Transparent
    											SetBkColor( hDCChild2, RGB(255, 0, 0) ); // funktioniert wenn die SetbkMode(hDC, TRANSPARENT); nich vorhanden ist, ändert Hintergrundfarbe des Textes 1. Wert rot-wert, 2. Wert grün-wert, 3.Wert blau-wert
    											SetTextColor (hDCChild2, RGB(255, 255, 255) );//ändert Textfarbe des Textes 1. Wert rot-wert, 2. Wert grün-wert, 3.Wert blau-wert
    											TextOut ( hDCChild2, 50, 100, szTextChild2, strlen(szTextChild2) ); //2Zahlen am Anfang sind Koordinaten wo Text anfangen soll, 3. Ziffer ist die Anzahl der Zeichen des c-stirngs
    											EndPaint ( hWndChild2, &psChild2); //beendet das neu gestalten des ChildWindows2
    
    									//Settings 1.ChildWindow
    									SetBkMode (hDCChild, TRANSPARENT); //setzt die Hintergrundfarbe des Textes auf Transparent
    									SetBkColor( hDCChild, RGB(255, 0, 0) ); // funktioniert wenn die SetbkMode(hDC, TRANSPARENT); nich vorhanden ist, ändert Hintergrundfarbe des Textes 1. Wert rot-wert, 2. Wert grün-wert, 3.Wert blau-wert
    									SetTextColor (hDCChild, RGB(0, 0, 0) );//ändert Textfarbe des Textes 1. Wert rot-wert, 2. Wert grün-wert, 3.Wert blau-wert
    									TextOut ( hDCChild, 50, 100, szTextChild, strlen(szTextChild) ); //2Zahlen am Anfang sind Koordinaten wo Text anfangen soll, 3. Ziffer ist die Anzahl der Zeichen des c-stirngs
    									EndPaint ( hWndChild, &psChild); //beendet das neu gestalten des ChildWindows
    
    							//Settings Parent Window
    							SetBkMode (hDCParent, TRANSPARENT); //setzt die Hintergrundfarbe des Textes auf Transparent
    							SetBkColor( hDCParent, RGB(255, 0, 0) ); // funktioniert wenn die SetbkMode(hDC, TRANSPARENT); nich vorhanden ist, ändert Hintergrundfarbe des Textes 1. Wert rot-wert, 2. Wert grün-wert, 3.Wert blau-wert
    							SetTextColor (hDCParent, RGB(0, 0, 0) );//ändert Textfarbe des Textes 1. Wert rot-wert, 2. Wert grün-wert, 3.Wert blau-wert
    							TextOut ( hDCParent, 10, 10, szTextParent, strlen(szTextParent) ); //2Zahlen am Anfang sind Koordinaten wo Text anfangen soll, 3. Ziffer ist die Anzahl der Zeichen des c-stirngs
    							EndPaint ( hWnd, &psParent); //beendet das neu gestalten des ParentWindows
    
    							break;
    
                            case WM_DESTROY:        //Fenster Ende (Wenn auf das X-geklickt wird
    
    							if(hWnd == hWndParent)
    								{
                                PostQuitMessage(0);
    								}
    
                                break;
    
                            default:
    						     return DefWindowProc ( hWnd, msg, wParam, lParam);
    
    				   }
    				return 0;
                }
    
    bool InitWndClassEx ( WNDCLASSEX *WndClassEx , HINSTANCE hInstance, const char *szClassName)     //Funktion mit Defaultwerten für zB ChildWindows
        {
            WndClassEx->cbSize      = sizeof( *WndClassEx);
            WndClassEx->style       = NULL;
            WndClassEx->lpfnWndProc = (WNDPROC)WndProc;  // hWnd -> CreateWindow (szClassName ) -> WndClass.
            WndClassEx->cbClsExtra  = NULL;
            WndClassEx->cbWndExtra  = NULL;
            WndClassEx->hInstance   = hInstance;
            WndClassEx->hIcon      = LoadIcon( NULL, IDI_WARNING); //Icon
            WndClassEx->hCursor    = LoadCursor( NULL,IDC_ARROW); //Cursor
            WndClassEx->hbrBackground = (HBRUSH) GetStockObject ( WHITE_BRUSH) ;    //Fensterfarbe
            WndClassEx->lpszMenuName = NULL;
            WndClassEx->lpszClassName =  szClassName;   // C-String
            WndClassEx->hIconSm      =  LoadIcon (NULL, IDI_APPLICATION);
    
            if ( !RegisterClassEx ( WndClassEx ))
                 {MessageBox ( NULL, "Register Class failed", "Error", MB_OK);
                  return false;
                 }
    
        }
    

    Mit der SetWindowPos-Funktion funktioniert es auch nicht 😕 und auch WS_CLIPSIBLINGS bringt nichts :/.
    Was mache ich falsch ?
    Gruß
    silent12


  • Mod

    Was ist denn bitte das für ein absoluter oberunfug.!
    Du kannst nicht in WM_PAINT BeginPaint mehrfach aufrufen.
    Warum willst Du das?

    Wenn Du eine Child Window Prozedur für viele Fenster baust, dann bekommt jedes Fenster "persönlich" eine WM_PAINT Nachricht.
    Wenn sich die Fensterunterschieldich verhalten sollen, dann musst Du jeder Instanz eben eigene Daten geben oder eine eigene WindowProc.

    Wie wäre es zuerst mal mit einem klassichen Tutorial?

    PS: Was soll SetClassLong in dem Code, wenn Du die Klasse zuvor selbst anlegst. Da hättest Du den Brush doch setzen können



  • Der Code ist mithilfe von Sterminio-Productions (Sehr bekannte c++ Tutorials soweit ich weiß) erstellt und darauf baut sich mein gesamtes Win-API Wissen auf.
    Das SetClassLong ist nur dabei um den Gebrauch der Funktion zu kennen.
    Funktioniert das mit der WndClassEx Funktion nicht, dass für jedes einzelne Child/Parent Window eine eigene WndProc erstellt wird ?
    Wie dies funkionieren sollte habe ich bei dem Tutorial nicht ganz verstanden 😕
    Ich würde mich sehr über gute Tutorial-Links zu diesem Thema freuen.
    Sorry völliger Anfänger 😕
    Gruß
    silent12



  • Ich würde mich sehr über Tipps zur Behebung meiner Fehler freuen (sorry wegen Doppelpost), damit ich nicht schon mit falschen Grundlagen anfange.
    gruß
    silent12



  • Das sehr bekannte Tutorial von "Sterminio Productions" ???

    Nee, kannte ich noch nicht. Hab ich jetzt aber nachgeholt.

    z.B. C++ Tutorial 18 || Part 1 || OOP - Klassen
    http://www.youtube.com/watch?v=nLKAZ95GUCM

    Der Junge ist ja total wuschig ...

    Will OOP erklären und erklärt nebenbei wie man eine Header Datei einfügt ?

    Nee, den Rest sehe ich mir lieber nicht an ...

    Hoffe das dir jemand bessere Tutorials empfehlen kann.

    Ich lese lieber Bücher ...



  • Hat noch irgendjemand gute Tutorials oder kann mir sagen wo die Fehler in meinem Code liegen und wo ich lern diese zu beheben ?
    Gruß
    silent12


  • Mod

    Ich habe es bereitsgeschrieben: Du rifst zeimal BeginPaint in einem WM_PAINT Aufruf auf.
    Wenn Du unterschiedliches Verhalten für Child Windows willst benötigst Du unterschieldiche WindowProcs, oder Du programmierst Deine WindowProc, so, dass die unterschiedlichen Daten in der Fensterklasse gespeichert werden können.

    Lies den Petzold. Meine Empfehlung.



  • silent12 schrieb:

    //          Registrierung      //
    InitWndClassEx ( &WndClassEx, hInstance, szClassName);
    InitWndClassEx ( &WndClassExChild, hInstance, "WndClassExChild");
    InitWndClassEx ( &WndClassExChild2, hInstance, "WndClassExChild2");
    

    Wenn Du nur eine WinProc verwenden möchtest (was du ja machst) macht es keinen
    Sinn dafür verschiedene WindowsKlassen zu registrieren. Ansonsten müsste man
    auch die Adressen der WinProcs zusätzlich übergeben und nicht (nur) den Namen.

    Beispiel: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633575(v=vs.85).aspx

    silent12 schrieb:

    LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
       //Jede Message hat 2 Informationen ( wParam und lParam)
       switch (msg) {  
          case WM_PAINT:                                 //Text ausgeben
             hDCParent = BeginPaint (hWnd,&psParent);    //ParentWindow neu gestalten
    

    Ich will es nochmal etwas deutlicher formulieren:

    Martin hat dich nun wiederholt darauf aufmerksam gemacht, das der Handle des
    neuzuzeichnenden Fensters hWnd als Parameter von WndProc übergeben wird und
    sich WM_PAINT genau auf dieses Fenster bezieht.

    Es ist möglich alles in einer Winproc zu handeln. Die Fenster die keine Nachricht erhalten sollten dann aber auch in Ruhe gelassen werden ...


Anmelden zum Antworten