 |
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Plasmarain Mini JLI'ler
Anmeldedatum: 21.11.2003 Beiträge: 37
Medaillen: Keine
|
Verfasst am: 28.11.2003, 12:08 Titel: Beenden über ESC funktioniert nicht richtig |
|
|
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 |
|
 |
Fallen JLI MVP


Alter: 41 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 28.11.2003, 12:18 Titel: |
|
|
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 |
|
 |
Plasmarain Mini JLI'ler
Anmeldedatum: 21.11.2003 Beiträge: 37
Medaillen: Keine
|
Verfasst am: 28.11.2003, 12:44 Titel: |
|
|
Jetzt reagiert der garnicht mehr auf die ESC taste. |
|
Nach oben |
|
 |
The Lord of Programming Living Legend

Alter: 37 Anmeldedatum: 14.03.2003 Beiträge: 3122
Medaillen: Keine
|
Verfasst am: 28.11.2003, 13:30 Titel: |
|
|
Dann versuchs mal so:
Code: | case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
|
Einfach WM_CLOSE mit WM_DESTROY austauschen, dann sollte es funktionieren  _________________ 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 |
|
 |
Plasmarain Mini JLI'ler
Anmeldedatum: 21.11.2003 Beiträge: 37
Medaillen: Keine
|
Verfasst am: 28.11.2003, 13:38 Titel: |
|
|
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 |
|
 |
|
|
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
|