Well, the project has moved along rather nicely and we have a pretty darn good product, but a wrench has been thrown into the gear works.
We have a C# 2012 application that interacts with another application (written in VB 6 of all things) and we can do a good bit with it so far, but we have a problem.
We need to select a button on a toolbar at the top of this particular application's window, but the button is not available through an API search. We have the main window's handle and can see all of its children, but I think the Toolbar is a User type control that we can't access through the API Calls. This application is very poorly designed and we had to do a LOT of work just to discover TWO User ID text boxes on the logon screen.
Anyway, my question is this: How would I set up a call to the main window and click a certain X, Y coordinate of that window's viewable area? I am using SendMessage to send mouse clicks to press a button control already, but if I can't get access to that button control, the idea was to send mouse clicks to a specific coordinate of the window.
Any ideas folks? Thanks!
It looks like the solution will be to get the Window's rectangle and add the offset in order to use the mouse event API call.
Thank you to #Idle_Mind for the suggestion. It is at least working on our test environment. It will be next week before we can test the solution out in our client's environment.
I tried writing code several different times, but I came to an error with each one.
Basically, I'm trying to make "windows" similar to say Explorer, Paint, MediaPlayer, where you could drag then around, interact with them, minimize and close. Of course, if you clicked on a window, the one below it (they can overlap) shouldn't get affected.
I know how to do this, I have a list of the class I call Window, loop through it, and I only interact with the first window to contain the location of the mouse-click. This way, other windows overlap won't get affected.[1]
Next, I had to make it so that two buttons that are overlapping don't get activated when the user clicks in the "intersection of both buttons." I handled this by using the same method I used above.[2]
But the problem I'm facing now is that, if I hold the left click, but then I decide not to click a button, I drag the mouse away from the button, and release the left click, so that the button-click event won't be activated. But, when I remove the mouse from the boundaries of the button, and say, into another.. the new button get activated. Which it should not.[3]
My set up is like this:
I have a class called Window.
In Window, I have a list of the class called Interface (similar to the Control class in WinForms).
And each Interface has a struct in it that contains 4 bools, if the left/right is currently down, and if they were down in the previous processing. (prevLeft, prevRight, currLeft, currRight)
So, I'm ready to discard that (I have not yet, so I still have the source code), but I need a good structure for making an object-oriented type of application. However, I am not using WinForms. I need help with the structure alone, so no actual code is necessary, description is enough. I need to avoid the 3 problems I mentioned above.
Creating your own Window Manager is not an easy task. I know it because I'm making one too ;)
You can use an existing, though maybe not the best solution, like for example Nuclex.UI, which I personally rejected when I first saw it, but if you're not dead set on making your own WM, I suggest to use that or hybrid WinForms-XNA approach.
But if you're really dead set on implementing a custom Window Manager, you have to understand how any other WM works. Since we're talking about XNA, it means Windows, and that means Windows Explorer, which is a great thing to learn from.
You have to recognize how the simplest things work, and it's really not so hard. The hard part is figuring out what logic is updated when, and how to not spend all the CPU on only UI updates. Let me just give you a few hints on how to solve the problems you mention in your question.
To keep track of all windows, I'm using a Dictionary<string, Window>, where Window is a custom class, and the string is its unique name for rare cases where I have to call windows by name. Think of it as a window GUID or Handle. But you can just make it so that a "Form" can only appear once, and store all references in static variables.
To make WM understand what control you're clicking I use rectangles and check if they contain a Point which is at Cursor coordinates and has {1; 1} pixel size, which is probably about the same way it's done in Windows Explorer. To do that your WM needs to know in which order to update the active windows. Usually you'd want to start from the topmost window and continue towards the end of the list of active windows. For that you can just iterate through the list with a foreach loop.
But that's not all, because every window itself is a Container, which means it contains other controls, some of which may even be Containers themselves, like WinForms Panel class. This means you have to iterate through each of the Windows' Children controls. The update order should make sense too - update from the topmost child to the bottommost, recursively for Container controls, in case they also have Containers in them. This basically means you'd want to implement a recursive GetAllControls() method for your WindowManager class that would iterate through all Containers and return a list of all Controls.
Drawing all those Controls should be done in reverse order of updating them, so you can just GetAllControls().Reverse() and iterate through that in a foreach loop.
Where to draw and what to update depends on all the parent containers the current container has and their combined offset from the top-left corner of the game window. I solve this by storing a ParentContainer reference in all children controls to get the appropriate DrawRectangles and update areas via recursive properties.
When you click somewhere on the screen and a click is registered on a Control, make the WindowManager remember that (bool clickRegistered) and not run any OnClick events on any underlying Controls.
Windows Explorer remembers the control you clicked and will activate its OnRelease event if the cursor is then released in the update area of the very same control. So basically Windows Manager only does something when you release the mouse button. You can make your WindowManager and Controls to handle click events differently, like firing an event right after you press the mouse button, i.e. OnMouseDown. But remember that Microsoft aren't noobs and there's a reason for that behavior in Windows Explorer, and it's because if you accidentally press a mouse button somewhere you didn't intend, you can still fix it by moving the cursor outside the pressed control's update area and not run its action.
At this point you might be thinking "Is it really worth implementing all this?" For me the answer was "maybe", because I was a total noob in both C# and XNA at the time I started, and now I know my game, which was originally supposed to use some Window Manager, is going to benefit from my own WM implementation far more than from ready third-party solutions. And besides, it's a great exercise in logic and programming.
But if you'd like to think of yourself as a game developer, you should think in terms of reaching your goal as quickly as possible, i.e. actually making a game, and not the game engine. So in this case, better make use of existing solutions and start selling your product.
Instead of having the structure with the 4 booleans (similar to xna), how about you make a way to tell where the mouse "is." So in a sense, the mouse is in Window number 5 which is Paint, and the user is holding the mouse down on interface/control number 2 which is a button.
That sounds like it could work.
I need to create a application which is similar to those we will get when we buy a laptop. It will be visible only when the mouse pointer reaches the top of the window. So how can I able to do this using C# 4.0 ?
http://www.notebookcheck.net/uploads/pics/win2_12.jpg
this link u can see the application. I need to create such type
Any idea pls share. Thanks
I suppose there are several different ways to achieve this effect:
You can place part of the window of your application above the visible screen, so only a part of it is visible (let's say you can see only it's bottom). Then you need to handle events when mouse enters (MouseEnter) and leaves (MouseLeave) the form to move the form up and down.
You can use a background thread to call GetCursorPos method at a set interval (i.e. each 500ms) second to check where currently the mouse is. See this link for more information about it and a sample code: http://www.pinvoke.net/default.aspx/user32.getcursorpos.
(If you need only to check the mouse position, you can use a timer to simplify you application.)
When you hit what's possible with C#, you can always start invoking native code - such as the windows API. Since you don't ask a specific question, I'll leave you with:
Position your app where you want it to appear and hide it.
Capture mouse position with windows api (see this SO answer)
When mouse is at screen corner / top, etc; make your app visible.
Now make sure all this works with dual screen setup, and you are done.
I can't seem to find the topic of manipulating the size of the double-click area anywhere. By this I mean that on the SUR40 and some programs I made, the double-click area is way to small for me and some others. While we try double-clicking on a file, folder, item, etc. if we double click by a hair's width off from the first touchdown, the second touch is registered as a drag. I was hoping if anyone would know how to manipulate this to enlarge the area of the click so we could double click without needing to have pin-point precision on both clicks.
I'm almost certain this could be coded in my programs (written in C#) but I haven't the faintest idea where/how to do this. My only guess would be to create a new doubleclick event or class, but apart from that; I'm in the dark as to how I would code it. I'm also hoping there is a way to manipulate this problem for the Windows 7 desktop as well.
I have C# add-in for Word and would like to implement an interactive tutorial like games usually have. I'd like to somehow highlight (maybe by circling) certain visual elements and display text boxes that describe what the element does. For example, say the add-in is a generic workflow editor. I'd like to show to the user, step by step, what needs to be done by visually selecting elements and explaining what they do and what options (s)he has. My first question is: can this be done in C#? My second question is how? :) I suppose I'd have to get the positions of said visual elements and then draw an image on top but I don't know how that could be done.
I'm a bit disappointed that not even a single member of the Stack Overflow community took the the time to at least give a hint about this. But such is life and I'm just going to share my findings here because I'm certain someone else will benefit from them.
To be able to do an interactive tutorial you need three things:
a method to find where a control is located in terms of screen coordinates
a method to point the user to the control by highlighting it or
surrounding it with a red line for example.
a method to do its default action (ie: click a button).
In other words, the idea is to have some sort of window with text describing a control and some graphical way of indicating the control in the app. Optionally, the window could provide something like a ShowMe button which shows the user how to use the control by taking control of the mouse and keyboard.
This is trivial when the controls are made by yourself and thus have source code access. However, when doing such a thing for a black box app such as Word you can use the Windows IAccessible interface. Searching for that with your favorite search engine will yield everything you need to understand it and use it. IAccessible allows one to do many things but most importantly it can get a control's position and can also do the default action.
Having sorted out these things the next step is to figure out how to graphically point out the control. There are many ways to do this but in my case I chose to surround it with a red rectangle. I did this by creating an invisible, borderless form with an empty red rectangle on it. Having the control's position and size, I had no problems placing the aforesaid form over the control.
So there you have it. I laid out the building blocks that one needs to make an interactive tutorial for any app.