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

killmichnich

unregistriert

1

08.03.2009, 11:27

[Erledigt] thread funzt nicht

Hi Leute,
ich hab ein ganz einfaches Programm geschrieben:
ich hab 2 textboxen, und in denen soll mithilfe von threads gleichzeitig hochgezählt werden. In dem Feld, in dem in der normalen spiel-schleife hochgezählt wird, klappts auch, aber in dem, in dem der thread hochzählen soll, klappts nich. Es sieht so aus:

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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// Dieses Programm zeigt, wie eine Oberflaeche mit Farben gefuellt  und angezeigt wird.


// Headerdateien

#include<map>
#include<iostream>
#include<fstream>
#include<windows.h>
#include<string>
#include <wininet.h>
#include "Direct3D.h"
using namespace std;

// Anwendungsfenster erzeugen

HWND CreateMainWindow(HINSTANCE hInstance);

DWORD WINAPI ThreadProc(LPVOID lpParam) ;

// Callback Funktion zur Nachrichtenbehandlung

LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

// Das Fensterhandle

HWND hWnd = 0;
static HWND feld;
static HWND feld2;
char cfeld1[100];
char cfeld2[100];
int i1=0;
int i2=0;

DWORD    threadId;
HANDLE    threadHandle;
CRITICAL_SECTION g_csPrint;


// 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


    //MessageBox(NULL, "Druecke A und D um dich nach links und rechts zu bewegen\nEsc zum beenden", NULL, MB_OK);


    hWnd = CreateMainWindow(hInstance);

    // Wenn der Rueckgabewert 0 ist, ist ein Fehler aufgetreten

    if(0 == hWnd)
    {
        MessageBox(0, "Fenster konnte nicht erzeugt werden", "Fehler", MB_OK);
        return -1;
    }
    InitializeCriticalSection(&g_csPrint);


    MSG msg;
    //SetTimer(hWnd, 1, 2000, NULL);


    threadHandle = CreateThread(NULL, 0, ThreadProc, NULL, CREATE_SUSPENDED, &threadId);

    // Diese Schleife laeuft bis die Nachricht WM_QUIT empfangen wird

    while(msg.message != WM_QUIT)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            
            i1++;
            sprintf(cfeld1, "%d", i1);
            SetWindowText(feld, cfeld1);


        }
    }

    // Rueckgabewert an Windows

    return 0;
}


HWND CreateMainWindow(HINSTANCE hInstance)
{
    WNDCLASSEX wndClass =
    {
        sizeof(WNDCLASSEX),                                 // Groesse angeben

        CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW,    // Standardstile

        MessageHandler,                                     // Callback-Funktion

        0,                                                  // Zusaetzliche Angaben

        0,                                                  // nicht benoetigt

        hInstance,                                          // Anwendungsinstanz

        LoadIcon(NULL, IDI_WINLOGO),                        // Windows-Logo

        LoadCursor(NULL, IDC_ARROW),                        // Normaler Cursor

        (HBRUSH)GetStockObject(WHITE_BRUSH),                // Weisser Pinsel

        NULL,                                               // kein Menue

        "WindowClass",                                      // Der Name der Klasse

        LoadIcon(NULL, IDI_WINLOGO)                         // Windows Logo

    };

    // Klasse registrieren

    RegisterClassEx(&wndClass);

    return CreateWindowEx(NULL,                   // Keine erweiterten Stile nutzen

                          "WindowClass",          // Klassenname

                          "Surface",              // Fenstertitel

                          WS_OVERLAPPEDWINDOW |   // Fenster

                          WS_VISIBLE,             // Eigenschaften

                          0, 0,                 // Anfangsposition

                          1024, 768,  // und Groesse des Fensters

                          NULL,                   // Handle des Elternfensters

                          NULL,                   // Handle des Menues

                          hInstance,              // Anwendungsinstanz

                          NULL);                  // wird nicht benoetigt

}


// Diese Funktion wird von Windows aufgrufen, wenn

// eine Nachricht fuer Ihr Programm vorliegt

LRESULT CALLBACK MessageHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

    switch(msg)
    {
        case WM_CREATE:
        {
            feld=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "hans", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 50, 550, 100, 50, hwnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);
            feld2=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "hans", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL, 150, 550, 100, 50, hwnd, NULL, ((LPCREATESTRUCT) lParam) -> hInstance, NULL);
            break;
        }
        // Programm beenden, wenn das Fenster

        // geschlossen wird

        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
             break;





        case WM_KEYDOWN:
            switch(wParam)
            {

                case VK_ESCAPE:
                CloseHandle(threadHandle);
                DeleteCriticalSection(&g_csPrint);
                PostQuitMessage(0);
                break;

            }
            break;
    }

    // Standardnachrichtenverarbeitung von Windows

    return DefWindowProc(hwnd, msg, wParam, lParam);
}

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    EnterCriticalSection(&g_csPrint);
    i2++;
    sprintf(cfeld2, "%d", i2);
    SetWindowText(feld2, cfeld2);
    LeaveCriticalSection(&g_csPrint);
    return 5;
}


Es wird nur in einem fenster hochgezählt ...
Ich weiß, dass ich das hochzählen auch nacheinander machen kann, ich will nur mal das programmieren mit threads üben und schaun obs klappt. Ach und ich programmier unter Vista, falls es wichtig ist.
Ich hoff ihr könnt mir sagen, was ich falsch mach :D

MfG Daniel

2

08.03.2009, 11:56

Du erstellst den Thread mit CREATE_SUSPENDED.
Das heißt, er wartet und tut solange nichts, bis du ihn mit ResumeThread wieder startest.
fka tm

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

08.03.2009, 12:15

Warum is cfeld2 eigentlich eine globale variable und für was is die CriticalSection da gut?

killmichnich

unregistriert

4

08.03.2009, 15:29

aso ... ok thx
ich hab das CREATE_SUSPENDED jetzt einfach mal durch 0 ersetzt, und in dem thread noch ne for(;;)-schleife drum rum gemacht, dass er weiterzählt. Jetzt wird in dem 2. Feld aber viel schneller gezählt, und in dem 1. so ziemlich garnich ... =(

ach und die CriticalSection is da nur so zum spaß da ... ^^

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

08.03.2009, 15:40

Zitat von »"killmichnich"«

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
        { 
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        } 
        else  // du zählst nur wenn es keine nachricht zu verarbeiten gibt...

        { 
            
            i1++; 
            sprintf(cfeld1, "%d", i1); 
            SetWindowText(feld, cfeld1); 


        } 

killmichnich

unregistriert

6

08.03.2009, 15:44

also kann ich diese schleife wenn ich threads am laufen hab quasi garnicht verwenden, oder?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

08.03.2009, 15:58

ähm naja. schonmal dran gedacht das else einfach wegzulassen?
aber im prinzip...wenn du willst das beide exakt gleich schnell zählen musst du dir was einfallen lassen das geht dann so einfach nimmer. da musst du dann z.b. die zeit stoppen oder was ähnliches...

killmichnich

unregistriert

8

08.03.2009, 16:16

lol stimmt so einfach gehts ^^
naja dass es genau gleich is is mir eigentlich wurscht ... war ja nur zu testzwecken dass die threads auch funktionieren ^^

Also danke für die Hilfe :D

Werbeanzeige