Newbe-Problem beim Window-Erstellen



  • Ich habe versucht ein ganz normales Fenster zu erstellen aber irgendwas stimmt nicht. Ich habe schon stundenlang gedebuggt und Fehler verfolgt, aber ich komme absolut nicht weiter. Ich bin noch ein totaler Newbe und ich hoffe ihr seid so nett und könnt mir helfen.
    Hier mein Code

    // This program doesn't try to be oo
    
    // Includes needed
    #include <windows.h>
    
    // declaring the needed prototypes
    LRESULT CALLBACK MyMainWndProc (HWND, UINT, WPARAM, LPARAM);
    
    // The starting point
    int WINAPI WinMain (HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine,
                       int nShowCmd)
    {
        // Registering my MyMainWnd-class
        WNDCLASSEX wcMyMainWnd;
        memset(&wcMyMainWnd, 0, sizeof (wcMyMainWnd));
        wcMyMainWnd.cbSize = sizeof(WNDCLASSEX);
        wcMyMainWnd.cbClsExtra = 0;
        wcMyMainWnd.cbWndExtra = 0;
        wcMyMainWnd.hbrBackground = NULL;
        wcMyMainWnd.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcMyMainWnd.hIcon = NULL;
        wcMyMainWnd.hIconSm = NULL;
        wcMyMainWnd.hInstance = hInstance;
        wcMyMainWnd.lpfnWndProc = MyMainWndProc;
        wcMyMainWnd.lpszClassName = "MyMainWnd";
        wcMyMainWnd.lpszMenuName = NULL;
        wcMyMainWnd.style = CS_VREDRAW | CS_HREDRAW;
    
        //Error handling
        if (!RegisterClassEx (&wcMyMainWnd))
        {
            ::MessageBox (NULL, "Error ocurring while registering window", "Error", MB_OK);
            return (0);
        }
    
        // Creating my Window
        HWND hwndMyMainWnd; // handle to my Window
        hwndMyMainWnd = CreateWindowEx (0,                  // Play around with this and ...
                                        "MyMainWnd",
                                        "My Main Window",
                                        WS_POPUP,   // Play around with this!
                                        100,
                                        100,
                                        300,
                                        100,
                                        NULL,
                                        NULL,
                                        hInstance,
                                        0);
    
        // Error handling
        if(!hwndMyMainWnd)
        {
            ::MessageBox (NULL, "Error ocurring while creating window", "Error", MB_OK);
    
            LPVOID lpMsgBuf;
            FormatMessage( 
                FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                FORMAT_MESSAGE_FROM_SYSTEM | 
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                GetLastError(),
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                (LPTSTR) &lpMsgBuf,
                0,
                NULL );
    
            // Display the string.
            ::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
    
            // Free the buffer.
            LocalFree( lpMsgBuf );
    
            return (0);
        }
    
        // Show my Window
        ShowWindow(hwndMyMainWnd, SW_SHOW );
    
        // Message Pump
        MSG msgMessage;
        while (1)
        {
            if(PeekMessage (&msgMessage, hwndMyMainWnd, 0, 0, PM_NOREMOVE))
            {
                if (!GetMessage (&msgMessage, hwndMyMainWnd, 0, 0))
                    return msgMessage.wParam;
                TranslateMessage (&msgMessage);
                DispatchMessage (&msgMessage);
            }
        }
    
        return (1);
    }
    
    LRESULT CALLBACK MyMainWndProc (HWND hWnd,
                                    UINT uMsg,
                                    WPARAM wParam,
                                    LPARAM lParam)
    {
        switch (uMsg)
        {
        case WM_CLOSE:
            PostQuitMessage (0);
            return 0;
        case WM_CHAR:
            PostQuitMessage (0);
            return 0;
        case WM_PAINT:
            {
                PAINTSTRUCT ps;
                BeginPaint (hWnd, &ps);
                char buf[] = "My first drawings";
                TextOut (ps.hdc, 0, 0, buf, strlen (buf));
                EndPaint(hWnd, &ps);
            }
            return 0;
        default:
            DefWindowProc(hWnd, uMsg, wParam, lParam);
            return 0;
        }
    }
    

    Würde mich freuen, wenn ihr mir helfen könntet. Das Problem liegt übrigens bei der CreateWindowEx-Funktion.

    Danke schonmal im Voraus,
    Michael Besue



  • Da sind ein paar Sachen drin, die nicht normal sind:

    while (1)
        {
            if(PeekMessage (&msgMessage, hwndMyMainWnd, 0, 0, PM_NOREMOVE))
            {
                if (!GetMessage (&msgMessage, hwndMyMainWnd, 0, 0))
                    return msgMessage.wParam;
                TranslateMessage (&msgMessage);
                DispatchMessage (&msgMessage);
            }
        }
    

    Warum benutzt du diese Art einer Nachrichtenschleife? Du weißt wahrscheinlich gar nicht, was die genau macht (ist nicht böse gemeint). Für deine Zwecke reicht folgende Version vollkommen aus:

    while(GetMessage(&msgMessage, NULL, 0, 0))
    {
      TranslateMessage (&msgMessage);
      DispatchMessage (&msgMessage);
    }
    return msgMessage.wParam;
    

    Achja: Der dritte Parameter muss NULL sein. Sonst bleibt dein Programm auch nach dem Schließen des Fensters aktiv, weil die letzte Nachricht (WM_QUIT) nicht ans Fenster sondern an den Thread gerichtet ist.

    Noch ein Fehler:
    Auf WM_PAINT reagierst du etwas ungewohnt, aber das müsste so funktionieren. Aber bei WM_CLOSE und WM_CHAR ist die Reaktion falsch. Du postest einfach WM_QUIT, ohne das Fenster zu schließen. WM_QUIT sollte nur bei WM_DESTROY gepostet werden. Bei WM_CHAR sollte man DestroyWindow(hWnd) aufrufen, wenn man das Fenster unbedingt schließen will.
    Und bei deinem default-Zweig: Das muss "return DefWindowProc(bla);" heißen. Du darfst nicht einfach immer 0 zurückgeben. Das führt zwangsläufig zu Fehlern.

    btw:
    Was für ein Tutorial oder Buch benutzt du denn? Ich würde dir einen Umstieg empfehlen.

    p.s.:
    Mir ist eben noch folgende Zeile aufgefallen:

    wcMyMainWnd.hbrBackground = NULL;
    

    Das ist nicht gut. Nimm wenigstens einen Standardbruch, z.B. einen schwarzen oder einen weißen.

    wcMyMainWnd.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    

    [ Dieser Beitrag wurde am 21.11.2002 um 21:00 Uhr von cd9000 editiert. ]



  • Jetzt sagste auch was. Mein Message Processor gibt immer null zurück. Dann kann das ja nicht klappen. Stand auch in meinem Buch drin. Ist übringens: Special effects Game Programming with DirectX

    Außerdem ist doch wohl klar warum die Message Pump so ausschaut. Sie ist auf Spiele zugeschnitten und die warten bekanntlich nicht auch Usereingaben. Aber wieso sollte man die nicht auch in normalen Proggis verwenden? Schadet doch nicht.

    [ Dieser Beitrag wurde am 21.11.2002 um 21:14 Uhr von BadBeu editiert. ]



  • Doch, denn wenn dein Programm nicht wartet, läuft es immer und die CPU-Auslastung ist immer bei 100%.

    ChrisM



  • Na gut. Da magst du natürlich auch wieder Recht haben. Danke für den Hinweis!


Anmelden zum Antworten