Button im Child - Fenster



  • Hallo,

    mein Problem liegt darin in einem Childwindow ein neues Childwindow (zB. Button) zu erzeugen und dann die Nachricht des Buttons in der WindowProc zu empfangen.
    Ist es überhaubt möglich soetwas zu machen ohne für den Button eine eigene Proc - Funtion zu schreiben? So wie ich es bis jetzt gelesen habe werden die Nachrichten vom Child an den Parent geschickt. Wenn Dieses Parent wieder ein Child ist bleibt die Nachricht dann auf der Strecke?

    Wenn ich bei WM_LBUTTONDOWN: einen Breakpoint setze wird dieser nur ausgelöst wenn ich in die L"STATIC" Fenster klicke bei Klicken in der Trackbar passiert nichts 😡

    hWndLeft	= CreateWindow( L"STATIC", L"", WS_CHILD  | WS_BORDER | WS_VISIBLE, 0, 0, 700, 768, hParentWnd , NULL, hInstance, NULL );   
    	hWndRight	= CreateWindow( L"STATIC", L"", WS_CHILD  | WS_BORDER | WS_VISIBLE, 700, 0, 324, 768, hParentWnd, NULL, hInstance, NULL );  
    
    	//Trackbars erstellen
    	hSpeedSlider = CreateWindow( TRACKBAR_CLASS, L"speedSlider", WS_CHILD  | WS_BORDER | WS_VISIBLE, 10, 30, 286, 100, hWndRight, NULL, hInstance, NULL );
    
    LRESULT CALLBACK SimpleProgram::WindowProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
    
        //Message verarbeiten
        switch( msg ) {
    
            case WM_KEYDOWN : 
    
    			switch( wParam ) {
    
    				case VK_ESCAPE:
    
    					PostQuitMessage( 0 );
    
    					break;
    			}
    
            break;
    
    		case WM_LBUTTONDOWN: {
    
    		} 
           break;
    
           case WM_COMMAND : {
    
    			BREAKPOINT			  
    		}
    
    		break;
    
    		case WM_LBUTTONDOWN: {
    
    		}
    
    		case WM_HSCROLL : {
    
    		}
    
    		break;
    
    		break;
    
    		case WM_CLOSE : 
    
    			PostQuitMessage( 0 );
    
    		break;
    
    		case WM_QUIT :
    
    			PostQuitMessage( 0 );
    
    		break;
    
            case WM_DESTROY :
    
                PostQuitMessage( 0 );
    
            break;
    
    		default :
    
    			// oder Windows Standardverarbeitung aufrufen
    			return DefWindowProc( hWnd, msg, wParam, lParam );
    
    		break;
    	}
    
    	return 0;
    }
    

  • Mod

    Click Events für einen Button werden per WM_COMMAND an das Parent gesendet.

    Petzold Windows API Programmierung 1. Stunde... 🕶



  • ok, ich hätte die ganze Winproc posten sollen. Ich habe für die Buttons WM_COMMAND und für die Trackbar WM_HSCROLL eingebaut aber die jeweiligen Haltepunkte werden nicht ausgelöst.



  • Ludwig schrieb:

    ok, ich hätte die ganze Winproc posten sollen.

    Deinen ersten Beitrag kannst du ja noch editieren, so kann nur ins Blaue geraten werden.

    Du erstellst zwei statische Controls und gibst beiden die gleiche ID (nämlich 0), du kannst also nicht unterscheiden, woher die Nachricht kommt.
    Damit eine solche Nachricht überhaupt gesendet wird, muss das Flag SS_NOTIFY gesetzt sein:

    const int fstID = 40000;
    ...
    hWndLeft    = CreateWindow( L"STATIC", L"", WS_CHILD  | WS_BORDER | WS_VISIBLE | SS_NOTIFY, 0, 0, 700, 768, hParentWnd , reinterpret_cast<HMENU>(fstID), hInstance, NULL );
    

    Für den Slider solltest du dir die Doku noch einmal durchlesen, WM_HSCROLL sollte mMn aber immer gesendet werden...



  • leider habe ich immernoch keinen Erfolg.

    Um es übersichtlicher zu machen nehme ich jetzt mal einen Button und keine Trackbar.
    Ich habe wie oben beschrieben mein STATIC Fenster abgeändert und diesem Fenster einen Button angefügt. Dieser wird auch dargestellt aber WM_COMMAND wird beim drücken nicht aufgerufen. Muss der Button auch das Flag SS_NOTIFY gesetzt haben? Wenn ich das auf msdn richtig vertanden habe ist der hMenu Parameter unteranderem dazu da um das Fenster zu identifizieren? Dh auch bei einem Fehler in dem Bereich müsste trotzdem WM_COMMAND aufgerufen werden oder?

    Der Button wird NICHT in WM_CREATE erstellt, kann es damit zusammen hängen?

    hButtonTwo	= CreateWindow( L"Button", L"2x", WS_CHILD | WS_VISIBLE , 169, 40, 30, 20, hWndLeft, NULL, hInstance, NULL );
    

    danke, Ludwig



  • Achso, du willst die statischen Controls nur als Rahmen um die Buttons legen (oder?).

    SS_NOTIFY ist dann nicht nötig, auf Mausevents muss ja nicht reagiert werden. Das Problem bei deinem Code ist aber, dass du die Fensterhandles auf die statischen Controls als parents an CreateWindow übergibst (es ist möglich, du müsstest dann aber die statischen Controls subclassen).

    Warum übergibst du nicht stattdessen das Handle des Hauptfensters?

    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HWND button, static_, slider;
    
    	switch (message)
    	{
    		case WM_CREATE:
    			InitCommonControls();
    			button = CreateWindow( TEXT("Button"), TEXT("2x"), WS_CHILD | WS_VISIBLE , 169, 40, 30, 20, hwnd,(HMENU)1,((LPCREATESTRUCT)lParam)->hInstance, NULL);
    			static_ = CreateWindow( TEXT("STATIC"), TEXT(""), WS_CHILD | WS_VISIBLE | SS_NOTIFY, 169, 70, 30, 20, hwnd,(HMENU)2,((LPCREATESTRUCT)lParam)->hInstance, NULL);
    			slider = CreateWindow( TRACKBAR_CLASS, L"speedSlider", WS_CHILD  | WS_BORDER | WS_VISIBLE, 10, 10, 200, 20, hwnd,(HMENU)3,((LPCREATESTRUCT)lParam)->hInstance, NULL );
    			break;
    		case WM_COMMAND:
    			switch(LOWORD(wParam))
    			{
    				case 1:
    					SetWindowText(hwnd, TEXT("Button gedrückt"));
    					break;
    				case 2:
    					SetWindowText(hwnd, TEXT("static_ gedrückt"));
    					break;
    			}
    			break;
    		case WM_HSCROLL:
    			SetWindowText(hwnd,TEXT("Wert verändert"));
    			break;
    		case WM_DESTROY :
    			PostQuitMessage (0) ;
    			return 0 ;
    	}
    	return DefWindowProc(hwnd,message,wParam,lParam);
    }
    

    So sollte das eigentlich funktionieren...

    Edit: Die C-Casts habe ich jetzt aus Faulheit genommen, du kannst es ja noch überarbeiten.



  • Ich brauche das STATIC, weil ich ein Hauptfenster habe was ich mit 2 STATICs teile, in der linken Hälfte läuft meine directx Anwenung und in der rechten Hälfte habe ich die Einstellungsmöglichkeiten. Bei der Suche nach einer Lösung bin ich auch auf subclassing gestoßen, hatte dann aber das Gefühl das es dafür da ist für die Controls eine eigene wndProc zu erstellen. Werde mich dann mal in die Richtung schlau machen.


  • Mod

    Wenn der Button ein Kind des CStatic ist, dann bekommt dieses auch die WM_COMMAND nachrichten.
    Du müsstest also entweder:
    - Ein Static superclass-en, d.h. die satic Klasse holen und eine eigene WndProc definieren. (siehe MSDN)
    - Oder das Static subclassen um an die WM_COMMAND Nachrichten zu kommen



  • Danke!

    habe es geschaft die Nachricht in der wndProc zu empfangen 👍

    ( WNDPROC )SetWindowLong( hParent, GWL_WNDPROC, ( LONG )WindowProc );
    

Anmelden zum Antworten