How to drag Custom Usercontrol on windows form? - c#

I have a sln file with two projects in it, the first project contains a Custom Usercontrol inherited from Button, the second project has a form and a button on it, when i click the button on the form the Custom Usercontrol which is a button will be added to the form, now i should be able to drag the button on the form wherever i want to on the form after i run it, how to do it.
public partial class buttCustom : Button
{
public buttCustom()
{
InitializeComponent();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
this.Controls.Add(buttControl);
}
}
i should be able to move that green custom button in the image to move anywhere i want using mouse.

I think you can add the code below in your custom User Control class.
[DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
private extern static void ReleaseCapture();
[DllImport("user32.DLL", EntryPoint = "SendMessage")]
private extern static void SendMessage(System.IntPtr one, int two, int three, int four);
private void CustomCtrl_MouseDown(object sender, MouseEventArgs e)
{
ReleaseCapture();
SendMessage(Handle, 0x112, 0xf012, 0);
}
So the result would be something like:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyViewer.CustomControls
{
public partial class CustomCtrl : UserControl
{
public string formTitleText
{
get { return label1.Text; }
set { label1.Text = value; }
}
public CustomCtrl()
{
InitializeComponent();
}
[DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]
private extern static void ReleaseCapture();
[DllImport("user32.DLL", EntryPoint = "SendMessage")]
private extern static void SendMessage(System.IntPtr one, int two, int three, int four);
// Add MouseDown Event
private void CustomCtrl_MouseDown(object sender, MouseEventArgs e)
{
ReleaseCapture();
SendMessage(Handle, 0x112, 0xf012, 0);
}
}
}
Then you can add the custom User Control which can be draggable to your form from the toolbox.

Agula Otgonbaatar has the correct answer, however I use these values
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
I also check for MouseButton.Left in my MouseDown handler, so it would be:
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
This works for me.

Related

C# . How to take effect for regitstry edited Caret Width immediately?

I found a path for Caret Width in my registry: HKEY_USERS\S-1-5-21-1217365396-2387141574-3682890637-1001\Control Panel\Desktop. Value "CaretWidth" = 1. I want to change it for 5, for example.
But how take effect for this change immediately? I think need to use some method from pinvoke.net, but I don't know how do it. Can you help me?
You can use SystemParametersInfo and pass SPI_SETCARETWIDTH
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices; // Add
namespace Caret_Changer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
const int SPIF_UPDATEINIFILE = 0x01;
const int SPIF_SENDCHANGE = 0x02;
public const uint SPI_SETCARETWIDTH = 0x2007;
[DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, uint pvParam, uint fWinIni);
private void ChangeCaret(uint caret)
{
SystemParametersInfo(SPI_SETCARETWIDTH, 0, caret, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
}
// Start button
private void Button1_Click(object sender, EventArgs e)
{
ChangeCaret(0x0000005); // New caret width
}
// Stop Button
private void Button2_Click(object sender, EventArgs e)
{
ChangeCaret(0x0000001); // Return default width
}
}
}

How to endlessly check if key was pressed?

I was making a small program that shows if numlock or capslock was on or off (because my laptop doesn't have those LEDs so I touhgt it would be interesting to make something like this). What I was trying to achieve is that text would change if key was pressed or not. What I have so far is program showing if they was on or off before running the program it self. How to make program react to changes?
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;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
public static extern short GetKeyState(int keyCode);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
looper();
}
public void looper()
{
cLock_check();
nLock_check();
sLock_check();
}
public void cLock_check()
{
bool CapsLock = (((ushort)GetKeyState(0x14)) & 0xffff) != 0;
if (CapsLock)
lbl_cLock_onOff.Text = "ON";
else
lbl_cLock_onOff.Text = "OFF";
}
public void nLock_check()
{
bool NumLock = (((ushort)GetKeyState(0x90)) & 0xffff) != 0;
if (NumLock)
lbl_nLock_onOff.Text = "ON";
else
lbl_nLock_onOff.Text = "OFF";
}
public void sLock_check()
{
bool ScrollLock = (((ushort)GetKeyState(0x91)) & 0xffff) != 0;
if (ScrollLock)
lbl_sLock_onOff.Text = "ON";
else
lbl_sLock_onOff.Text = "OFF";
}
}
}
You should implement a global keyboard hook, as described in this article. Compare vkCode to VK_NUMLOCK, VK_CAPITAL and VK_SCROLL and call your relevant update function.
Create a timer object, give it a reasonable interval (For most 'responsive' UI issues 300 msec is appropriate), and set the Tick handler to call the looper method:
Timer checkState;
public Form1()
{
InitializeComponent();
checkState = new Timer { Interval = 300};
checkState.Tick += (o,e) => looper();
chechState.Start();
}

Any Hotkey I want to register seems to already be taken

I am trying to register a global hotkey in Visual c# 2012, build target framework .NET3, after using http://www.dreamincode.net/forums/topic/180436-global-hotkeys/ as a tutorial, I got the following (abbreviated) files:
GlobalHotkey.cs
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace barcodelabel
{
public class GlobalHotkey
{
private int modifier;
private int key;
private IntPtr hWnd;
private int id;
public GlobalHotkey(int modifier, Keys key, Form form)
{
this.modifier = modifier;
this.key = (int)key;
this.hWnd = form.Handle;
id = this.GetHashCode();
}
public bool Register()
{
return RegisterHotKey(hWnd, id, modifier, key);
}
public bool Unregister()
{
return UnregisterHotKey(hWnd, id);
}
public override int GetHashCode()
{
return modifier ^ key ^ hWnd.ToInt32();
}
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
}
}
GlobalHotkeyConstants.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace barcodelabel
{
class GlobalHotkeyConstants
{
public const int NOMOD = 0x0000;
public const int ALT = 0x0001;
public const int CTRL = 0x0002;
public const int SHIFT = 0x0004;
public const int WIN = 0x0008;
//windows message id for hotkey
public const int WM_HOTKEY_MSG_ID = 0x0312;
}
}
My Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace barcodelabel
{
public partial class Form1 : Form
{
private GlobalHotkey ghk;
protected override void WndProc(ref Message m)
{
if (m.Msg == GlobalHotkeyConstants.WM_HOTKEY_MSG_ID) {
MessageBox.Show("HOTKEY PRESSED");
}
base.WndProc(ref m);
}
public Form1()
{
InitializeComponent();
this.ghk = new GlobalHotkey(GlobalHotkeyConstants.SHIFT, Keys.F10, this);
}
private void Form1_Load(object sender, EventArgs e)
{
if (!this.ghk.Register())
{
MessageBox.Show("Hotkey could not be registered");
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
this.ghk.Unregister();
}
}
No matter what hotkey I want to choose, it can not be registered. I tried using Hotkey Explorer from http://hkcmdr.anymania.com/ to check if the hotkey already was taken, but it only told me it was free.
What can I do to solve this?
I've wrote down your code in my VS and it worked properly. If you want to find the error, don't check a Boolean returned form API only. if it returns False, try using GetLastError API. Then you will have an error code. Refer to MSDN and get the error's description.

Cursor doesn't hide while taking a screenshot

Simple question. I want to take a screenshot of a part of my screen without the mouse pointer in it. I tried this but it doesn't work.
private void button1_Click(object sender, EventArgs e)
{
Cursor.Hide();
gfxScreenshot.CopyFromScreen(//...);
Cursor.Show();
}
The code above was on a button_click event. I transferred the code in a timer_tick event except from the Cursor.Hide() and made the timer's interval 1000. The timer starts when the button is clicked.
private void button1_Click(object sender, EventArgs e)
{
Cursor.Hide();
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
gfxScreenshot.CopyFromScreen(//...);
Cursor.Show();
timer1.Stop();
}
It works this way but I have to wait 1 sec. When I reduce the interval to 100 the pointer is visible on the image.
I can only assume that the hide method is slower than the CopyFromScreen method...
Is there any way to make it work without the 1 sec delay??
Get cursor location, move to (0,0), take screenshot, put back cursor. The code works using APIs:
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Test1
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
public static extern bool SetCursorPos(int X, int Y);
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public static implicit operator Point(POINT point)
{
return new Point(point.X, point.Y);
}
}
public Form1()
{
InitializeComponent();
POINT lpPoint;
//Get current location of cursor
GetCursorPos( out lpPoint );
//Move to (0,0)
SetCursorPos( 0, 0 );
//Take screenshot
//gfxScreenshot.CopyFromScreen(//...);
MessageBox.Show("just for create a delay", "Debug", MessageBoxButtons.OK, MessageBoxIcon.Information);
//Put back cursor
SetCursorPos( lpPoint.X, lpPoint.Y );
}
}
}

WinForms: Detect when cursor enters/leaves the form or its controls

I need a way of detecting when the cursor enters or leaves the form. Form.MouseEnter/MouseLeave doesn't work when controls fill the form, so I will also have to subscribe to MouseEnter event of the controls (e.g. panels on the form). Any other way of tracking form cursor entry/exit globally?
You can try this :
private void Form3_Load(object sender, EventArgs e)
{
MouseDetector m = new MouseDetector();
m.MouseMove += new MouseDetector.MouseMoveDLG(m_MouseMove);
}
void m_MouseMove(object sender, Point p)
{
Point pt = this.PointToClient(p);
this.Text = (this.ClientSize.Width >= pt.X &&
this.ClientSize.Height >= pt.Y &&
pt.X > 0 && pt.Y > 0)?"In":"Out";
}
The MouseDetector class :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
class MouseDetector
{
#region APIs
[DllImport("gdi32")]
public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool GetCursorPos(out POINT pt);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
#endregion
Timer tm = new Timer() {Interval = 10};
public delegate void MouseMoveDLG(object sender, Point p);
public event MouseMoveDLG MouseMove;
public MouseDetector()
{
tm.Tick += new EventHandler(tm_Tick); tm.Start();
}
void tm_Tick(object sender, EventArgs e)
{
POINT p;
GetCursorPos(out p);
if (MouseMove != null) MouseMove(this, new Point(p.X,p.Y));
}
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
X = x;
Y = y;
}
}
}
You can do it with win32 like in this answer:
How to detect if the mouse is inside the whole form and child controls in C#?
Or you could just hook up all the top level controls in OnLoad of the form:
foreach (Control control in this.Controls)
control.MouseEnter += new EventHandler(form_MouseEnter);

Categories

Resources