Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.8k views
in Technique[技术] by (71.8m points)

c++ - Why is Windows's SetCursorPos ineffective when certain programs are in foreground?

The win32 API's SetCursorPos moves the mouse to a location on the screen. However, sometimes it does nothing.

See the following C++ code (Visual Studio 16.8.1, Windows 10)

#include <iostream>
#include <windows.h>

int main()
{
    while (true)
    {
        std::cout << "Hello World!
";
        SetCursorPos(100, 200);
        Sleep(2000);
    }
}

Every 2 seconds, if SetCursorPos works then the cursor teleports to (100, 200). This works normally.

However if I leave this running and open the built-in Windows app called "On-Screen Keyboard", SetCursorPos no longer works (the cursor no longer teleports every 2 seconds).
Note: If trying this yourself, On-Screen Keyboard usually unfocuses itself automatically. To keep it focused to observe SetCursorPos not working, alt+tab to it, which causes it not to unfocus itself.

There are other third-party applications that, when in foreground, also seem to obstruct SetCursorPos. (When I observed those, I wasn't using the above C++ script. I was using the Python package mouse which uses SetCursorPos under the hood.)

How are these applications able to "swallow" my SetCursorPos API calls, and is there a different API or technique I can use in place of SetCursorPos to not allow those applications to interfere?


A physical USB mouse, as well as remote desktop software such as TeamViewer and Anydesk, are not obstructed by such applications, which leads me to believe they utilize some pathway besides SetCursorPos to get reliable mouse movement.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answer is admin privileges.

As explained by @chris in the comments, some programs have elevated privileges, and when they are in the foreground (and thus, accepting user input), Windows doesn't let programs without elevated privileges control the mouse or keyboard. Otherwise, untrusted programs would be able to utilize trusted programs to do things untrusted programs aren't normally allowed to do.

Think of it like this. A wizard without FBI security clearance shouldn't be allowed to use an Imperius Curse on an FBI agent to effectively gain clearance.

See these links others supplied in comments: relevant SO post #1, relevant SO post #2, tangential Windows accessibility article.

Solution: run your mouse-control program with elevated privileges, too.

If running your program in Cmd, for example, open Cmd as admin by right-clicking the Cmd icon in the Start Menu or Task Bar and select "Run as admin", and then run your script inside it. If your program is a batch file, you can right-click a shortcut to it and "Run as admin".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...