Avatar billede freakofnature Nybegynder
28. marts 2003 - 23:06 Der er 4 kommentarer og
1 løsning

Hvorfor vil programmet ikke lave nyt vindue?

Hej,

Jeg er rimelig newbie til C++, men det er alligevel lykkes mig at bakse noget sammen - problemet er bare, at det ikke rigtigt virker?

Det er i min MainLoop() fejlen ligger - tror jeg. Det er når det trykkes F1, så skal programmet fjerne det gamle og lave et nyt - dog i som windowed el. fullScreen... Alt efter, hvad det var før.

Hvad kan jeg gøre?

#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")

#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>

HDC            g_hDC;
HGLRC        g_hRC;
HWND        g_hwnd;
HINSTANCE    g_hInstance;
bool        g_fullScreen=TRUE;

LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);

void DeInit(char* strClassName){

    if (g_fullScreen){

        ChangeDisplaySettings(NULL,0);
        ShowCursor(TRUE);
    }

    if (g_hDC && !ReleaseDC(g_hwnd,g_hDC)){

        MessageBox(NULL,"Release Device Context Failed","SHUTDOWN_ERROR",MB_OK | MB_ICONINFORMATION);
        g_hDC=NULL;
    }
   
    if (g_hwnd && !DestroyWindow(g_hwnd)){
        MessageBox(NULL,"Could Not Release hwnd","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
        g_hwnd=NULL;
    }

    if (!UnregisterClass(strClassName,g_hInstance)){

        MessageBox(NULL,"Could Not Unregister Class","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
        g_hInstance=NULL;
    }
}

void ChangeToFullScreen(int width,int height,int depth){

    DEVMODE dmSettings;

    memset(&dmSettings,0,sizeof(dmSettings));

    if(!EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dmSettings)){

        MessageBox(NULL,"Could Not Enum Display Settings","ERROR",MB_OK);
        return;
    }
   
    dmSettings.dmSize        = sizeof(dmSettings);
    dmSettings.dmPelsWidth    = width;
    dmSettings.dmPelsHeight    = height;
    dmSettings.dmBitsPerPel = depth;
   
    if(ChangeDisplaySettings(&dmSettings,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL){
   
        MessageBox(NULL,"Display Mode Not Compatible","ERROR",MB_OK);
        PostQuitMessage(0);
    }
}

bool CreateGLWindow(char* strWindowName,int width,int height,int depth,bool fullScreen){

    WNDCLASS    wndclass;
    DWORD        dwExStyle;
    DWORD        dwStyle;
    RECT        wRect;
    wRect.left    = 0;
    wRect.right    = width;
    wRect.top    = 0;
    wRect.bottom= height;

    g_hInstance                = GetModuleHandle(NULL);
    wndclass.style            = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
    wndclass.lpfnWndProc    = (WNDPROC) WinProc;
    wndclass.cbClsExtra        = 0;
    wndclass.cbWndExtra        = 0;
    wndclass.hInstance        = g_hInstance;
    wndclass.hCursor        = LoadCursor(NULL,IDC_ARROW);
    wndclass.hIcon            = LoadIcon(NULL,IDI_WINLOGO);
    wndclass.hbrBackground    = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName    = NULL;
    wndclass.lpszClassName    = strWindowName;

    if (!RegisterClass(&wndclass)){

        MessageBox(NULL,"Failed To Register The Window Class","ERROR",MB_OK | MB_ICONEXCLAMATION);
        return FALSE;
    }

    if (fullScreen){

        ChangeToFullScreen(width,height,depth);
        dwExStyle=WS_EX_APPWINDOW;
        dwStyle=WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
        ShowCursor(FALSE);
    }

    else {

        dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
        dwStyle=WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    }

    AdjustWindowRectEx(&wRect,dwStyle,FALSE,dwExStyle);

    if (!(g_hwnd = CreateWindowEx(    dwExStyle,
                                    strWindowName,
                                    strWindowName,
                                    dwStyle,
                                    0,0,
                                    wRect.right-wRect.left,
                                    wRect.bottom-wRect.top,
                                    NULL,
                                    NULL,
                                    g_hInstance,
                                    NULL))){

        DeInit(strWindowName);
        MessageBox(NULL,"Window Creation Error","ERROR",MB_OK | MB_ICONEXCLAMATION);
        return FALSE;
    }

    if (!(g_hDC = GetDC(g_hwnd))){

        DeInit(strWindowName);
        MessageBox(NULL,"Can't Create A GL Device Context","ERROE",MB_OK | MB_ICONEXCLAMATION);
        return FALSE;
    }

    ShowWindow(g_hwnd,SW_SHOWNORMAL);
    SetForegroundWindow(g_hwnd);
    SetFocus(g_hwnd);

    return TRUE;
}

WPARAM MainLoop(){

    MSG        msg;
   
    while (1){
   
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
            if (msg.message == WM_QUIT)
                break;
           
// HER ER PROBLEMET -->>

            else if (msg.wParam == VK_F1){
                DeInit("OpenGL");
                g_fullScreen=!g_fullScreen;
                CreateGLWindow("OpenGL",640,480,16,g_fullScreen);
                MessageBox(NULL,"JEK","ERROR",MB_OK);
                break;
            }

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else {
           
        }
    }

    return(msg.wParam);
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,PSTR cmdLine,int iShow){

    if(MessageBox(NULL,"Click Yes to go to full screen (Recommended)","Options",MB_YESNO | MB_ICONQUESTION) == IDNO)
        g_fullScreen=FALSE;

    if (!CreateGLWindow("OpenGL",640,480,16,g_fullScreen))
        return 0;

    return MainLoop();
}

LRESULT CALLBACK WinProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam){

    switch(iMsg){

    case WM_CLOSE:
        PostQuitMessage(0);

    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE) DeInit("OpenGL");
        break;

    }

    return DefWindowProc(hwnd,iMsg,wParam,lParam);
}
Avatar billede soreno Praktikant
29. marts 2003 - 17:14 #1
Jeg tror du vil kunne få glæde af at læse lesson1 og 2 her:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=01
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=02

Det er "basecode" til OpenGL.
Avatar billede freakofnature Nybegynder
29. marts 2003 - 17:39 #2
Det er ikke OpenGL, som er problemet, men det at den ikke vil skifte...
Avatar billede soreno Praktikant
29. marts 2003 - 17:50 #3
Jow, men den kode du kan downloade i bunden af hver tutorial er mere korrekt end din.

F.eks. synes jeg ikke om måden du strukturerer din "WPARAM MainLoop()" på.

Dette er bedre:
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,PSTR cmdLine,int iShow)
[..]
    if (!CreateGLWindow("OpenGL",640,480,16,g_fullScreen))
        return 0;

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

Og så bør du håndtere messages i WinProc (ligesom du gør med VK_ESCAPE). F.eks.
  case WM_KEYDOWN:
        if (wParam == VK_ESCAPE) DeInit("OpenGL");
        else if(wParam == VK_F1) [..]
        break;
Avatar billede freakofnature Nybegynder
29. marts 2003 - 21:08 #4
Tak... Jeg omstrukturerede min MainLoop, som du foreslog, og det virkede. Men hvorfor er det bedre at have WinMain() og MainLoop() samlet?
Avatar billede soreno Praktikant
29. marts 2003 - 22:21 #5
Well, jeg kan ikke lige huske forklaringen - men den bog jeg har læst foreslår det. De fleste (alle?) eksempler bruger den konstruktion.

Hvis du er interesseret i at vide mere kan du evt. kigge her:
http://www.winprog.org/tutorial/
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester