JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=2be1fc7f7416f364a3e54c3d7213db91Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Beenden über ESC funktioniert nicht richtig

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Fragen, Antworten und Kritik
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Plasmarain
Mini JLI'ler



Anmeldedatum: 21.11.2003
Beiträge: 37

Medaillen: Keine

BeitragVerfasst am: 28.11.2003, 12:08    Titel: Beenden über ESC funktioniert nicht richtig Antworten mit Zitat

Hallo zusammen,

ich habe ein Problem, vielleicht weiß ja einer wie das kommt.
Ich habe ein kleines Programm gemacht indem ich einmal einen Stehenden Bildschirm habe und durch einfaches ändern eines bools ein scrollenden.

Wenn ich dieses programm über das kleine X oben rechts am Fenster schließe läuft es einwandfrei, aber wenn ich das mit der ESC taste tue muß ich jedesmal über den "Affengriff" (Strg, Alt, Entf) das Programm beenden da ich sonst nicht mehr schreibend auf die exe zugrefen kann.

Code:

//Erzeugt ein einfaches Fenster, Grundgerüst eines Windowsprogramms mit
//DirectX 9 Klasse

//Headerdateien -------------------------------------------------------------
#include "Direct3D.h"

//#include Einbindungen -----------------------------------------------------

//Funktionen deklarieren ----------------------------------------------------
//Anwendungsfenster erzeugen
HWND CreateMainWindow(HINSTANCE hInstance);

//Callback-Funktion zur Nachrichtenbehandlung
LRESULT CALLBACK MessageHandler(HWND hWnd,
                        UINT msg,
                        WPARAM wParam,
                        LPARAM lParam);

//Variablen deklarieren -----------------------------------------------------
HWND hWnd = 0;

//Klassen Instanz -----------------------------------------------------------
CDirect3D Direct3D;

//WinMain -------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance,
               HINSTANCE hPrevInstance,
               LPSTR lpCmdLine,
               int nShowCmd)
{
   //Fenster erzeugen und Handle speichern
   hWnd = CreateMainWindow(hInstance);

   //Wenn der Rückgabewert 0 ist, ist ein Fehler aufgetreten
   if(0 == hWnd)
   {
      MessageBox(0, "Fenster konnte nicht erzeugt werden",
         "Fehler!", MB_OK);
      return 0;
   }

    // Direct3D initialisieren
    if(!Direct3D.Init(hWnd, TRUE))
    {
        return -1;
    }

   // Farbe die beim Löschen verwendet werden soll
    Direct3D.SetClearColor(D3DCOLOR_XRGB(0,0,0xFF));

    //Hintergrundart wählen
    Direct3D.Hintergrundart(AUSWAHLHINTERGRUND, SCROLLBACKGROUND, BACKGROUND);

   //Struktur, in der Informationen zur Nachricht gespeichert werden
   MSG msg;

   //Spieleschleife & Message- Behandlung
   while(msg.message != WM_QUIT)
   {
      if(PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
      {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
      }
      else
      {
         // Text ausgeben
            Direct3D.BeginScene(AUSWAHLHINTERGRUND);
            Direct3D.DrawText("Hallo Direct3D",100,100,D3DCOLOR_XRGB(0xFF,0,0));
            Direct3D.EndScene();
      }
   }

    //Rückgabe an Windows
   return 0;
}

//Funktionen definieren -----------------------------------------------------
HWND CreateMainWindow(HINSTANCE hInstance)
{
   WNDCLASSEX wndClass = {
      sizeof(WNDCLASSEX),                       //Größe angeben
         CS_DBLCLKS | CS_OWNDC |               //Standartstile
         CS_HREDRAW | CS_VREDRAW,
         MessageHandler,                       //Callback-Funktion
         0,                                    //Zusätzliche Angaben
         0,                                    //nicht benötigt
         hInstance,                            //Anwendungsinstanz
         LoadIcon(NULL, IDI_WINLOGO),          //Windows-Logo
         LoadCursor(NULL, IDC_ARROW),          //Normaler Cursor
         (HBRUSH)GetStockObject(WHITE_BRUSH),  //Weißer Pinsel
         NULL,                                 //kein Menü
         "WindowClass",                        //Der Name der Klasse
         LoadIcon(NULL, IDI_WINLOGO)           //Windows-Logo
   };

   //Fensterklasse registrieren, damit sie von
   //CreateWindowEx() verwendet werden kann
    RegisterClassEx(&wndClass);

   //Der Rückgabewert von CreateWindowEx() ist auch der
   //Rückgabewert der Funktion
   return CreateWindowEx(
      NULL,                                     //Ohne erweiterte Stile
      "WindowClass",                            //Klassenname
      "Ein einfaches Fenster",                  //Fenstertitel
      WS_OVERLAPPEDWINDOW |                     //Fenster
      WS_VISIBLE,                               //Eigenschaften
      0, 0,                                     //Anfangspositionen
      SCR_WIDTH, SCR_HEIGHT,                    //Größe
      NULL,                                     //Handle des Elternfensters
      NULL,                                     //Handle des Menüs
      hInstance,                                //Anwendungsinstanz
      NULL);                                    //Nicht benötigt
}

//---------------------------------------------------------------------------
LRESULT CALLBACK MessageHandler(HWND hWnd,
                        UINT msg,
                        WPARAM wParam,
                        LPARAM lParam)
{
   //Entscheiden, welche Nachricht empfangen wurde
   switch(msg)
   {
       //wenn das Fenster geschlossen wird, wid
      //WM_QUIT gesendet, um das Programm zu beenden
   case WM_CLOSE:
      
      PostQuitMessage(0);
      return 0;
      break;

    case WM_KEYDOWN:
        switch(wParam)
      {
           // Wenn ESC gedrückt, Anwendung beenden
           case VK_ESCAPE:
               DestroyWindow(hWnd);
               break;
        }
        break;
   }

   //Wenn eine andere Nachricht gesendet wurde,
   //Standartfunktion aufrufen
   return (DefWindowProc(hWnd, msg, wParam, lParam));
}

//---------------------------------------------------------------------------

und nun noch die Direct3D:

Code:

//Headerdateien -------------------------------------------------------------
#include "Direct3D.h"

//#include Einbindungen -----------------------------------------------------
#include <dxerr9.h>

//Klasse zur Grafikausgabe mit DirectX9 -------------------------------------
CDirect3D::CDirect3D()
{
    m_lpD3D       = NULL;   //Direct3D9- Interface (anlegen)
    m_lpD3DDevice = NULL;   //Grafikkarte auswählen/ Einstellung
    m_lpD3DFont   = NULL;   //Text

   m_lpSurface   = NULL;
   m_lpBackBuffer = NULL;
   m_lpScrollSurface = NULL;
    m_lpScrollBuffer     = NULL;

    // Definition der Rechtecke für das Scrolling
    m_ScrollRect1.left   =    0;
    m_ScrollRect1.top    =    0;
    m_ScrollRect1.right  = 1024;
    m_ScrollRect1.bottom =  768;

    m_ScrollRect2.left   =    0;
    m_ScrollRect2.top    =    0;
    m_ScrollRect2.right  =    0;
    m_ScrollRect2.bottom =  768;

    m_PosSurface = 1024;
}

CDirect3D::~CDirect3D()
{
    CleanUp();
}

// Direct3D initialisieren
BOOL CDirect3D::Init(HWND hWnd, BOOL bWindowed)  //bWindowed -> Vollbild oder Fenster
{
    // Direct3D-Objekt erzeugen
    m_lpD3D = Direct3DCreate9(D3D_SDK_VERSION);

    if(NULL == m_lpD3D)
    {
        // Fehler, D3D-Objekt wurde nicht erzeugt
        return FALSE;
    }

    // Parameter für den Modus festlegen
    D3DPRESENT_PARAMETERS PParams;
    ZeroMemory(&PParams,sizeof(PParams));

    PParams.SwapEffect       = D3DSWAPEFFECT_DISCARD;
    PParams.hDeviceWindow    = hWnd;
    PParams.Windowed         = bWindowed;               

    PParams.BackBufferWidth  = SCR_WIDTH;               //Breite
    PParams.BackBufferHeight = SCR_HEIGHT;              //Höhe
    PParams.BackBufferFormat = D3DFMT_A8R8G8B8;

    HRESULT hr;
   
    // Direct3D-Gerät anlegen
    if(FAILED(hr = m_lpD3D->CreateDevice(
                                 D3DADAPTER_DEFAULT,
                                 D3DDEVTYPE_HAL,
                                 hWnd,
                                 D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                 &PParams,
                                 &m_lpD3DDevice)))
    {
        // Fehler, Gerät kann nicht angelegt werden
        const char* Err = DXGetErrorDescription9(hr);
 
        DXTRACE_MSG(Err);

        return FALSE;
    }
   
    CreateFont();
 
    return TRUE;
}

//Klassenmethoden -----------------------------------------------------------
//Farbe für den Backbuffer festlegen ----------------------------------------
void CDirect3D::SetClearColor(D3DCOLOR Color)
{
    m_ClearColor = Color;
}

//Auswahl Hintergrund Scroll oder normal ------------------------------------
void CDirect3D::Hintergrundart(BOOL bAuswahl, LPCSTR Scroll, LPCSTR Back)
{
   if(bAuswahl)
   {
       //Scroll Hintergrund setzen
      SetScrollBackGround(Scroll);
   }
   if(!bAuswahl)
   {
       //Hintergund setzen
      SetBackGround(Back);
   }
}

//Text an Position x,y ausgeben ---------------------------------------------
void CDirect3D::DrawText(LPCSTR Text, int x, int y, D3DCOLOR TextColor)
{
    RECT r = { x, y, 0, 0 };

    // Größe des Rechtecks berechnen
    m_lpD3DFont->DrawText(Text, -1, &r, DT_CALCRECT, TextColor);

    // Text ausgeben
    m_lpD3DFont->DrawText(Text, -1, &r, DT_CENTER, TextColor); 
}

//Methoden zum Start/Beenden der Szene --------------------------------------
void CDirect3D::BeginScene(BOOL bAuswahl)
{
   
   // Puffer mit blau füllen
    m_lpD3DDevice->Clear(0,0,D3DCLEAR_TARGET, m_ClearColor, 0,0);

    m_lpD3DDevice->BeginScene();

   if(bAuswahl)
   {
   
    // Um das Scrolling zu realisieren, wird in m_lpScrollBuffer in jedem
    // Durchlauf eine neue Spalte aus der Grafik kopiert.
    // Die beiden Rechtecke werden angelegt, da bei dieser Methode zwei
    // Kopiervorgänge stattfinden müssen.
    // Die Größe der Rechtecke muss in jedem Schritt angepasst werden.
   

    // Rechtecke definieren
    RECT r1, r2;

    // testen, ob das Rechteck breiter als ein Pixel wird
    if(m_ScrollRect1.left != m_ScrollRect1.right)
    {
        // neues Rechteck konstruieren
        r1.left   =    0;
        r1.right  = 1024 - m_ScrollRect1.left;
        r1.top    =    0;
        r1.bottom =  768;
        m_lpD3DDevice->StretchRect(m_lpScrollBuffer,&m_ScrollRect1,
         m_lpBackBuffer,&r1,D3DTEXF_NONE);
    }       

    // testen, ob das Rechteck breiter als ein Pixel wird
    if(m_ScrollRect2.left != m_ScrollRect2.right)
    {
        // neues Rechteck konstruieren
        r2.left   = 1024 - m_ScrollRect2.right;
        r2.right  = 1024;
        r2.top    =    0;
        r2.bottom =  768;

        m_lpD3DDevice->StretchRect(m_lpScrollBuffer,&m_ScrollRect2,
         m_lpBackBuffer,&r2,D3DTEXF_NONE);
    }

    // die Oberfläche m_lpScrollBuffer sperren und einen Zeiger
    // auf die der Oberfläche Pixel holen
    D3DLOCKED_RECT LockedRectBuffer;

    m_lpScrollBuffer->LockRect(&LockedRectBuffer,NULL,0);
   
    int PitchBuffer = LockedRectBuffer.Pitch / 4;
   
    D3DCOLOR* PixelsBuffer = (D3DCOLOR*)LockedRectBuffer.pBits;


    // die Oberfläche m_lpScrollSurface sperren und einen Zeiger
    // auf die der Oberfläche Pixel holen
    D3DLOCKED_RECT LockedRectSurface;   
   
    m_lpScrollSurface->LockRect(&LockedRectSurface,NULL,0);
   
    int PitchSurface = LockedRectSurface.Pitch / 4;
   
    D3DCOLOR* PixelsSurface = (D3DCOLOR*)LockedRectSurface.pBits;

    // Kopieren einer Spalte aus m_lpSurface in m_lpScrollBuffer
    for(int i=0;i<768;i++)
    {       
        PixelsBuffer[i * PitchBuffer + m_ScrollRect1.left] = PixelsSurface[i * PitchSurface + m_PosSurface];
    }
   
    // beide Oberflächen entsperren
    m_lpScrollBuffer->UnlockRect();
    m_lpScrollSurface->UnlockRect();
 
    // testen, ob noch gescrollt werden soll, oder ob
    // das Ende der Grafik erreicht wurde
    if(m_PosSurface < 5*1024)
    {
        m_PosSurface++;
   
        m_ScrollRect1.left++;
        m_ScrollRect2.right++;
   
        if(m_ScrollRect1.left > 1024)
        {
            m_ScrollRect1.left  = 0;
            m_ScrollRect2.right = 0;
        }
    }
   }
   if(!bAuswahl)
   {

   // aktuellen Bereich in den Backbuffer kopieren
    m_lpD3DDevice->StretchRect(m_lpSurface,
                               NULL,
                               m_lpBackBuffer,
                               0,
                               D3DTEXF_NONE);
   }

}

//---------------------------------------------------------------------------

void CDirect3D::EndScene(void)
{
    m_lpD3DDevice->EndScene();

    m_lpD3DDevice->Present(0,0,0,0);
}

//Erzeugen der D3D-Schrift --------------------------------------------------
void CDirect3D::CreateFont(void)
{
    // Struktur für die Beschreibung der Schriftart
    // anlegen und Elemente mit 0 initialisieren
    LOGFONT    LogFont = { 0 };

    // das Element lfFaceName muss den Namen der
    // gewünschten Schriftart enthalten
    strcpy(LogFont.lfFaceName, "Arial");

    // nach erfolgreichem Aufruf zeigt lpD3DFont
    // auf ein Objekt vom Typ D3DXFont
    D3DXCreateFontIndirect(m_lpD3DDevice,
                           &LogFont,
                           &m_lpD3DFont);
}

//Hintergrund anlegen -------------------------------------------------------
void CDirect3D::SetBackGround(LPCSTR lpBackground)
{
   //Offscreen surface erschaffen
   m_lpD3DDevice->CreateOffscreenPlainSurface(
      1024, 768,
      D3DFMT_X8R8G8B8,
      D3DPOOL_DEFAULT,
      &m_lpSurface,
      0);


   
   //Rechteck erschaffen
   RECT r= {0, 0, 1024, 768};

   //Grafik laden
    D3DXLoadSurfaceFromFile(m_lpSurface, 0, &r,
      lpBackground,
      0, D3DX_DEFAULT, 0, NULL);

    // Zeiger auf dem Hintergrundpuffer holen
    m_lpD3DDevice->GetBackBuffer(0,0,
                                 D3DBACKBUFFER_TYPE_MONO,
                                 &m_lpBackBuffer);

   // Wahlweise roter Hintergrund
    //m_lpD3DDevice->ColorFill(m_lpSurface, NULL, 0xF0FF0000);

}

//Scrollender Hintergrund anlegen -------------------------------------------
void CDirect3D::SetScrollBackGround(LPCSTR lpScrollBackground)
{
// Dieser Puffer wird im Hauptspeicher (D3DPOOL_SCRATCH)
    // erzeugt. Dadurch kann er beliebig groß sein.
    // Der Nachteil besteht darin, dass er nicht mit StretchRect
    // kopiert werden kann, da die Grafikkarte nicht auf Puffer,
    // die mit D3DPOOL_SCRATCH erzeugt wurden zugreifen kann.
    // Aus diesem Grund müssen wir ihn "von Hand", mittels
    // LockRect()/UnlockRecht() kopieren.
    m_lpD3DDevice->CreateOffscreenPlainSurface(
                                        1024*5,768,
                                        D3DFMT_X8R8G8B8,
                                        D3DPOOL_SCRATCH,
                                        &m_lpScrollSurface,
                                        0);

    // Einen weiteren Puffer für die Zwischenspeicherung
    // der Grafik verwenden. In diesen Buffer wird später
    // spaltenweise aus der neuen Grafik kopiert
    m_lpD3DDevice->CreateOffscreenPlainSurface(
                                        1024,768,
                                        D3DFMT_X8R8G8B8,
                                        D3DPOOL_DEFAULT,
                                        &m_lpScrollBuffer,
                                        0);
    RECT r = { 0, 0, 1024, 768 };

   
    // Die Grafik Landschaft_mit_Brücke_5120_768.png ist 5120 * 768 Pixel groß

    // In m_lpScrollBuffer werden nur die ersten 1024 * 768 Pixel kopiert
    D3DXLoadSurfaceFromFile(m_lpScrollBuffer, 0,&r,
      lpScrollBackground,&r,D3DX_DEFAULT,0,NULL);
   
    // In m_lpScrollSurface wird die komplette Grafik kopiert
    D3DXLoadSurfaceFromFile(m_lpScrollSurface,0, 0,
      lpScrollBackground, 0,D3DX_DEFAULT,0,NULL);

 
    // Zeiger auf dem Hintergrundpuffer holen
    m_lpD3DDevice->GetBackBuffer(0,0,
                                 D3DBACKBUFFER_TYPE_MONO,
                                 &m_lpBackBuffer);
}

//Freigeben der Objekte -----------------------------------------------------
void CDirect3D::CleanUp(void)
{
    // testen, ob die Objekt angelegt
    // wurden und ggf. freigeben
    if(NULL != m_lpD3DFont)
    {
        m_lpD3DFont->Release();
        m_lpD3DFont = NULL;
    }

    if(NULL != m_lpScrollBuffer)
    {
        m_lpScrollBuffer->Release();
        m_lpScrollBuffer = NULL;
    }

    if(NULL != m_lpScrollSurface)
    {
        m_lpScrollSurface->Release();
        m_lpScrollSurface = NULL;
    }
   
    if(NULL != m_lpBackBuffer)
    {
        m_lpBackBuffer->Release();
        m_lpBackBuffer = NULL;
    }

    if(NULL != m_lpSurface)
    {
        m_lpSurface->Release();
        m_lpSurface = NULL;
    }

    if(NULL != m_lpD3DDevice)
    {
        m_lpD3DDevice->Release();
        m_lpD3DDevice = NULL;
    }
   
    if(NULL != m_lpD3D)
    {
        m_lpD3D->Release();
        m_lpD3D = NULL;
    }
}

//---------------------------------------------------------------------------




Ich hoffe mir kann einer helfen, ich weiß da echt nichtmehr weiter.

MFG

Matthias
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 41
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 28.11.2003, 12:18    Titel: Antworten mit Zitat

Probier mal folgendes:

Code:
case WM_KEYDOWN:
        switch(wParam)
      {
           // Wenn ESC gedrückt, Anwendung beenden
           case VK_ESCAPE:
               //DestroyWindow(hWnd);
               SendMessage(hWnd,WM_QUIT,0,0);
               break;
        }
        break;

_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Plasmarain
Mini JLI'ler



Anmeldedatum: 21.11.2003
Beiträge: 37

Medaillen: Keine

BeitragVerfasst am: 28.11.2003, 12:44    Titel: Antworten mit Zitat

Jetzt reagiert der garnicht mehr auf die ESC taste.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 28.11.2003, 13:30    Titel: Antworten mit Zitat

Dann versuchs mal so:
Code:
case WM_DESTROY:
       
      PostQuitMessage(0);
      return 0;
      break;

Einfach WM_CLOSE mit WM_DESTROY austauschen, dann sollte es funktionieren Wink
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Plasmarain
Mini JLI'ler



Anmeldedatum: 21.11.2003
Beiträge: 37

Medaillen: Keine

BeitragVerfasst am: 28.11.2003, 13:38    Titel: Antworten mit Zitat

Ja super!

Das geht!

Wenn man das erstaml weiß ist das auch ganz klar aber daruf zu kommen.... (als anfänger)


Danke!! euch beiden!

Matthias
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Fragen, Antworten und Kritik Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum