Page 1 of 1

C# overridden OnPaint seems to have multiple copies

Posted: Mon Apr 13, 2009 7:38 pm
by MarauderIIC
So if I trace this, after the return; in the win condition (put there for testing) I pick up in the middle of the function somewhere, but only if I have a breakpoint. This leads me to believe that I somehow have multiple copies of OnPaint running. In other words, I'll be inside the gameHasStarted check with gameHasStarted being false. This does not occur on a Windows XP (VM on a Mac), but it does happen on my native Windows Vista. Any ideas on how this could happen?
No critiques on the function, please. I didn't write it. One of my group members did.

Code: Select all

        /// <summary>
        /// Anytime we need to redraw the screen, OnPaint will be called.
        /// Our overrided version will take care of drawing the correct number
        /// of cards we want to the screen, and then calls the base version to
        /// take care of everything else.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            if (gameHasStarted) //This *MUST* be here -- as opposed to a !...return, or it won't work on Vista (seriously what the heck)
            {
                // We only do pictureBox stuff if the game has started
                // if i have called set or there are selected pictureBoxCalledSeten, then set is invisible
                bSet.Visible = !(selectedPictureBoxes.Count > 0 || localCalledSet);

                //Tell gameHandler to gimme some cards
                list = gameHandler.displayCards(numberOfCardsToBeDisplayed);
                if (list.Count == 0) // endgame condition
                {
                    if (!announcedWinner)    //only display the win once
                    {
                        announcedWinner = true;
                        if (theProject.Form1.gameHandler.exitCurGame(highScores) == 0)  //win condition
                        {
                            // oh mi gawd!
                            MessageBox.Show(gameHandler.getWinner() + " won the game.", "Game Over");
                            initGame();
                            System.Diagnostics.Debug.WriteLine(Environment.OSVersion.ToString());
                            //this.Dispose();   //If we can't find out what's causing what seems like multiple OnPaints in Vista, check above & do this
                            return;
                        }
                        //bHint.Visible = true;
                    }
                }
                else // if the game is not over...
                {
                    // If we need to draw more cards && we have more cards to draw
                    while ((numberOfCardsToBeDisplayed != cardsOnScreen.Count) && list.Count == numberOfCardsToBeDisplayed)
                    {
                        scrollVal = panel1.HorizontalScroll.Value;
                        // If we're going to draw some extra cards, just reposition that Horizontal scroll bar
                        panel1.HorizontalScroll.Value = 0;
                        // Then we add more cards to the screen.
                        addThreeCards();
                        bHint.Visible = false;
                    }

                    // However, if we have more cards on the screen than we have cards, 
                    // we need to remove some pictureBoxes.
                    bool redrawPanel = false;
                    while (cardsOnScreen.Count > list.Count)
                    {
                        redrawPanel = true;
                        // Let's remove the picture box
                        panel1.Controls.RemoveAt(panel1.Controls.Count - 1);

                        // And decrement the count
                        cardsOnScreen.RemoveAt(cardsOnScreen.Count - 1);
                    }
                    if (redrawPanel)    //Only redraw when necessary, otherwise it looks terrible
                        panel1.Invalidate();

                    // Draw those suckers to the screen.
                    for (int i = 0; i < cardsOnScreen.Count; i++)
                    {
                        PictureBox pb = (PictureBox)cardsOnScreen[i];
                        pb.Image = null;
                        pb.BackgroundImage = null;
                        pb.Name = list.ElementAt(i).cardNum.ToString();

                        // Set the color of the card
                        switch (list.ElementAt(i).color)
                        {
                            case 0: pb.BackColor = Color.Blue;
                                break;
                            case 1: pb.BackColor = Color.Red;
                                break;
                            case 2: pb.BackColor = Color.Green;
                                break;
                        }

                        // Since we have slightly different backgrounds for each shape, and for each of the
                        // number of different shapes on the card, we need to do the background here too.
                        switch (list.ElementAt(i).shape)
                        {
                            // oval
                            case 0: pb.Image = ovalForeground[list.ElementAt(i).number];
                                if (list.ElementAt(i).shade == 1)
                                {
                                    pb.BackgroundImage = ovalBackground[list.ElementAt(i).number % 2];
                                }
                                break;
                            // rect
                            case 1: pb.Image = rectForeground[list.ElementAt(i).number];
                                if (list.ElementAt(i).shade == 1)
                                {
                                    pb.BackgroundImage = rectBackground[list.ElementAt(i).number % 2];
                                }
                                break;
                            // star
                            case 2: pb.Image = starForeground[list.ElementAt(i).number];
                                if (list.ElementAt(i).shade == 1)
                                {
                                    pb.BackgroundImage = starBackground[list.ElementAt(i).number % 2];
                                }
                                break;
                        }
                        // By default, the shade will be solid (type 0)
                        if (list.ElementAt(i).shade == 2)
                        {
                            pb.BackgroundImage = shadeBackground;
                        }
                    }

                    // Repaint the scores to the screen.
                    lBScores.Items.Clear();
                    string scores = gameHandler.getScores();
                    string[] split = scores.Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < split.Length; i++)
                    {
                        lBScores.Items.Add(split[i]);
                    }
                }
                // Let Windows do its own paint stuff.
//                base.OnPaint(e);
            }
        }

Re: C# overridden OnPaint seems to have multiple copies

Posted: Sun Apr 19, 2009 4:41 pm
by LeonBlade
I'm sorry, but the only thing I can think of is that Vista sucks... lol