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

NukeNoob

Frischling

  • »NukeNoob« ist der Autor dieses Themas

Beiträge: 48

Beruf: Student

  • Private Nachricht senden

1

11.11.2012, 22:18

[Erledigt] [C++] Windowsprogrammierung | Fenster schließt sofort

Hallo!
Habe mal wieder ein Problem. Da ich sonst nur den schon vorgegeben Windowsquellcode zur Programmierung von Fenstern verwendet habe, habe ich mich dazu entschlossen, selber einen zu schreiben.
War eigentlich auch kein Problem, nur leider schließt das Fenster immer sofort wieder, d.h. der Quellcode wird kompiliert, die Anwendung startet und beendet so schnell, das man das Fenster nicht einmal erkennen kann.
Hier der Quellcode:

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
#include <Windows.h>

// Prototyp Callback-Funktion
LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// WinMain -> Main Funktion
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpcmdline, int cmdshow)
    {
        // Variablen
        WNDCLASSEX  windowclass;                                            // Struktur Fenstereigenschaften
        HWND        hWnd;                                                   // Handle Hautpfenster
        MSG         message;                                                // Nachricht

        HBRUSH      hbrFarbe = CreateSolidBrush(RGB(212, 212, 212));        // Farbe
        const char  szClassName[] = "Eigenes Fenster";                      // Name des Fensters
        int         nX = 0, nY = 0;                                         // X & Y zur Speicherung der aktuellen Auflösung


        // Aussehen & Eigenschaften Fenster
        windowclass.cbSize          = sizeof (WNDCLASSEX);                  // Größe Struktur speichern
        windowclass.hCursor         = LoadIcon (NULL, IDC_ARROW);           // Cursor
        windowclass.hIcon           = LoadIcon (NULL, IDI_APPLICATION);     // Icon Fenster
        windowclass.hIconSm         = LoadIcon (NULL, IDI_APPLICATION);     // Icon Taskleiste
        windowclass.hbrBackground   = (HBRUSH)(hbrFarbe);                   // Farbe
        windowclass.style           = CS_HREDRAW | CS_VREDRAW;              // Bei Fensterbewegung neu zeichnen
        
        windowclass.lpszMenuName    = NULL;                                 // Kein Menü
        windowclass.cbClsExtra      = NULL;                                 // Keine Extras
        windowclass.cbWndExtra      = NULL;                                 // Keine Extras

        windowclass.lpfnWndProc     = WindowProc;                           // --> Zeiger auf Callback-Funktion
        windowclass.hInstance       = hInstance;                            // --> Instanz speichern
        windowclass.lpszClassName   = (LPCWSTR)(szClassName);               // --> Klassennamen angeben

        if (!RegisterClassEx (&windowclass));                               // ==> Fensterklasse registireren, testen ob alles geklappt hat
            return (0);


        // Fenster erzeugen
        nX      = GetSystemMetrics  (SM_CXSCREEN);                                              // aktuelle Auflösung: X auslesen
        nY      = GetSystemMetrics  (SM_CYSCREEN);                                              // aktuelle Auflösung: Y auslesen 

        hWnd    = CreateWindowEx    (NULL, (LPCWSTR)(szClassName), TEXT("Eigenes Fenster"),     // Fensternamen angeben
                                     WS_OVERLAPPEDWINDOW | WS_VISIBLE,                          // Fenstermerkmale
                                     CW_USEDEFAULT, 0, (nX/2), (nY/2),                          // Zeichnungsort und Größe
                                     NULL, NULL, hInstance, NULL);                              // -

        // Testen ob alles glatt ging
        if (hWnd == NULL)                                                                   
            return (0);


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


        // Programm beenden
        return (int)(message.wParam);
    }
// WinMain


// Callback-Funktion -> wertet Nachrichten aus
LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
            {
                // Fenster schließen (X-Button oder Alt-F4)
                case WM_DESTROY:
                    PostQuitMessage(0);
                    return (0);
                    break;
                                        
                // Taste oder Button ausgewählt?
                case WM_KEYDOWN:
                case WM_COMMAND:
                    switch(wParam)
                        {
                            case VK_ESCAPE:
                                PostQuitMessage(0);
                                return (0);
                        }
                    break;

                // Keine Anweisung?
                default:
                    return (DefWindowProc (hWnd, message, wParam, lParam));
            }
    }

das Problem müsste ja irgendwo in der Callback-Funktion stecken, finde nur nicht heraus, wo genau. Freue mich auf Antworten ;)

LG

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »NukeNoob« (11.11.2012, 23:22) aus folgendem Grund: Problem gelöst und [Erledigt].


Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

2

11.11.2012, 22:38

Wirf doch mal den Debugger an und schau, ob einer der Zeiger NULL ist, bei sowas würde ich immer zuerst die return-Zeilen abarbeiten :)
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

birdfreeyahoo

Alter Hase

Beiträge: 756

Wohnort: Schorndorf

Beruf: Junior Software Engineer

  • Private Nachricht senden

3

11.11.2012, 22:42

Im MSDN hab ich gelesen, dass while(GetMessage(...)) kein guter Stil ist, da GetMessage Zahlen zurückgibt.
Es scheint als würde deine while-Schleife gleich beendet werden.

Ich glaube zwar nicht, dass es daran liegt, aber leere mal message mit ZeroMemory vor der Schleife.

NukeNoob

Frischling

  • »NukeNoob« ist der Autor dieses Themas

Beiträge: 48

Beruf: Student

  • Private Nachricht senden

4

11.11.2012, 22:48

@ Nimelrian: Debugger zeigt nichts auffälliges.

@ birdfreeyahoo: Habe folgendes hinzugefügt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
        ZeroMemory(&message, sizeof(MSG));

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

Kenne die "ZeroMemory()" Funktion nicht, aber als erster Paramter erwartet die "destination" - denke also die Adresse der Variablen und als zweites "lenght" - also die Länge in Bytes. Müsste so stimmen.
Bringt aber nix ;)

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

5

11.11.2012, 22:52

Wie der Debugger zeigt dir nichts? Damit siehst du doch, ob dein Programm bei einer der Return-Anweisungen schon beendet, bzw ob die Schleife abbricht und wenn ja, warum???
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

NukeNoob

Frischling

  • »NukeNoob« ist der Autor dieses Themas

Beiträge: 48

Beruf: Student

  • Private Nachricht senden

6

11.11.2012, 23:01

@ Schorsch: Mit nichts auffälliges meinte ich, dass ich daran nicht erkennen kann, woran es liegt - habe beim genauen hingucken jetzt aber doch etwas endeckt:

Habe jetzt trotzdem einen anderen Fehler gefunden, das Problem damit aber noch nicht komplett gelöst.
In Zeile 35:

C-/C++-Quelltext

1
2
        if (!RegisterClassEx (&windowclass));                               // ==> Fensterklasse registireren, testen ob alles geklappt hat
            return (0);

Das ";" muss weg:

C-/C++-Quelltext

1
2
        if (!RegisterClassEx (&windowclass))                                // ==> Fensterklasse registireren, testen ob alles geklappt hat
            return (0);

Jetzt beendet der Prozess nicht mehr sofort, dass Fenster wird aber nicht gezeichnet ...

LG

EDIT: Habs hinbekommen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
        hWnd    = CreateWindowEx    (NULL, (LPCWSTR)(szClassName), TEXT("Eigenes Fenster"),     // Fensternamen angeben
                                     WS_OVERLAPPEDWINDOW | WS_VISIBLE,                          // Fenstermerkmale
                                     CW_USEDEFAULT, 0, (nX/2), (nY/2),                          // Zeichnungsort und Größe
                                     NULL, NULL, hInstance, NULL);                              // -

        // Testen ob alles glatt ging
        if (hWnd == NULL)                                                                   
            return (0);

        // Fenster zeigen
        ShowWindow(hWnd, cmdshow);  

Komischerweise musste ich noch "ShowWindow()" hinzufügen, obwohl schon "WS_VISIBLE" als Parameter übergeben war, hat Jemand eine Idee woran das liegt?

EDIT2: Alle Probleme gelöst. Das "ShowWindow()" war nur bei "CW_USEDEFAULT" erforderlich. Warum weiß ich nicht, aber es ist Tatsache ;).
Wie immer, danke für die schnelle Hilfe!

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »NukeNoob« (11.11.2012, 23:22) aus folgendem Grund: Problem gelöst.


Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

7

11.11.2012, 23:07

Geh doch einfach per Debugger mal einen Durchlauf Zeile für Zeile durch und schau, wo er dich rausschmeißt :)
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

11.11.2012, 23:20

C-/C++-Quelltext

1
(LPCWSTR)(szClassName)

Der Compiler regt sich hier aus gutem Grund auf und ihn per Cast zum Schweigen zu bringen, ist absolut keine gute Idee. Schau z.B. mal hier...

NukeNoob

Frischling

  • »NukeNoob« ist der Autor dieses Themas

Beiträge: 48

Beruf: Student

  • Private Nachricht senden

9

11.11.2012, 23:26

@dot: So?

C-/C++-Quelltext

1
        const TCHAR szClassName[] = TEXT("Eigenes Fenster");                // Name des Fensters

;)

LG

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

10

11.11.2012, 23:31

Ja, das wäre eine Variante, wobei ich persönlich heutzutage einfach nurmehr mit WCHAR arbeiten würde und fertig...

Werbeanzeige