Click here to Skip to main content
15,891,597 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to make a borderless Windows form application movable via mouse. initially I tried this code:

C#
bool mousedown = false;

mouse_down_event_handler()
{
mousedown=true;
}

mouse_up_event_handler()
{
mousedown=false;
}

mouse_move_event_handler()
{

this.location = e.location; // "e" is the mouse pointer and "this" is the windows form
}



------------------------------------------------------------------------->

It didn't seem to work properly. So I spent some time searching for a better code and ended up with this:

C#
protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case 0x84:
                    base.WndProc(ref m);
                    if ((int)m.Result == 0x1)
                        m.Result = (IntPtr)0x2;
                    return;
            }
            base.WndProc(ref m);

        }


____________But I didn't understand a single line.__________


I have seen such types of codes while I was searching for " How to change desktop background from my c# application ".

(1) What does these code mean ?
(2)Are these the codes that we should use while working with windows'
components ?

----------------------------------------
Please explain the code line by line
----------------------------------------

Thanks in Advance,(^_^)
Posted
Comments
Andreas Gieriet 4-Jan-15 9:03am    
You code of the initial attempt is broken C# code. What do you mean by not working properly? This would not even compile. What exactly do you want to achieve? See Control.WndProc Method for MSDN description.
Cheers
Andi

Do you have any idea how much work explaining code line by line is?
Every single line needs a paragraph of explanation! For example:
int next = r.Next();

Create a new variable called "next" which can hold a integer value. From the previously declared Random instance "r", call the "Next" method to get a new random number, and assign it to the "next" variable.

Can you imagine how long it would take us to explain even a very short code fragment like your example, line by line?

No. It is not going to happen. If you have a specific problem, then ask a question about it. But think first - would you want to sit down for 45 minutes and type up a line-by-line description for no good reason?
 
Share this answer
 
Going over code that doesn't work for you line-by-line is generally a waste of time.

What's important is for you to analyze the code and understand what it does ... or doesn't do ... now.

Take the example using MouseDown and MouseMove: when you do this:

this.location = e.location;

Then you are saying: make the top-left corner of the Control that is receiving the MouseMove Event be positioned where the Mouse is now on the Control. Remember that what e.Location returns are co-ordinates based on the Control, not co-ordinates of a Location on the Form ! So, if e.Location reports you are at 100,100, you will set the Location of the Control to 100,100 in Form co-ordinates !

The WndProc example is just a mistake; and I'd forget about it: there are working WndProc solutions that will do this, like: [^], but, in this simple case you don't need them.

Example:

1. set a boolean flag to 'true when the Mouse goes down in the Control; set it to 'false when the Mouse is up.

a. when the Mouse goes down set two integer variables mx,my to the e.X and e.Y of the MouseDown handler. This records the location on the Control where the Mouse went down, in Control co-ordinates.

2. in the MouseMove EventHandler:

a. if the Mouse is up ... based on the value of the flag ... exit

b. if the Mouse is down:

1. create a horizontal offset based on the subtracting the initial value of the Mousedown mx from the current mouse location e.X; create a similar vertical offset.

2. add the horizontal offset to the 'Left property of the Control; add the vertical offset to the 'Top property.
C#
private bool isMouseUp = true;

private int mx, my;

private void SomeControl_MouseDown(object sender, MouseEventArgs e)
{
    isMouseUp = false;
   
    mx = e.X;
    my = e.Y;
}

private void SomeControl_MouseUp(object sender, MouseEventArgs e)
{
    isMouseUp = true;
}

private void SomeControl_MouseMove(object sender, MouseEventArgs e)
{
    if(isMouseUp) return;

    SomeControl.Left += e.X - mx;
    SomeControl.Top += e.Y - my;
}
Now this is really simple stuff ... when you understand the difference between Control co-ordinates, and Form (or other Container Control) co-ordinates.

To make this more interesting, I challenge you to figure out how ... when the user moves the Control, or Form ... to always make sure all of its area is on-screen, or within the bounds of its Container Control. Hints: ClientRectangle, Rectangle.Intersect.
 
Share this answer
 
Comments
BibhutiAlmighty 4-Jan-15 9:20am    
I tweaked your suggested code and it worked.

Thanks your suggestions worked.

here is it :

bool mouse_up = true;
int m_x;
int m_y;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouse_up = false;
m_x = e.X;
m_y = e.Y;
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouse_up = true;
m_x = 0;
m_y= 0;
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mouse_up == false)
{
this.Location = new Point(Cursor.Position.X - m_x, Cursor.Position.Y - m_y);
}
}

But I still haven't got what I asked for. i.e. The meaning of the code I posted.

Hoping to get the answer (^.^)
See the respective MSDN documentation.
Your copied code is a good example of the bad effect of "magic" numbers: you have no chance to search for their meaning.

Other sources in the internet give better examples.

A perfectly working version in C# is this:
C#
namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        private const int WN_NCHITTEST = 0x0084;
        private const int HTCLIENT     = 0x0001;
        private const int HTCAPTION    = 0x0002;

        public Form1()
        {
            InitializeComponent();
        }
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WN_NCHITTEST:
                    base.WndProc(ref m);
                    if (m.Result == (IntPtr)HTCLIENT) m.Result = (IntPtr)HTCAPTION;
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }

    }
}
Looking up the WndProc function in MSDN, the meaning of the WN_NCHITTEST message, and finally the HTCLIENT and HTCAPTION result values of the Message structure tell you

  1. the WndProc overridden method processes windows messages
  2. the WN_NCHITTEST message asks what part of the window corresponds to a particular screen coordinate
  3. the HTCLIENT result tells that the coordinate is in the client area
  4. the HTCAPTION result tells that the coordinate is in the title bar

Putting all together: This code re-directs all client area clicks to the title bar. I.e. from a window manager point of view, the window behaves as if it was one title bar and no client area for what concerns mouse clicks.
Cheers
Andi
 
Share this answer
 
v2
Comments
BillWoodruff 5-Jan-15 8:37am    
+5 Very useful.
Andreas Gieriet 5-Jan-15 15:16pm    
Thanks for your 5!
Cheers
Andi
In addition to the other solutions (and in no way contradicting them!) a brief description of what that function does can be found on this blog[^]
 
Share this answer
 

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