I am connected to a Windows VM via RDP. The host system is also Windows. On the VM, I run an application that uses SetCursorPos to change the position of the mouse cursor. I have observed that the call sometimes causes the mouse cursor to arrive at a completely different location.
If I run the application on the host system, it runs without errors. So it seems to be related to RDP.
Consider the following C# demo application. Basically, it calls SetCursorPos a thousand times with random positions and checks with GetCursorPos whether the mouse cursor has landed at the specified position.
using System;
using System.Runtime.InteropServices;
using System.Threading;
namespace CursorDemoApp
{
class Program
{
static void Main()
{
var random = new Random(1);
var displayWidth = GetDisplayWidth();
var displayHeight = GetDisplayHeight();
for (var run = 1; run <= 1000; run++)
{
SetAndCheckCursorPosition(0, 0);
var x = random.Next(displayWidth);
var y = random.Next(displayHeight);
SetAndCheckCursorPosition(x, y);
Thread.Sleep(10);
}
}
private static void SetAndCheckCursorPosition(int x, int y)
{
SetCursorPosition(x, y);
var currentPosition = GetCursorPosition();
if (currentPosition.X != x || currentPosition.Y != y)
{
Console.WriteLine("Failed! Expected: ({0},{1}) - Got: ({2},{3})", x, y, currentPosition.X, currentPosition.Y);
}
}
private static void SetCursorPosition(int x, int y)
{
Console.WriteLine("SetCursorPosition({0},{1})", x, y);
SetCursorPos(x, y);
}
[DllImport("user32.dll")]
private static extern bool SetCursorPos(int x, int y);
private static Point GetCursorPosition()
{
GetCursorPos(out var point);
Console.WriteLine("GetCursorPosition() == ({0},{1})", point.X, point.Y);
return point;
}
[DllImport("user32.dll")]
private static extern bool GetCursorPos(out Point point);
private static int GetDisplayWidth()
{
return GetSystemMetrics(16 /* SM_CXFULLSCREEN */);
}
private static int GetDisplayHeight()
{
return GetSystemMetrics(17 /* SM_CYFULLSCREEN */);
}
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int index);
[StructLayout(LayoutKind.Sequential)]
private struct Point
{
public int X;
public int Y;
}
}
}
When I run this in the VM, I get as output, for example:
...
SetCursorPosition(0,0)
GetCursorPosition() == (0,0)
SetCursorPosition(1330,269)
GetCursorPosition() == (1330,269)
SetCursorPosition(0,0)
GetCursorPosition() == (0,0)
SetCursorPosition(18,10)
GetCursorPosition() == (1330,269)
Failed! Expected: (18,10) - Got: (1330,269)
SetCursorPosition(0,0)
GetCursorPosition() == (0,0)
SetCursorPosition(973,392)
GetCursorPosition() == (973,392)
...
Can anyone explain this behavior or provide a solution?
(Originally, I noticed this when using Eclipse SWT and Display.setCursorLocation(..). Since that also uses SetCursorPos under the hood, I wanted to leave this as a hint for search engines.)
Faced the same problem. Googling "SetCursorPos RDP" leads to older question:
SetCursorPos not working over remote desktop (reading from WM_INPUT event)
raffallo provided an answer, SO requires me to cite it:
It's a really old thread, but in the current world situation, it might be helpful.
To fix problems with RDP and mouse you need to open Local Group Policy Editor and go to:
Local Computer Policy > Computer Configuration > Administrative Templates > Windows Components > Remote Desktop Services > Remote Desktop Session Host > Remote Session Environment.
In the Remote Session Environment you need to set Use WDDM graphic display driver for Remote Desktop Connections to disable.
Probably Windows 10 Pro is required, but I can't check it.
This change you need to make in the machine you want to connect to (host).
Restarting Windows is recommended.
Related
I just want my computer's screen not to turn off while a program is runnig. I know I can set it on my PC settings but I just want this app to do it.
Can anybody help me?
Thanks!
I found the following code here
import java.awt.Robot;
import java.awt.MouseInfo;
long robotLastMove = 0;
Robot robot=null;
setup(){
try{
robot = new Robot();
}catch(Exception e){e.printStackTrace();}
}
draw(){
long now = System.currentTimeMillis();
if(robot!=null && now-robotLastMove>1000*60*15){
//TODO: move back the mouse
int x = MouseInfo.getPointerInfo().getLocation().x;
int y = MouseInfo.getPointerInfo().getLocation().y;
//robot.
robot.mouseMove(x+2, y+2);
robot.mouseMove(x, y);
robotLastMove=now;
}
}
This moves the mouse automatically when your PC tries to sleep, but only a little. If you save the code inside the draw function from the above code into a different function, you can call it in the the draw to make the code look better. Like this:
import java.awt.Robot;
import java.awt.MouseInfo;
long robotLastMove = 0;
Robot robot=null;
setup(){
try{
robot = new Robot();
}catch(Exception e){e.printStackTrace();}
}
void stayAwake(){
long now = System.currentTimeMillis();
if(robot!=null && now-robotLastMove>1000*60*15){
//TODO: move back the mouse
int x = MouseInfo.getPointerInfo().getLocation().x;
int y = MouseInfo.getPointerInfo().getLocation().y;
//robot.
robot.mouseMove(x+2, y+2);
robot.mouseMove(x, y);
robotLastMove=now;
}
}
void draw(){
background(0);
stayAwake();
// the code you want to run without your pc falling asleep.
}
Good luck!
I'm trying to follow the tutorial about Watchfaces creation, but I'm stuck.
I copied the code from the wiki so there shouldn't be any error whatsoever, but I'm getting this error while compiling
error: implicit declaration of function 'PBL_IF_ROUND_ELSE' [-Werror=implicit-function-declaration]
I tried to google it but I couldn't find anything useful.
This is the code
#include <pebble.h>
static Window *s_main_window;
static TextLayer *s_time_layer;
static void update_time() {
// Get a tm structure
time_t temp = time(NULL);
struct tm *tick_time = localtime(&temp);
// Write the current hours and minutes into a buffer
static char s_buffer[8];
strftime(s_buffer, sizeof(s_buffer), clock_is_24h_style() ? "%H:%M" : "%I:%M", tick_time);
// Display this time on the TextLayer
text_layer_set_text(s_time_layer, s_buffer);
}
static void tick_handler(struct tm *tick_time, TimeUnits units_changed) {
update_time();
}
static void main_window_load(Window *window) {
// Get information about the Window
Layer *window_layer = window_get_root_layer(window);
GRect bounds = layer_get_bounds(window_layer);
// Create the TextLayer with specific bounds
s_time_layer = text_layer_create(
GRect(0, PBL_IF_ROUND_ELSE(58, 52), bounds.size.w, 50));
// Improve the layout to be more like a watchface
text_layer_set_background_color(s_time_layer, GColorClear);
text_layer_set_text_color(s_time_layer, GColorBlack);
text_layer_set_text(s_time_layer, "00:00");
text_layer_set_font(s_time_layer, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD));
text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter);
// Add it as a child layer to the Window's root layer
layer_add_child(window_layer, text_layer_get_layer(s_time_layer));
}
static void main_window_unload(Window *window) {
// Destroy TextLayer
text_layer_destroy(s_time_layer);
}
static void init() {
// Create main Window element and assign to pointer
s_main_window = window_create();
// Set handlers to manage the elements inside the Window
window_set_window_handlers(s_main_window, (WindowHandlers) {
.load = main_window_load,
.unload = main_window_unload
});
// Show the Window on the watch, with animated=true
window_stack_push(s_main_window, true);
// Make sure the time is displayed from the start
update_time();
// Register with TickTimerService
tick_timer_service_subscribe(MINUTE_UNIT, tick_handler);
}
static void deinit() {
// Destroy Window
window_destroy(s_main_window);
}
int main(void) {
init();
app_event_loop();
deinit();
}
I'm using the CloudPebble SDK.
I got it, PBL_IF_ROUND_ELSE works only with 3.X SDK (I was using the 2.X).
"PBL_IF_ROUND_ELSE(58, 52)" Only works with Pebble Time or SDK3.
You can replace "PBL_IF_ROUND_ELSE(58, 52)" with a range between 0 and 100. 0 meaning it will be at the top of the screen. 100 means it will be at the bottom of the screen.
Replace the "PBL_IF_ROUND_ELSE(58, 52)" with a 0. That should do the trick. Im assuming you are trying to run this program on the aplite version?
I'm attempting to emulate user clicking and mouse-moving, specifically in Mozilla Firefox, in a Windows 7 environment. The solution I frankensteined together from various tutorials, forum posts, and MSDN documents works for 99% of Windows Applications out there, but it won't work for Firefox 8.0.
From my preliminary research, the most accurate (low-level) way of emulating keyboard and mouse input in Windows is to use the SendInput function from the User32.dll Windows Library. To test this, I wrote a short C# program to loop through and make a call to SendInput that creates a programmatic mouse-click every 5 seconds, no matter where the mouse cursor is on screen.
Once running, the program perfectly emulates a mouseclick for almost every application window I switch focus to, even including the Windows interface itself (Start Button, Taskbar, Windows Explorer, etc.), but no programmatic mouse-clicks occur when I bring the cursor into a Mozilla Firefox Window.
In order to get a better handle on what was happening under the hood, I booted up Microsoft Spy++ and began inspecting what messages were actually getting passed to the Firefox window's message queue. Sure enough, the Firefox window would receive no messages even though my cursor would be situated directly above it while it had focus. When I manually clicked my mouse, the Firefox Spy++ listener would then go nuts and display the full "nHittest:HTCLIENT wMouseMsg:WM_LBUTTONDOWN" that I saw when observing other applications' correct responses to my emulation program.
Can anyone provide an explanation for how/why Mozilla Firefox is one of the only applications that does not even receive any messages at all from the SendInput function and perhaps a suggestion for how to overcome this?
Source Code
(Imports/external references removed for clarity):
static void Main(string[] args)
{
for (; ; )
{
System.Threading.Thread.Sleep(5000);
INPUT[] inp = new INPUT[2];
inp[0].type = INPUT_MOUSE;
inp[0].mi = createMouseInput(0, 0, 0, 0, MOUSEEVENTF_LEFTDOWN);
inp[1].type = INPUT_MOUSE;
inp[1].mi = createMouseInput(0, 0, 0, 0, MOUSEEVENTF_LEFTUP);
SendInput((uint)inp.Length, inp, Marshal.SizeOf(inp[0].GetType()));
}
}
private static MOUSEINPUT createMouseInput(int x, int y, uint data, uint t, uint flag)
{
MOUSEINPUT mi = new MOUSEINPUT();
mi.dx = x;
mi.dy = y;
mi.mouseData = data;
mi.time = t;
mi.dwFlags = flag;
return mi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Explicit)]
private struct INPUT
{
[FieldOffset(0)]
public int type;
[FieldOffset(sizeof(int))] //[FieldOffset(8)] for x64
public MOUSEINPUT mi;
[FieldOffset(sizeof(int))] //[FieldOffset(8)] for x64
public KEYBDINPUT ki;
[FieldOffset(sizeof(int))] //[FieldOffset(8)] for x64
public HARDWAREINPUT hi;
}
Did you run your program as an administrator? It could be an UIPI, i.e. integrity level issue.
I'm writing a Java application in BlackBerry JDE 4.5 that will start listening for some event at the start up. I want to display a small icon at the status bar.
I know its support in version 4.6.0 of the BlackBerry API set with ApplicationIcon, ApplicationIndicator and ApplicationIndicatorRegistry classes but which classes are there in BlackBerry JDE 4.5.0 API set?
Update
I think some support is there for 4.5.0 as I'm using Blackberry Pearl 8100 with OS v4.5.0.81 which displays Notification Icons at status bar for any incoming messages or calls.
I made the Alternale Entry point & Main CLDC app like this article below,
How To - Setup an alternate entry point for my application
I have got an article as,
How to - Make a running UI application go to the background and resume in the foreground
in which its said that
The alternate entry is going to call the main method with the parameter that is passed in, regardless of whether the application is running.
But in my case the main() is not getting called when I click on appIcon when the app is running in background.
It only updates appIcon & appName which is previously set in Alternate Entry Point.
So I m not getting where the control goes if its not calling main() when clicked on updatedIcon?
Is anyone has any idea on this issue?
I updated the appIcon & appName.
Now what I want is "When clicked on updatedIcon a particular screen should be opened & when the user goes back to Main Menu the app should get its original Icon, app name & the flow should go through main() when clicked on original app Icon"
I was thinking when I click on updated appIcon the control will go to main() but instead of calling main() it says,
Starting AppName
AppName already running
& directly it goes to first screen. and when I come back to Main Menu the app has updated icon & name
So how to get it?
Unfortunately it's not possible. What you can do is update application icon.
Also there are alternative ways of notification:
Notification Service for Blackberry OS 4.5 application
Update Application Icon
alt text http://img211.imageshack.us/img211/4527/icoupdate1.jpgalt text http://img697.imageshack.us/img697/3981/icon.jpgalt text http://img687.imageshack.us/img687/256/iconactive.jpgalt text http://img130.imageshack.us/img130/3277/icoupdate2.jpgalt text http://img691.imageshack.us/img691/6459/icoupdate3.jpg
Background running application:
public class NotifIconSrvc extends Application {
private int mCount = 0;
private int mSize = 0;
public NotifIconSrvc() {
Timer timer = new Timer();
timer.schedule(sendEventTask, 1000, 3000);
}
TimerTask sendEventTask = new TimerTask() {
public void run() {
// Post the GlobalEvent.
// Long = ci.samples.45.notificon
ApplicationManager.getApplicationManager().postGlobalEvent(
0x5a9f7caa171ab7b8L, mCount++, mSize++);
}
};
public static void main(String[] args) {
NotifIconSrvc app = new NotifIconSrvc();
app.enterEventDispatcher();
}
}
Main application:
public class NotifIconApp extends UiApplication
implements GlobalEventListener {
private Bitmap mIcon = Bitmap.getBitmapResource("icon.png");
private Bitmap mIconActive =
Bitmap.getBitmapResource("icon_active.png");
private Scr mScreen = new Scr();
public NotifIconApp() {
addGlobalEventListener(this);
pushScreen(mScreen);
}
public static void main(String[] args) {
NotifIconApp app = new NotifIconApp();
app.enterEventDispatcher();
}
public void eventOccurred(long guid, int count, int size,
Object object0, Object object1) {
if (0x5a9f7caa171ab7b8L == guid) {
Bitmap icon = getUpdateIconBitmap(mIcon, count, size);
HomeScreen.updateIcon(icon);
Bitmap rolloverIcon =
getUpdateIconBitmap(mIconActive, count, size);
HomeScreen.setRolloverIcon(rolloverIcon);
mScreen.updateScreen(count, size);
}
}
private Bitmap getUpdateIconBitmap(Bitmap bmp, int count, int size) {
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap iconBmp = new Bitmap(width, height);
Graphics g = new Graphics(iconBmp);
XYRect rect = new XYRect(0, 0, width, height);
g.drawBitmap(rect, bmp, 0, 0);
g.setFont(g.getFont().derive(Font.BOLD, 20, Ui.UNITS_px,
Font.ANTIALIAS_STANDARD, Font.COLORED_OUTLINE_EFFECT));
String text = Integer.toString(count);
g.setColor(Color.BLACK);
g.drawText(text, 0, 2);
text = Integer.toString(size) + " Kb";
g.setColor(Color.GREEN);
g.drawText(text, 0, height - 22);
return iconBmp;
}
}
class Scr extends MainScreen {
LabelField mMessages;
String mLabelText = "message count: ";
String mTitleText = "message counter";
public Scr() {
add(mMessages = new LabelField(mLabelText));
setTitle(mTitleText);
}
void updateScreen(int count, int size) {
StringBuffer sb = new StringBuffer(Integer.toString(count));
sb.append("/");
sb.append(Integer.toString(size));
sb.append("Kb");
String text = sb.toString();
setTitle(mTitleText + "(" + text + ")");
mMessages.setText(mLabelText + text);
}
protected void makeMenu(Menu menu, int instance) {
super.makeMenu(menu, instance);
menu.add(mMenuGoBG);
}
MenuItem mMenuGoBG = new MenuItem("go background", 0, 0) {
public void run() {
UiApplication.getUiApplication().requestBackground();
}
};
}
Is there a way to limit mouse pointer movement to a specific area in wxWidgets? I know there is an API function ClipCursor() in Windows, but is there a method in wxWidgets for all platforms?
No. There is no such function in wx by all i know. Start up a timer (say 50ms) checking the global mouse position. If the mouse is outside the region, then set it into again.
If you want to restrict the mouse for some certain reason, for example to make some sort of game, then you can capture the mouse (see wxWindow::CaptureMouse). You will get mouse events even if the pointer is outside your window. Then you could react to mouse-motion events and do the check for the position there, without a timer. Downside of this is that the mouse won't be able to be used somewhere else for other programs since they won't receive events.
wxWidgets manual states that OSX guidelines forbid the programs to set the mouse pointer to a certain position programmatically. That might contribute to the reason there is not much support for such stuff in wx, especially since wx tries really hard to be compatible to everything possible.
Small sample. Click on the button to restrict the mouse to area 0,0,100,100. Click somewhere to release it.
#include <wx/wx.h>
namespace sample {
class MyWin : public wxFrame {
public:
MyWin()
:wxFrame(0, wxID_ANY, wxT("haha title")) {
mRestricted = wxRect(0, 0, 100, 100);
mLast = mRestricted.GetTopLeft();
wxButton * button = new wxButton(this, wxID_ANY, wxT("click this"));
}
private:
void OnClicked(wxCommandEvent& event) {
if(!HasCapture()) {
CaptureMouse();
CheckPosition();
}
}
void OnMotion(wxMouseEvent& event) {
CheckPosition();
}
void OnLeft(wxMouseEvent& event) {
if(HasCapture())
ReleaseMouse();
}
void CheckPosition() {
wxPoint pos = wxGetMousePosition();
if(!mRestricted.Contains(pos)) {
pos = ScreenToClient(mLast);
WarpPointer(pos.x, pos.y);
} else {
mLast = pos;
}
}
wxRect mRestricted;
wxPoint mLast;
DECLARE_EVENT_TABLE();
};
BEGIN_EVENT_TABLE(MyWin, wxFrame)
EVT_BUTTON(wxID_ANY, MyWin::OnClicked)
EVT_MOTION(MyWin::OnMotion)
EVT_LEFT_DOWN(MyWin::OnLeft)
END_EVENT_TABLE()
class MyApp : public wxApp {
virtual bool OnInit() {
MyWin * win = new MyWin;
win -> Show();
SetTopWindow(win);
return true;
}
};
} /* sample:: */
IMPLEMENT_APP(sample::MyApp)