[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 380
  • Last Modified:

How do I move a form without a Title bar?

Hi All,

I am trying to get the code running to move a form when the mouse is clicked & dragged, but something is wrong???
I am clearly doing something stupid, but I can't see it :-O
Can anyone see what is wrong?
Thanks,
James
Point lastClick;
private void SplashScreen_MouseDown(object sender, MouseEventArgs e)
{
    lastClick = new Point(e.X, e.Y);
}

private void SplashScreen_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        this.Left = e.X - lastClick.X;
        this.Top = e.Y - lastClick.Y;
    }
}

Open in new window

0
James Atkin
Asked:
James Atkin
  • 4
  • 3
  • 2
2 Solutions
 
AndyAinscowFreelance programmer / ConsultantCommented:
       Point pt = new Point();
        private void OnMouseDown(object sender, MouseEventArgs e)
        {
            pt.X = e.X;
            pt.Y = e.Y;
        }

        private void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                int x = pt.X - e.X;
                int y = pt.Y - e.Y;
                this.Left -= x;        // note adjusting not setting
                this.Top -= y;
            }
        }

tested - OK.
0
 
James AtkinSenior Principle Software EngineerAuthor Commented:
Interesting...
The code works great for a new project, but not when embedded into mine...
The main difference I guess is that mine is a none-rectangular form with its region specified by an image.
This appears to be messing up the drag - what you see is the form 'wobbling' around the mouse location (very strange!!!)
Below is the code for the region stuff...
Any thoughts???
private void SplashScreen_Load(object sender, EventArgs e)
{
    this.BackgroundImage = global::MyApp.Properties.Resources.img;
    this.Size = this.BackgroundImage.Size;
    this.Region = BitmapToRegion.getRegionFast((Bitmap)this.BackgroundImage, Color.FromArgb(255, 0, 255), 100);
}

********************* BitmapToRegion Code ******************
//Downloaded from
//Visual C# Kicks - http://vckicks.110mb.com/
using System;
using System.Collections.Generic;
using System.Text;
//Needed
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace CustomShapedFormRegion
{
    class BitmapToRegion
    {
        //This method uses only safe code (no pointers) to scan an imagine
        //and create a region from it
        public static Region getRegion(Bitmap inputBmp, Color transperancyKey, int tolerance)
        {
            //Stores all the rectangles for the region
            GraphicsPath path = new GraphicsPath();

            //Scan the image
            for (int x = 0; x < inputBmp.Width; x++)
            {
                for (int y = 0; y < inputBmp.Height; y++)
                {
                    if (!colorsMatch(inputBmp.GetPixel(x, y), transperancyKey, tolerance))
                        path.AddRectangle(new Rectangle(x, y, 1, 1));
                }
            }

            //Create the Region
            Region outputRegion = new Region(path);

            //Clean up
            path.Dispose();

            //Finish
            return outputRegion;
        }

        private static bool colorsMatch(Color color1, Color color2, int tolerance)
        {
            if (tolerance < 0) tolerance = 0;
            return Math.Abs(color1.R - color2.R) <= tolerance &&
                   Math.Abs(color1.G - color2.G) <= tolerance &&
                   Math.Abs(color1.B - color2.B) <= tolerance;
        }

        private unsafe static bool colorsMatch(uint* pixelPtr, Color color1, int tolerance)
        {
            if (tolerance < 0) tolerance = 0;

            //Convert the pixel pointer into a color
            byte a = (byte)(*pixelPtr >> 24);
            byte r = (byte)(*pixelPtr >> 16);
            byte g = (byte)(*pixelPtr >> 8);
            byte b = (byte)(*pixelPtr >> 0);
            Color pointer = Color.FromArgb(a, r, g, b);

            //Each value between the two colors cannot differ more than tolerance
            return Math.Abs(color1.A - pointer.A) <= tolerance &&
                   Math.Abs(color1.R - pointer.R) <= tolerance &&
                   Math.Abs(color1.G - pointer.G) <= tolerance &&
                   Math.Abs(color1.B - pointer.B) <= tolerance;
        }

        //Uses pointers to scan through the bitmap a LOT faster
        //Make sure to check "Allow unsafe code" in the project properties      
        public unsafe static Region getRegionFast(Bitmap bitmap, Color transparencyKey, int tolerance)
        {
            //Bounds
            GraphicsUnit unit = GraphicsUnit.Pixel;
            RectangleF boundsF = bitmap.GetBounds(ref unit);
            Rectangle bounds = new Rectangle((int)boundsF.Left, (int)boundsF.Top,
                                             (int)boundsF.Width, (int)boundsF.Height);

            int yMax = (int)boundsF.Height;
            int xMax = (int)boundsF.Width;

            //Transparency Color
            if (tolerance <= 0) tolerance = 1;


            //Lock Image
            BitmapData bitmapData = bitmap.LockBits(bounds, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            uint* pixelPtr = (uint*)bitmapData.Scan0.ToPointer();

            //Stores all the rectangles for the region
            GraphicsPath path = new GraphicsPath();

            //Scan the image, looking for lines that are NOT the transperancy color
            for (int y = 0; y < yMax; y++)
            {
                byte* basePos = (byte*)pixelPtr;

                for (int x = 0; x < xMax; x++, pixelPtr++)
                {
                    //Go on with the loop if its transperancy color

                    if (colorsMatch(pixelPtr, transparencyKey, tolerance))
                        continue;

                    //Line start
                    int x0 = x;

                    //Find the next transparency colored pixel
                    while (x < xMax && !colorsMatch(pixelPtr, transparencyKey, tolerance))
                    {
                        x++;
                        pixelPtr++;
                    }

                    //Add the line as a rectangle
                    path.AddRectangle(new Rectangle(x0, y, x - x0, 1));
                }

                //Go to next line
                pixelPtr = (uint*)(basePos + bitmapData.Stride);
            }            

            //Create the Region
            Region outputRegion = new Region(path);

            //Clean Up
            path.Dispose();
            bitmap.UnlockBits(bitmapData);

            return outputRegion;
        } 
    }
}

Open in new window

0
 
AndyAinscowFreelance programmer / ConsultantCommented:
>>what you see is the form 'wobbling' around the mouse location (very  strange!!!

Are you adjusting the top, left co-ordinates or just replacing them with the difference between the mouse down point and the current mouse point ?
The non-rectangular shape shouldn't make a difference, because you still have a rectangular block it is on.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
James AtkinSenior Principle Software EngineerAuthor Commented:
Thanks for the reply.
I have actually replaced my original code with the one you posted; please see below
Point pt = new Point();
private void SplashScreen_MouseDown(object sender, MouseEventArgs e)
{
    pt.X = e.X;
    pt.Y = e.Y;
}

private void SplashScreen_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        int x = pt.X - e.X;
        int y = pt.Y - e.Y;
        this.Left -= x;        // note adjusting not setting
        this.Top -= y;
    }
}

Open in new window

0
 
AndyAinscowFreelance programmer / ConsultantCommented:
odd.  I'll have to think about that.
0
 
PablaHPCommented:
Only mouseMove event needs to be handled to enable click n drag functionality on a form's client area. Please see below:

public partial class Form1 : Form
    {      
        public Form1()
        {
            InitializeComponent();          
        }
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.Location = new Point(MousePosition.X, MousePosition.Y);
            }
        }              
    }
0
 
James AtkinSenior Principle Software EngineerAuthor Commented:
Excellent - a combination of both solutions works perfectly...
PablaHP, the move works, but always references by the top left of the form. Adding the start point offset on Mouse Down provides the offset.

Thanks both of you for the help :-)
Point pt = new Point();
private void SplashScreen_MouseDown(object sender, MouseEventArgs e)
{
    pt.X = e.X;
    pt.Y = e.Y;
}
private void SplashScreen_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        this.Location = new Point(MousePosition.X - pt.X, MousePosition.Y - pt.Y);
    }
}

Open in new window

0
 
PablaHPCommented:
Glad to assist. Thanks Jatkin for feedback.
0
 
AndyAinscowFreelance programmer / ConsultantCommented:
My code works for a top window - was this region a child of another window?
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 4
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now