Main Window Procedure

LRESULT CALLBACK 
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    HDC         hdc; 
    PAINTSTRUCT ps; 
    LRESULT     lResult; 
    HRESULT     hRes; 
    char        szBuffer[128]; 
 
    switch (msg) 
    { 
        case WM_CREATE: 
            hRes = CreateDirect3D(hwnd); 
            if (FAILED(hRes)) 
            { 
                ReportError(hwnd, IDS_ERRMSG_CREATEDEVICE, hRes); 
                ReleaseDirect3D(); 
                return -1L; 
            } 
 
            hRes = CreatePrimary(hwnd); 
            if (FAILED(hRes)) 
            { 
                ReportError(hwnd, IDS_ERRMSG_INITSCREEN, hRes); 
                ReleasePrimary(); 
                ReleaseDirect3D(); 
                return -1L; 
            } 
 
            hRes = ChooseDevice(); 
            if (FAILED(hRes)) 
            { 
                ReportError(hwnd, IDS_ERRMSG_NODEVICE, hRes); 
                ReleasePrimary(); 
                ReleaseDirect3D(); 
                return -1L; 
            } 
 
            // Update the title to show the name of the chosen device. 
 
            wsprintf(szBuffer, "%s: %s", WINDOW_TITLE, szDeviceName); 
            SetWindowText(hwnd, szBuffer); 
 
            return 0L; 
 
        case WM_MOVE: 
            return OnMove(hwnd, (int)LOWORD(lParam), 
                (int)HIWORD(lParam)); 
 
        case WM_SIZE: 
            return OnSize(hwnd, (int)LOWORD(lParam), 
                (int)HIWORD(lParam)); 
 
        case WM_ERASEBKGND: 
        // Our rendering fills the entire viewport so we won't bother 
        // erasing the background. 
 
            return 1L; 
 
        case WM_PAINT: 
            hdc = BeginPaint(hwnd, &ps); 
 
            lResult = OnPaint(hwnd, hdc, &ps); 
 
            EndPaint(hwnd, &ps); 
            return lResult; 
 
        case WM_ACTIVATEAPP: 
            fActive = (BOOL)wParam; 
            if (fActive && !fSuspended && (NULL != lpddPalette)) 
            { 
                // Realizing the palette using DirectDraw is different 
                // from GDI. To realize the palette we call SetPalette 
                // each time our application is activated. 
 
                // NOTE: DirectDraw recognizes that the new palette 
                // is the same as the old one and so does not increase 
                // the reference count of the palette. 
 
                hRes = lpddPrimary->lpVtbl->SetPalette(lpddPrimary, 
                    lpddPalette); 
                if (FAILED(hRes)) 
                { 
                    FatalError(hwnd, IDS_ERRMSG_REALIZEPALETTE, hRes); 
                    return 0L; 
                } 
 
            } 
            else 
            { 
                // If we have been deactived, invalidate to show 
                // the suspended display. 
 
                InvalidateRect(hwnd, NULL, FALSE); 
            } 
            return 0L; 
 
        case WM_KEYUP: 
            // We use the escape key as a quick way of 
            // getting out of the application. 
 
            if (VK_ESCAPE == (int)wParam) 
            { 
                DestroyWindow(hwnd); 
                return 0L; 
            } 
            break; 
 
        case WM_CLOSE: 
            DestroyWindow(hwnd); 
            return 0L; 
 
        case WM_DESTROY: 
            // All cleanup is done here when terminating normally or 
            // shutting down due to an error. 
 
            ReleaseScene(); 
            ReleaseDevice(); 
            ReleasePrimary(); 
            ReleaseDirect3D(); 
 
            PostQuitMessage(0); 
            return 0L; 
    } 
 
    return DefWindowProc(hwnd, msg, wParam, lParam); 
}