Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Toxic

Frischling

  • »Toxic« ist der Autor dieses Themas

Beiträge: 53

Wohnort: Niedersachsen

Beruf: Ingenieur

  • Private Nachricht senden

1

27.02.2009, 22:14

Problem bei der Windows Programmierung (Kapitel 10)

Hallo, Forum :D

Ich arbeite derzeit das Buch, welchem sich dieses Forum widmet, durch.
Im Kapitel 10. der 2. erweiterten Auflage bin ich nun auf ein Problem gestossen. Beim Listing 10.1 hat mein Compiler ein Problem mit der Benenung einiger Variablen.

Das fängt in Zeile 9 an, 1Param mag er so gar nicht.
Die Fehlermeldung lautet dabei: error C2059: Syntaxfehler: 'Ungültiges Suffix für Zahl', ist ja auch logisch da die Variable mit einer Zahl beginnt was nach Kapitel 2.3 nicht sein dürfte.
Auf Seite 31 heisst es dort: ,,Beginnt man einen Variablennamen mit einer Zahl, so wird uns der Compiler eine Fehlermeldung um die Ohren hauen".

Im Listing 10.1 kommen dann noch öfter solche Variablen vor und die Fehlermeldungen summieren sich entsprechend.
Ich bin mir auch wirklich sicher das der Fehler hier zu finden ist da ich im Listing 9.5 eine ähnliche Meldung bei der Variablen 1Daten hatte, die ich dann dadurch beseitigt habe das ich die 1 weggelassen habe.

Obwohl es sich natürlich um einen Widerspruch handelt, kann ich mir nicht vorstellen das der Autor hier einen Fehler gemacht hat. Das würde nämlich so ganz und gar nicht zum Rest des Buches passen...

Ich gehe mal davon aus das etwas an meinem Compiler falsch eingestellt ist. Ich benutze derzeit die Visual C++ 2008 Express Edition.

Ich hoffe mir kann jemand weiterhelfen :D
Wenn Architekten ihre Häuser so bauen würden wie Programmierer ihre Programme, könnte ein einziger Specht ganze Städte zerstören !

Käsekönig

1x Contest-Sieger

  • Private Nachricht senden

2

27.02.2009, 22:25

Hm. Bei mir hat das funktioniert! Kannst du mal einen Code-Ausschnitt posten?

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

3

27.02.2009, 22:34

Hi und Willkommen. Was passiert denn, wenn du andere Namen dafür nimmst?

btw:
Wäre nett,wenn du einen kleineren Avatar hochlädst. ;)

Toxic

Frischling

  • »Toxic« ist der Autor dieses Themas

Beiträge: 53

Wohnort: Niedersachsen

Beruf: Ingenieur

  • Private Nachricht senden

4

27.02.2009, 22:57

@Käsekönig
Der Code ist exakt der selbe wie im Buch, ist natürlich möglich das ich mal wieder irgendwo das ; vergessen habe, aber wer tut das nicht :)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <windows.h>

//Prototypen der Callback-Funktion 

LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, 
                             WPARAM wParam, LPARAM 1Param); 

//Hauptprogramm

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, 
                    LPSTR 1pcmdline, int ncmdshow) 
{
    WNDCLASSEX windowclass; //Struktur für Fenstereigenschaften 

    HWND       hWnd;        //Fenster-Handle

    MSG        message;     //Nachricht


    //Der Klassen-Name des Fensters ist frei wählbar

    const char szClassName[] = "Erstes Fenster"; 

    //Struktur mit gewünschten Eigenschaften füllen 

    //Größe der Struktur zwischenspeichern 

    windowclass.cbSize = sizeof (WNDCLASSEX); 

    //Fenster soll beim Verschieben neu gezeichnet werden 

    windowclass.style = CS_HREDRAW | CS_VREDRAW; 

    //Zeiger auf Callback-Funktion 

    windowclass.1pfnWndProc = WindowProc; 

    //Keine erweiterten Einstellungen 

    windowclass.cbC1sExtra = 0; 
    windowclass.cbWndExtra = 0; 

    //Instanz speichern 

    windowclass.hInstance = hInst; 

    //Icons und Cursor festlegen 

    windowclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); 
    windowclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); 
    windowclass.hCursor = LoadCursor (NULL, IDC_ARROW); 

    //Hintergrundfarbe festlegen 

    windowclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND+1; 

    //Ein Menü brauchen wir nicht 

    windowclass.1pszMenuName = NULL; 

    //Klassenname angeben 

    windowclass.1pszClassName = szClassName; 

    //Fensterklasse registrieren 

    if (!RegisterClassEx (&windowclass))
        return (0); 


    //Das Fenster erzeugen

    hWnd = CreateWindowEx (NULL, szClassName, 
                           "Das erste Fenster!", 
                           WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                           100, 100,
                           300, 250, 
                           NULL, 
                           NULL, 
                           hInst,
                           NULL); 

    //Prüfen, ob alles glatt ging 

    if (hWnd == NULL)
        return (0); 

    //Der "Der Herzschlag" des Programms.

    //Hier werden alle Nachrichten abgeholt, 

    //übersetzt und weitergeleitet 

    while (GetMessage (&message, NULL, 0, 0))
    {
        TranslateMessage (&message); 
        DispatchMessage (&message); 
    }

    //Programm beenden 

    return (int) (message.wParam); 

}//WinMain


//Callback-Funktion zur Nachrichtenübermittlung 

LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, 
                             WPARAM wParam, LPARAM 1Param)
{
    //Messages auswerten 

    switch (message)
    {
        //Fenster schließen? (Auch Alt+F4)

    case WM_DESTROY:
        {
            //Nachricht zum Beenden schicken

            PostQuitMessage (0); 
            return (0); 
        }

        //Wurde eine Taste gedrückt?

    case WM_KEYDOWN:
        {
            //Ja, also je nach Taste verzweigen 

            switch (wParam)
            {
                //Wurde "Escape" gedrückt?

            case VK_ESCAPE:
                {
                    //Ja, also Nachricht zum Beenden schicken 

                    PostQuitMessage(0);
                    return (0); 
                }
            }
        }break; 
    }

    //Die Nachricht wurde nicht von uns verarbeitet, also 

    //von Windows verarbeiten lassen 

    return (DefWindowsProc (hWnd, message, wParam, 1Param)); 

}//WindowProc


@drakon
Habe eben schnell ein kleineres Profilbild zusammengebastelt :)
In dem anderen Beispiel 9.5 habe ich ja schon erfolgreich den Fehler vermeiden können indem ich Daten anstelle 1Daten geschrieben habe.
Hier kann ich leider nicht alle Variablen durchtauschen da beispielsweise die Variable 1pfnWndProc in Zeile 26 zur Struktur WNDCLASSEX gehört.
Naja und auf diese habe ich ja keinen Zugriff da sie ja über die Header Datei <windows.h> eingebunden wurde...
Wenn Architekten ihre Häuser so bauen würden wie Programmierer ihre Programme, könnte ein einziger Specht ganze Städte zerstören !

DasBlub

Alter Hase

Beiträge: 802

Wohnort: Schweiz

Beruf: Programmierer

  • Private Nachricht senden

5

27.02.2009, 23:37

C-/C++-Quelltext

1
2
3
4
5
    //Ein Menü brauchen wir nicht

    windowclass.1pszMenuName = NULL;

    //Klassenname angeben

    windowclass.1pszClassName = szClassName; 

das ist keine '1' sondern n 'l' (kleines 'L') ;)

Toxic

Frischling

  • »Toxic« ist der Autor dieses Themas

Beiträge: 53

Wohnort: Niedersachsen

Beruf: Ingenieur

  • Private Nachricht senden

6

28.02.2009, 16:41

Zitat

das ist keine '1' sondern n 'l' (kleines 'L')

Oh...Ja klar, vielen Dank. :D :roll:

Also die Fehlermeldungen deswegen sind jetzt weg.
Allerdings sind zwei Fehler übrig geblieben, obwohl ich jetzt den Quellcode aus der Buch-CD kopiert habe, tauchen die Fehlermeldungen weiterhin auf. Soweit ich das verstehe möchte der Compiler das ich etwas caste, habe damit eben auch schon rumprobiert, aber es läuft nicht so recht.

Fehler 1:

1>bigtest.cpp(54) : error C2440: '=': 'const char [15]' kann nicht in 'LPCWSTR' konvertiert werden

1> Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.

Fehler 2:

1>bigtest.cpp(70) : error C2664: 'CreateWindowExW': Konvertierung des Parameters 2 von 'const char [15]' in 'LPCWSTR' nicht möglich

1> Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.


Hier noch einmal der Quellcode, so wie oben nur eben l anstelle von 1 :)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// C++ für Spieleprogrammierer

// Listing 10.1

// Ein Windows-Grundgerüst

//

#include <windows.h>

// Prototyp der Callback-Funktion

LRESULT CALLBACK WindowProc (HWND hWnd, UINT message,
                             WPARAM wParam, LPARAM lParam);

// Hauptprogramm

//

int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
                    LPSTR lpcmdline, int ncmdshow)
{
  WNDCLASSEX windowclass; // Struktur für Fenstereigenschaften

  HWND       hWnd;        // Fenster-Handle

  MSG        message;     // Nachricht


  // Der Klassen-Name des Fensters ist frei wählbar

  const char szClassName[] = "Erstes Fenster";

  // Struktur mit gewünschten Eigenschaften füllen

  //


  // Größe der Struktur zwischenspeichern

  windowclass.cbSize = sizeof (WNDCLASSEX);

  // Fenster soll beim Verschieben neu gezeichnet werden

  windowclass.style = CS_HREDRAW | CS_VREDRAW;

  // Zeiger auf Callback-Funktion

  windowclass.lpfnWndProc = WindowProc;

  // Keine erweiterten Einstellungen

  windowclass.cbClsExtra = 0;
  windowclass.cbWndExtra = 0;

  // Instanz speichern

  windowclass.hInstance = hInst;

  // Icons und Cursor festlegen

  windowclass.hIcon   = LoadIcon (NULL, IDI_APPLICATION);
  windowclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  windowclass.hCursor = LoadCursor (NULL, IDC_ARROW);

  // Hintergrundfarbe festlegen

  windowclass.hbrBackground = (HBRUSH)COLOR_BACKGROUND+1;

  // Ein Menü brauchen wir nicht

  windowclass.lpszMenuName = NULL;

  // Klassenname angeben

  windowclass.lpszClassName = szClassName;

  // Fensterklasse registrieren

  if (!RegisterClassEx (&windowclass) )
    return (0);

  // Das Fenster erzeugen

  hWnd = CreateWindowEx (NULL,
                         szClassName,
                         "Das erste Fenster!",
                         WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                         100, 100,
                         300, 250,
                         NULL,
                         NULL,
                         hInst,
                         NULL);

  // Prüfen, ob alles glatt ging

  if (hWnd == NULL)
    return (0);

  // Der "Herzschlag" des Programms.

  // Hier werden alle Nachrichten abgeholt,

  // übersetzt und weitergeleitet.

  while (GetMessage (&message, NULL, 0, 0) )
  {
    TranslateMessage (&message);
    DispatchMessage (&message);

  }

  // Programm beenden

  return (int)(message.wParam);

} // WinMain



// Callback-Funktion zur Nachrichtenverarbeitung

//

LRESULT CALLBACK WindowProc (HWND hWnd, UINT message,
                             WPARAM wParam, LPARAM lParam)
{
  // Messages auswerten

  switch (message)
  {
    // Fenster schließen? (Auch Alt-F4)

    case WM_DESTROY:
    {
      // Nachricht zum Beenden schicken

      PostQuitMessage (0);
      return (0);

    }

    // Wurde eine Taste gedrückt?

    case WM_KEYDOWN:
    {
      // Ja, also je nach Taste verzweigen

      switch (wParam)
      {
        // Wurde "Escape" gedrückt?

        case VK_ESCAPE:
        {
          // Ja, also Nachricht zum Beenden schicken

          PostQuitMessage (0);
          return (0);

        }
      }
    } break;
  } 

  // Die Nachricht wurde nicht von uns verarbeitet, also

  // von Windows verarbeiten lassen.

  return (DefWindowProc (hWnd, message, wParam, lParam) );

} // WindowProc
Wenn Architekten ihre Häuser so bauen würden wie Programmierer ihre Programme, könnte ein einziger Specht ganze Städte zerstören !

7

28.02.2009, 16:49

Stichwort Zeichensatz

8

28.02.2009, 16:50

geh in die Prjektoptionen und änder den Zeichensatz von Unicode auf Multibyte. Von allen Windows-Funktionen, die was mit text zu tun haben, gibts ne Version mit unicode (wchar_t) und eine mit multibyte (hierzulande Latin-1, Datentyp: char), zwischen denen in abhängigkeit vom Makro UNICODE umgeschaltet wird, das der compiler eben setzt, wenn der Zeichensatz auf Unicode eingestellt ist.

Toxic

Frischling

  • »Toxic« ist der Autor dieses Themas

Beiträge: 53

Wohnort: Niedersachsen

Beruf: Ingenieur

  • Private Nachricht senden

9

28.02.2009, 17:07

Ok habe es endlich hinbekommen, vielen Dank an alle die mir geholfen haben :D

@Mod, von meiner Seite aus kann das hier geschlossen werden.
Wenn Architekten ihre Häuser so bauen würden wie Programmierer ihre Programme, könnte ein einziger Specht ganze Städte zerstören !

Werbeanzeige