It is amazing to move the controls on a form to everwhere of the form. Some one might think of handling the MouseDown event of a control and to reset its Location property to implement this goal. I used to hold the same thought. But the fact told me that this solution was not satisfy. The control could not be moved smoothly. To make the solution perfectly, I came to use Win32 API at the end.
In this solution, I chose to use two API, ReleaseCapture and SendMessage which located in User32.dll. Before I used these API, I should first using the namespace System.Runtime.InteropServices. The System.Runtime.InteropServices namespace provides a wide variety of members that support COM interop and platform invoke services.
Here is the code of a Runtime moveable Panel
public class MoveablePanel : Panel
{
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2;
[DllImport("User32.dll")]
public static extern bool ReleaseCapture();
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
private bool _enableRuntimeMoveable;
public MoveablePanel()
{
_enableRuntimeMoveable = false;
this.MouseDown += new MouseEventHandler(MoveablePanel_MouseDown);
}
void MoveablePanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && _enableRuntimeMoveable == true)
{
ReleaseCapture();
SendMessage(this.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
}
public bool EnableRuntimeMoveable
{
get { return _enableRuntimeMoveable; }
set { _enableRuntimeMoveable = value; }
}
}
In this example, I have handled the MouseDown event to call ReleaseCapture and SendMessage method. The first parameter of SendMessage method is the Hanle of the control that will be move. The WM_NCLBUTTONDOWN message is posted when the user presses the left mouse button while the cursor is within the nonclient area of a window. This message is posted to the window that contains the cursor. If a window has captured the mouse, this message is not posted. Also I have created a property named EnableRuntimeMoveable in the MoveablePanel, when you want this panel moveable, you can set the value to true. Otherwise you can set it to false then it is a normal panel.
Let’s create a moveable Panel and test it.
public partial class Form1 : Form
{
private MoveablePanel moveablePanel;
public Form1()
{
InitializeComponent();
moveablePanel = new MoveablePanel();
moveablePanel.Location = new Point(10, 10);
moveablePanel.BorderStyle = BorderStyle.Fixed3D;
moveablePanel.BackColor = Color.YellowGreen;
moveablePanel.EnableRuntimeMoveable = true;
this.Controls.Add(moveablePanel);
}
}
In order to see the panel clearly, I have set its background color to yellow green. Then you can enjoy moving it. You can create your own runtime moveable control such as TextBox, ComboBox, DataGridView etc. in this way.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment