|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Fossil Mini JLI'ler
Alter: 89 Anmeldedatum: 07.03.2006 Beiträge: 11 Wohnort: Tübingen Medaillen: Keine
|
Verfasst am: 09.03.2006, 22:54 Titel: DDFenster aus Kapitel 17 |
|
|
Hallo jli-Gemeinde!
ich bin ein neuer Pilger im Land der Spieleprogrammierer, reiner Autodidakt in C++ und DirectX. Zwar bin ich schon bis Kapitel 17 des Buches vorgedrungen, habe aber beträchtliche Schwierigkeiten. Deshalb habe ich mich der jli-Gemeinde angeschlossen.
Meine erste Frage ist gewesen, warum das von der CD kopierte Programm DDFenster in Kapitel 17 nicht laufe, sondern die MessageBox "Fehler beim Erzeugen des Fenster" bringe. Diese Frage habe ich schon Christian Rousselle vorgelegt. Er wunderte sich, fragte nach Rechnersystem und Cd-Installation.
Der Grund ist viel einfacher: Ich habe das Programm verändert - und das einfach vergessen (Fossil). Ich habe mich gewundert, warum in diesem Programm sowohl die HWND-Variable hWnd (das Fenster-Handle) als auch hwnd (wofür steht das?) verwendet ist und habe im Befehl der CALLBACK Funktion return statt (DefWindowProc(hwnd,msg,wParam,lParam) geschrieben: (DefWindowProc(hWnd,msg,wParam,lParam). Darauf konnte das Fenster nicht mehr geöffnet werden.
Dennoch ist mir die Bedeutung der beiden Variablen hWnd und hwnd und die Notwendigkeit ihrer Unterscheidung nicht klar. Denn wenn man hWnd sowohl in die CALLBACK Funktion WindowFunc(...) als auch DefWindowProc(....) einsetzt, läuft das Programm auch. Kann mir das jemand erkären?
Und nun noch eine ganz blöde Frage: wenn man eine Funktion wie "WindowFunc( " zu schreiben beginnt, poppt die gesamte Funktion auf. Gibt es eine Taste mit der man dies ins Programm übernehmen kann, sodaß man es nicht mehr shreiben muß?
Euer Fossil _________________ Weissjurabeta |
|
Nach oben |
|
|
Chriss Senior JLI'ler
Anmeldedatum: 18.08.2004 Beiträge: 267
Medaillen: Keine
|
Verfasst am: 10.03.2006, 06:53 Titel: |
|
|
Hi Fossil
Generell wäre es gut wenn du den entsprechende Codestelle posten würdest da man sonst nur vermuten kann warum das so ist.
Zitat: |
Und nun noch eine ganz blöde Frage: wenn man eine Funktion wie "WindowFunc( " zu schreiben beginnt, poppt die gesamte Funktion auf. Gibt es eine Taste mit der man dies ins Programm übernehmen kann, sodaß man es nicht mehr shreiben muß? |
Bei Visual Studio sollte es bei der Standardeinstellung reichen Return zu drücken.
Grüße |
|
Nach oben |
|
|
KI JLI Master
Alter: 39 Anmeldedatum: 04.07.2003 Beiträge: 965 Wohnort: Aachen Medaillen: Keine
|
Verfasst am: 10.03.2006, 09:03 Titel: |
|
|
Bei meinen JLI-Beispielen gibt es keinen Ordner für das 17. Kapitel.
Aber für Kapitel 12 gibt es ein Beispiel namens HelloWindows, welches auf deine Frage passt.
Wir haben hier zum einen die Deklaration der globalen Variable hWnd, welche sofort mit 0 initialisiert wird und zum anderen die main-Funktion
CPP: | // Das Fensterhandle
HWND hWnd = 0;
// Windows main-Funktion
int WINAPI WinMain(HINSTANCE hInstance, // Handle der Programminstanz
HINSTANCE hPrevInstance, // Handle der letzten Instanz
LPSTR lpCmdLine, // Kommandozeile
int nCmdShow) // Art wie das Fenster angezeigt werden soll
{
// 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;
}
// Struktur, in der Informationen zur Nachricht gespeichert werden
MSG msg;
// Diese Schleife läuft bis die Nachricht WM_QUIT empfangen wird
while(GetMessage(&msg,NULL,0,0))
{
// Nachricht an die Callbackfunktion senden
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Rückgabewert an Windows
return 0;
}
|
Auf der anderen Seite ist der Messagehandler.
CPP: | // Diese Funktion wird von Windows aufgrufen, wenn eine Nachricht
// für Ihr Programm vorliegt
LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// testen, um welche Nachticht es sich handelt
switch(msg)
{
// wenn das Fenster geschlossen wird, eine Nachricht senden,
// die das Programm beendet
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
}
// Wenn wir uns nicht um die Nachricht gekümmert haben
// wird sie an die Standardnachrichtenverarbeitung von Windows
// geschickt
return DefWindowProc(hwnd, msg, wParam, lParam);
} |
Jetzt zum Unterschied der beiden HWND-Variablen. Deine Vermutung ist richtig, die beiden HWND-Zeiger zeigen tatsächlich auf den selben Speicherbereich. Also ist es im Endeffekt Wurst welche HWND-Variable man benutzt.
Denn die CALLBACK-Funktion zur Behandlung der Fensternachrichten wird vom Betriebssystem mit dem dazugehörigen Fensterhandle aufgerufen. Und das ist im unseren Fall hWnd.
Wenn man mit dem Debugger das Programm im MessageHandler anhält (z.B. durch einen vorher gesetzten Haltepunkt), stellt man fest, dass die beiden Zeiger auf die gleiche Adresse zeigen.
Für die Praxis ist es allerdings ratsam die HWND-Variale aus dem Funktiosnkopf des Messagehandlers zu benutzen, denn der Handler des Fensters muss nicht zwingend global deklariert werden.
Gruß KI
Zuletzt bearbeitet von KI am 10.03.2006, 10:55, insgesamt einmal bearbeitet |
|
Nach oben |
|
|
AFE-GmdG JLI MVP
Alter: 45 Anmeldedatum: 19.07.2002 Beiträge: 1374 Wohnort: Irgendwo im Universum... Medaillen: Keine
|
Verfasst am: 10.03.2006, 10:32 Titel: |
|
|
Es ist immer Sinnvoll im Fensterhander den Lokalen Parameter hWnd zu nutzen. Ob er nun klein geschrieben ist, oder mit Großem W oder auch "FensterHandle" heisst, ist quasi egal. Nicht egal hingegen ist es, wenn mann von Vorne herein immer nur eine Global definierte Variable nutzt - und zwar immer dann, wenn man nicht nur ein Fenster hat, dass man behandeln muss. Das mag ganz am Anfang nie vorkommen - ich hingegen habe öfters mit mehreren Fensterhandles zu tun.
PS.: noch eine Frage am Rand: Bist du wirklich 70 Jahre alt??? Nicht übelnehmen, aber ich keinne keinen 70Jährgen, der sich noch so intensiv mit Computern bzw. sogar mit deren Programmierung beschäftigt - bzw. damit anfängt.
MFG, AFE-GmdG _________________
CPP: | float o=0.075,h=1.5,T,r,O,l,I;int _,L=80,s=3200;main(){for(;s%L||
(h-=o,T= -2),s;4 -(r=O*O)<(l=I*I)|++ _==L&&write(1,(--s%L?_<(L)?--_
%6:6:7)+\"World! \\n\",1)&&(O=I=l=_=r=0,T+=o /2))O=I*2*O+h,I=l+T-r;} |
|
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 10.03.2006, 13:19 Titel: |
|
|
Ja, ich hatte schon mla Probleme damit, als ich mein Fensterhandle Global hatte und innerhalb der Fenstercallback Funktion genutzt habe. Da diese als Parameter ja eh immer das Fensterhandel mitgeliefert bekommt, gibt es eignetilch keinen Grund innerhalb der Callback funktion ein globales Handel zu benutzen. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
Fossil Mini JLI'ler
Alter: 89 Anmeldedatum: 07.03.2006 Beiträge: 11 Wohnort: Tübingen Medaillen: Keine
|
Verfasst am: 11.03.2006, 17:30 Titel: hWnd und hwnd |
|
|
Hallo Chriss, KI, AFE-GmdG und Jonathan_Klein,
vielen Dank für Eure Antworten. Ich sehe, daß das Fensterhandle der CALLBACK-Funktion übergeben wird. Dann ist es wohl besser, nicht das globale hWnd, sondern das lokale hwnd zu verwenden, wie AFE-GmdG vorschlägt. Es ist einsichtig, wenn man mehrere Fenster hat. Damit ist meien Frage beantwortet, Dank Euch allen.
Ja, AFE-GmdG, ich bin 70 und habe vor etwa einem Jahr mit C++ begonnen. Allerdings habe ich schon in meiner Doktorarbeit 1964 ein großes ALGOL Programm geschrieben, seither aber nicht mehr aktiv programmiert und damit die zwischenzeitlich aktuellen Sprachen wie Fortran oder Pascal übersprungen.
Euer Fossil _________________ Weissjurabeta |
|
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
|