Cursor doesn't hide while taking a screenshot - c#

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 );
}
}
}

Related

How to make a disable button to pause script

Well, I made a script to just jump to work in several games, and I would like my program to have a button to activate and deactivate it so that it doesn't disturb me when I'm not playing (when minimizing the game), I managed to make the script run when I clicked on the activate button, but I don't have the slightest idea of how to put it to disable / pause on the "Desativar" button, and when I click again on "Activate" where it left off.
I'm going to apologize for my English if something is wrong
ps: I'm a newbie
Code:
public partial class Pular : Form
{
[DllImport("user32.dll")]
static extern short GetAsyncKeyState(Keys vKey);
[DllImport("user32.dll")]
static extern void mouse_event(int a, int b, int c, int d, int swed);
int m3DOWN = 0x0020;
int m3UP = 0x0040;
public Pular()
{
InitializeComponent();
btnDesativar.Enabled = false;
}
private void Pular_Load(object sender, EventArgs e)
{
}
void jump()
{
while (true)
{
if (GetAsyncKeyState(Keys.Space) <0)
{
mouse_event(m3DOWN, 0, 0, 0, 0);
Thread.Sleep(9);
mouse_event(m3UP, 0, 0, 0, 0);
Thread.Sleep(9);
}
Thread.Sleep(10);
}
}
private void btnAtivar_Click(object sender, EventArgs e)
{
btnAtivar.Enabled = false;
btnDesativar.Enabled = true;
Thread jp = new Thread(jump) { IsBackground = true };
jp.Start();
}
private void btnDesativar_Click(object sender, EventArgs e)
{
btnDesativar.Enabled = false;
btnAtivar.Enabled = true;
}

How to drag Custom Usercontrol on windows form?

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.

Move form without border through a panel

I been searching around for a solution for my problem but for now I wasn't able to get any sucessfull code for what I want to do. So, I have a form without border that is filled with 2 custom panels, so there is no way to the user click on the frame, thinking in that, I implement a code that when user click on a panel, this will call a function on my form that recive by parameter the event of the mouse.
This is the code of my Panel (note that both of my panels in the frame are the same class, it's just 2 diferent instances)
public class MyPanel : System.Windows.Forms.Panel{
(...)
private void MyPanel_MouseDown(object sender, MouseEventArgs e)
{
BarraSms.getInstance().mouseDown(e);
}
private void MyPanel_MouseMove(object sender, MouseEventArgs e)
{
BarraSms.getInstance().mouseMove(e);
}
}
And this is the code of my form:
public partial class BarraSms : Form
{
private Point mousePoint;
(...)
public void mouseDown(MouseEventArgs e) {
mousePoint = new Point(-e.X, -e.Y);
}
public void mouseMove(MouseEventArgs e) {
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Point mousePos = Control.MousePosition;
mousePos.Offset(mousePoint .X, mousePoint .Y);
this.Location = mousePos;
}
}
}
Is there something that I'm missing?
Thank you in advance for the help.
The working code (update), problem solved by: x4rf41
The MyPanel Class :
MouseMove += MyPanel_MouseMove; // added in class constructer
the BarraSms class (Form)
public partial class BarraSms : Form
{
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
public void mouseMove(MouseEventArgs e) {
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
ReleaseCapture();
SendMessage(this.Handle, WM_NCLBUTTONDOWN, new IntPtr(HT_CAPTION), IntPtr.Zero);
Point loc = this.Location;
writeCoordToBin(loc.X, loc.Y);
}
}
}
There is much better solution for that using the windows api function.
The way you use it, you will have a problem when you move the form very fast and the mouse goes out of the panel. I had the exact same problem.
try this:
using System.Runtime.InteropServices;
and in your Form class
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
public void mouseMove(MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
ReleaseCapture();
SendMessage(this.Handle, WM_NCLBUTTONDOWN, new IntPtr(HT_CAPTION), IntPtr.Zero);
}
}
no need for a mouseDown event for this
Your private methods in MyPanel cannot be called by the framework. You need to declare them as follows:
protected override void OnMouseDown(MouseEventArgs e)
{
var parent = this.Parent as BarraSms;
parent.mouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
var parent = this.Parent as BarraSms;
parent.mouseMove(e);
}
Try this:
public void mouseMove(MouseEventArgs e) {
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Point currentPos = Location;
currentPos.Offset(e.X + mousePoint.X, e.Y + mousePoint.Y);
this.Location = currentPos;
}
//Or simply use Location.Offset(e.X + mousePoint.X, e.Y + mousePoint.Y);
}
You have to use Location (the current location of the form), not the Control.MousePosition which is the location of mouse on screen.
UPDATE: Looks like you don't even know how to register event handlers, try modifying your panel class like this:
public class MyPanel : System.Windows.Forms.Panel{
//(...)
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
BarraSms.getInstance().mouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
BarraSms.getInstance().mouseMove(e);
}
}

How can i capture the screen without the Form?

This is a class i'm using to capture my screen and mouse cursour as screenshot.
But i want to make somehow that if the Form is in the middle of the screen don't capture it captrue the screen and the area behind the Form but not the Form it self.
Even if the form is in the front and i click on buttons or change something in the Form while the application is running do not capture it just keep capture the screen the area behind the Form like the Form is not there.
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
namespace ScreenShotDemo
{
public class ScreenCapture
{
[StructLayout(LayoutKind.Sequential)]
struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public POINTAPI ptScreenPos;
}
[StructLayout(LayoutKind.Sequential)]
struct POINTAPI
{
public int x;
public int y;
}
[DllImport("user32.dll")]
static extern bool GetCursorInfo(out CURSORINFO pci);
[DllImport("user32.dll")]
static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon);
const Int32 CURSOR_SHOWING = 0x00000001;
public static Bitmap CaptureScreen(bool CaptureMouse)
{
Bitmap result = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
try
{
using (Graphics g = Graphics.FromImage(result))
{
g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
if (CaptureMouse)
{
CURSORINFO pci;
pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(CURSORINFO));
if (GetCursorInfo(out pci))
{
if (pci.flags == CURSOR_SHOWING)
{
DrawIcon(g.GetHdc(), pci.ptScreenPos.x, pci.ptScreenPos.y, pci.hCursor);
g.ReleaseHdc();
}
}
}
}
}
catch
{
result = null;
}
return result;
}
}
What i mean is that i will see the Form when it's running and i will be able to change things click buttons but the captured screenshot if i will edit it with Paint i will not see the Form .
This is in Form1 how i make the capture:
private void StartRecording_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
And timer1 tick event:
private void timer1_Tick(object sender, EventArgs e)
{
using (bitmap = (Bitmap)ScreenCapture.CaptureScreen(true))
{
ffmp.PushFrame(bitmap);
}
}
This line make the actual capture: using (bitmap = (Bitmap)ScreenCapture.CaptureScreen(true))
Um.. Hide the form?
this.Visible = false; and THEN run the screenshot method.
Like this:
protected Bitmap TakeScreenshot(bool cursor)
{
Bitmap bitmap;
this.Visible = false;
bitmap = CaptureScreen(cursor);
this.Visible = true;
return bitmap;
}
and use it in your code the way you wanted:
private void timer1_Tick(object sender, EventArgs e)
{
using (bitmap = (Bitmap)ScreenCapture.TakeScreenshot(true))
{
ffmp.PushFrame(bitmap);
}
}

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