Identifying something on the screen - visual-studio

I'm curious as to how the CodedUI Test functionality in Visual Studio works.
I can see how it can identify keypresses and what's typed by querying the keyboard state, but I'm having a hard time figuring out how (i.e. code-wise) it identifies what button was clicked, where that button is located, and how to track it if between the recording and test runs the button has moved or happens to be scrolled off the screen. I'm mainly interested in items which are foreign to me (i.e. I don't have access to the source code and/or it's running on a different process from my programs process).

Related

MFC: GUI freezes, but keeps working

I’ve encountered a problem I can’t solve.
I’m working on a project with MFC in Visual Studio. The problem is, sometimes GUI just stop visibly reacting, but technically it keeps doing the functions it was intended to do. It means, when I press a button, the function OnBnXXXPressed is executing, but the button doesn’t look like it was pressed, as if I’ve pressed on a picture of button, not the button itself. And it’s not just this button — every other element of GUI seems to keep working, but doesn’t show that it is working.
Also, in this state dialog windows don’t show up upon their call. If I call AfxMessageBox, the message box won’t show up, and the thread that called this function, will not be blocked; AfxMessageBox will basically be skipped.
I have absolutely no idea what can possibly cause that behavior. The question is: what should be happening in program for it to behave this way? Especially if it’s built with MFC?
The project consists of 50+ files, and every function responsible for GUI makes changes to the elements it is about. I do not know where the error is, and I ask you, to the very least, where should I look for it.
Thank you for attention!
The answer was originally provided in the comment section. My code indeed has a GDI resource leak that was provoking this behavior.
When a button is clicked, are you doing a bunch of processing, or do you return fast? If you don't return, maybe locking the UI thread. After a user presses on the button, how long is it taking before the OnClick for that finishes running?
If that's it, here's some more info: https://learn.microsoft.com/en-us/windows/desktop/Win7AppQual/preventing-hangs-in-windows-applications
The solution I've generally used for long-running logic on a UI click is to run it a background thread.

How can I determine the source process/hWnd for a Drag and Drop operation from drop target

My C# Windows application accepts drag operations, and I'd like to be able to identify the hWnd and/or Process ID of the source. Is this possible, and how would I go about determining it?
I've tried getting the active window when the drag-over commences, but if the user has activated other windows during the drag operation (for example, by pressing Alt+Tab one or more times), that isn't very reliable.
I've also tried inspecting the formats on the IDataObject, but that signature isn't enough to reliably identify the source window.

Intercepting a window's attempt to steal global focus on Windows

I'm a developer and a long-time Windows user with an obsession about making my system as convenient to use as possible.
Yesterday I thought about something that has always annoyed me in Windows and that I've taken for granted, and I realized that I have a better idea for how it could work, and I'm now wondering whether it's possible to tweak Windows to work like that.
The thing that annoys me is when windows steal focus. For example, I could be running an installer for some program. While it's working, I'll switch to my browser and browse, maybe entering some text into an email in my browser. Then suddenly the installer finishes and its window steals the focus. Now I'm in the middle of writing an email, so I might press a key that happens to be bound to a button on that installer, and then that button gets invoked, doing some action that I never intended to happen!
This is doubly annoying to me because I'm using a multiple-desktop program called DexPot, and when a window steals focus, it also brings itself to the desktop I'm currently on, which can be really annoying, because then I have to put it back into its original desktop.
How my ideal solution to this problem would work: Every time a window tries to steal focus, we intercept that, and don't let it. We show something like a toaster message saying "Foobar installer wants focus, press Win-Whatever to switch to it". If and when you press the key combo, it switches to the window.
The question is: Is there an easy way to tweak Windows to make this happen? I know very little about Windows programming. I do know AHK and if it's possible with that, that'd be great.
No, there isn't an easy way to add this behavior, but Windows tries to do this automatically.
In theory apps shouldn't be able to steal the foreground while you're actively using another app. Unfortunatly there are some scenarios where Windows can't tell the difference between legitimate user actions that should change the foreground and unwanted foreground-theft. The window manager generally tightens up the holes a bit with each new version of Windows, but also needs to make sure that apps can come to the foreground when the user wants them to, even if that desire is expressed indirectly.
For example, a process launched by the current foreground process can put a window into the foreground. This is necessary so that when a user launches a window from Explorer the newly launched process can open its main window. This permission only lasts until the next user input, so if an application is slow to launch and you start working on an email the app may lose its foreground permissions before it can use them.
See the SetForegroundWindow function documentation for a list of requirements for a process to be able to set a window into the foreground.
There are also apps which specifically make use of these requirements to steal the permission (by joining the foreground queue or synthsising user input to themselves), but I suspect in your installer scenario it is accidental.
I'm not sure what exactly is going on, but I suspect that the problem comes from the installer running as a service and accidentally stealing the foreground permission when it tries to launch the app on your current desktop.
It would be theoretically possible for an external process to hook into the foreground system to override this and show your confirmation toast, but it would be tricky to get right and would require significant low level code (I'd probably start with a CbtHook). It would not be possible in a scripting package like AHK (assuming you mean AutoHotKey) but would need to be native C/C++ code injected into every running process.

Step-through in VS without VS having focus

I find myself working with GUI code where the GUI program needs input focus and remain the topmost window, but whenever I'm debugging with VS stepping-through with F5/F10/F11 requires that VS has focus.
Is it possible to have VS intercept the F-keys whilst the debugee has focus? If VS doesn't have this functionality I imagine it should be possible to write a simple program or VS add-in that has a keyboard book and commands the debugger accordingly - has anyone developed such a program?
I'm working with a GUI test automation framework that sends mouse-clicks and other events by moving the cursor. When the debugee program is out of focus any click on its surface brings the main window forward but does not activate any controls, but the automation framework assumes that its focus of the application will never be interrupted. So if I set a breakpoint before a click that is meant to open the File menu then the click that is sent will only restore the debugee's focus and not open the File menu (if that makes sense).
I've done some searching but couldn't find anything immediately.
Why do you need to maintain focus? Have you specific hooks in the GotFocus/LostFocus?
I've had problems before with the Paint event being called as soon as F5 was hit causing the debugger to show again and therefore requiring another repaint. I got around these simply by arranging my windows so they didn't overlap. I'm pretty sure the LostFocus/GotFocus pair also don't fire when the windows are arranged this way too.

Instruments' UI Recorder hi-jacks my entire system

What am I doing wrong here? :(
I open Instruments.app, create a new UI Recorder template, select my application's .app bundle from the Target -> Choose Target menu, hit Record, open a couple of documents, type some stuff on them, close the documents, quit the app.
At this point UI Recorder stops and the Record button changes to "Drive & Record". I hit it, I see my application get launched and Instruments start recording data. Then Instruments gets confused (somehow)... my application loses focus, and suddenly UI Recorder is replaying all of my actions in Instruments!!, which just screws with Instruments in all kinds of messy ways. In this state I'm unable to move the mouse (the system just steals the cursor back), and I'm unable to quit instruments, since when I hit CMD+Q I'm prompted to Save the document, which I can't do because I have no control of the keyboard or mouse.
This is really frustrating. Has anyone got experience with this tool who can tell me where I'm going wrong? I'm scared to run it a third time as it literally hijacks my entire system.
So, you have a memory leak, and it happens when you do a specific series of actions.
The hard way to debug this would be to just have the Allocations and/or Leaks instruments and do the actions yourself every time, and every time you screw up (leave something out, do something wrong), kill the process and start over.
The easy way is the UI Recorder.
The first time you record with it, it records your actions (at the events level, not the target-action level). Mouse movements, clicks, etc.
The way UI Recorder differs from other instruments—which is why it surprised you—is that when you record with it thereafter, it plays them back.
It's not just swinging around your mouse cursor willy nilly; it's doing what you did the first time. Every time after you do things the first time, the UI Recorder does the exact same things for you.
That's what UI Recorder is for: Perfect, mechanically-ensured reproducibility. It's doing what it's meant to do; it's working as it should.
And yeah, aborting that is hard. I haven't looked yet, but there may be a stop-recording global system hotkey you can use. There is one when Instruments is in mini mode.
Also, you can set whether UI Recorder is in “drive” (playback) or “record” mode in the little pop-over that comes up when you click on the (i) button for the instrument. Switch it to record mode to re-record your interaction for different results in future runs. (I don't know whether it preserves the recording(s) in past runs.)

Resources