I have an old color picker utility written c++ that I coded years back and want to rewrite using c#.
I implemented the global hook to pick pixels off the screen and so on. Everything is ok but...
The cross cursor reverts to the pointer once the mouse moves outside the form and onto the desktop. This does not happen with my c++ code (MFC actually).
How is this accomplished in c#?
Thank you all.
(I'm using this http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C for the hook)
The solution (or a workaround) is to simulate the first part of a mouse click event. This will lock the mouse on the calling window, thus preserving the chosen cursor.
[DllImport( "user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall )]
public static extern void mouse_event( uint dwFlags, uint dx, uint dy, uint cButtons, uint dwExtraInfo );
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
And then after enabling the mouse capture in the code:
mouse_event(
MOUSEEVENTF_LEFTDOWN,
(uint)Cursor.Position.X,
(uint)Cursor.Position.Y,
0,
0 );
this.Cursor = Cursors.Cross;
Hope it helps.
Related
I am trying to make a makeshift onscreen keyboard for Windows 10 and need the background to be transparent, to make it more convenient for the user (the keys are already transparent). I, however, have no idea how to make the background transparent.
Any help would be greatly appreciated.
I believe that I am essentially looking for an updated version of the code in this thread show below:
using System;
using System.Runtime.InteropServices;
using UnityEngine;
public class TransparentWindow : MonoBehaviour
{
[SerializeField]
private Material m_Material;
private struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll")]
static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, byte bAlpha, int dwFlags);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern int SetWindowPos(IntPtr hwnd, int hwndInsertAfter, int x, int y, int cx, int cy, int uFlags);
[DllImport("Dwmapi.dll")]
private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);
const int GWL_STYLE = -16;
const uint WS_POPUP = 0x80000000;
const uint WS_VISIBLE = 0x10000000;
const int HWND_TOPMOST = -1;
void Start()
{
// You really don't want to enable this in the editor, but it works there..
int fWidth = Screen.width;
int fHeight = Screen.height;
var margins = new MARGINS() { cxLeftWidth = -1 };
var hwnd = GetActiveWindow();
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
// Transparent windows with click through
SetWindowLong(hwnd, -20, 524288 | 32);//GWL_EXSTYLE=-20; WS_EX_LAYERED=524288=&h80000, WS_EX_TRANSPARENT=32=0x00000020L
SetLayeredWindowAttributes(hwnd, 0, 255, 2);// Transparency=51=20%, LWA_ALPHA=2
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64); //SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
DwmExtendFrameIntoClientArea(hwnd, ref margins);
}
void OnRenderImage(RenderTexture from, RenderTexture to)
{
Graphics.Blit(from, to, m_Material);
}
}
The code given did not work, so I assume that it is outdated. I have no idea how to update it myself, since it is a bit out of my skill set. When I upload the code to Unity, it just says that there are errors in the code and that it is not a valid script. When I open the script, however, no errors appear.
I expect to be able to have a relatively good view of whatever is behind my keyboard, like my desktop, but I actually just see a black plane.
Update:
So apparently the error message was caused by my script not having the same name as my class. I spent over 4 hours yesterday trying to fix that error message, and this naming incident was the cause :(. Thanks Ruzihm. Anyway, now that the error message is gone, when I run or build the program, my transparent window material just comes up: a dark pink. I then changed my Unity version back to 2018.2.16f1, with no success. Then I removed the #if !Unity Editor line to get the transparency to work perfectly in the editor, but not when I build it. Note, click through does work when I build it and when I run it in the editor.
As discovered in the comments, the problem was fixed when the camera's clear flags were set to solid color and the pink transparent window material was replaced a with white transparent material.
As described in the title I've been trying to search for a way to set the mouse coordinates by using a Cursor.Position = new Point(58, 128); Then while holding the Left Mouse button (Down) I'm trying to scroll to another direction(random direction). For example, if I was to go onto Google Earth and set the cursor position at 0,0 the cursor would then scroll around the map. If anyone can help out I would surely appreciate it.
Thanks
Solution: floatas, thanks again for responding to this post. I spent yesterday and today trying to figure this out and I finally got it working. I will post my code in hopes this helps others out.
First of all you will need to import some functions.
To change cursor position:
[DllImport("user32.dll", EntryPoint = "SetCursorPos")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetCursorPos(
[In] int X,
[In] int Y);
To simulate mouse events:
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(
[In] uint dwFlags,
[In] uint dx,
[In] uint dy,
[In] int dwData,
[In] uint dwExtraInfo);
Possible mouse events:
public enum MouseEvents
{
MOUSEEVENTF_LEFTDOWN = 0x02,
MOUSEEVENTF_LEFTUP = 0x04,
MOUSEEVENTF_RIGHTDOWN = 0x08,
MOUSEEVENTF_RIGHTUP = 0x10,
MOUSEEVENTF_WHEEL = 0x0800,
}
You can send mouse down and mouse up, simulating click:
mouse_event((uint)MouseEvents.MOUSEEVENTF_LEFTDOWN | (uint)MouseEvents.MOUSEEVENTF_LEFTUP, X, Y, 0, 0);
Didn't tested this, but should press mouse, drag and release:
mouse_event((uint)MouseEvents.MOUSEEVENTF_LEFTDOWN, X, Y, 0, 0);
SetCursorPos((int)X+10, (int)Y+10);
mouse_event((uint)MouseEvents.MOUSEEVENTF_LEFTUP, X+10, Y+10, 0, 0);
I'm busy making a application where i can use the Leap as a mouse. I'm making a WPF application with C# and XAML.
I allready can move the cursor, but i have problems making a function to activate the left mouse button.
Can someone help me with this problem? I need to activate buttons created in XAML.
Another solution could be a function that activates a button when de Leap cursor is on the button for like 3 seconds. I can't find any examples on the Internet. Does someone have a simple basic program or example for me? Please help!
Here is a link to the application i allready have. Maybe it helps
https://www.dropbox.com/sh/kp51hdbhcacaky7/pdinDQpA-6
About the "mouse over button" thing - u can try this solution (worked for me):
create hover event for buttons (mouse entered / leave)
create a bool flag for like "isHovered" (true if hovered, false if not)
start a DispacherTimer, set it's Tick (3 sec?)
on Tick do mouse click (previous answer)
hope it halped :)
try this:
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08;
private const int MOUSEEVENTF_RIGHTUP = 0x10;
public static void DoMouseClick()
{
Point mousePoint = GetMousePosition();
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, (int)mousePoint.X, (int)mousePoint.Y, 0, 0);
}
Is there any way I can send a left click event to a TextBox? for what ever the reason although I am doing a TextBox.Focus() and the cursor is blinking inside the TextBox but I cannot start typing in it, But if I do an extra click with the mouse inside the text box then I can start typing. So, I was wondering how to send that event to it?
To send mouse events, you'll need to import user32.dll and use mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
Example
class Mouse
{
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
private const int MOUSEEVENTF_LEFTDOWN = 0x02; //Left click
private const int MOUSEEVENTF_LEFTUP = 0x04;
private const int MOUSEEVENTF_RIGHTDOWN = 0x08; //Right click
private const int MOUSEEVENTF_RIGHTUP = 0x10;
public static void sendMouseRightclick(Point p)
{
mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, p.X, p.Y, 0, 0); //Sends a mouse right click at the specified Point
}
public static void sendMouseClick(Point p)
{
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, p.X, p.Y, 0, 0); //Sends a mouse left click at the specified Point
}
}
When using this, you may call Mouse.sendMouseClick(Point p) to send a mouse left click at the specified point.
In your case, I think that you might want to use Mouse.sendMouseClick(TextBox.Location); to send a mouse left click at the current TextBox position.
Thanks,
Have a great day :)
Ok to fix this first we should make sure the form itsself is activate.
To do that, in the Form_Shown event we should call this.Activate()
I'm working on an Windows Form Application in C#, Framework 4 (32 bit).
I have a list that holds coords of the mouse, and I can capture them. So far so good.
But at some point, I want to go to those coords and left mouse click on it.
This is how it looks like right now:
for (int i = 0; i < coordsX.Count; i++)
{
Cursor.Position = new Point(coordsX[i], coordsY[i]);
Application.DoEvents();
Clicking.SendClick();
}
And the Clicking class:
class Clicking
{
private const UInt32 MOUSEEVENTF_LEFTDOWN = 0x0002;
private const UInt32 MOUSEEVENTF_LEFTUP = 0x0004;
private static extern void mouse_event(
UInt32 dwFlags, // motion and click options
UInt32 dx, // horizontal position or change
UInt32 dy, // vertical position or change
UInt32 dwData, // wheel movement
IntPtr dwExtraInfo // application-defined information
);
// public static void SendClick(Point location)
public static void SendClick()
{
// Cursor.Position = location;
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, new System.IntPtr());
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, new System.IntPtr());
}
}
But I'm getting this error:
Could not load type 'program.Clicking' from assembly 'program, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because the method 'mouse_event' has no implementation (no RVA).
And i realy don't understand what the problem is... Do you guys know what the problem is? or do you know an better way to do what i'm trying to do?
Have you included the following line?
[DllImport("user32.dll")]
static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData,
UIntPtr dwExtraInfo);
This will import the function mouse_event from the user32 dll, which is what you are trying to use within your program. Currently your program does not know about this method within the DLL untill you specify wher it comes from.
The website PInvoke.net user32 Mouse Event is quite handy for the basics on this sort of thing.
The answer to Directing mouse events [DllImport(“user32.dll”)] click, double click will be of great help to your understanding as well.
The flags are what commands you want to send into the mouse_input function, in that example you can see that he is sending both mouse down and mouse up in the same line, this is fine because the mouse_event function will split those flags up and execute them consecutively.
Also note that this method has been superseded by the SendInput command, a good example of SendInput and SetMousePos can be found At this Blog
I guess you are missing the following line
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]