Why doesn't narrator report itself as a screen reader to windows? - windows

I'm trying to detect if a screen reader is attached to my application so that I can improve the experience for blind and low vision users. I'm using this win32 api (http://msdn.microsoft.com/en-us/library/ms724947%28VS.85%29.aspx), and specifying SPI_GETSCREENREADER as the uiAction. Call looks something like this:
int iAction = 70; // SPI_GETSCREENREADER constant;
int iParam = 0;
int iUpdate = 0;
bool result = false;
bool bReturn = SystemParametersInfo(iAction, iParam, &result, iUpdate);
If JAWS is running, or for that matter the magnification utility, this API reports that a screen reader is attached. However, if I only have the built in screen reader running (MS Narrator), this API reports that no screen reader is attached.
Is this really happening? Did the folks over at Microsoft really decide not to report the built in screen reader as a screen reader?

I can’t test the code out but sadly you are probably correct. Narrator is a very basic screen reader that provides almost no useful functionality other than allowing you to see if your main screen reader has crashed. Rumor has it that Microsoft wanted to make it a full featured screen reader when it was originally released but backed off do to possible antitrust issues from companies that were already producing Screen Readers. Note this is what I’ve heard on some of the blindness email lists I used to be on but cannot verify whether there’s any truth to it. If it is true it would explain why Narrator has limped along with no real improvements for as long as I can remember. I wouldn’t worry about Narrator, if a user is using your application they will be using a decent screen reader such as Jaws. I’ve been using screen reading software all my life and have never known anyone to use Narrator as a primary screen reader. If you wish to test with a free screen reader I would recommend NVDA In my experience it isn’t quite as good as jaws but is a quite usable screen reader without the high price tag.

If anyone falls into this horrible trap. Narrator sets a mutex when it starts running (this is totally not documented, but it appears to work if you need to detect ms narrator)
wstring m_wstrMutexKey = L"NarratorRunning";
// security attributes are part of windows API for CreateMutex
LPSECURITY_ATTRIBUTES securityAttributes = new _SECURITY_ATTRIBUTES();
securityAttributes->bInheritHandle = false;
securityAttributes->lpSecurityDescriptor = NULL;
securityAttributes->nLength = sizeof(LPSECURITY_ATTRIBUTES);
// initialize values
bool isRunning = false;
// CreateMutex returns a windows application HANDLE
HANDLE m_applicationHandle = CreateMutex(securityAttributes, false, m_wstrMutexKey.c_str());
// This should never happen
if (m_applicationHandle == NULL) {
isRunning = false;
}
// This condition indicates that narrator is running.
if (GetLastError() == ERROR_ALREADY_EXISTS) {
isRunning = true;
}
if (isRunning)
{
cout<<"Narrator is running.";
} else {
cout<<"No Mutex found. Narrator is not running.";
}
delete(securityAttributes);

Related

What has changed? Wake Windows and turn on monitor from Windows API

I have an old C program for displaying caller ID called YAC. Fortunately, the author Jensen Harris provided the source.
15 years ago, I modified the source to turn on the monitor if the computer was awake but the monitor was off. The code below worked well, turning on the monitor and making the caller ID message visible on the screen.
// TG - add a call to turn on the monitor if it is sleeping.....
SendMessage(hwnd, WM_SYSCOMMAND, SC_MONITORPOWER, -1);
Recently the behavior has changed (presumably a Windows update changed something)
Now when a Caller ID message should be displayed, the monitor turns on (as evidenced by the LED), but the screen remains black. The monitor remains in the black-screen condition for a few seconds, then turns off again.
What additional or different call is now required to cause Windows to activate the display and show the desktop? Possibly this could be forced by sending a mouse move, but is there a better way?
EDIT:
I have implemented the following additional code to press and release ESC. I was unable to find a good example of a relative mouse move of 1 pixel, so I used an example for keyboard. I will test and see if it is effective.
INPUT inputs[2];
UINT uSent;
// reference: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_ESCAPE;
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = VK_ESCAPE;
inputs[1].ki.dwFlags = KEYEVENTF_KEYUP;
uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
EDIT2 - I can confirm this approach does work to cause the monitor to display video, but of course has the potential for side-effects as any keyboard or mouse action would. I would still be interested in learning of a pure API function that works to fully wake the system like SC_MONITORPOWER used to.

Apple Mac disable screen dimming and/or lock

Is there a way to programatically (e.g. from Python code) to prevent my Mac from dimming and subsequently locking the screen? Of course, after my application is done, I would like to enable normal operation again. I know about caffiniate, but that applies to the whole application...that is not what I want. At some point in my code I want to disable dimming and then at some other point I want to enable it again.. Any tips, hints, suggestions?
You can try IOKit. Use IOPMAssertionDeclareUserActivity will wake the screen if necessary and keep it awake until the user's display sleep Energy Saver settings:
IOReturn ret;
CGError err;
IOPMAssertionID assertId;
ret = IOPMAssertionDeclareUserActivity(CFSTR("Stay awake!"), kIOPMUserActiveLocal, &assertId);
if (ret == kIOReturnSuccess)
{
// The screen is on
}
However, from the documentation for that method:
"If you prefer to hold the display awake for a longer period and you know how long you'd like to hold it, consider taking assertion kIOPMAssertionTypePreventUserIdleDisplaySleep using IOPMAssertionCreateWithDescription API instead."
Sounds closer to what you want. But I haven't tried it so I don't have a sample.

Detect if compositor is running

I want my UI to change design depending on whether the screen is composited (thus supporting certain effects) or not. Is it possible to
Reliably query whether the X server is running a compositing window manager
Get notified when compositing is switched on/off?
Solution:
To elaborate on Andrey Sidorov's correct answer for people not so familiar with the X11 API, this is the code for detecting a EWMH-compliant compositor:
int has_compositor(Display *dpy, int screen) {
char prop_name[20];
snprintf(prop_name, 20, "_NET_WM_CM_S%d", screen);
Atom prop_atom = XInternAtom(dpy, prop_name, False);
return XGetSelectionOwner(dpy, prop_atom) != None;
}
EWMH-compliant compositors must acquire ownership of a selection named _NET_WM_CM_Sn, where n is the screen number
To track compositor you'll need to check if selection is _NET_WM_CM_S0 is owned by anyone (assuming you are on screen 0) using XGetSelectionOwner. If not owned, acquire ownership yourself and monitor SelectionClear events to detect when compositor is started.

Is it possible to embed one application in another application in Windows?

I'm writing a Windows application in Visual C++ 2008 and I want to embed the calculator (calc.exe) that comes with Windows in it. Does anyone know if that is possible, and if it is, can you give me hints on how I could achieve that?
Yes, it's possible to embed the calc in your own application but it will still run in it's own process space. There may also be some restrictions imposed by UAC but that will depend on how calc is launched. All you need to do is change the parent of the main calc window and change it's style to WS_CHILD.
void EmbedCalc(HWND hWnd)
{
HWND calcHwnd = FindWindow(L"CalcFrame", NULL);
if(calcHwnd != NULL)
{
// Change the parent so the calc window belongs to our apps main window
SetParent(calcHwnd, hWnd);
// Update the style so the calc window is embedded in our main window
SetWindowLong(calcHwnd, GWL_STYLE, GetWindowLong(calcHwnd, GWL_STYLE) | WS_CHILD);
// We need to update the position as well since changing the parent does not
// adjust it automatically.
SetWindowPos(calcHwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
}
Microsoft has various technologies to support embedding, most famously OLE which is a COM-based technology. This is, for example, how you can embed an Excel spreadsheet in your application. However, I'm fairly certain that calc does not implement any of the required interfaces for that to happen.
So that only leaves you with hacky solutions, like trying to launch it yourself and play games with the window hierarchy, or try to present it to users and then copy the results out through the clipboard, etc. This is all technically possible, but not a good idea. In fact, it's probably more difficult than just writing your own calculator app... depending on what you want to to enable users to do. If you explain why you want to do this someone may have some better solutions to propose.

Minimize/restore windows programmatically skipping the animation effect

I need to perform several operations on a list of windows (minimize some of them, restore others) in order to switch between two or more set of windows at once.
The problem with this are those animations you can see when minimizing and restoring a window. The whole process look terrible with all those animations going in and out, up and down.
I cannot, however, disable those animations because this is for other computers and i dont want to change other people's settings, plus those animations are actually useful when you minimize/restore one window only (i.e. when YOU do it manually) because you can see what is happening, but for doing it programmatically on several windows at a time, it's not nice.
I'm currenlty using the SendMessage function to send the WM_SYSCOMMAND message with params SC_MINIMIZE/SC_RESTORE. I dont know whether there is another way.
So, the question:
How can I minimize/restore a window programatically without the animation effect??
PS: The programming language is not important. I can use any language that's nessesary for accomplishing this.
SetWindowPlacement with SW_SHOWMINIMIZED or SW_RESTORE as appropriate for showCmd in WINDOWPLACEMENT seems to bypass window animation. I'd keep an eye on the functionality for future versions of the OS though since documentation does not mention anything about animation.
How about Hide > Minimize > Show ?
You could temporarily disable the animations and then restore the user's original setting.
class WindowsAnimationSuppressor {
public:
WindowsAnimationSuppressor() : m_suppressed(false) {
m_original_settings.cbSize = sizeof(m_original_settings);
if (::SystemParametersInfo(SPI_GETANIMATION,
sizeof(m_original_settings),
&m_original_settings, 0)) {
ANIMATIONINFO no_animation = { sizeof(no_animation), 0 };
::SystemParametersInfo(SPI_SETANIMATION,
sizeof(no_animation), &no_animation,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
m_suppressed = true;
}
}
~WindowsAnimationSuppressor() {
if (m_suppressed) {
::SystemParametersInfo(SPI_SETANIMATION,
sizeof(m_original_settings),
&m_original_settings,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
}
}
private:
bool m_suppressed;
ANIMATIONINFO m_original_settings;
};
void RearrangeWindows() {
WindowsAnimationSuppressor suppressor;
// Rearrange the windows here ...
}
When the suppressor is constructed, it remembers the user's original setting and turns off the animation. The destructor restores the original settings. By using a c'tor/d'tor, you ensure that the user's settings are restored if your rearranging code throws an exception.
There is a small window of vulnerability here. In theory, the user could change the setting during the operation, and then you'll slam the original setting back. That's extremely rare and not really that bad.

Resources