Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Die Artikel ::  wxWidgets Tutorial Part II: Spiel mit mir  
Gehen Sie zu Seite 1, 2, 3  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
phlox81
Moderator

Benutzerprofil
Anmeldungsdatum: 21.04.2001
Beiträge: 7474
Beitrag phlox81 Moderator 21:38:15 12.03.2007   Titel:   wxWidgets Tutorial Part II: Spiel mit mir            Zitieren

1 Vorbemerkungen

Nachdem ich im ersten Artikel die Grundlagen von wxWidgets behandelt habe, möchte ich in diesem Artikel die Grundlagen etwas vertiefen, und an einer kleinen Beispielanwendung zeigen, was man mit wxWidgets so realisieren kann. Diese Beispielanwendung wird ein Tic-Tac-Toe Spiel sein. Im Gegensatz zum ersten Artikel verwende ich nun jedoch eine neue wxWidgets-Version(2.8.0), welche aber kompatibel zu 2.6 ist, somit sollte sich die Beispielanwendung auch mit einer älteren wxWidgets-Version kompilieren lassen.

1.1 wxWidgets 2.8.0

Bevor ich mit dem eigentlichen Tutorial anfange, möchte ich kurz noch auf einige Änderungen und Neuerungen hinweisen, die wxWidgets 2.8.0 mit sich bringt. wxWidgets verfügt nun über eine eigene RichTextCtrl-Library, für die Ein- bzw. Ausgabe von formatiertem Text (Allerdings kann diese Library noch keine Standard rtf-Dateien lesen).
Auch wurde eine Dockinglibrary in wxWidgets aufgenommen, mit wxAUI (Advanced User Interface) lassen sich Fenster erstellen, welche sich in der Anwendung dann verschieben und an/abdocken lassen. Alle Neuerungen finden sich in diesem Artikel.

Ein kleiner Hinweis noch an alle MinGW-Benutzer, die bisher die Library mit Msys gebaut haben:
Die mitgelieferten Builddateien scheinen fehlerhaft zu sein, ich konnte jedenfalls wxWidgets2.8.0 nicht mit Msys kompilieren. Alternativ geht es aber über die Windowskommandozeile, einfach in das Verzeichnis %wxDir%/build/msw wechseln, und mit "mingw32-make.exe -f makefile.gcc" den Buildprozess starten. Wer die Library als Releaseversion bauen will, muss in der config.gcc den Wert BUILD von debug auf release setzen.

2 Implementierung eines eigenen Steuerelementes

Beim Erstellen eines eigenen Steuerelementes ist vor allem das Eventhandling wichtig. Man muss in seinem Steuerelement bestimmte Events empfangen können, und auf diese dann entsprechend reagieren. Falls es schon ein Steuerelement gibt, welches einen Teil der Anforderungen abdeckt, empfiehlt es sich von diesem abzuleiten. Wenn dies nicht möglich ist, sollte man sein Steuerelement von wxPanel ableiten, oder falls man ein "scrollbares" Steuerelement will, von wxScrolledWindow.
Bei der Beispielanwendung ist es so, dass wir ein Steuerelement brauchen, welches als Spielfeld, bzw. Spielstein fungiert.
Dafür leiten wir von wxPanel ab, und richten für wxEVT_PAINT und wxEVT_LEFT_DOWN eigene Handler ein:

2.1 Selber zeichnen

Für den Spielstein ist es wichtig, anhand seines Stati ein X oder ein O zu zeichnen. Wenn man den wxPaintEvent überschreibt, muss man in der OnPaint-Methode einen wxPaintDC anlegen, damit wxWidgets weiß, dass das Fenster neugezeichnet wurde, ansonsten würde wxWidgets weiter Paintevents an das Fenster schicken.

C++:
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
void FieldPanel::OnPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);
    dc.DrawRectangle(2,2,GetSize().GetWidth()-2,GetSize().GetHeight()-2);
    int abstand = 10;
    if(status == GameLogic::X)
    {
        wxPen pen = *wxRED_PEN;
        pen.SetStyle(wxSOLID);
        pen.SetWidth(4);
        dc.SetPen(pen);
        dc.DrawLine(abstand,abstand,GetSize().GetWidth()-abstand,GetSize().GetHeight()-abstand);
        dc.DrawLine(GetSize().GetWidth()-abstand,abstand,abstand,GetSize().GetHeight()-abstand);
    }
    else if(status == GameLogic::O)
    {
        wxPen pen(wxColour(0,0,250),4);
        dc.SetPen(pen);
        int x = GetSize().GetWidth()/2;
        int y = GetSize().GetHeight()/2;
        if( x < y )
            dc.DrawCircle(x,y,x - abstand);
        else
            dc.DrawCircle(x,y,y - abstand);
    }
}


2.2 Mausevent

Da nur der Linksklick als Mausevent registriert wurde, reagiert auch das Steuerelement nur auf diesen.
In diesem Fall muss geprüft werden, ob der aktuelle Status noch den Anfangswert ist, und dann ein neuer Wert gesetzt werden:
C++:
1
2
3
4
5
6
7
8
void FieldPanel::OnLeftClick(wxMouseEvent& event)
{
    if(status == GameLogic::EMPTY)
    {
        status = GameLogic::X;// Der Spieler hat den X Stein.
        Refresh();// Panel aktualisieren
    }
}


Jetzt stellt das Panel zwar den Zug dar, aber außerhalb von dieser Panelinstanz hat niemand etwas von diesen Event wahrgenommen. Wenn wir davon ausgehen, das jeder Spielstein einem Spielfeld liegt, so müsste dieses Spielfeld das Parent des Steuerelementes sein. Man könnte also mittels eines Casts den Parentzeiger auf die Spielfeldklasse casten, und dort dann eine Methode aufrufen. Für den aktuellen Fall würde dies gehen, solange bis das Control eine andere Parentklasse hätte.
Es wäre also eleganter wenn das Steuerelement einen Event an sein Parentfenster senden könnte.

2.3 Ein eigener Notifyevent

Die Implementierung unseres eigenen Events sieht so aus:
C++:
1
2
3
4
5
6
7
8
9
10
class TurnEvent : public wxNotifyEvent
{
    int status;
    int field;
public:
    TurnEvent(int status, int field, wxEventType eventType = wxEVT_NULL, int id = 0);
    TurnEvent(const TurnEvent& copy);
    virtual ~TurnEvent();
    virtual TurnEvent* Clone()const {return new TurnEvent(*this);};
};


Über die Variablen status und field wird übergeben welches Spielfeld den Event auslöst, und welcher Spielstein dort gesetzt werden soll.
Damit wxWidgets die Eventklasse auch kennt, und den Event entsprechend weiterleiten kann, sind noch einige Makros nötig:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// in der TurnEvent.hpp (nach der Klassendeklaration)
 
// ein Typedef auf die entsprechenden EventHandler
typedef void(wxEvtHandler::*TurnEventFunction)(TurnEvent&);
 
// wxWidgets den neuen Event mitteilen
BEGIN_DECLARE_EVENT_TYPES()
  DECLARE_EVENT_TYPE(EVT_TURN_CHANGE, -1)
END_DECLARE_EVENT_TYPES()
 
// dieses #define sorgt dafür das man den Event über den Makro EventTable einbinden kann
#define EVT_TURN_CHANGE_MACRO(id, fn) DECLARE_EVENT_TABLE_ENTRY(               \
        EVT_TURN_CHANGE, id, -1, (wxObjectEventFunction)               \
        (wxEventFunction)(TurnEventFunction) & fn,                             \
        (wxObject*) NULL),
 
// dieses #define sorgt dafür das man den Event auch über Connect verbinden kann
#define TurnEventHandler(func)                                                 \
        (wxObjectEventFunction)                                                \
        (wxEventFunction)wxStaticCastEvent(TurnEventFunction, &func)
 
// in der TurnEvent.cpp muss nun 'nur' noch der Event Definiert werden:
DEFINE_EVENT_TYPE(EVT_TURN_CHANGE)


Nun ist der Event fertig implementiert, und kann nun von FieldPanel in der OnLeftClick Methode gesendet werden:
C++:
1
2
3
4
5
6
7
8
9
10
void FieldPanel::OnLeftClick(wxMouseEvent& event)
{
    if(status == GameLogic::EMPTY)
    {
        status = GameLogic::X;
        Refresh();// Panel aktualisieren
        TurnEvent myevent(GameLogic::X,id,EVT_TURN_CHANGE);
        GetParent()->AddPendingEvent(myevent);
    }
}


... und wird in der Klasse GamePanel empfangen:
C++:
1
2
3
4
5
6
7
8
// im Konstruktor wird Connect aufgerufen
Connect(EVT_TURN_CHANGE,TurnEventHandler(GamePanel::OnTurnChange));
 
// Und in der GamePanel.cpp entsprechend die Event Methode definiert:
void GamePanel::OnTurnChange(TurnEvent& event)
{
    wxMessageBox("TurnChange Event!");
}


Nun ist unser eigenes Steuerelement fertig.

3 Das Programm

Mit Fieldpanel verfügt die Anwendung nun über ein Steuerelement welches als Spielstein fungieren kann. Das Programm hat einen recht einfachen Aufbau, als Basisgerüst dient eine von wxFrame abgeleitete Klasse, welches ja schon aus dem ersten Teil des Tutorials bekannt ist. In unserer Anwendung ist die Klasse MyFrame aber eher ein Nebendarsteller, abgesehen von ihren Standardaufgaben (Exit, Infotext anzeigen, Menuhandling) werden ihr die restlichen Aufgaben von GamePanel abgenommen. Das ist ganz bewusst so gewählt, es bietet einige Vorteile, zum einen kann man später das Aussehen der Applikation leicht verändern, falls man z.B. ein MDI Tic Tac Toe Spiel umsetzen will, oder aber auch die Klasse MyFrame kopieren, und wo anders wieder als Basis für z.b. ein 4 Gewinnt Spiel nutzen.
Die Klasse GamePanel kümmert sich nun um das eigentliche Spielgeschehen, und empfängt auch die Events unseres Steuerelementes FieldPanel:
C++:
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
class GamePanel : public wxPanel
{
    GameLogic gamelogic;// die eigentliche Spiellogik wurde (teilweise) ausgelagert
    std::vector<FieldPanel*> panels;// das Spielfeld
    int freefields;// Hilfsvariable
    wxStaticText* player1;// Damit es netter aussieht
    wxStaticText* player2;// Damit es netter aussieht Vol2
    int player1_won;// Counter zum zählen wer wann gewonnen hat
    int player2_won;
    wxString playername;
protected:
public:
    GamePanel(wxWindow* parent, int id);
    virtual ~GamePanel();
    void OnTurnChange(TurnEvent& event);// Die Eventmethode
    void Clear();
};
// GamePanel Constructor
GamePanel::GamePanel(wxWindow* parent, int id): wxPanel(parent,id)
{
    wxFlexGridSizer* flexgridsizer= new wxFlexGridSizer(1,2,0,0);
    flexgridsizer->AddGrowableRow(0);
    flexgridsizer->AddGrowableCol(0);
    wxGridSizer *gSizer1;
    gSizer1 = new wxGridSizer(3, 3, 0, 0);// Spielfeldsizer
    for(int i =0; i < 9; i++)// füllen des Spielfeldes mit Spielsteinen
    {
        panels.push_back(new FieldPanel(this,i));
        gSizer1->Add(panels.back(), 0, wxEXPAND | wxALL, 5);
    }
    flexgridsizer->Add(gSizer1,0, wxEXPAND | wxALL, 5);
    wxBoxSizer* box= new wxBoxSizer(wxVERTICAL);
    playername = wxT("Player1");
    player1_won =0;
    player2_won=0;
    // Zum Anzeigen wer wie oft gewonnen hat
    player1 = new wxStaticText(this,-1,playername + wxString::Format(" wins %i games",player1_won));
    box->Add(player1,0, wxALL, 5);
    player2 = new wxStaticText(this,-1,wxString::Format("Computer wins %i games",player2_won));
    box->Add(player2,0, wxALL, 5);
    flexgridsizer->Add(box,0, wxALL, 5);
    this->SetSizer(flexgridsizer);
    this->SetAutoLayout(true);
    this->Layout();
    // Der Event für den nächsten Spielzug
    Connect(EVT_TURN_CHANGE,TurnEventHandler(GamePanel::OnTurnChange));
   
    freefields = 9;
}


Ich habe mich entschlossen die eigentliche Spiellogik nicht in diesem Tutorial zu behandeln, da sie im eigentlichen Sinne nichts mit wxWidgets zu tun hat, dennoch ist sie vollständig in der Beispielanwendung implementiert, den Link zum vollständigen Code der Anwendung befindet sich am Ende des Tutorials.

Die Anwendung sieht nun so aus:




4 Ein eigener Dialog


Wie man auf dem obigen Bild und im GamePanel Konstruktor sieht, ist der Standardname für den Spieler "Player1". Als Programmierer kann man den Namen des Spielers nicht wissen, folglich sollte man dem Spieler eine Möglichkeit geben, diesen zu ändern, ebenfalls kann man in diesem Settingsdialog die Farben von X und O ändern:



Die Klasse SettingsDlg ist von wxDialog abgeleitet, und hat neben einem Konstruktor jeweils Handler für die X und O Buttons:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class SettingsDlg : public wxDialog
{
    wxColour xcolor;
    wxColour ocolor;
    wxButton* btn_xcolor;
    wxButton* btn_ocolor;
    // Diese Panel dienen der Darstellung der Farbe
    wxPanel* xpanel;
    wxPanel* opanel;
    wxTextCtrl* txt_name;
protected:
public:
    SettingsDlg(wxString playername, wxWindow* parent, int id);
    virtual ~SettingsDlg();
    void OnXColor(wxCommandEvent& event);
    void OnOColor(wxCommandEvent& event);
};


Der Konstruktor:
C++:
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
SettingsDlg::SettingsDlg(wxString playername, wxWindow* parent, int id):
    wxDialog(parent,wxT("Application Settings"),id), xcolor(FieldPanel::xcolor), ocolor(FieldPanel::ocolor)
{
    wxBoxSizer* mainbox = new wxBoxSizer(wxVERTICAL);
   
    // xcolor Settings
    wxStaticBoxSizer* xcolorbox = new wxStaticBoxSizer(wxHORIZONTAL,this,wxT("X Colorsettings"));
   
    xpanel = new wxPanel(this,-1);
    xpanel->SetBackgroundColour(xcolor);
    xcolorbox->Add(xpanel,0,wxALL|wxEXPAND,5);
    btn_xcolor = new wxButton(this,wxNewId(),wxT("Change Color"));
    xcolorbox->Add(btn_xcolor,0,wxALL,5);
   
    mainbox->Add(xcolorbox,0,wxALL|wxEXPAND,5);
   
    // ocolor Settings
    wxStaticBoxSizer* ocolorbox = new wxStaticBoxSizer(wxHORIZONTAL,this,wxT("O Colorsettings"));
   
    opanel = new wxPanel(this,-1);
    opanel->SetBackgroundColour(ocolor);
    ocolorbox->Add(opanel,0,wxALL|wxEXPAND,5);
    btn_ocolor = new wxButton(this,wxNewId(),wxT("Change Color"));
    ocolorbox->Add(btn_ocolor,0,wxALL,5);
   
    mainbox->Add(ocolorbox,0,wxALL|wxEXPAND,5);
   
    // name Settings
    wxBoxSizer* namebox = new wxBoxSizer(wxHORIZONTAL);
   
    namebox->Add(new wxStaticText(this,-1,wxT("Playername: ")),0,wxALL,5);
    txt_name = new wxTextCtrl(this,wxNewId(),playername);
    namebox->Add(txt_name,0,wxALL,5);
   
    mainbox->Add(namebox,0,wxALL,5);
    // Ok und Cancel Buttons hinzufügen
    mainbox->Add(CreateStdDialogButtonSizer(wxOK|wxCANCEL),0,wxALL,5);
    SetSizer(mainbox);
    SetAutoLayout(true);
    Layout();
    Fit();
   
    // Eventhandler
    Connect(btn_xcolor->GetId(),wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(SettingsDlg::OnXColor));
    Connect(btn_ocolor->GetId(),wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(SettingsDlg::OnOColor));
}


4.1 wxWidgets Standarddialoge

wxWidgets bietet für verschiedene Aufgaben Standarddialoge an (z.B. Datei- oder Verzeichnisauswahl, Passwortabfragen, Textabfragen etc.), welche dann den jeweiligen Standarddialogen auf der jeweiligen Plattform entsprechen. Als Beispiel für Standarddialoge verwende ich aber nun wxColourDialog, da wir ja dem Benutzer ermöglichen wollen für das X und O eigene Farben zu vergeben:

C++:
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
// direkter Aufruf des Standarddialoges
void SettingsDlg::OnXColor(wxCommandEvent& event)
{
    wxColourData data;
    data.SetChooseFull(true);
    // der ColourDialog bietet 16 "Standardfarben" an.
    for (int i = 0; i < 16; i++)
    {
        wxColour colour(i*16, i*16, i*16);
        data.SetCustomColour(i, colour);
    }
    // Die vorausgewählte Farbe, Standard ist Schwarz
    data.SetColour(xcolor);
    wxColourDialog dialog(this,&data);
    if (dialog.ShowModal() == wxID_OK)
    {
        wxColourData retData = dialog.GetColourData();
        xcolor = retData.GetColour();
        xpanel->SetBackgroundColour(xcolor);
        xpanel->Refresh();
    }
}
// wxWidgets bietet auch vorgefertigte Funktionen, mit denen man die Standarddialoge aufrufen kann:
void SettingsDlg::OnOColor(wxCommandEvent& event)
{
    wxColour col = wxGetColourFromUser(this, ocolor);
    // mit col.Ok() wird der Returnwert des Dialoges überprüft
    if(col.Ok())
    {
        ocolor = col;
        opanel->SetBackgroundColour(ocolor);
        opanel->Refresh();
    }
}


In der Klasse GamePanel wird der Dialog aufgerufen:

C++:
1
2
3
4
5
6
7
8
9
10
11
void GamePanel::ShowSettings()
{
    SettingsDlg dlg(playername,this,-1);
    if(dlg.ShowModal() == wxID_OK)
    {
        FieldPanel::xcolor = dlg.Getxcolor();
        FieldPanel::ocolor = dlg.Getocolor();
        playername = dlg.Getplayername();
        Refresh();
    }
}


5. Dateien speichern und laden

Jetzt fehlt nur noch dass die Anwendung die Einstellungen auch speichern kann. Man kann problemlos unter wxWidgets die STL nutzen, und mittels <fstream> Dateien schreiben und lesen. wxWidgets bietet jedoch auch eigene Streamklassen an, welche auch Support für Zipstreams oder Sockets bieten.
Für die Beispielanwendung jedoch reicht ein simpler wxFileStream aus:
C++:
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
// Die Einstellungen in einer Datei speichern
void GamePanel::SaveSettings()
{
    wxFileOutputStream file("settings");
    if(file.Ok())
    {
        wxTextOutputStream out(file);
        out << FieldPanel::xcolor.Red() << ' ' << FieldPanel::xcolor.Green() << ' '<< FieldPanel::xcolor.Blue() << endl;
 
        out << FieldPanel::ocolor.Red() << ' '<< FieldPanel::ocolor.Green() << ' '<< FieldPanel::ocolor.Blue() << endl;
 
        out << playername;
    }
}
 
// Die Einstellungen aus einer Datei laden
void GamePanel::LoadSettings()
{
    wxFileInputStream file("settings");
    if(file.Ok())
    {
        wxTextInputStream in(file);
        int r,g,b;
        in >> r >> g >> b;
        FieldPanel::xcolor.Set(r,g,b);
        in >> r >> g >> b;
        FieldPanel::ocolor.Set(r,g,b);
        playername = in.ReadLine();
    }
}


Den Code der Beispielanwendung findet sich hier.

Weitere Links zum Thema wxWidgest:
http://www.wxwidgets.org
Die offizielle wxWidgets Klassenliste (englisch)
Das offizielle wxWidgets Forum (englisch)

_________________
Intelligenz ist eine Illusion des Menschen

phlox81.de | The Black Board | Code Node | Xing | Blog | C++ Kurs | Meeting C++ | Twitter


Zuletzt bearbeitet von estartu am 07:43:58 04.04.2007, insgesamt 3-mal bearbeitet
Ben04
Autor

Benutzerprofil
Anmeldungsdatum: 10.10.2004
Beiträge: 1635
Beitrag Ben04 Autor 23:02:33 19.05.2007   Titel:              Zitieren

Gute Einführung in das Zeichnen mit wxWidgets. :) :live:

Ist es mit wxWidgets eigentlich irgendwie möglich auf ähnliche Zeichenfunktionen zuzugreifen wie sie beispielsweise GDI+ bietet? Damit meine ich zum Beispiel das Antialiasing von Linien oder Alphablending von Bitmaps.
phlox81
Moderator

Benutzerprofil
Anmeldungsdatum: 21.04.2001
Beiträge: 7474
Beitrag phlox81 Moderator 13:26:10 20.05.2007   Titel:              Zitieren

Ich mein es gäbe mittlerweile dafür Klassen, aber ich finds jetzt gerade nicht in der Doku. Gesehen hab ich das aber mal.
Evtl. wirst du auch auf wxCode fündig. wxCairo gibts glaub ich da auch noch.

_________________
Intelligenz ist eine Illusion des Menschen

phlox81.de | The Black Board | Code Node | Xing | Blog | C++ Kurs | Meeting C++ | Twitter
Dummie
Mitglied

Benutzerprofil
Anmeldungsdatum: 19.06.2004
Beiträge: 439
Beitrag Dummie Mitglied 13:39:42 20.05.2007   Titel:              Zitieren

Hi :)

Erstmal muss ich auch sagen: Gute Einführung :)

Aber was mich interessiert:

Heißt es tatsächlich:
"Player X wins 4 games"

Vielleicht ist mein Sprachgefühl ja wieder kaputt jetzt sogar im Englischen :D

Aber ich würde schreiben: Player X won 4 games

Was ist nun richtig?

Danke im Voraus

Gruß Patrick
phlox81
Moderator

Benutzerprofil
Anmeldungsdatum: 21.04.2001
Beiträge: 7474
Beitrag phlox81 Moderator 13:44:48 20.05.2007   Titel:              Zitieren

Ich würde sagen beides ;)
Das eine ist halt die Vergangenheitsform, wobei ich noch nicht so lange gespielt habe, das sie sinnvoll wäre ;)

_________________
Intelligenz ist eine Illusion des Menschen

phlox81.de | The Black Board | Code Node | Xing | Blog | C++ Kurs | Meeting C++ | Twitter
bloodycross
Mitglied

Benutzerprofil
Anmeldungsdatum: 16.04.2007
Beiträge: 44
Beitrag bloodycross Mitglied 20:55:32 03.06.2007   Titel:              Zitieren

[klugscheiß]Ich würde eher sagen "Player has won 4 games" da er die Spiele zwar schon gewonnen hat, aber derzeit noch spielt.[/klugscheiß]

Zum Tutorial selbst: Gut struktiert und auch der Code ist gut lesbar, auch für diejenigen die wxWidgets nicht kenne. :live:

lg, bloodycross
Lurnon
Mitglied

Benutzerprofil
Anmeldungsdatum: 21.05.2008
Beiträge: 41
Beitrag Lurnon Mitglied 22:02:15 30.12.2008   Titel:              Zitieren

Schönes Tut (hat mir schon gut geholfen), nur leider kommt beim kompilieren (Build) der Dateien folgender Fehler:

undefined reference to `__imp__EVT_TURN_CHANGE

Woran kann dies liegen?

Edit: Als Programm nutze ich Code::Blocks mit MinGW


Zuletzt bearbeitet von Lurnon am 22:02:56 30.12.2008, insgesamt 1-mal bearbeitet
phlox81
Moderator

Benutzerprofil
Anmeldungsdatum: 21.04.2001
Beiträge: 7474
Beitrag phlox81 Moderator 23:23:43 30.12.2008   Titel:              Zitieren

Klingt nach einem Linkerfehler. Sind die Dateien auch korrekt im Projekt eingetragen?

_________________
Intelligenz ist eine Illusion des Menschen

phlox81.de | The Black Board | Code Node | Xing | Blog | C++ Kurs | Meeting C++ | Twitter
Lurnon
Mitglied

Benutzerprofil
Anmeldungsdatum: 21.05.2008
Beiträge: 41
Beitrag Lurnon Mitglied 11:44:20 31.12.2008   Titel:              Zitieren

@phlox81
Meiner Meinung ja.
Wenn es dir nichts ausmacht, wärest du bereit mal selbst einen Blick drauf zuwerfen:
http://rapidshare.com/files/178409139/TTT.rar.html


Gruß
Lurnon
phlox81
Moderator

Benutzerprofil
Anmeldungsdatum: 21.04.2001
Beiträge: 7474
Beitrag phlox81 Moderator 13:43:41 31.12.2008   Titel:              Zitieren

Also ich hab gerade das Zipfile im Original runter geladen, und das kompiliert hier ohne Probleme.

_________________
Intelligenz ist eine Illusion des Menschen

phlox81.de | The Black Board | Code Node | Xing | Blog | C++ Kurs | Meeting C++ | Twitter
C++ Forum :: Die Artikel ::  wxWidgets Tutorial Part II: Spiel mit mir  
Gehen Sie zu Seite 1, 2, 3  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können keine Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.