Child-Window-Fehler



  • Schuldigung, ich meine natürlich Nachrichtenbehandlungscallbackfunktion (oder wie das auch immer heißt). Also das eben, mit den Nachrichten!!! 😉

    Das mit dem minimierten Modus hat sich schon erledigt. Es lag an einer falschen Config-Einstellung.

    Falls mein Problem nicht gefunden werden kann, könnte mir jemand vielleicht den Code einer Windows-Anwendung posten, die ein Fenster erstellt und zusätzlich ein Childfenster. Vielleicht sehe ich dann im Vergleich, was ich falsch gemacht habe!

    Danke,

    Chrissi



  • Hallo,

    #include <windows.h>
    
    #define IDC_BTN 100
    
    HINSTANCE hInstGlobal;
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	hInstGlobal = hInstance;
    
    	WNDCLASS WndMain;
    	WndMain.style         = CS_HREDRAW | CS_VREDRAW;
    	WndMain.cbClsExtra    = 0;
    	WndMain.cbWndExtra    = 0;
    	WndMain.lpfnWndProc   = WndProc;
    	WndMain.hbrBackground = (HBRUSH) COLOR_WINDOW;
    	WndMain.hCursor       = LoadCursor(NULL, IDC_ARROW);
    	WndMain.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    	WndMain.hInstance     = hInstance;
    	WndMain.lpszClassName = "WndClass";
    	WndMain.lpszMenuName  = 0;
    
    	RegisterClass(&WndMain);
    
    	HWND hWndMain;
    	hWndMain = CreateWindowEx(
    		0,
    		"WndClass",
    		"SomeWindow",
    		WS_OVERLAPPEDWINDOW,
    		(int) (GetSystemMetrics(SM_CXSCREEN) / 2) - 300, 
    		(int) (GetSystemMetrics(SM_CYSCREEN) / 2) - 250, 
    		600, 
    		500,
    		NULL,
    		NULL,
    		hInstance,
    		NULL
    	);
    
    	ShowWindow(hWndMain, nCmdShow);
    	UpdateWindow(hWndMain);
    
    	MSG msg;
    
              // Das ist die MessageLoop, die bei Dir Fehlt
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	return (msg.wParam);
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	static HWND hBtn;
    
    	switch(msg)
    	{
    	case WM_CREATE:
    		hBtn = CreateWindowEx(0, "BUTTON", "Test", 
    				WS_CHILD | WS_VISIBLE, 2, 200, 75, 25, hWnd, (HMENU) IDC_BTN, hInstGlobal, NULL);
    		return 0;
    	case WM_COMMAND:
    		switch (HIWORD(wParam))
    		{
    		case BN_CLICKED:
    			switch (LOWORD(wParam))
    			{
    			case IDC_BTN:
    				MessageBox(hWnd, "Hallo", "Test", MB_OK);
    				return 0;
    			}
    
    			return 0;
    		}
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	default:
    		return DefWindowProc(hWnd, msg, wParam, lParam);
    	}
    }
    

    MfG
    tuküe



  • Wo registrierst du denn überhaupt deine verwendete Fensterklasse "TEST" 😕



  • Hi,

    erstmal vielen Dank für die Antworten.

    Ich habe war die Fensterklasse regestriert und eine Nachrichtenschleife habe ich auch (in einer externen Funktion), aber funktioniert hat es noch nicht. Jetzt habe ich die ganze Anwendung neu gecodet, aber herausgekommen ist nicht die Lösung meines Problemes.

    ich wollte nämlich was anderes:

    Es soll ein extra verschiebbares Fenster (Mit Symbolleiste etc.) zu dem Hauptfenster erstellt werden, welches auch Aktionen im Hauptfenster auslösen kann. (z.B. neuer Hintergrund...). Eben soetwas wie bei GIMP, dort gibt es nämlich einmal gibt es das Hauptfenster mit dem Bild und einmal gib es das Werkzeugfenster.

    Danke,
    Chrissi



  • Was ist jetzt dein Problem 😕



  • Ich weiß nicht, wie ich solch ein Fenster, welches Aktionen im Main-Fenster auslösen kann, erstelle. 🙂

    Ich hoffe, jemand kennt die Antwort auf mein Problem,

    Schüssi,

    Chrissi



  • Du erstellst einfach für jedes (unterschiedliche) Fenster eine Fensterklasse mit eigener WndProc. Aus dieser heraus kannst du ja (selbstdefinierte) Messages an dein Hauptfenster schicken 😉



  • ~chrissi schrieb:

    ...soetwas wie bei GIMP, dort gibt es nämlich einmal gibt es das Hauptfenster mit dem Bild und einmal gib es das Werkzeugfenster...

    das klingt für mich nach MDI...



  • Ich denke nicht, dass er sowas meint 🙄
    Ich hatte das so verstanden, dass er einfach eine Anwendung will, die auf mehreren Fenstern besteht, die alle andere Aufgaben haben 😉



  • Hallo,

    @dot
    Schon mal Gimp gesehen? Sieht nicht nach MDI aus.

    @~chrissi
    ich hab auch mal sowas ähnliches gemacht. Hier der Code, falls du noch Probleme damit hast:

    LRESULT CALLBACK ChildProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	static HWND hBtnChild;
    	static HWND hParent;
    
        switch(msg)
        {
        case WM_CREATE:
    		hParent = (HWND) GetWindowLong(hWnd, GWL_HWNDPARENT);
            hBtnChild = CreateWindowEx(0, "BUTTON", "foo", WS_CHILD | WS_VISIBLE, 
    			10, 150, 75, 25, hWnd, (HMENU) IDC_BTNCHILD, hInstGlobal, NULL);
            return 0;
        case WM_COMMAND:
            switch (HIWORD(wParam))
            {
            case BN_CLICKED:
                switch (LOWORD(wParam))
                {
                case IDC_BTNCHILD:
    				SendMessage(hParent, WM_SETTEXT, 0, (LPARAM) "foo");
    				return 0;
                }
    
                return 0;
            }
            return 0;
        case WM_DESTROY:
    		EnableWindow(hBtn, TRUE);
            SendMessage(hWnd, WM_CLOSE, 0, 0);
            return 0;
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
        }
    }
    
    HWND CreateChild(HWND hParent, HINSTANCE hInst)
    {
    	WNDCLASS WndChild;
        WndChild.style         = CS_HREDRAW | CS_VREDRAW;
        WndChild.cbClsExtra    = 0;
        WndChild.cbWndExtra    = 0;
        WndChild.lpfnWndProc   = ChildProc;
        WndChild.hbrBackground = (HBRUSH) COLOR_WINDOW;
        WndChild.hCursor       = LoadCursor(NULL, IDC_ARROW);
        WndChild.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        WndChild.hInstance     = hInst;
        WndChild.lpszClassName = "ChildClass";
        WndChild.lpszMenuName  = 0;
    
        RegisterClass(&WndChild);
    
        HWND hWnd;
        hWnd = CreateWindowEx(
            0,
            "ChildClass",
            "ChildWindow",
            WS_OVERLAPPEDWINDOW,
            (int) (GetSystemMetrics(SM_CXSCREEN) / 2) - 300,
            (int) (GetSystemMetrics(SM_CYSCREEN) / 2) - 300,
            300,
            300,
            hParent,
            NULL,
            hInst,
            NULL
        );
    
    	return hWnd;
    }
    
    // Aufruf in der Haupt-WndProc
    
        case WM_COMMAND:
            switch (HIWORD(wParam))
            {
            case BN_CLICKED:
                switch (LOWORD(wParam))
                {
                case IDC_BTN:
    				hChild = CreateChild(hWnd, hInstGlobal);
    				ShowWindow(hChild, SW_SHOW);
    				EnableWindow(hBtn, FALSE);
    				return 0;
                }
    
                return 0;
            }
            return 0;
    

    MfG
    tuküe



  • tuküe schrieb:

    Hallo,

    @dot
    Schon mal Gimp gesehen? Sieht nicht nach MDI aus.

    nein hatts noch nicht gesehn
    hast aber recht, sieht nicht nach MDI aus...



  • Ganz normale Tool-Windows denke ich.



  • Hi,

    jetzt funktioniert es. Nur noch zwei Fragen:

    1. Wie mache ich, dass das "Child"-Fenster nach dem Erstellen im Vordergrund (und aktiviert) ist, zusätzlich zu dem Hauptfenster(welches auch aktiviert bleibt!)???

    2. Warum funktioniert dies nicht:

    [cpp]ss << "CHILDWINDOWCLASS_FOR_" << sWindowTitle << "_" << CExporter::m_iNumCreatedChildWindows++;
    ex.lpszClassName=ss.str().c_str();[cpp]

    Vielen Dank nochmal,

    Chrissi

    [EDIT]Gibt es eigentlich eine Funktion, die überprüft, ob eine bestimmte HWND-Struktur gülltig ist, bzw die checkt, ob das Fenster einer HWND-Struktur erstellt oder nicht erstellt ist???[/EDIT]



  • Hallo,

    1. in meinem Beispiel sollte doch das Fenster aktiviert und im Vordergrund sein, oder was meinst du? Das beide gleichzeitig den Fokus haben? Das geht nicht.

    2. Weiss ich nicht. Aber näher Angaben was genau nicht funktioniert und was überhaupt da gemacht wird wären hilfreich.

    Gibt es eigentlich eine Funktion, die überprüft, ob eine bestimmte HWND-Struktur gülltig ist, bzw die checkt, ob das Fenster einer HWND-Struktur erstellt oder nicht erstellt ist

    Wenn du eine Funktion aufrufst, die ein HWND zurückgibt, einfach überprüfen, ob dieser 0 ist.

    MfG
    tuküe



  • tuküe schrieb:

    In meinem Beispiel sollte doch das Fenster aktiviert und im Vordergrund sein, oder was meinst du? Das beide gleichzeitig den Fokus haben? Das geht nicht.

    Hier wird u.a. erklärt, wie du genau dies erreichen kannst ("Prevent window deactivation" & "Proper window activation")



  • hi,

    vielen Dank für die Antworten. Jetzt funktioniert alles. Frage 1 hat sich erledigt, bei Frage 2 nehme ich jetzt uncoole c-Strings mit sprintf, was aber funktioniert 🙂 , und Frage 3 hat sich auch erledigt.

    @ Flenders: Der Link hört sich interessant an. Werde gleich mal reinschauen.

    Vielen Dank nochmals,

    Schüssi,

    Chrissi

    [EDIT]Wer deutsch kann, ist hier eindeutig im Vorteil...[/EDIT]


Anmelden zum Antworten