I've a Windows Form Application that does a simple task : the user selects a video in the main form, and the application pops up a new form with a Shockwave Flash Object reproducing it.
What i would like to do now is to move in the Movie timeline when the user scrolls the mouse wheel. The problem is, the Flash object steals the focus from the form as soon as it pops up, and it doesn't support a mousewheel event.
Is there a way to do it, other than hooking the MouseWheel event and redirect it to the application when the popup has the focus?
The window displayed by Flash is owned by a different process. That makes messing with messages difficult, you'll at least need a low-level mouse hook to see the mouse message before it disappears into the other process.
The boilerplate code is available here. Beware that it has a bug that prevents it from working on .NET 4 and up, see this answer for the workaround.
Related
I'm working on a screen capture utility that captures active windows. I'm using transparent overlays to capture the full screen and then overlay the active windows based on mouse move events passed through to the underlying desktop/windows.
Both of the overlay windows currently use the WS_EX_TRANSPARENT style to allow mouse events to pass through to the underlying windows so I can detect where the mouse cursor is located. I grab the window handle and rect size to outline the window and then use Global Mouse and Keyboard Hooks to accept or reject a capture.
It's pretty ugly and spread out code (which is why I'm not posting here for now) but it all works very well and I can highlight the windows in mousemove and capture clicks with the global mouse and key handlers.
It all works except for this problem:
The Global Windows Hooks do not fire over an Admin Window so when I want to capture a Powershell, Command or Visual Studio (in Admin mode) Window no hook events are forwarded.
Apparently there's no way to work around this security issues using Windows hooks (or GetAsyncKeystate() for that matter).
I've tried a couple of different approaches to work around this issue:
Instead of using Hooks I tried using the highlight window to capture mouse/key events
This sort of works, but it's clumsy - fails if no window is selected at all (no way to get out) and doesn't allow for selecting contained windows once the parent is selected (ie. no drill down)
I also tried Win32 GetAsyncKeystate() which captures the last mouse or keyboard input and that would work, but it too fails to send mouse or key interactions from Admin windows.
So I have two choices imperfect solutions at the moment: using Hooks or GetAsyncKeyState to get the proper Window browsing selection behavior for all but admin windows, or I can capture all windows but lose the ability to drill into child windows after a parent window is selected.
I'm at the end of my rope and the real question is this:
Is there some way to create a semi-transparent or transparent window that can intercept mouseclicks and pass them on to the window area below?
I am trying to make a program which plays video and receives user input on specific frames. i need to make a click event for the axvlc video player. Is this possible?
my program contains an instance of the VLC ActiveX Plugin in a windows form in visual studios.
I want, while the program is paused, for the user to be able to single click a point on the frame, trigger an event, add the location of the mouse to a list.
otherwise, i have considered rendering a bitmap of whatever frame it is on while paused so that i can add click events to that. but i would very much like to avoid that solution as it would complicate what i am doing.
I found a tremendously helpful control in this question.
Making a control transparent
the top answer has code for a control that supports real transparency even on top of video. this is perfect.
I have written an application that currently handles clicks from multiple mouse devices.
I used this project and modified to handle mouse clicks as apposed to keyboards.
This is working fine, however now I need to know if there is a way to suppress a click event if it has been handled by my app. The app is a quiz game so the idea is that the quiz master will have (and still be able to use) 1 mouse, and the other contestants will have their own mouse (as buzzers). So when they buzz in, I don't want the mouse click events to fire in the operating system (or at least this application).
The concept is the familiar override of void WndProc(ref Message message), and so I have tried not calling base.WndProc(ref Message) when I don't want the click events to fire, but this has not worked.
Can anybody point me in the right direction here?
Should I be going down the windows hook route? I have looked at this, but I can't seem to work out how I could hook to each mouse device individually.
Any help would be greatly appreciated.
Edit:
This is a Windows Form UI project, and not WPF. So the MultiPoint SDK from Microsoft won't work.
The solution to this lies within not WndProc, but PreFilterMessage(). By intercepting messages before they even reach the form, you can remove them from the message pump causing them to never reach the control that was clicked. This also works for child controls within the form.
I answered this and posted the full source in the following question:
C# Get Mouse handle (GetRawInputDeviceInfo)
I have a NotifyIcon in the system tray. How can I detect when the user has left-clicked down on it? I assumed the MouseDown event would be what I want to use but it only handles right click and middle-button click. For left-click, it only fires after the user has let go (as in they've just performed a normal click). Is there a way to get the MouseDown event only?
This is by design, the shell synthesizes the MouseDown message from the up event. You'll see why it works this way when you click and hold the button down and then start dragging. Note how the notification area overflow window pops up and lets you drag the icon into it to remove it from the visible area. It can't work both ways.
Technically you could hook the window owned by Explorer.exe to get a crack at the messages before Explorer does with SetWindowsHookEx(). That however requires a kind of DLL that you cannot write in C#, it needs to be injected into Explorer. Very destabilizing and hard to beat the competition that is trying to do the same thing. Also the kind of code that causes sleepless nights for the Microsoft appcompat team.
It appears that the underlying Win32 API Shell_NotifyIcon sends a WM_LBUTTONDOWN message when the user clicks the icon. According to MSDN anyway.
Examining the Windows Forms source code for NotifyIcon reveals standard mouse down event handling, so if the Win32 message was being sent at the "correct" time it would work as you want/expect.
I have to agree with a previous comment that NotifyIcon will be swallowing WM_LBUTTONDOWN since it needs to do mouse capture to allow the user to drag the icons about.
It's possible that this article about creating a tray icon for WPF will be useful since it shows how to use SetWindowsHookEx etc from C#.
We have implemented some custom tooltip-drawing code that fires on Tick events of a timer. Whenever this event fires, we check to make sure our control is visible (this.Visible) and is the foreground window (GetForegroundWindow()).
The problem we are having involves "always on top" windows like Task Manager or Process Explorer (when the "always on top" option is enabled). Because these windows are always on top, sometimes our application is occluded/covered by such windows, but our tooltip still pops up and gets drawn on top of the top window.
I have tried to use the Form.TopMost property, but this is not acceptable because then, tooltips never appear if there is an "always on top" window anywhere. In this case, our application is even active, so we should be showing the tooltips.
How do I detect/determine whether there is an "always on top" window covering the area on my form where the mouse is hovering? I want to prevent the tooltip from showing "through" the window.
It sounds like you're polling the mouse position with a timer, and then displaying a tooltip. That's the wrong way to go. What you should do is detect mouse-move messages. If you get mouse-move events telling you that the mouse is in a certain region, then set a timer, and if the mouse hasn't left that region by the time the timer fires, display the tooltip. (Incidentally, that's how native Windows tooltips work. See TrackMouseEvent.)
That solves your problem with always-on-top windows automatically because if part of your window is obscured by an always-on-top window, your form simply won't receive mouse-move events for that region, so you don't need to check whether the mouse is really there.
If you're set on using your current technique, then you can use the WindowFromPoint API function to determine what window is visible at any given point on the screen. Use that to determine whether your window is on top at the place you plan to display the tooltip. (The .Net Framework API map says the .Net equivalent to that API function is Form.GetChildAtPoint, but that only gives children of a .Net form, whereas you need to consider all top-level windows, including non-.Net windows.)