Read item being dragged by mouse - c#

I'm wondering if their is any way to see what's currently being dragged by the mouse. I don't mean over a winforms as i can handle events and get it that way but has anyone been able to invoke some of the win api to read the object or information about it?
I'm trying 'monitor' (probably not the best choice of words) the cursor and see whats being dragged and then potentially read that object.
C# / C++ idea's all welcome !
Thanks in advance

One way to do this by design is to inject code into all applications, by means of a hook.
Using Hooks (Windows): http://msdn.microsoft.com/en-us/library/windows/desktop/ms644960(v=vs.85).aspx
This will allow you to detect when dragging is occurring, and you can use the standard windows APIs that the application itself can use to find out what is being dragged.
SetWindowsHookEx: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
A second way is to use Windows UI automation. This will not give you exactly what the application sees, or give you access to the exact data being dragged or dropped, but it may give you enough information for whatever your purposes are.
UI Automation support for drag and drop: http://msdn.microsoft.com/en-us/library/windows/desktop/hh707386(v=vs.85).aspx
Try using UISpy or Inspect.exe to see UI Automation events.
https://stackoverflow.com/questions/1848721/where-do-i-get-ui-spy

Related

Logging Drag and Drop Actions of Users

I am trying to figure out a way to log user drag and drop actions across the entire Windows desktop. I've found various mouse hooks which detect what has been clicked and the Windows UI Automation which also helps with this. I wondered if anybody knew any way to log drag and drop events on Windows? At the moment I can detect drags by monitoring the mouse down, move, then up but I believe the key is to actually determine whether the item has been dropped into another object. This has been an ongoing issue for some weeks now and so I could really do with some help pointers on whether this is actually possible and how difficult it is going to be. As I say, I've exhausted many avenues to try and get it working but although I can detect what was dragged (sometimes - due to Windows UI Automation ambiguous names) I cannot determine if it was dropped onto anything and is therefore a drag and drop action?
Many thanks,
Jonathan
This is an article about Windows drag and drop action across the Windows Desktop.Please check it
http://www.codeproject.com/Articles/9017/A-Simple-Drag-And-Drop-How-To-Example

Taking mouse control in C# WPF

I watnt o create a tutorial/guide inside in my application, creating a "demonstration". For this purpose, I need to capture the mouse of the computer, and to be able to move it and click with it.
I want it to feel like if somebody else were there controling your computer. This will be completed with a video of someone, to make you feel like this someone is doing it live in that moment.
Thank you in advance!!!
There isn't WPF solution. You have to use P/Invoke.
To disable keyboard/mouse use BlockInput API (as far as I understand, you don't want user to break up your "demo").
To simulate user input, use SendInput API.
SendInput at pinvoke.net: http://www.pinvoke.net/default.aspx/user32.sendinput
Another option is to use third-party simulators, like this.

Selecting an item from pop-up menu

I'm trying to make an application that will test some features of an existing app and I wanted it not to be window-size dependent and not to require focusing the window or etc.
I've already figured out how to get window handles for different controls in the tested app so I can click buttons, enter text to textboxes etc. with Send/Post Message but still got a few unsolved problems.
The first is selecting an item from a pop-up menu that can be triggered by button click (TAdvGlowMenuButton class) or right click somewhere- I can't even see any messages related to it in Spy++ so I have no idea how to do it, is it possible to select an item by name? as I don't have it's id
The second thing is clicking next to something, for example 10 pixels to the right of a button.
I have the button handle so I can get it's size and it's parent but I still don't know how to get it's position inside the parent - any ideas?:)
And also a quick one but I don't believe it is possible - can I somehow get position of a label in the tested app? I can't even see it in Spy++ .
I hope you can help me to find it out ;)
Edit: I forgot about the most important thing:P , I'd like to achieve it with Send/Post Message if only it is possible.
My recommendation would be to abandon the message sending/posting model altogether and instead use UI Automation. Automated testing tools is exactly what the UI Automation APIs were designed for, and they are much more capable than SendMessage/PostMessage.
Yes, I realize that this is exactly the opposite of the answer you were looking for. But you will have no end of trouble getting messages to do what you want. A fair number of them rely on the application having the focus, and it is completely reasonable for your code to make this assumption when you receive e.g. a WM_KEYDOWN message. A testing tool should not flag that as a bug.
I notice you've tagged this question with the C# and .NET tags. In that case, you may be interested to learn that the UI Automation APIs have been wrapped in the .NET Framework.

I want to drag an image from a Silverlight UIElement and drop it on the users Desktop or Windows Explorer

I have a Silverlight control containing an image. I want the user to be able to drag the image out of the Silverlight application and drop it anywhere they would be able to drop an image. For example, to the Desktop or to a PowerPoint slide or Word document. Everything that I have read thus far says it cannot be done but I find that hard to believe. I'm very new to Silverlight and RIA development so any help would be much appreciated.
Below is the code sample in my WinForm Form but the drag never starts.
string[] aString = { imagePath };
DataObject data = new DataObject(DataFormats.FileDrop, aString);
data.SetData(DataFormats.StringFormat, imagePath);
DoDragDrop(data, DragDropEffects.Copy);
Well the trouble is that a drag operation in Silverlight doesn't have simple access to anything outside the browser (by design). Depending on the user's settings you even have to get explicit permission for clipboard operations and sandboxed temporary file storage. This really sounds like a task better suited to a WPF application (perhaps with web deployment?) or some other desktop application technology.
However, that being said here are some things you could try/consider:
Silverlight/Javascript/ActiveX combination hosted in Internet Explorer
Silverlight 5 "Out of Brower" & P/Invoke (I heard P/Invoke will be supported when Silverlight 5 comes out)
Silverlight connecting to a web service running on the same computer (crazy, but you didn't ask for "not crazy", you asked for possible)
I am not very familiar with drag and drop in the Win32 API so it would take a lot of research and experimentation before I could confirm that this was even possible (and I can already tell you it isn't practical).
Edit: Based on the extra information you provided about the question I suspect it is possible to do what you are attempting. First, are you using WPF or WinForms? I assume WPF but one of your comments says WinForms. I wasn't very familiar with WPF drag/drop operations, but having looked into it, I think your code is on the right path. I created a WPF application and initiated a drag during a KeyDown event. This meant that the mouse button was not necessarily pressed. If I initiated the DragDrop while the button was down it worked. If I initiated while the mouse button wasn't down, I had to push the mouse button down and the drag operation would start (this was unexpected since I assumed the mouse would have to already be down). If I pressed the mouse down outside the application, then gave the WPF app focus (ALT+Tab), then initiated the DragDrop while the mouse button was still down, it didn't work. I got a reference to the MouseDevice and checked the LeftButton property, and the state was showing as "Released" even though the button was still being held down. It seems the key here is the way drag/drop interacts with internal mouse state. You might have to find a way to set the mouse state (maybe with the UI Automation API?). At this point it should be painfully obvious that this whole thing is a hack (even though it is probably possible to get it to work somehow).
The solution we came up with was as follows. The RIA i.e. Silverlight sends a message to our Desktop application WinForms with the path of the image to drag along with the bounding rectangle in screen coordinates that we want to start the drag from. The Desktop code creates and places a Panel over the area that we want to drag from. This panel is where we use DoDragDrop to initiate the native drag when the user left clicks. Since this panel is placed outside and above the silverlight control, everything works perfect. Sandbox defeated.
I have been working on some Silverlight apps for the past few months and fully investigated your exact requirements only to find it was not possible. I believe you can drag from the file system, from Silverlight control to control, but not to the file system.
Does Silverlight 4 support drag and drop from app to desktop?
http://msdn.microsoft.com/en-us/library/dd772166%28v=vs.95%29.aspx

Is there a way to ask about the status of a drag operation while it is in progress?

I know that when a drag/drop operation is completed, upon receiving a MouseUp or Esc key event, it returns an enum that indicates what happened (Move, Copy, None, etc.) My question is this: is there a way to send back status information to the form/control that initiated the drag event, while it is going on?
The use case is as follows (think Visual Studio-esque layout manager for all of this): I am writing a layout/window managing component that allows regions of the layout to be dragged around. I use a transparent form to paint a semi-transparent overlay that changes based on where the mouse is dragging over, a la the preview overlay that appears when dragging windows around in Visual Studio.
Another motivation is that the serialization process I describe is relatively resource intensive, and I'd prefer not to do it if the dragging is all going to occur within the same process/window. So, if there was a way to lazily serialize only when an actual "drop" in another window happens, that would probably make all the difference in usability.
What I want to do is enable dragging between different windows or even different instances of the application. I've already plumbed out the serialization code and everything, but the issue is that, when I drag a chunk of layout into another window, the first window doesn't have any way of knowing that the mouse is now over another instance of the application, which is more than capable of painting its own overlay. So, the original overlay hangs around like an idiot and my program looks like crap.
Is there any way for me to pass along some kind of callback or is there any message or property I can listen for/poll during a drag operation that will tell me if my mouse pointer is over a region that can accept its data? Please don't make me resort to listening for the CursorChanged event, I've already lost too much self respect using reflection to hack around weird wpf/winforms dragging interop bugs. If anyone could suggest a clean resolution for this problem I would be extremely grateful.
Additionally, if anyone could point me to any favorite sites which describe how to go about doing reeeeally funky things with drag and drop, it would be appreciated, as I've found there is quite a lack of really nitty gritty information available about dragging. Usual things like custom cursors and the like are okay, but I'm probably more interested in Win32 black arts and the like.
UPDATE:
I actually just found out about the GiveFeedback event a second ago, came back to my question, and there it was. Huge facepalm moment. However, since I've got you here, what about my second question: is there any way to lazily load the information only when it encounters a valid target? Could I somehow implement my own IDataObject or do things get marshaled righ when the mouse leaves the form? GiveFeedback provides me only with whether there's a valid target under the cursor, but doesn't let me change what data is being dragged...
ANOTHER UPDATE:
Is there any way to determine the source of a drag operation? That is, when my control receives a DragEnter message, how can I tell if the source of the drag is my own control or a foreign one? I know I can hackishly encode it by messing with the AllowedEffects property, but is there any more direct route?
Check out the GiveFeedback event (there's a nice article here) - that sounds to me to be exactly what you're after.

Categories

Resources