Warten bis Child geschlossen wurde



  • Hiho.

    Ich hab nen Child, das in einer Klasse aufgerufen wird.

    Solange das Child offen ist, soll der Srccode angehalten bzw unterbrochen werden.

    Erst wenn das Child mit WM_CLOSE oder WM_DESTROY geschlossen wurde, soll es weiter gehen.

    Hatte schon ne Schleife, die so lange läuft, bis FindWindow() false ist.

    Doch dadurch wird ja GetMessage() nicht mehr abgearbeitet (wird ja dann angehalten).

    Also hab ich versucht die Schleife mit GetMessage() zu besetzten.

    Nur läuft die Schleife selbst dann noch weiter, wenn das Child geschlossen wurde.

    Irgendwo ist der Wurm.

    Jemand ne Idee?

    EDIT: Tschuldigung, sollte eigentlich ins WinApi Forum!



  • WaitForSingleObject() und ein event mutex oder so was in der art sollte dein problem lösen



  • WaitForSingleObject() würde ja direkt wieder verschwinden, weil er das Handle zu meinem Window ja bekommt. Oder missverstehe ich die Funktion?

    CTecS schrieb:

    und ein event mutex oder so was in der art

    ???



  • du sollst ja auch net das handle deines windows abfragen sondern ein event benutzen

    http://msdn.microsoft.com/en-us/library/ms686211(VS.85).aspx

    und das soll ja nur ein anstoß sein



  • Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    Erzeuge einen neuen Thrad mit einer eigenen Message-Loop! Dort kannst Du das andere Fenster erzeugen und diesen Thread mit PostQuitMessage wie ein eigenes Windows Programm beenden. Der Main-Thread kann mit WaitForSingleObjekt auf diesen Thread waten.

    Fenster sind threadafin. Man kann einen Thread nicht lahmlegen ohne damit auch die Fenster dieses Threads lahmzulegen.

    IMHO ist es einfacher die aktuelle Applikation wie bei einem modalen Dialog lahmzulegene durch EnableWindow und das Child dann abarbeiten zu lassen.

    Warum darf der Thread nicht weiter arbeiten?



  • Martin Richter schrieb:

    Warum darf der Thread nicht weiter arbeiten?

    Weil in dem neuen Fenster auf eine Eingabe gewartet wird.

    Sobald es eingegeben wurde, schließt sich das Fenster.

    Anschließend soll es weiter im Text gehen ...


  • Mod

    Dann ist doch ein modaler Dialog alles was Du brauchst...
    Ich verstehe nicht wo Dein Problem ist?



  • Hab meine Gründe, es soll einfach auf eine Eingabe gewartet werden.

    Auf ne DialogBox() mit Resourcedateien verzichte ich lieber.



  • unlimieD.paSe schrieb:

    Auf ne DialogBox() mit Resourcedateien verzichte ich lieber.

    Darf ich fragen, warum?



  • Weil ich keine Scriptartige resource Datei benutzen möchte.



  • Einen Dialog kannst du mit CreateDialogIndirect() auch ohne Ressourcendatei erzeugen.

    Oder du disablest dein Parentwindow und regierst im Childwindow auf das Closeevent mit einer Nachricht an dein Prantwindow, nach deren Empfang du es wieder enablest.

    /Ulli



  • Ich hab jetzt einfach mal ein "Testprogramm" gemacht, das auf Resourcedatei aufbaut.

    Wie ihr meintet, habe ich diesmal ne DialogBox benutzt.

    Leider komme ich jetzt an dem Punkt immer noch nicht weiter, wo ich schon voher nicht weiter kam.

    Hier erstmal der vollständige Sourcecode:

    #define STATIC
    
    #include <windows.h>
    #include "resource.h"
    
    LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
    BOOL CALLBACK DialogProc( HWND, UINT, WPARAM, LPARAM );
    
    const char szWndName[] = "Test";
    const char szDialogName[] = "Dialog";
    
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iShowCmd )
    {
    	HWND hWnd;
    	MSG msg;
    	WNDCLASS ws;
    
    	ws.cbClsExtra = 0;
    	ws.cbWndExtra = 0;
    	ws.hbrBackground = ( HBRUSH )CreateSolidBrush( RGB( 240, 240, 240 ) );
    	ws.hCursor = LoadCursor( NULL, IDC_ARROW );
    	ws.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    	ws.hInstance = hInstance;
    	ws.lpfnWndProc = WndProc;
    	ws.lpszClassName = szWndName;
    	ws.lpszMenuName = NULL;
    	ws.style = CS_VREDRAW | CS_HREDRAW;
    
    	RegisterClass( &ws );
    
    	hWnd = CreateWindow( szWndName,
    						 szWndName,
    						 WS_OVERLAPPED | WS_SYSMENU,
    						 CW_USEDEFAULT, CW_USEDEFAULT,
    						 300, 100,
    						 NULL,
    						 NULL,
    						 hInstance,
    						 NULL );
    
    	ShowWindow( hWnd, iShowCmd );
    	UpdateWindow( hWnd );
    
    	while( GetMessage( &msg, NULL, 0, 0 ) )
    	{
    		TranslateMessage( &msg );
    		DispatchMessage( &msg );
    	}
    
    	return msg.wParam;
    };
    
    LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
    	static RECT clientRect;
    
    	static HWND hButton;
    	static HWND hChild;
    	static HWND hDialog;
    
    	static char szText[100];
    	const char szT1[] = "Noch nicht...";
    	const char szT2[] = "Jetzt aber !!";
    
    	switch( uMsg )
    	{
    		case WM_SIZE:
    		{
    			GetClientRect( hWnd, &clientRect );
    
    			MoveWindow( hButton, 10, 10, clientRect.right - 20, 25, true );
    
    			return 0;
    		}
    
    		case WM_CREATE:
    		{
    			hButton = CreateWindow( "button",
    									"W E I T E R",
    									WS_CHILD | WS_VISIBLE,
    									0, 0,
    									0, 0,
    									hWnd,
    									NULL,
    									( ( LPCREATESTRUCT )lParam )->hInstance,
    									NULL );
    
    			memcpy( szText, szT1, lstrlen( szT1 ) );
    
    			return 0;
    		}
    
    		case WM_COMMAND:
    		{
    			if( lParam == ( LPARAM )hButton )
    			{
    				if( HIWORD( wParam ) == BN_CLICKED )
    				{
    					hDialog = CreateDialog( NULL,
    											MAKEINTRESOURCE( IDD_INFO ),
    											hWnd,
    											DialogProc );
    
    					ShowWindow( hDialog, 1 );
    
    					WaitForSingleObject( hDialog, INFINITE ); // Funktioniert nicht
    
    					memcpy( szText, szT2, lstrlen( szT2 ) );
    
    					InvalidateRect( hWnd, NULL, true );
    
    					return 0;
    				}
    			}
    
    			return 0;
    		}
    
    		case WM_PAINT:
    		{
    			PAINTSTRUCT ps;
    			HDC hDc;
    			SIZE size;
    
    			hDc = BeginPaint( hWnd, &ps );
    			{
    				GetTextExtentPoint32( hDc, szText, lstrlen( szText ), &size );
    
    				SetBkColor( hDc, RGB( 240, 240, 240 ) );
    
    				TextOut( hDc, clientRect.right / 2 - size.cx / 2, clientRect.bottom - 15 - size.cy / 2, szText, lstrlen( szText ) );
    			}
    			EndPaint( hWnd, &ps );
    
    			return 0;
    		}
    
    		case WM_DESTROY:
    		{
    			PostQuitMessage( 0 );
    
    			return 0;
    		}
    	}
    
    	return DefWindowProc( hWnd, uMsg, wParam, lParam );
    };
    
    BOOL CALLBACK DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
    	switch( uMsg )
    	{
    		case WM_COMMAND:
    		{
    			switch( wParam )
    			{
    				case IDC_CONTINUE:
    					EndDialog( hWnd, 0 );
    				break;
    			}
    
    			return true;
    		}
    	}
    
    	return false;
    };
    

    Kurze Beschreibung der Funktionsweise...

    Das Programm startet.
    Unter dem "Weiter" Button steht "Noch nicht...".
    Klickt man auf den "Weiter" Button, erscheint ein neues Fenster (in diesem Fall die DialoxBox ).
    In dem neuen Fenster ist ebenfalls ein "Weiter" Button.
    Sobald dieser geklickt wird, soll sich der Text auf "Jetzt aber !!" ändern.

    Das sollte eigentlich passieren.

    Leider entspricht das kompilierte Programm nicht meiner oben beschriebenen Vorstellung. Denn sobald ich schon auf den ersten "Weiter" Button im Hauptprogramm klicke, ändert sich bereits der Text.

    Klar ! - Immerhin wird der Text genau nach dem Erstellen des Childs geändert.

    Mir ist auch durchaus bewusst, dass ich den Text auch kurz vor dem EndDialog ändern kann. Dadurch würde es genau so funktionieren wie ich es wollte.

    Leider ist mein Problem ja, dass es dort nicht geändert werden kann, sondern die Verarbeitung dringend angehalten werden muss.

    Ich hoffe man versteht was ich meine.

    Gruß, paSe.



  • Hi,
    wie waers mit: DialogBox() statt CreateDialog. Einfach mal in der MSDN gucken.

    Blessed Love C0de4Fun



  • Sehr geil.

    Es funktioniert.

    Ich bedanke mich sehr bei euch!

    #define STATIC
    
    #include <windows.h>
    #include "resource.h"
    
    LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
    BOOL CALLBACK DialogProc( HWND, UINT, WPARAM, LPARAM );
    
    const char szWndName[] = "Test";
    const char szDialogName[] = "Dialog";
    
    static INT_PTR iptDialog;
    
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iShowCmd )
    {
    	HWND hWnd;
    	MSG msg;
    	WNDCLASS ws;
    
    	ws.cbClsExtra = 0;
    	ws.cbWndExtra = 0;
    	ws.hbrBackground = ( HBRUSH )CreateSolidBrush( RGB( 240, 240, 240 ) );
    	ws.hCursor = LoadCursor( NULL, IDC_ARROW );
    	ws.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    	ws.hInstance = hInstance;
    	ws.lpfnWndProc = WndProc;
    	ws.lpszClassName = szWndName;
    	ws.lpszMenuName = NULL;
    	ws.style = CS_VREDRAW | CS_HREDRAW;
    
    	RegisterClass( &ws );
    
    	hWnd = CreateWindow( szWndName,
    						 szWndName,
    						 WS_OVERLAPPED | WS_SYSMENU,
    						 CW_USEDEFAULT, CW_USEDEFAULT,
    						 300, 100,
    						 NULL,
    						 NULL,
    						 hInstance,
    						 NULL );
    
    	ShowWindow( hWnd, iShowCmd );
    	UpdateWindow( hWnd );
    
    	while( GetMessage( &msg, NULL, 0, 0 ) )
    	{
    		TranslateMessage( &msg );
    		DispatchMessage( &msg );
    	}
    
    	return msg.wParam;
    };
    
    LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
    	static RECT clientRect;
    
    	static HWND hButton;
    	static HWND hChild;
    
    	static char szText[100];
    	const char szT1[] = "Noch nicht...";
    	const char szT2[] = "Jetzt aber !!";
    
    	switch( uMsg )
    	{
    		case WM_SIZE:
    		{
    			GetClientRect( hWnd, &clientRect );
    
    			MoveWindow( hButton, 10, 10, clientRect.right - 20, 25, true );
    
    			return 0;
    		}
    
    		case WM_CREATE:
    		{
    			hButton = CreateWindow( "button",
    									"W E I T E R",
    									WS_CHILD | WS_VISIBLE,
    									0, 0,
    									0, 0,
    									hWnd,
    									NULL,
    									( ( LPCREATESTRUCT )lParam )->hInstance,
    									NULL );
    
    			memcpy( szText, szT1, lstrlen( szT1 ) );
    
    			return 0;
    		}
    
    		case WM_COMMAND:
    		{
    			if( lParam == ( LPARAM )hButton )
    			{
    				if( HIWORD( wParam ) == BN_CLICKED )
    				{
    					iptDialog = DialogBox( NULL,
    										   MAKEINTRESOURCE( IDD_INFO ),
    										   hWnd,
    										   DialogProc );
    
    					memcpy( szText, szT2, lstrlen( szT2 ) );
    
    					InvalidateRect( hWnd, NULL, true );
    
    					return 0;
    				}
    			}
    
    			return 0;
    		}
    
    		case WM_PAINT:
    		{
    			PAINTSTRUCT ps;
    			HDC hDc;
    			SIZE size;
    
    			hDc = BeginPaint( hWnd, &ps );
    			{
    				GetTextExtentPoint32( hDc, szText, lstrlen( szText ), &size );
    
    				SetBkColor( hDc, RGB( 240, 240, 240 ) );
    
    				TextOut( hDc, clientRect.right / 2 - size.cx / 2, clientRect.bottom - 15 - size.cy / 2, szText, lstrlen( szText ) );
    			}
    			EndPaint( hWnd, &ps );
    
    			return 0;
    		}
    
    		case WM_DESTROY:
    		{
    			PostQuitMessage( 0 );
    
    			return 0;
    		}
    	}
    
    	return DefWindowProc( hWnd, uMsg, wParam, lParam );
    };
    
    BOOL CALLBACK DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
    {
    	switch( uMsg )
    	{
    		case WM_COMMAND:
    		{
    			switch( wParam )
    			{
    				case IDC_CONTINUE:
    					EndDialog( hWnd, 0 );
    				break;
    			}
    
    			return true;
    		}
    	}
    
    	return false;
    };
    

Log in to reply