In a C# Windows application there are 2 different mouse events, MouseEnter and MouseHover, which are both triggered when the cursor is over the object.
What is the difference between them?
Assuming you are in Windows Forms:
Mouse Enter occurs:
Occurs when the mouse pointer enters the control.
(MSDN)
Mouse Hover:
Occurs when the mouse pointer rests on the control.
A typical use of MouseHover is to display a tool tip when the mouse
pauses on a control within a specified area around the control (the
"hover rectangle"). The pause required for this event to be raised is
specified in milliseconds by the MouseHoverTime property.
(MSDN)
To set MouseHoverTime globally (not recommended, see #IronMan84's link here for a better solution), you can use the SystemParametersInfo function. Because thats a Win32 API call, you'll need PInvoke:
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, IntPtr pvParam, SPIF fWinIni);
Called as:
SystemParametersInfo(SPI.SPI_SETMOUSEHOVERTIME,
desiredHoverTimeInMs,
null,
SPIF.SPIF_SENDCHANGE );
Sigantures from PInvoke.NET: SystemParametersInfo, SPIF (Enum), SPI (Enum)
I didn't include the Enum signatures here because they are so freaking long. Just use the ones on PInvoke.Net (linked above)
For complete information on the SystemParametersInfo API call and its parameters, see MSDN.
MouseEnter is when your mouse just goes into the area.
MouseHover is when your mouse stays there for a bit (typically used for tooltips).
As far as mouse events go, the MouseEnter event occurs before any others. Also, you can manually set how long the mouse must hover over the area before the MouseHover event gets fired. You can see more about that here.
EDIT: I changed the link on adjusting MouseHoverTime. It turns that you can't easily do it, and that it is highly recommended not to, since it's a system value, which will affect all applications on the machine. Instead, the new link shows how to use a new, application-specific variable to do it manually.
Related
I hope to simulate a left mouse button click on another window, and hold the button for about 2 seconds. I have tried the following code:
int WM_LBUTTONDOWN = 0x0201;
int WM_LBUTTONUP = 0x0202;
SendMessage(hd, WM_LBUTTONDOWN, new IntPtr(1), lParam);
Thread.Sleep(2000);
SendMessage(hd, WM_LBUTTONUP, new IntPtr(1), lParam);
The parameter "hd" is the handle of another window and "lParam" contains coordinate infomation. But it didn't work as my expectation.I used breakpoint to debug the code. When "WM_LBUTTONDOWN" message was sent to another window, the push button in another window was clicked immediately, rather than be held and wait for the message "WM_LBUTTONUP".
When I used real mouse to click and hold the button, spy++ showed that there are not any other messages except "WM_MOUSEMOVE" between "WM_LBUTTONDOWN" and "WM_LBUTTONUP".
Picture of Spy++ showed
So, how to simulate mouse button down and being hold in C#? Any advice would be helpful, thank you!
You can’t simulate keyboard input by sending window messages. You need to use SendInput() instead (C# declaration).
See: Send keys through SendInput in user32.dll.
"mouse_event" API function can solve the problem.But the side effect is the mouse poiter will move actually, when the program is running you cannot move your mouse or unexpected wrong position would be clicked.
I am trying to positioning EO.WebBrowser.Wpf.WebControl using .NET 4.5. It is one of WPF webbrowsers from NuGet. For some reasons, I need the instance of that webbrowser to be bigger than its parent object. My expectation was, that it is possible to clip it with the parent by something like this:
WebControl Browser = new WebControl()
{
ClipToBounds = true
};
Unfortunately, it is not working. For illustration following pictures (sorry for the links, but I don't have rights to send images directly):
http://unsite.cz/StackOverflow/7XJrP.png
http://unsite.cz/StackOverflow/DHwud.png
On the picture, there is used red System.Windows.Controls.Border to highlight the problem. Left and top part is OK, but bottom and right not, beacause the browser overflows its bounds. The hierarchy used for illustration is Window > Border > ScrollViewer > WebControl.
I tried to place some panels between ScrollViewer and Webcontrol, but without results.
I also tried to manipulate the Z-Index with no influence on it.
My last try was to solve this problem by following extern function for clipping:
[DllImport("User32.dll", SetLastError = true)]
private static extern Int32 SetWindowRgn(IntPtr hWnd, IntPtr hRgn, Boolean bRedraw);
The function is OK when I clipping whole window, but I don't know (and I think that it is not possible) to clip with it just one specific WPF window descendant.
So here is my question: How to force EO.WebBrowser.Wpf.WebControl to autoclipping, or how to do it manually?
Thanks
P.S. Sorry for my english...
I need to be able to programmatically scroll a window up and down given only a point on a screen. I've managed to retrieve a handle using Windows API, but I am unable to get it to scroll up or down.
Assume the following code:
//retrieves the correct window.
IntPtr hWnd = Win32.WindowFromPoint(new Point(xPos, yPos));
Win32.Rect rect = default(Win32.Rect);
//retrieves a rectangle with the desired windows dimensions
Win32.GetWindowRect(hWnd, ref rect);
//Insert scroll code here...
to scroll a window you need to send it a windows message by calling SendMessage with the appropriate parameters - for full details regarding scrolling and associated messages etc. see MSDN.
UPDATE - as per comments:
Another option might be to call ScrollWindowEx on the hWnd - as per comments calling ScrollwindowEx should NOT be used since it would create an inconsistency between the displayed state and the internal state of the respective window!
Have you tried using SendMessage() function with WM_VSCROLL and WM_HSCROLL messages?
Also check SetScrollInfo (pInvoked version here). Even this post may be helpful to you.
I'm working on my own software to operate the mouse on my computer using C# and the kinect SDK. I really want to try using it to play a game like Red Alert, or some sort of RTS, or even just for general navigation.
The problem that I've found is that when using a program with a different mouse, like red alert or going into a virtual machine where mouse integration isn't supported, the program will not pick up on the calls that the C# program is making to the System.Windows.Forms.Cursor calls, let alone the mouse_event calls. I'm new to interfacing with windows and what is happening here, can someone explain/pose a solution?
--UPDATE--
As an update, I'm still not entirely sure what's going on, but I seem to have found a workaround for red alert in particular;
Since red alert is a fairly low graphics program, it is trivial to run it within a virtual machine specifically for me, vmware workstation with an XP client. If you use the mouse_event code it works well, HOWEVER, something that I struggled with was finding the correct code to represent mouse movement. It would seem that the MOVE flag moves the mouse relatively, which I didn't want, and the absolute tag didn't move the mouse at all. It is, in fact, the OR of them that produces absolute movement on the screen, so my code for mouse movement and clicking emulation ended up looking like this:
mouse_event((int)0x00000002, cursor.X, cursor.Y, 0, 0);
for clicking and
mouse_event((int)(0x00000001 | 0x00008000), x, y, 0 0);
for mouse movement, where x and y are the new coordinates out of 65535 (the absolute range). Is it perfect? Nah. But it works for now. I think there's something to do with the way windows ignores certain programs when it runs ra, maybe because of compatibility mode? I don't have another game to test it with right now, but I'll post results with a non-compatibility mode in the future.
Pete
(It wouldn't let me post as an answer for another two hours and I have to sleep to catch a flight in the morning!)
You will have to do some low level windows messages to get this to work properly. Games using DirectX like Red Alert will not look at the System.Windows.Forms.Cursor at all. You will need to interface with the Windows User32.dll to send the appropriate messages to windows so it can route them appropriately to the other applications.
Here is some code to get you started looking in to sending messages via the User32 DLL in C#:
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);
// Activate an application window.
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
I hope this gets you started, but I don't have the time to go through each mouse message, what the wParam and lParam are, and what the Msg should be for each. I'm sure if you search around you can find the specific messages to send for each event such as mouse move, left click and right click.
Good luck.
I'm building a WPF application with some hackery involved to embed Form elements on the same render layer. Essentially what I do is I render the form off-screen and have a mock-up of the form in a WPF image. I also have a low level mouse hook which steals events from the WPF application if they are destined for the Form mock-up and instead use PostMessage(...) to send the events off to the hidden form element.
If I return a non-zero value from my hook procedure indicating to eat the event (even if I still call all the mouse hooks in the queue), the cursor gets stuck in one position. I'm assuming this is because the cursor position gets handled in some sort of WPF application layer that the event isn't reaching.
I figured that it was fine to prevent the WPF application from knowing about the event at all because I could just set the cursor position myself-- there are coordinates attached to a mouse event after all. Unfortunately, it seems that these mouse coordinates are horribly incorrect. In fact, no matter where my cursor is located, I always receive the same coordinates.
Here is my code:
if (nCode >= 0){
MOUSEHOOKSTRUCT_LL mousehookstruct_ll1 =
((MOUSEHOOKSTRUCT_LL)Marshal.PtrToStructure(((IntPtr)lParam), typeof(MOUSEHOOKSTRUCT_LL)));
if (mousehookstruct_ll1 != null) {
if ((user != null) && user.SystemMouseHookProc(nCode, wParam, lParam, new Point(mousehookstruct_ll1.pt_x, mousehookstruct_ll1.pt_y), mousehookstruct_ll1.dwExtraInfo)) {
return new IntPtr(1);// CallNextHookEx(this.MessageHookHandle, 1, wParam, lParam);// It doesn't matter that I don't call CallNextHook here.
}
}
}
GC.KeepAlive(this);
return CallNextHookEx(this.MessageHookHandle, nCode, wParam, lParam);
}
Then in user.SystemMouseHookProc(...) I print out the correct cursor position followed by the coordinates pulled by the mouse hook, and the output is always something like the following:
Cursor: 523,578
{X=1985777551,Y=1985777602} //This coordinate never changes
That output is clearly wrong. What can I do to get the correct mouse coordinates from a mouse hook?
Thank you.
P.S. This solution is derived from a popular one online. Unfortunately, that solution didn't meet my needs so I've had to alter it to this form.
Any reason the static property System.Windows.Forms.Control.MousePosition won't work?