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

1

10.12.2013, 14:41

Farbauswahl aus colorDialog in Form2 auf die Form1 übergeben

Hallo Leute

Ich hoffe Ihr könnt mir ein wenig helfen. Bin Anfänger und stehe vor dem Problem eine ausgewählte Farbe aus dem colorDialog, der ich auf einer zweiten Form öffne dann auf die Form1 zu übergeben. Das ganze in C++/CLI Forms. (Denn allgemeinen Hinweis: Windows Forms und C++ macht keinen Sinn kenne ich) Trotzdem muss ich Windows Form und C++ anwenden.

Diese Übergabe müsste geschehen, wenn der colorDialog noch offen ist, weil, wenn ich in mit OK beende, dann funktioniert die Farbänderung zwar auf der zweiten Form, aber die Übergabe an die Form1 klappt dann nicht mehr. Das ganze benötige ich für ein Pongspiel in dem ich über ein Einstellungsdialog die Farbe von Ball, Schläger und Rahmen ändern kann.

Ich hoffe Ihr könnt mit diesen Angaben etwas anfangen. Falls Ihr Code zur Hilfe braucht, lasst es mich Wissen.

Lieben Dank für Eure Hilfe

lempy

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

2

10.12.2013, 14:58

Ich weiß nicht, in wie weit sich die Windows.Forms Entwicklung mit C++/CLI von der mit C# unterscheidet, allerdings könnte doch das Hauptfenster einfach das Optionsfenster aufrufen (und darauf, dass dieses wieder geschlossen wird), öffnest im Optionsfenster die Farbauswahl, wartest, bis die Auswahl bestätigt wurde, übernimmst ggf. die ausgewählte Farbe und übernimmst nach dem Schließen des Optionsfensters ggf. all dessen Einstellungen.
Eine kurze Google-Suche brachte die MSDN-Seite Displaying Modal and Modeless Windows Forms
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

3

10.12.2013, 16:04

Hallo Sacaldur

Dein Link hat mir nicht wirklich weiter geholfen, weil es ja quasi drei Formen sind die ich öffne.

Manche Dinge unterscheiden sich anscheinend dadurch das bei C# bei manchen Anweisungen einen Punkt verwendet und C++/CLI eben das Zeichen -> (Operator oder so genannt) denke ich jedenfalls. Na ja auch egal.

Meine Hauptform ist die Form1 (oder auch Pong) darin habe ich ein Panel, was mir als Zeichenfläche dient und gleichzeitig mein Spielfeld ist. Der Rahmen wird mit einem Pinsel in das Spielfeld gezeichnetl, der auf meiner Form1 nur pinsel heißt. Mein Schläger und der Ball sind einfach zwei weitere Panels, die ich auf mein Spielfeld "abgelegt" habe. Die Farben des Hintergrundes (Panel = Spielfeld) des Pinsels und der beiden Panel (Schläger und Ball) sind anfangs festgelegt damit ich beim Starten schon mal Farbe sehe. Das alles passiert in Funktionen oder Methoden, wie auch immer man das nennen möchte.

Über einen MenüStrip öffne ich dann die zweite Form (einstellungenDialog). Das ist kein Problem.

Meine zweite Form enthält ebenfalls ein Panel für die Vorschau. Dieses Panel ist die Zeichenfläche für die Vorschau. Die habe ich hier Malfläche genannt, damit ich sie nicht mit der Zeichenfläche aus Form1 verwechsle. Der Rahmen wird wieder mit dem Pensel, der hier pinsel1 heißt, mittel Funktion in die Malfläche gezeichnet und der Ball und Schläger wieder jeweils als Pannels in dem Panel Vorschau abgelegt. Die Farben werden wieder zu Anfang festgelegt, damit die Vorschau die gleichen Farben hat wie das Spielfeld in der Form1.

Zudem gibt zwei Buttons 1. Für die Hintergrundfarbe(also dem Panel selber) und der 2. Für die Farbe des Rahmens, der mit dem pinsel1 gezeichnet wird. Außerdem habe ich zwei colorDailoge in die Form2 eingefügt. Eins für das Ändern der Farbe im Hintergrund und eins zum Ändern der Farbe des Rahmens und des Schlägers und des Balles.

Diese Buttons rufen den jeweiligen colorDialog auf. Für das Ändern des Hintergrunds ist alles klar und einfach doch der Rahmen macht Probleme bei der Übergabe an die Form1.

Hier mal der Code für das Ändern der Rahmenfarbe mit colorDialog: Auf der Form2 funktioniert das und in der Vorschau wird die neu gewählte Farbe gezeigt.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private: System::Void buttonRahmenfarbe_Click(System::Object^ sender, System::EventArgs^ e) 
{ 
/*colorDialog2->ShowDialog();*/ 
/* Color rahmenfarbe;*/if(colorDialog2->ShowDialog() == Windows::Forms::DialogResult::OK) 
{ 
/*Color rahmenfarbe;*//*rahmenfarbe = colorDialog2->Color; 
pinsel1->Color = rahmenfarbe; 
panelBallvorschau->BackColor = rahmenfarbe; 
panelSchlaegervorschau->BackColor = rahmenfarbe;*/ 
pinsel1->Color = colorDialog2->Color; 
panelBallvorschau->BackColor = colorDialog2->Color; 
panelSchlaegervorschau->BackColor = colorDialog2->Color; 
/*Color liefereRahmenfarbe();*/ 
maleVorschau(); 
// /*return;*/ 
}


und die Funktion, in der ich versuche es an die Form1 zu übergeben:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Color liefereRahmenfarbe() 
{/*if(colorDialog2->ShowDialog() == Windows::Forms::DialogResult::OK) 
{ 
pinsel1->Color = colorDialog2->Color; 

maleVorschau(); 
}*/return pinsel1->Color; 
/*return rahmenfarbe;*/ 
/*return pinsel1->Color = colorDialog2->Color;*/ 
/*return maleVorschau();*/ 
/*return malflaeche->pinsel1->Color;*/ 
/*return maleVorschau();*/ 
/*pinsel2 = pinsel1->Color;*/ 
/*return pinsel1->Color = colorDialog2->Color;*/ 
/*return pinsel2; */ 
/*return malflaeche;*/ 
/*return pinsel1->Color = colorDialog2->Color;*/ 
/*return colorDialog2->Color;*/ 
/*return panel1Vorschau;*/ 
}


Wenn Du zur Hilfe noch den Code meines Toolstrips haben möchtest melde Dich.

Lieben Dank

lempy

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »lempy« (10.12.2013, 16:09) aus folgendem Grund: Anmerkung vergessen


Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

4

10.12.2013, 16:36

C++ und C# macht dort keinen Unterschied. Lediglich in der Syntax der beiden Sprachen, aber das sollte denke ich klar sein. Wenn du das ganze mit F# entwickelst dann wird halt eben auch F# benutzt und nicht C++. Die API ist jedoch die selbe. Warum du nun C++ und nicht C# oder vergleichbares benutzt soll uns auch relativ egal sein;) Ich vermute du tust es aus den falschen Gründen, aber das ist ja im Prinzip deine Sache.
Wenn du die auskommentierten Zeilen in deinem Code entfernen würdest könnte man ihn viel viel einfacher lesen. Was ist denn jetzt eigentlich dein Problem? Du bekommst von dem Dialog die Farbe auf den Pinsel für die Vorschau. Bis jetzt läuft ja alles wie du selbst sagst. Die Farbe kannst du dir anscheinend von deiner Form holen. Sollte auch kein Problem hier sein. Bei C# würde ich das ganze wohl über ein Event lösen. Das könnte man dann ColorChanged nennen. Ob sowas hier möglich ist kann ich dir nicht sagen da ich keine CLI Erfahrung habe. Ansonsten kannst du dir einen vergleichbaren Mechanismus bauen. Das Observer Pattern ist ein Beispiel dafür. C++ 11 bietet bestimmt auch ein paar nette Features die vielleicht helfen. Hatten hier letztens mal ein paar Beispiele als es um Funktionszeiger ging. Ansonsten sollte es aber auch möglich sein deiner Form einen Zeiger mit zu geben. Diesen kannst du dann ja im Dialog mit der gewählten Farbe füllen.
Habe schon ziemlich lange nichts mehr mit Windows Forms gemacht. Du kannst aber auch ein Ergebnis von einem Dialog zurück liefern. Ein Beispiel wären die fertigen Dialogs bei denen du einfach einen OK Button, oder Ja/Nein klicken kannst. Das Ergebnis kannst du dir am Ende ja holen. Ein anderes Beispiel wären die Dateiauswahl Dialogs. Auch diese liefern dir ein Ergebnis zurück. Wenn du dir also einen eigenen Dialog dafür schreibst, dann kannst du auch hier ein eigenes Ergebnis zurück liefern. Ich denke auch das ist das was du eigentlich möchtest. Kein neues Fenster erstellen, sondern einen modalen Dialog. Dazu ist der Link von Sacaldur vielleicht doch nicht so falsch wie du erst dachtest.
„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.“

5

10.12.2013, 16:47

Hallo Schorsch

Stichwort abholen ist schon ganz gut!! Kann es sein, das der Pinsel auf der Form1 sich die neu Farbe nicht abholt? Hier mal der Code vom ToolStrip:

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
private: System::Void spielfeldToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) 
{ 
Point neueGroesse; 
Color rahmen; 
// bitte jeweils in einer Zeile eingebeneinstellungenDialog ^neueWerte = gcnew einstellungenDialog(); 
// wenn der Dialog ber OK beendet wirdif (neueWerte -> ShowDialog() == Windows::Forms::DialogResult::OK) 
{ 
// die neue Gre holen 
neueGroesse = neueWerte -> liefereWert(); 
spielfeld->BackColor = neueWerte->liefereBackColor(); 
/*pinsel->Color = gcnew pinsel();*/ 
rahmen = neueWerte->liefereRahmenfarbe(); 
/* zeichneSpielfeld()= neueWerte->maleVorschau();*/ 
/*pinsel->Color= neueWerte->liefereRahmenfarbe();*/ 
pinsel->Color = rahmen; 
/*pinsel->Color = rahmen;*/ 
// den Dialog wieder schlieen 
neueWerte -> Close(); 
// das Formular ndernthis -> Width = neueGroesse.X; 
this -> Height = neueGroesse.Y; 
// neu ausrichten 
// bitte jeweils in einer Zeile eingebenthis -> Left = (Screen::PrimaryScreen -> Bounds.Width - this -> Width) / 2; 
this -> Top = (Screen::PrimaryScreen -> Bounds.Height - this -> Height) / 2; 
// die Zeichenflche neu beschaffen 
zeichenflaeche = spielfeld -> CreateGraphics(); 
/* pinsel->Color = rahmenfarbe;*/ 
/* zeichneSpielfeld();*/ 
// das Spielfeld neu setzen 
setzeSpielfeld(); 
// Spielfeld lschen 
zeichenflaeche -> Clear(spielfeld -> BackColor); 
/*zeichneSpielfeld();*/ 
// und einen neuen Ball und Schlger zeichnen 
neuerBall(); 
/*Refresh spielfeld();*/ 
} 
}


Na ja die Kommentare sind alles Eigenversuche, die nichtgeklappt haben. Vielleicht ist ja einer dabei, der den richtigen Ansatz hat. Wie gesagt ich bin Anfänger.

Lieben Dank

lempy

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

10.12.2013, 17:21

neueWerte ist deine Form und liefereRahmenFarbe wäre die Funktion die du darauf aufrufst? Wann wird der ganze Code denn aufgerufen? Unmittelbar nachdem dein Fenster geöffnet wird, oder wenn du auf einen Button klickst? Was helfen kannst ist den Debugger zu benutzen. Du setzt Breakpoints im Code und guckst ob die jeweiligen Stellen im Code überhaupt aufgerufen werden. Dann kannst du Schritt für Schritt deinen Code durchgehen lassen und gucken welche Werte wie aussehen. Wenn du nicht weißt wovon ich hier rede, dann guck mal bei Google. Wenn du damit nicht weiter kommst natürlich gern hier im Forum fragen. Benutzt du Visual Studio zum entwickeln? Hier hast du ein Beispiel für Visual Studio 2010. Hab es nur überflogen, aber sieht ganz gut aus.
Ansonsten sagst du, du bist Anfänger. Das ist natürlich nicht schlimm, aber ich frage mich warum du unbedingt Windows Forms und C++/CLI verwenden möchtest. Warum machst du dir das ganze nicht ein wenig einfacher? Hier geht es ja denke ich primär erst mal um dein Spiel. Benutz doch vielleicht SFML. Das ist nun mal extra für Spiele gemacht und damit solltest du denke ich einfacher zurecht kommen. Andere Sprachen bieten sich natürlich auch an. Vielleicht wäre C# ja was für dich. Da hättest du die Möglichkeit mit Unity zu arbeiten. Einfacher heißt nicht unbedingt schlechter. Ich arbeite seit längerem nicht mehr mit C++ und größtenteils benutze ich eigentlich C#, bis auf wenige Ausnahmen. Ist natürlich nur ein Hinweis, den du beherzigen kannst oder eben nicht.
Aber noch mal kurz zu deinem Problem. Sinnvoll sind 2 Herangehensweisen wie ich finde.
1: Du benutzt einen Dialog. Dieser liefert direkt deinen gewünschten Wert zurück sobald er beendet wird. In Pseudocode läuft das dann in etwa so ab:

Quellcode

1
2
ColorDialog dialog = new ColorDialog();
Color color = dialog.Show();

Wichtig ist, das ist nur Pseudocode. Kein C++ und auch nichts anderes. Du erstellst im Prinzip deinen Dialog, zeigst ihn an, die eigentliche Logik deines Fensters wird angehalten. Wenn dein Dialog dann beendet wird, wird ein Wert zurück gegeben. In diesem Fall ein Objekt vom Typ Color. Die Syntax musst du dann an deine Sprache anpassen und die Funktionen passend zusammen suchen. Ich zeige hier nur die Logik.
2: Du benutzt ein weiteres nicht modales Fenster. Dein eigentliches Fenster wird dadurch nicht unterbrochen (der Thread des Fensters). Dein zweites Fenster für die Farbwahl kennst möglichst das Hauptfenster und kann bevor es sich beendet die gewünschten Werte an dein Hauptfenster übergeben. Noch mal ein wenig Pseudocode. Für den Code gilt das selbe wie oben. Ich zeige nur Logik. Wie das ganze dann umgesetzt wird musst du selbst gucken.

Quellcode

1
2
3
4
5
6
// im Hauptfenster passiert das:
ColorPicker picker = new ColorPicker(this);


// im ColorPicker passiert vor dem schließen das:
mainWindow.SetColorPickerResult(color);

Ein wenig zum Verständnis. Wenn du dein Fenster für die Farbauswahl erzeugst so gibst du diesem eine Referenz, einen Zeiger, was auch immer, auf das Hauptfenster mit. Hier willst du das Ergebnis am Ende ja haben. Dein Hauptfenster bekommt eine Funktion um ihm den Wert zu übergeben. In diesem Fall SetColorPickerResult. Wenn im Farbauswahlfenster die Farbe gesetzt wurde und das Fenster geschlossen werden soll, dann rufst du vorher diese Funktion auf dem Hauptfenster auf.

Ich persönlich würde zur ersten Variante tendieren. Du wirst vermutlich wollen, dass das Hauptfenster eingefroren wird solange in den Optionen Dinge eingestellt werden. Du kannst erst wieder zum Hauptfenster zurück, wenn dein Optionsfenster geschlossen ist. So ist das Verhalten in den meisten Programmen und auch Spielen. Wie gesagt, das oben ist alles nur Pseudocode um ein wenig zu veranschaulichen wie der Ablauf dabei ist. Wie das ganze dann am Ende mit C++/CLI und Windows Forms umgesetzt werden kann, wirst du dann im Internet mit Hilfe von MSDN und Co raus finden. Aber denk noch mal darüber nach ob du damit überhaupt weiter arbeiten möchtest.

edit: Hier wäre ein Link zu Möglichkeit 1.
„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.“

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

10.12.2013, 17:21

C++/CLI ist eben kein C++, Schorsch ;)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

8

10.12.2013, 17:24

Das habe ich ja nicht behauptet. In meinen Vorschlägen kommen ja auch keine Sprachspezifischen Dinge vor. Ich selbst habe damit halt nie arbeiten müssen und werde das denke ich so schnell auch nicht tun;) Wozu auch.
„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.“

9

10.12.2013, 17:58

Hallo Ihr Lieben

Wow, da kommt im Moment sehr viel Info rüber, die ich erst mal gedanklich sortieren und in meine "Sprache" umsetzen muss.

Also für mich als Hilfe zur "Sprachübersetzung":

Für mich Form1 = Hauptform (Das Spiel Pong)

Dann für mich Form2 = Einstellungsdialog

Und zum Schluss für mich colorDialog = Form3 , weil wie ein Fenster aufgebaut usw.

Das heißt, bevor ich die sogenannte "Form3" durch das Anklicke von OK schließe muss sich die Form1 die entsprechende Auswahl (Farbe) abholen.

Kann man die Info von Schorsch so interpretierten? Oder spreche ich doch eine völlig andere Sprache?

Lieben Dank

lempy

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

10

10.12.2013, 18:33

Es läuft doch so ab. Form1 öffnet Form2. Form2 öffnet Form3. In Form3 wird die Farbe eingestellt und auf ok geklickt. Form3 schließt sich und gibt den Wert an Form2 zurück. In Form2 wird auf ok geklickt. Form2 schließt sich und gibt den Wert an Form1 zurück. Form1 stellt jetzt irgendetwas mit dem Wert an. Oder möchtest du den Wert in Form1 haben obwohl Form2 noch offen ist? Wenn ja, dann gib Form2 eine Referenz auf Form1 mit und als Parameter einer Funktion von Form1 kannst du dann aus Form2 aus den Wert an Form1 übergeben. Noch mal Pseudocode:

Quellcode

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
class Form1
{
    void starteForm2() {
        Form2 form2 = new Form2(this); // der Konstruktor von Form2 bekommt eine Referenz auf Form1. Bei C++ also ein wenig aufpassen, Stichwort Referenz bzw Zeiger
        form2.anzeigen(); // Diese Funktion sorgt dafür dass das Fenster angezeigt wird.
    }

    void setValue(int val) { // diese Funktion kann von außen aufgerufen werden um Form1 den gewünschten Wert zu übergeben
        // mach irgendwas
    }
}

class Form2
{
    Form1 mainWindow;
    int sampleValue = 10;

    Form2(Form1 form1)
    {
        mainWindow = form1;
    }

    void okButtonWurdeGeklickt() { // Diese Funktion wird aufgerufen, wenn der Wert an Form1 übergeben werden soll. Beispiel, Button wird geklickt.
        mainWindow.setValue(sampleValue);
    }
}


Form1 erstellt also Form2. Wenn in Form2 die Funktion okButtonWurdeGeklickt aufgerufen wird, dann wird der Wert sampleValue an Form1 übergeben. Das geschieht über einen einfachen Funktionsaufruf. Das selbe kannst du jetzt auch für Form2 und Form3 machen. Form3 gibt dann den Wert an Form2 und Form2 gibt am Ende den Wert an Form1. Aber wie gesagt, modale Dialoge sind mit ziemlicher Sicherheit das was du eigentlich möchtest. Guck dir zum Beispiel einfach mal fertige Dialogs an. BrowseFolderDialog wäre ein Beispiel.
„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.“

Werbeanzeige