Click here to Skip to main content
15,905,781 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm working on a base for a small simple game-style program and I'm using Form1_Resize to control the scale and location of the premade controls i've placed. Currently they're just a picturebox and two blank buttons for testing however they scale and work perfect when the screen is being resized in this method.

I added a custom control to place images with transparency, and it functions fine as well however when I resize the screen the image from the custom control will disappear. I know it's to do with it being painted over and not being repainted when the screen is being resized. By telling it to refresh in the form1_Resize method it does reappear after resizing is done but still is gone while being resized. I've tried everything I could find really but this is still mostly new to me and i'm having no luck.

Here are my classes below.

What I have tried:

Form1.cs
C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace List_Game
{
    public partial class Form1 : Form
    {

        int baseFormWidth = 1280;
        int baseFormHeight = 720;
        int baseStartButtonWidth = 250;
        int baseStartButtonHeight = 100;
        int baseSettingsButtonWidth = 250;
        int baseSettingsButtonHeight = 60;
        // When resized, difference of form size and window size
        int windowWidthOffset;
        int windowHeightOffset;


        //Position of button box to center it when scaling screen
        int startButtonXOffset;
        int startButtonYOffset;
        int settingsButtonXOffset;
        int settingsButtonYOffset;




        public Form1()
        {
            InitializeComponent();


            windowWidthOffset = this.Width - GameWindow.Width;
            windowHeightOffset = this.Height - GameWindow.Height;


        }

        float WidthScale()
        {
            return (float)this.Width / (float)baseFormWidth;
        }

        float HeightScale()
        {
            return (float)this.Height / (float)baseFormHeight;
        }


        private void Form1_Resize(object sender, EventArgs e)
        {
             GameWindow.Width = this.Width - windowWidthOffset;
            GameWindow.Height = this.Height - windowHeightOffset;

            float scaledStartButtonWidth = baseStartButtonWidth * WidthScale();
            float scaledStartButtonHeight = baseStartButtonHeight * HeightScale();

            StartButton.Width = (int)scaledStartButtonWidth;
            StartButton.Height = (int)scaledStartButtonHeight;


            float scaledSettingsButtonWidth = baseSettingsButtonWidth * WidthScale();
            float scaledSettingsButtonHeight = baseSettingsButtonHeight * HeightScale();

            SettingsButton.Width = (int)scaledSettingsButtonWidth;
            SettingsButton.Height = (int)scaledSettingsButtonHeight;



            startButtonXOffset = GameWindow.Width / 2 - StartButton.Width / 2;
            startButtonYOffset = (int)(GameWindow.Height / 1.44) - StartButton.Height / 2;


            settingsButtonXOffset = GameWindow.Width / 2 - (SettingsButton.Width / 2);
            settingsButtonYOffset = GameWindow.Height - (int)(SettingsButton.Height * 1.25);


            Point startButtonLocation = new Point(startButtonXOffset, startButtonYOffset);
            Point settingsButtonLocation = new Point(settingsButtonXOffset, settingsButtonYOffset);

            StartButton.Location = startButtonLocation;
            SettingsButton.Location = settingsButtonLocation;
          
        }



        private void Settings_Click(object sender, EventArgs e)
        {

        }

        private void Start_Click(object sender, EventArgs e)
        {

        }
    }
}


ScreenDrawing.cs
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace List_Game
{
    abstract public class ScreenDrawing : Panel
    {
        public ScreenDrawing()
        {
            this.ResizeRedraw = true;
        }

        protected Graphics graphics;

        abstract protected void OnDraw();

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT

                return cp;
            }
        }

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            // Update the private member so we can use it in the OnDraw method
            this.graphics = e.Graphics;

            // Set the best settings possible (quality-wise)
            this.graphics.TextRenderingHint =
                System.Drawing.Text.TextRenderingHint.AntiAlias;
            this.graphics.InterpolationMode =
                System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
            this.graphics.PixelOffsetMode =
                System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            this.graphics.SmoothingMode =
                System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            // Calls the OnDraw subclass method
            OnDraw();

        }
      }
    }


DrawControl.cs
C#
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace List_Game
{
    class DrawControl : ScreenDrawing
    {
        public DrawControl()
        {
            this.ResizeRedraw = true;
        }


        Image displayedImage = null;
        int width; 
        int height;
        Rectangle big;
        public void SetImage()
        {
        if (this.BackgroundImage == null)
            {
                displayedImage = global::List_Game.Properties.Resources.StartButton2;
            }
            else displayedImage = this.BackgroundImage;
        }

        protected override void OnDraw()
        {
             SetImage();
             // Sets the images' sizes and positions
            width = displayedImage.Size.Width;
            height = displayedImage.Size.Height;
            this.Width = width;
            this.Height = height;
            big = new Rectangle(0, 0, width, height);
            // Draws the two images
            this.graphics.DrawImage(displayedImage, big);
        }



    }
}
Posted
Comments
Hermann Jung 30-Dec-17 3:05am    
I assume Form1.GameWindow is a DrawControl instance. You are updating its size in Form1.Resize and in DrawControl.Paint with different values. You should never update control properties in Paint-event.
Have a look at Form.SetStyle, ControlStyles.AllPaintingInWmPaint and Form.OnPaintBackground documentation. It looks like you want to paint the image as background.
Dark_Dragoon 30-Dec-17 9:33am    
Actually no GameWindow is just a default picturebox im using as a background which works fine. I don't have any code or anything that changes the used DrawControl's size or location currently. The DrawControl is going to be used to paint transparent images on top of the GameWindow which is the background. It works fine, just when resizing the form it dissapears. If I add something like drawControl1.Refresh(); in the Form1_Resize method, then it does reappear after resizing is does, but while the form is being resized it turns invisible I assume do to it not being painted while the form is being resized.
Hermann Jung 31-Dec-17 1:59am    
Creating ScreenDrawing transparent (CreateParam: WS_EX_TRANSPARENT) harms internal visibility-order logic. You can fix it calling:
foreach (var drawControl in Controls.OfType<DrawControl>()) drawControl.Invalidate();
or similar in Form.Resize or:

1.) Use an image specific region (Control.Region property) instead of transparency. See https://www.codeproject.com/articles/6048/creating-bitmap-regions-for-forms-and-buttons

or 2.)
Handle paint event of your PictureBox to draw the sprites. This approach will require some additional code to invalidate drawing area when moving sprites.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900