Autor Beitrag
OliverK
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Do 04.09.14 07:44 
Hallo zusammen.

Ich habe als Neueinsteiger in C# versucht ein kleines Projekt in WinForms anzufangen.
Dabei möchte ich wenn möglich ein Hexfeld darstellen. Ich habe jedes Feld als PictureBox angelegt und mit einem Bild gefüllt.
Das ganze ist nicht besonders lang oder kompliziert:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
//-----------------------------------------------------------------------
            // Karte initial zeichnen
            //-----------------------------------------------------------------------
            
            for (int iY = iRows-1; iY >=0; iY--)
            {
                for (int iX = 0; iX < iCols; ++iX)
                {
                    feld[iX, iY] = new PictureBox();
                    feld[iX, iY].Image = Armalion.Properties.Resources.Feld;
                    feld[iX, iY].SizeMode = PictureBoxSizeMode.AutoSize;
                    
                    feld[iX, iY].Left = 370 + iX * feld[iX, iY].Width + (iY + 1) % 2 * feld[iX, iY].Width / 2;
                    feld[iX, iY].Top = 25 + iY * feld[iX, iY].Height * 3 / 4;
                    feld[iX, iY].Parent = this;
                    feld[iX, iY].Name = iX + "-" + iY;
                    feld[iX, iY].BackColor = Color.Transparent;
                    feld[iX, iY].MouseClick += new System.Windows.Forms.MouseEventHandler(FeldKlick);
                    //feld[iX, iY].Controls.Add(??);
                }
            }


Allerdings habe ich nun ein Problem bei der Darstellung der transparenten Flächen. Normalerweise kann ich über Controls.Add() einem Objekt das zuweisen, welches darüber liegen soll, bei dem Hexfeld allerdings stoße ich damit an meine Grenze des Verständnisses. Wenn ich eine Kaskadierung der Zuweisung vornehme( Beispiel: eins.Controls.Add(zwei), zwei.Controls.Add(drei), etc... ) werden die einzelnen PictureBoxes nicht mehr angezeigt.
Kann mir jemand hier weiterhelfen?

Ich möchte ungern - wenn nicht unbedingt nötig - von WinForms weg, da ich hier gerade einen Einstieg habe.

Vielen Dank im Voraus,

Oliver
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.09.14 09:43 
Zitat:
werden die einzelnen PictureBoxes nicht mehr angezeigt.


Hast du die Location richtig gesetzt? Die Location ist relativ zum Parent nicht relativ zur Form. Wenn du nur die Picturebox siehst die direkt auf der Form liegt hast du die anderen möglicherweise einfach nur ausserhalb des sichtbaren Bereichs platziert.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 04.09.14 09:50 
Hallo und :welcome:

in WinForms sollte man mit der Anzahl der Controls immer recht sparsam umgehen (da es nur eine begrenzte Anzahl von internen Windows-Handles gibt) - je nachdem wie groß die Werte für iRows und iCols sind.
Für die Anzeige von einigen wenigen nicht-überlappenden Bildern kann man noch PictureBoxen verwenden - für die Anzeige von Spielfeldern sollte man jedoch diese immer selber zeichnen (dann hast du auch keine Probleme mehr mit der Transparenz, da alles auf einer Ebene liegt), s. meinen Beitrag in Pictureboxen übereinanderlegen, grafische Darstellung 2D (insb. der dortige Link).

PS: Die sog. Ungarische Notation (d.h. das Voranstellen des Datentyp-Kennzeichens vor Bezeichnern) solltest du dir für C# abgewöhnen, also in etwa so:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
for (int y = rows - 1; y >= 0; y--)
    for (int x = 0; x < cols; x++)
    {
        feld[x, y] = ...;
    }
OliverK Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Do 04.09.14 09:56 
Hallo und danke für die Antworten.

ich denke, auch das habe ich probiert. Ich habe zu Testzwecken versucht außerhalb der verschachtelten Schleifen folgendes manuell zu tun:


ausblenden C#-Quelltext
1:
2:
3:
feld[0,0].Controls.Add(feld[0,1]);
feld[0,1].Left = 50;
feld[0,1].Top = 50;



Selbst das klappt schon nicht, obwohl das überlappende Element definitiv noch im sichtbaren Bereich des Monitors sein müsste...

Die Werte für cols und rows sind je 7. Das sollte auch machbar sein, obwohl ich den Einwand natürlich gerne beherzigen würde. Ich fand es nur im ersten Schritt einfacher, als alles selbst zu zeichnen. Vorallem, weil ich später onClick-Events etc. nutzen könnte.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 04.09.14 10:14 
Hallo OliverK,

m.E. bist du mit der Kaskadierung auf dem falschen Weg (Holzweg - wie man so sagt ;-)).
Denn dann müsste das oberste Control die Fläche des ganzen Spielfeldes einnehmen, das innere Control dann versetzt werden, aber immer noch die Größe für untergeordnete Controls haben (denn dies ist der Grund warum du bisher die anderen PictureBoxen nicht siehst) etc. pp.

Unter www.bitel.net/dghm11...nshots/Brilliant.jpg habe ich mal einen Screenshot eines von mir adaptierten Spiels abgelegt (damals noch mit dem C++ Builder und dessen VCL entwickelt, aber heutige ähnliche Projekte realisiere ich mit C# und dem .NET-Framework) - alles komplett selber gezeichnet und auch die Positionen für die Click-Ereignisse selber berechnet.

Für das Click-Ereignis wirst du eh nicht darumherumkommen, die Logik selbst zu berechnen (denn gerade bei überlappenden PictureBoxen wird dein bisheriger Ansatz nicht mehr funktionieren!).
Alternativ kann man auch die Klasse GraphicsPath benutzen, s. z.B. [Tutorial] Gezeichnete Objekte mit der Maus verschieben.

PS: Ich weiß, das dies alles für einen Anfänger in C# etwas schwere Kost ist, aber ich möchte dich davor bewahren, daß du dich mit Sachen herumschlägst, die so einfach nicht funktionieren und der Frustfaktor dann immer größer wird - und du dann ganz die Lust an C# und dem Programmieren verlierst.

PPS: Um was für ein Projekt geht es denn?


Zuletzt bearbeitet von Th69 am Do 04.09.14 10:18, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.09.14 10:15 
Zitat:
Selbst das klappt schon nicht, obwohl das überlappende Element definitiv noch im sichtbaren Bereich des Monitors sein müsste...


Der Monitor ist egal es kommt auf die Größer der Picturebox an auf der die anderen Pictureboxen liegen. Da du Autosize eingestellt hast wird die Picturbox also genauso groß sein wie das Bild und nur diese Fläche ist für die ~Kind~ Pictureboxen nutzbar.
OliverK Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Do 04.09.14 10:35 
Oh je, das klingt ja nicht so gut :-)

Mit "Projekten" ist das ja immer so eine Sache... Sicher könnte ich jetzt erzählen, was ich Tolles vorhabe - aber als berufstätiger Anfänger kommt wahrscheinlich unweigerlich der Punkt, an dem ich mir denke, dass aus dem schönen Plan doch nichts wird :-)
Aber das der Punkt so schnell kommt, ist schade.

Meine Idee war eine Kombination aus Karten- und rundenbasiertem Strategiespiel. Sprich - man hält eine Reihe Karten auf der Hand, die man jede runde ausspielen kann und wenn es sich um eine Einheit handelt, wird diese auf dem Hexfeld platziert und kann sich in einer anderen Spielphase bewegen und interagieren (sprich angreifen).

Meines Erachtens gibt es so etwas noch nicht. Es gibt jede Menge Trading-Card-Cames, in denen man auch Karten ausspielen kann, aber keines, die auch die komplexere Interaktion auf einem Spielfeld zulässt.
Zu guten alten C++-Zeiten habe ich das schon einmal angestrebt, habe auch schon die Karten-Darstellung, Karten-Generierung und Hinterlegung in einer Datenbank fertiggestellt und auf C# portiert. Sogar Graphiken, etc. sind schon recht weit und optisch recht ansprechend (meine Photoshop-Kenntnisse scheinen besser zu sein als meine Programmierkenntnisse :-))
Zu Borland C++ Builder 6 - Zeiten scheiterte es an einer geeigneten Möglichkeit zur Kartendarstellung (war einfach ohne 2D/3D-DirectX / OpenGL zu langsam).

Daher dachte ich jetzt, ich könnte es erst einmal abgespeckt mit PictureBoxes erneut in modernerem Umfeld probieren.
Soviel zum große Plan, der wahrscheinlich wieder in der Schublade verschwinden wird...


Aber da habe ich doch einen interessanten Aspekt gerade in Ralfs Antwort gelesen... " Da du Autosize eingestellt hast wird die Picturbox also genauso groß sein wie das Bild und nur diese Fläche ist für die ~Kind~ Pictureboxen nutzbar."
Das könnte ja der Fehler sein, da die Boxen natürlich "nur halb" überlappen. Was passiert denn, wenn die obere aus dem Bereich herausläuft? Wird dann gar nichts oder nur der innenliegende Teil dargestellt?

Grüße,

Oliver



Oliver
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.09.14 10:40 
Zitat:
Das könnte ja der Fehler sein, da die Boxen natürlich "nur halb" überlappen. Was passiert denn, wenn die obere aus dem Bereich herausläuft? Wird dann gar nichts oder nur der innenliegende Teil dargestellt?


Die ~Kind~ Picturebox wäre dann teilweise auf der Fläche der ~Vater~ Picturebox zu sehen. Das was übersteht ist weg aber die Picturebox wäre nicht ganz weg wen sie nur teilweise anzeigbar ist.
OliverK Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Do 04.09.14 10:52 
Schade, dann ist das auch nicht das Problem, denn es ist ja "gar nichts" zu sehen von dem oben liegenden Element...
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.09.14 11:02 
Nunja, du arbeitest auch noch mit Transparenz vielleicht ist der nicht abgeschnittene Teil einfach Transparent und du siehst es nur nicht ;)

Für den Anfang wäre es vermutlich besser du machst erstmal ein paar Fingerübungen auf einer Form also wirf im Designer 2-3 Pictureboxen auf die Form (ohne Autosize ohne Transparenz) mit unterscheidbaren Bildern, weise dann im Code die Picturebox einer anderen zu (über die Controls) Collection und sie zu was passiert. Vielleicht bemerkst du anhand dieses kleinen Sandkastens wo der Denkfehler liegt. Und ich vermute es scheitert nur an irgendeiner Erwartung von dir die mit der Wirklichkeit leider nicht korreliert. Denn deinem Codeschnipsel kann man keinen prinzipiellen Fehler ansehen. Ich tippe weiterhin auf eine unsinnige Location.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 04.09.14 11:02 
Hallo nochmal,

lies dir mal den Artikel zum Selberzeichnen durch. Du wirst sehen, das ist nicht mehr Code-Aufwand als du mit den PictureBoxen hast.
Fang einfach mal klein an. Am besten du benutzt ein Panel und in dessen Paint-Ereignis zeichnest du dann ersteinmal ein Hexfeld (mittels e.Graphics.DrawImage(...)). Und wenn du das hast, dann benutze deine verschachtelte Schleifen, um das ganze Spielfeld mit Hexfeldern zu zeichnen (die Positionsberechnung hast du ja schon).
OliverK Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Do 04.09.14 11:07 
user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Hallo nochmal,

lies dir mal den Artikel zum Selberzeichnen durch. Du wirst sehen, das ist nicht mehr Code-Aufwand als du mit den PictureBoxen hast.
Fang einfach mal klein an. Am besten du benutzt ein Panel und in dessen Paint-Ereignis zeichnest du dann ersteinmal ein Hexfeld (mittels e.Graphics.DrawImage(...)). Und wenn du das hast, dann benutze deine verschachtelte Schleifen, um das ganze Spielfeld mit Hexfeldern zu zeichnen (die Positionsberechnung hast du ja schon).



Na gut. Überredet.
Obwohl ich immer noch gerne gewusst hätte, wie es auf diesem Wege gehen würde.
Aber ich gelobe, dass ich es mit dem selber zeichnen heute mal probieren werde. :-)

Danke,

Oliver
OliverK Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Do 04.09.14 11:56 
Hallo nochmals,


ich habe jetzt versucht, eure Tipps zu beherzigen, brauche aber doch ein wenig Hilfe.

Ich habe mein Projekt folgendermaßen umgeschrieben:


ausblenden volle Höhe 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:
const int cols = 7;
        const int rows = 7;
Panel[,] feld = new Panel[rows,cols];

private void KarteZeichnen()
        {
            //-----------------------------------------------------------------------
            // Karte initial zeichnen
            //-----------------------------------------------------------------------
            
            for (int y = 0; y < rows; y++)
            {
                for (int x = 0; x < cols; x++)
                {
                    feld[x,y] = new Panel();
                    feld[x, y].Size = new Size(153174);
                    feld[x, y].Left = 370 + x * feld[x, y].Width + (y + 1) % 2 * feld[x, y].Width / 2;
                    feld[x, y].Top = 25 + y * feld[x, y].Height * 3 / 4;
                    feld[x, y].Parent = this;
                    feld[x, y].Name = x + "-" + y;
                    feld[x, y].Paint += new System.Windows.Forms.PaintEventHandler(feldZeichnen);
                    feld[x, y].BackColor = Color.Transparent;
                    feld[x, y].MouseClick += new System.Windows.Forms.MouseEventHandler(FeldKlick);
                }
            }
            Invalidate();
        }

        private void feldZeichnen(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(Armalion.Properties.Resources.Feld, new Rectangle(new Point(00), new Size(153174)));
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            //-----------------------------------------------------------------------
            // Es ist wichtig, dass wir (zuerst) die Oberklasse machen lassen.
            //-----------------------------------------------------------------------
            base.OnPaint(e);

            //-----------------------------------------------------------------------
            // Wir lassen sich alle Objekte selbst (neu-)zeichnen.
            //-----------------------------------------------------------------------
            for (int y = 0; y < rows; y++)
            {
                for (int x = 0; x < cols; x++)
                {
                    e.Graphics.DrawImage(Armalion.Properties.Resources.Feld, new Rectangle(new Point(00), new Size(153174)));
                }
            }
        }


        private void FeldKlick(object sender, MouseEventArgs e)
        {
            Panel tmp = (Panel)sender;
            MessageBox.Show(tmp.Name);
        }


Ich habe versucht aus den PictureBoxes Panels zu machen.
Diese habe ich nicht direkt mit einer Graphik versehen, sondern erst in der Paint-Methode.
Das invalidate habe ich am Ende der Schleifen aufgerufen, um das Feld neu zeichnen zu lassen (so habe ich es zumindest verstanden).
Zusätzlich habe ich die Notation geändert und die Datentypen weggelassen.

Unsicher bin ich mir beim Überschreiben der OnPaint-Methode, da ich das für doppelt-gemoppelt halte (einmal das DrawImage im Paint des Panels, einmal in Paint der Form, oder verstehe ich das falsch? Wahrscheinlich sogar :-))
Einen Erfolg habe ich auch nicht, da es genauso aussieht wie vorher.

Bitte nochmals um einen Schub in die richtige Richtung, da es doch ein wenig viel ist für den ambitionierten Anfänger Oliver :-)

Oliver
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.09.14 12:13 
Wenn du Panels benutzt dann lass die Panel sich und ihre Oberfläche (in deren Paint Event oder deren OnPaint Methode) zeichnen. Wenn du die Form zeichnen läßt lass die Panels weg die tun dann ja auch nix mehr.

Das du in OnPaint der Form das gleiche Image in der Schleife immer wieder an die selbe Stelle schreibst ist auch irgendwie sinnfrei.
OliverK Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Do 04.09.14 12:56 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Wenn du Panels benutzt dann lass die Panel sich und ihre Oberfläche (in deren Paint Event oder deren OnPaint Methode) zeichnen. Wenn du die Form zeichnen läßt lass die Panels weg die tun dann ja auch nix mehr.


Das habe ich ja versucht indem ich das Ereignis feld[x, y].Paint += new System.Windows.Forms.PaintEventHandler(feldZeichnen); hinzugefügt habe.
Ich habe nun die überschriebene Methode OnPaint der Form weggelassen - es zeichnet nun schneller, aber noch immer nicht transparent, wie es sein soll.

Mehr kann ich aus dem Tipp nicht herauslesen.
"Sinnfrei" klingt für mich etwas hart ;-) Dass es nicht richtig sein konnte, habe ich ja selbst vermutet.

Oliver
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.09.14 13:06 
Also funktioniert das ansonsten ist nur nicht transparent?

Dann fehlt dir noch das du beim DrawImage sagst welche Farbe in dem Image den für Transparenz steht. Dafür müßte du eine Überladung von DrawImage benutzen der du ImageAttributes mitgeben kannst. ImageAttributes wiederum hat eine SetColorKey Methode über den du den Farbbereich festlegen kannst der als Transparent gelten soll (heißt der nicht gezeichnet werden soll).

Edit: Scheint auch einfacher zu gehen.
OliverK Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Do 04.09.14 13:30 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Also funktioniert das ansonsten ist nur nicht transparent?


Ja, genau das meinte ich.

Ich habe es jetzt (etwas umständlich aber funktionierend so hinbekommen (für alle, die auch so ein Problem haben):

Anlegen einer Klasse TransparentesPanel:

ausblenden 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:
class TransparentPanel : Panel
    {
        public TransparentPanel() : base()
        {
                        
        }
        
        const int WS_EX_TRANSPARENT = 0x00000020;
        
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= WS_EX_TRANSPARENT;
                return cp;
            }
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            //do not paint the background
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            //SolidBrush brush = new SolidBrush(Color.FromArgb(128, this.BackColor));//semi-transparent color.
            e.Graphics.DrawImage(Armalion.Properties.Resources.Feld, new Rectangle(new Point(00), new Size(153174)));
        }
    }


Dann das Anlegen der Felder (neue Klasse TransparentesPanel verwendet):

ausblenden volle Höhe 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:
        const int cols = 7;
        const int rows = 7;

        TransparentPanel[,] feld = new TransparentPanel[rows,cols];

        private void KarteZeichnen()
        {
            //-----------------------------------------------------------------------
            // Karte initial zeichnen
            //-----------------------------------------------------------------------
            
            for (int y = 0; y < rows; y++)
            {
                for (int x = 0; x < cols; x++)
                {
                    feld[x, y] = new TransparentPanel();
                    feld[x, y].Size = new Size(153174);
                    feld[x, y].Left = 370 + x * feld[x, y].Width + (y + 1) % 2 * feld[x, y].Width / 2;
                    feld[x, y].Top = 25 + y * feld[x, y].Height * 3 / 4;
                    feld[x, y].Parent = this;
                    feld[x, y].Name = x + "-" + y;
                    feld[x, y].BackColor = Color.Transparent;
                    feld[x, y].MouseClick += new System.Windows.Forms.MouseEventHandler(FeldKlick);
                    this.Controls.Add(feld[x, y]);
                }
            }
        }

        private void FeldKlick(object sender, MouseEventArgs e)
        {
            TransparentPanel tmp = (TransparentPanel)sender;
            MessageBox.Show(tmp.Name);
        }


So sieht es richtig aus. Was natürlich noch nicht sauber ist, ist die Erkennung der angeklickten Felder (in den überlappenden Bereichen), da muss ich nacharbeiten...

Danke an alle,

Oliver

P.S.: Wenn jemand was zu der Lösung sagen will, gerne.
Ich verstehe den Sinn bis auf den Zauber um
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
        const int WS_EX_TRANSPARENT = 0x00000020;
        
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= WS_EX_TRANSPARENT;
                return cp;
            }
        }

Diese Parameter sagen mir nichts. Scheint irgendwas auf Windwos-Ebene zu sein, oder?
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 04.09.14 13:32 
Oder aber die Überladung MakeTransparent(color) und die Farbe selbst bestimmen. Die Standard-Methode benutzt eines der Randpixel als Farbe (bin mir nicht ganz sicher, entweder unten rechts oder oben links).

Aber du solltest nur genau 1 Panel für dein ganzes Spielfeld nehmen (weil sonst hast du wieder dieselben Probleme mit sich überlappenden Controls und nicht funktionierender Transparenz).

Edit: ups, du hast schneller gepostet.

Ja, das ist direkt die Benutzung der WinAPI-Schnittstelle - dies habe ich dir extra nicht vorgeschlagen (obwohl ich wusste, daß es so geht ;-)).

WS_EX_TRANSPARENT (s.a. Extended Window Styles) verhindert, daß dieses Control sich (teilweise) über andere Controls zeichnen, indem es zuletzt gezeichnet wird.

Und das Überschreiben und Leerlassen der OnPaintBackground-Methode verhindert, daß das Control zuerst den ganzen Bereich mit der Hintergrundfarbe einfärbt, bevor das Paint-Ereignis aufgerufen wird.

Erst zusammen ergibt das dann einen wirklich transparenten Effekt.


Zuletzt bearbeitet von Th69 am Do 04.09.14 13:58, insgesamt 1-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 04.09.14 13:37 
Zitat:
Scheint irgendwas auf Windwos-Ebene zu sein, oder?


Genau das sind Styles die an die Windows Common Controls weitergeleitet werden. Winforms zeichnet sich in den wenigsten Fällen selber. Sondern ist nur ein Wrapper um die Standard Controls von Windows. Darum ist Winforms übrigens auch so begrenzt. Mann kann nicht einfach das zeichnen bestimmter Dinge ein bißchen ändern. Wenn Windows den Stil eines Controls so vorgibt dann bestimmt Windows wie das aussieht. Mann kann höchsten den Windows Theme ändern. Ebenso Transparenz. Das System kann eigentlich keine Transparenz es ist mehr oder weniger mit ein paar Kniffen dran gelogen. Die Kniffe fallen aber recht schnell unschön in sich zusammen.