Mein erstes eigenes Win32 Fenster. Aber was ist daran falsch?

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • Mein erstes eigenes Win32 Fenster. Aber was ist daran falsch?

    Hallo!
    Ich bin neu auf diesem Forum, also will ich erstmal schöne Grüße und ein großes Hallo hier in die Runde rufen! :D
    Kommen wir zur Sache:
    Ich hab ein Problem. Momentan lerne ich C++ aus dem Buch "C++ für Spieleprogrammierer" von Heiko Kalista.
    Ich bin gerade in Kapitel 10. Dort wird ein Sample gezeigt, wie man ein eigenes Fenster erstellt.
    Das sieht so aus:

    Source Code

    1. // C++ für Spieleprogrammierer
    2. // Listing 10.1
    3. // Ein Windows-Grundgerüst
    4. //
    5. #include <windows.h>
    6. // Prototyp der Callback-Funktion
    7. LRESULT CALLBACK WindowProc (HWND hWnd, UINT message,
    8. WPARAM wParam, LPARAM lParam);
    9. // Hauptprogramm
    10. //
    11. int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
    12. LPSTR lpcmdline, int ncmdshow)
    13. {
    14. WNDCLASSEX windowclass; // Struktur für Fenstereigenschaften
    15. HWND hWnd; // Fenster-Handle
    16. MSG message; // Nachricht
    17. // Der Klassen-Name des Fensters ist frei wählbar
    18. const char szClassName[] = "First Window";
    19. // Struktur mit gewünschten Eigenschaften füllen
    20. //
    21. // Größe der Struktur zwischenspeichern
    22. windowclass.cbSize = sizeof (WNDCLASSEX);
    23. // Fenster soll beim Verschieben neu gezeichnet werden
    24. windowclass.style = CS_HREDRAW | CS_VREDRAW;
    25. // Zeiger auf Callback-Funktion
    26. windowclass.lpfnWndProc = WindowProc;
    27. // Keine erweiterten Einstellungen
    28. windowclass.cbClsExtra = 0;
    29. windowclass.cbWndExtra = 0;
    30. // Instanz speichern
    31. windowclass.hInstance = hInst;
    32. // Icons und Cursor festlegen
    33. windowclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    34. windowclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    35. windowclass.hCursor = LoadCursor (NULL, IDC_ARROW);
    36. // Hintergrundfarbe festlegen
    37. windowclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND+1;
    38. // Ein Menü brauchen wir nicht
    39. windowclass.lpszMenuName = NULL;
    40. // Klassenname angeben
    41. windowclass.lpszClassName = szClassName;
    42. // Fensterklasse registrieren
    43. if (!RegisterClassEx (&windowclass) )
    44. return (0);
    45. // Das Fenster erzeugen
    46. hWnd = CreateWindowEx (NULL,
    47. szClassName,
    48. "First Window!",
    49. WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    50. 100, 100,
    51. 300, 250,
    52. NULL,
    53. NULL,
    54. hInst,
    55. NULL);
    56. // Prüfen, ob alles glatt ging
    57. if (hWnd == NULL)
    58. return (0);
    59. // Der "Herzschlag" des Programms.
    60. // Hier werden alle Nachrichten abgeholt,
    61. // übersetzt und weitergeleitet.
    62. while (GetMessage (&message, NULL, 0, 0) )
    63. {
    64. TranslateMessage (&message);
    65. DispatchMessage (&message);
    66. }
    67. // Programm beenden
    68. return (int)(message.wParam);
    69. } // WinMain
    70. // Callback-Funktion zur Nachrichtenverarbeitung
    71. //
    72. LRESULT CALLBACK WindowProc (HWND hWnd, UINT message,
    73. WPARAM wParam, LPARAM lParam)
    74. {
    75. // Messages auswerten
    76. switch (message)
    77. {
    78. // Fenster schließen? (Auch Alt-F4)
    79. case WM_DESTROY:
    80. {
    81. // Nachricht zum Beenden schicken
    82. PostQuitMessage (0);
    83. return (0);
    84. }
    85. // Wurde eine Taste gedrückt?
    86. case WM_KEYDOWN:
    87. {
    88. // Ja, also je nach Taste verzweigen
    89. switch (wParam)
    90. {
    91. // Wurde "Escape" gedrückt?
    92. case VK_ESCAPE:
    93. {
    94. // Ja, also Nachricht zum Beenden schicken
    95. PostQuitMessage (0);
    96. return (0);
    97. }
    98. }
    99. } break;
    100. }
    101. // Die Nachricht wurde nicht von uns verarbeitet, also
    102. // von Windows verarbeiten lassen.
    103. return (DefWindowProc (hWnd, message, wParam, lParam) );
    104. } // WindowProc
    Display All


    Ja, Das Problem ist nur, dass mir jetzt beim kompilieren 2 fette Fehlermeldungen raus gehauen werden:
    ------ Erstellen gestartet: Projekt: lernen021, Konfiguration: Debug Win32 ------
    Fenster.cpp
    q:\projekte c++\lernen021\lernen021\fenster.cpp(54): error C2440: '=': 'const char [13]' kann nicht in 'LPCWSTR' konvertiert werden
    Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.
    q:\projekte c++\lernen021\lernen021\fenster.cpp(70): error C2664: 'CreateWindowExW': Konvertierung des Parameters 2 von 'const char [13]' in 'LPCWSTR' nicht möglich
    Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========


    Ich bitte euch, was ist daran falsch? Ich selbst kann es nicht lösen, dazu sind zu viel neue Begriffe enthalten. Dürften so 80% des ganzen Samples sein..... :-/
    Ich danke schon mal für eure Hilfe.
    mfg
    ich^^
  • Hab das mal durch 2 Compiler gejagt.
    Der eine gibt drei Warnungen, das ich vereinbarte Variable nicht nutze -> vernachlässigbar
    Der andere gibt eine andere Warnung: winapi01.c|70|warning: passing argument 1 of 'CreateWindowExA' makes integer from pointer without a cast| -> das sollte man sich genauer ansehen, wenn es Probleme gibt.

    Bei beiden Compilern ist das Ergebnis ein einfaches Fenster, was ja wohl beabsichtigt war.

    So, welchen Compiler mit welchen Projekteinstellungen lässt du auf den Quelltext los?
    Sind da Empfehlungen in deinem Buch zur Nutzung des Compilers?

    So hab noch mal in der MSDN nachgesehen.
    Versuche mal folgendes:

    Source Code

    1. hWnd = CreateWindowEx (WS_EX_LEFT,
    2. szClassName,
    3. "First Window!",
    4. WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    5. 100, 100,
    6. 300, 250,
    7. NULL,
    8. NULL,
    9. hInst,
    10. NULL);


    Bin jetzt nicht des Spezi der Feinheiten - es scheint so das nicht bei allen Compilern NULL = 0L ist ;(

    MfG bcc-fan

    The post was edited 2 times, last by bcc-fan: Ergänzung anhand MSDN ().

  • Ich benutze Microsoft Visual C++ 2010 Express.

    Das Buch ist auch irgendwie doof, es zeigt die Beispiele nicht an wichtigen Beispielen, nein, an unwichtigen.
    Zumal hat der Autor anscheinend einen Fimmel für Asteroid Games. Das End-Spiel (was ich gerade programmiere) ist so eins und in gut jedem Kapitel kommen Raumschiffe o.Ä. vor....
    Naja egal. Mal so nebenbei, empfiehlt mir jemand ein GUTES Buch, wo es auch um die Spiele-Programmierung in 2D geht?

    Das Syntax das du mir zeigst, werde ich gleich mal ausprobieren.
  • Sorry, kann Beitrag nicht editieren.... Mein Browser schließt sich sofort wenn ich es versuche....
    Naja, es klappt auch dann nicht, wegen diesem Fehlers:

    ------ Erstellen gestartet: Projekt: Lernen021, Konfiguration: Debug Win32 ------
    Fenster.cpp
    q:\projekte c++\lernen021\lernen021\fenster.cpp(128): fatal error C1010: Unerwartetes Dateiende während der Suche nach dem vorkompilierten Header. Haben Sie möglicherweise vergessen, im Quellcode "#include "StdAfx.h"" einzufügen?
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========


    Vielleicht könnte ja ein Moderator das zusammenfügen.
  • Mensch Mensch Mensch, mein 3. Doppelpost....
    Ich hab den Fehlerlog eben falsch ab kopiert, war ein anderes Projekt. Hier der richtige mit beigefügtem Vorschlag:

    ------ Erstellen gestartet: Projekt: Fenster, Konfiguration: Debug Win32 ------
    Fenster.cpp
    q:\projekte c++\fenster\fenster\fenster.cpp(50): error C2440: '=': 'const char [13]' kann nicht in 'LPCWSTR' konvertiert werden
    Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.
    q:\projekte c++\fenster\fenster\fenster.cpp(66): error C2664: 'CreateWindowExW': Konvertierung des Parameters 2 von 'const char [13]' in 'LPCWSTR' nicht möglich
    Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
  • Hier mal wie Microsoft zur Zeit das Beispiel texten würde:
    msdn.microsoft.com/de-de/library/bb384843.aspx

    oben stehen da auch die Compilereinstellungen.

    Solche kleine Nicklichkeiten wirst du immer wieder begegnen - mal hast du älteren Quelltext, den du in ein neueres Projekt einpassen willst - ein anderes Mal wurde ein Projekt mit einem anderen Compiler entwickelt. Da reicht manchmal schon eine andere Versionsnummer beim gleichen Compiler.

    Hast ja gleichzeitig geschrieben - dann gibt deinem Compiler halt den Header den nur Microsoft gern hätte :D

    Hab keinen Microsoft vergleiche mal das Beispiel aus meinem Link mit deinem Quelltext und versuche dann ein positives Ergebnis aus dem ganzen zu ziehen ;)

    MfG bcc-fan

    The post was edited 1 time, last by bcc-fan ().

  • Selbst da gibt es Fehler!

    ------ Erstellen gestartet: Projekt: Fenster, Konfiguration: Debug Win32 ------
    Fenster.cpp
    q:\projekte c++\fenster\fenster\fenster.cpp(34): error C2065: 'szWindowClass': nichtdeklarierter Bezeichner
    q:\projekte c++\fenster\fenster\fenster.cpp(69): error C2065: 'szWindowClass': nichtdeklarierter Bezeichner
    q:\projekte c++\fenster\fenster\fenster.cpp(69): error C2065: 'szTitle': nichtdeklarierter Bezeichner
    q:\projekte c++\fenster\fenster\fenster.cpp(121): error C2059: Syntaxfehler: ')'
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
  • Ich kann mich irren, denke aber das der 2008er auch schon bei dem Quelltext Einwände hätte.

    Dachte da eher an den gcc, so wie der Quelltext geschrieben ist. Der alte free BCC5.5 kommt mit dem Beispiel aus dem Buch noch am Besten ohne Anpassung klar.

    Aber da du in die Spielegeschichte einsteigen willst ist wahrscheinlich dein Compiler die bessere Wahl. Musst halt nur das passende Buch oder Tutorial finden ;)
    Oder den Quelltext umschreiben. Ich hab am Anfang meiner WinAPI_Schritte damals auch einiges Umschreiben dürfen, weil ich die Hälfte der Zeit damals mit einem anderen Compiler als von den Beispielen gewünscht unterwegs war. Wenn man wieder im Stoff drin ist, geht das schon. Heute brauchte ich wahrscheinlich wieder eine Auffrischung, aber zur Zeit zieht mich noch nix wieder ;)

    MfG bcc-fan
  • Jetzt hab ich 2010 deinstalliert und 2008 installiert und jetzt geht es auch nicht. Eigentlich ja logisch, aber man weiß ja nie was Microsoft so macht und tut.... :D
    Joa, könnte mir denn jetzt jemand einen Code für ein einfaches, leeres Fenster geben?
    Das wird in diesem Buch fast gar nicht behandelt, es sind nur 3 Quelltexte dazu da wobei nur der 1. einem Fenster obliegt und der 2. einer Aufgabe..... der 3. ist Konsolen-Anwendung.
    Empfiehlt mir übrigens wer ein gutes Buch? Falls es hilft: Ich habe vor ein Jump´n Run zu machen.
  • Checkmateing wrote:

    Selbst da gibt es Fehler!

    ------ Erstellen gestartet: Projekt: Fenster, Konfiguration: Debug Win32 ------
    Fenster.cpp
    q:\projekte c++\fenster\fenster\fenster.cpp(34): error C2065: 'szWindowClass': nichtdeklarierter Bezeichner
    q:\projekte c++\fenster\fenster\fenster.cpp(69): error C2065: 'szWindowClass': nichtdeklarierter Bezeichner
    q:\projekte c++\fenster\fenster\fenster.cpp(69): error C2065: 'szTitle': nichtdeklarierter Bezeichner
    q:\projekte c++\fenster\fenster\fenster.cpp(121): error C2059: Syntaxfehler: ')'
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========



    ahhhhh .... hier steht nicht nur code sondern auch Text !!! :thumbdown:

    Beschäftige dich doch bitte mit den Fehlermeldungen. Du brächtest einfach nur mal nach "szWindowClass" und "szTitle" zu suchen, dann wirst du sehen das in dem vollständigen Beispiel folgende Zeilen fehlen:

    Source Code

    1. static TCHAR szWindowClass[] = _T("win32app");
    2. static TCHAR szTitle[] = _T("Win32 Guided Tour Application");


    Wenn du irgendetwas programmieren möchtest gehört es auch dazu Fehlermeldungen zu verstehen. Das das am Anfang schwierig ist und Zeit kostet und die später noch den ein oder anderen Nerv rauben wird ist ganz nomal, das erging und ergeht jedem so.


    Übrigens solltest du mit VS auch ein leeres Window-Projekt erstellen können, dann hättest du dein Fenster gehabt ;)
  • Source Code

    1. // C++ für Spieleprogrammierer
    2. // Listing 10.1
    3. // Ein Windows-Grundgerüst
    4. //
    5. #include <windows.h>
    6. // Prototyp der Callback-Funktion
    7. LRESULT CALLBACK WindowProc (HWND hWnd, UINT message,
    8. WPARAM wParam, LPARAM lParam);
    9. // Hauptprogramm
    10. //
    11. int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
    12. LPSTR lpcmdline, int ncmdshow)
    13. {
    14. WNDCLASSEX windowclass; // Struktur für Fenstereigenschaften
    15. HWND hWnd; // Fenster-Handle
    16. MSG message; // Nachricht
    17. // Der Klassen-Name des Fensters ist frei wählbar
    18. const char szClassName[] = "First Window";
    19. // Struktur mit gewünschten Eigenschaften füllen
    20. //
    21. // Größe der Struktur zwischenspeichern
    22. windowclass.cbSize = sizeof (WNDCLASSEX);
    23. // Fenster soll beim Verschieben neu gezeichnet werden
    24. windowclass.style = CS_HREDRAW | CS_VREDRAW;
    25. // Zeiger auf Callback-Funktion
    26. windowclass.lpfnWndProc = WindowProc;
    27. // Keine erweiterten Einstellungen
    28. windowclass.cbClsExtra = 0;
    29. windowclass.cbWndExtra = 0;
    30. // Instanz speichern
    31. windowclass.hInstance = hInst;
    32. // Icons und Cursor festlegen
    33. windowclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    34. windowclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    35. windowclass.hCursor = LoadCursor (NULL, IDC_ARROW);
    36. // Hintergrundfarbe festlegen
    37. windowclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND+1;
    38. // Ein Menü brauchen wir nicht
    39. windowclass.lpszMenuName = NULL;
    40. // Klassenname angeben
    41. windowclass.lpszClassName = szClassName;
    42. // Fensterklasse registrieren
    43. if (!RegisterClassEx (&windowclass) )
    44. return (0);
    45. // Das Fenster erzeugen
    46. hWnd = CreateWindowEx (WS_EX_LEFT,
    47. szClassName,
    48. "First Window!",
    49. WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    50. 100, 100,
    51. 300, 250,
    52. NULL,
    53. NULL,
    54. hInst,
    55. NULL);
    56. // Prüfen, ob alles glatt ging
    57. if (hWnd == NULL)
    58. return (0);
    59. // Der "Herzschlag" des Programms.
    60. // Hier werden alle Nachrichten abgeholt,
    61. // übersetzt und weitergeleitet.
    62. while (GetMessage (&message, NULL, 0, 0) )
    63. {
    64. TranslateMessage (&message);
    65. DispatchMessage (&message);
    66. }
    67. // Programm beenden
    68. return (int)(message.wParam);
    69. } // WinMain
    70. // Callback-Funktion zur Nachrichtenverarbeitung
    71. //
    72. LRESULT CALLBACK WindowProc (HWND hWnd, UINT message,
    73. WPARAM wParam, LPARAM lParam)
    74. {
    75. // Messages auswerten
    76. switch (message)
    77. {
    78. // Fenster schließen? (Auch Alt-F4)
    79. case WM_DESTROY:
    80. {
    81. // Nachricht zum Beenden schicken
    82. PostQuitMessage (0);
    83. return (0);
    84. }
    85. // Wurde eine Taste gedrückt?
    86. case WM_KEYDOWN:
    87. {
    88. // Ja, also je nach Taste verzweigen
    89. switch (wParam)
    90. {
    91. // Wurde "Escape" gedrückt?
    92. case VK_ESCAPE:
    93. {
    94. // Ja, also Nachricht zum Beenden schicken
    95. PostQuitMessage (0);
    96. return (0);
    97. }
    98. }
    99. } break;
    100. }
    101. // Die Nachricht wurde nicht von uns verarbeitet, also
    102. // von Windows verarbeiten lassen.
    103. return (DefWindowProc (hWnd, message, wParam, lParam) );
    104. } // WindowProc
    Display All


    Sag mir bitte wo da szWindowClass und szTitle sind...
    Ehrlich, ich finde es nicht.
    Des weiteren weiß ich ja wo der Fehler ungefähr liegt, aber ich kann es nicht lösen.
    Und: Ein leeres VS Projekt kann ich auch erzeugen, ich habe aus versehen das falsche Log-File kopiert - wie bereits erwähnt.

    Könnte mir jemand den vollständigen Code posten? Danke!
  • Ich denke Vince hat es bei sich getestet.

    Ist es denn so schwer das Beispiel aus dem MSDN zu kopieren und die beiden Zeile, die Vince erwähnt hat, dem Compiler zugänglich zu machen?

    Ist doch schon alles in dem Quelltext drin. 2 mal Zeilenvorschub ergänzen, dann hast du es doch.

    Das bekommt doch fast jeder Anfänger hin, selbst, wenn er keinen Plan hat was er kopiert.

    Ein wenig ratlos
    bcc-fan
  • bcc-fan wrote:

    Ich denke Vince hat es bei sich getestet.

    negativ, hab nur osx :whistling:

    Checkmateing wrote:

    Sag mir bitte wo da szWindowClass und szTitle sind...
    Ehrlich, ich finde es nicht.


    Du sollst auch nicht in dem fertigen Beispiel suchen, sondern in diesem Artikel !

    Da gibt es nicht nur unten das fertige Beispiel sondern zu jedem Part auch ne schöne Erläuterung.
    Wenn du denn nach "szWindowClass" suchst wirst du bei "So fügen Sie WinMain Funktionalität hinzu" Punkt 3 sehen das dort folgendes steht:

    Source Code

    1. static TCHAR szWindowClass[] = _T("win32app");
    2. static TCHAR szTitle[] = _T("Win32 Guided Tour Application");
    3. // The parameters to CreateWindow explained:
    4. // szWindowClass: the name of the application
    5. // szTitle: the text that appears in the title bar
    6. // WS_OVERLAPPEDWINDOW: the type of window to create
    7. // CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
    8. // 500, 100: initial size (width, length)
    9. // NULL: the parent of this window
    10. // NULL: this application dows not have a menu bar
    11. // hInstance: the first parameter from WinMain
    12. // NULL: not used in this application
    13. HWND hWnd = CreateWindow(
    Display All


    im vollständigen Beispiel fehlen die beiden Deklarationen.

    Source Code

    1. static TCHAR szWindowClass[] = _T("win32app");
    2. static TCHAR szTitle[] = _T("Win32 Guided Tour Application");



    Das ist nen Fehler vom Autor, aber wie es bcc-fan geschrieben hat ...

    bcc-fan wrote:

    Das bekommt doch fast jeder Anfänger hin, selbst, wenn er keinen Plan hat was er kopiert.

    ... brauchst du es nur an der Stelle einzufügen.