none
Bug with GetCursorPos in Windows 8 Pro

    Question

  • Hi,

    My desktop program has been working fine for more than 10 years, starting from Win95. I use in my program the simple lines in C :

    GetCursorPos(&pt);
    SetCursorPos(pt.x, pt.y);
    The aim in to reactivate a tooltip. Anyway, this kind of lines should not change the position of the mouse cursor.

    Now, one of my program users reports a very clear bug. He has legally bought Window 8 Pro to update Win 7, and now these lines make the mouse cursor move to the up left corner of the screen, by little steps of a few centimeters (10cm to the left the first time, then 8cm, then 4, and 3). The same (with different values) in the upward direction. A simple click allows my program (a card game) to progress from one player to the next, and at each time it's possible to see the cursor moving.

    I tried to replace GetCursorPos by GetCursorInfo : no change
    I tried to use a local Point variable and use memcpy : no change
     
    And when I disable the line SetCursorPos (that is, I don't move the cursor), the bug disappears.

    Only one user reported the bug (while 200 downloads every day), and the same user says it works fine on another laptop with Windows 8. Only the one with the update Win 7 to Win 8 Pro seems to show the bug.

    The bug can be shown also with the touchpad, or with another mouse. Or even just by the Enter key (which has the same effect as a click). So I think it's not a problem with the mouse itself. It really seems as if GetCursorPos (and GetCursorInfo) had a problem with this version.

    Is there any report of this kind of problem? And do you need some more tests (the user who contacted me is very kind and skilled, he can help)?

    Thanks for your answer, and sorry if the question is in the wrong place.

    Liquidambar

    Tuesday, July 23, 2013 11:21 AM

Answers

All replies

  • Only one user reported the bug (while 200 downloads every day), and the same user says it works fine on another laptop with Windows 8. Only the one with the update Win 7 to Win 8 Pro seems to show the bug.


    Cleary you don't have an easily reproducible issue. I'd suspect it's due to some interaction with some other software on that particular machine.
    Wednesday, July 24, 2013 7:00 AM
  • Thanks for your reply. I agree that one user is not enough to report a bug. But this user could use my program with Windows 7, and after having updated to Windows 8 Pro 64 bits, he can no longer play. It's like if I was responsible for it. I wanted to help him.

    Anyway, I made a little program to analyze the bug in a better way. Actually, it's not GetCursorPos which goes wrong, but SetCursorPos. Setting the cursor to the point (100,100) in screen coordinates moves it to (67,59) on this user's laptop. There is always a loss of 1/3 pixels in x, and 1/3 + 7 in y. For example, SetCursorPos(200,200) moves the cursor to (133,126).

    So, I begin to think that it is a problem with the graphics driver, which is not good for Windows 8 Pro 64. This user has a NVIDIA GeForce GTX 560M. He has uninstalled the previous driver, installed the last version, even in Compatibility mode for Win7, but no change. The cursor never goes to the right point, as if Windows 8 doesn't know his screen dimensions.

    Well, I'm afraid he'll have to wait until a new driver is available.

    Sorry for having reported an irrelevant bug.

    Liquidambar

     

    Thursday, July 25, 2013 7:31 PM
  • Is it possible this user is visually impaired and using some kind of screen magnifier?  I wonder if this is some interaction with a very large icon set or something.

    Tim Roberts, VC++ MVP Providenza & Boekelheide, Inc.

    Friday, July 26, 2013 6:06 AM
  • Have you asked that user to boot into safe mode and see if the problem persists?

    I'm not sure quite what that would prove if it then works OK - whether that would point to the graphics driver or something else, but it'd be nice to know.

    Friday, July 26, 2013 6:54 AM
  • Has the user set higher DPI than default?

    Both calls should just convert between virtualized and physical coordinates but something could have messed that up. Your application probably isn't declared as DPI aware, is it? Also check out the community additions in documentation to GetCursorPos if any of those situations applies to you. If viable, you may also consider changing the calls to GetPhysicalCursorPos/SetPhysicalCursorPos.

    But anyway, to display tooltip, consider just sending it the TTM_POPUP message.

    Friday, July 26, 2013 9:54 AM
  • Problem SOLVED!

    Sorry, I had to edit and change my previous message. First, I thought that the problem was due to the fact that my user had updated his graphics driver with the 150% setting in the menu :
    - To make the text on your screen larger or smaller

    After reinstalling with the 100% choice, he told me everything was OK, even with larger text. But he didn't tell me that he tried 125% instead of 150%. And later, he tried again 150% and the bug reappeared.

    The interesting thing is that I can now produce the bug on my one machine. I select 150%, and the cursor moves to the wrong place. Moreover, the screen size in centimeters is not correct. The same if I check the box about Windows XP.

    So, there may be a little bug about this option. But anyway, I know now what to say to my users : go back to a smaller size (125% seems all right).

    Thanks for your kind replies. They helped me, especially Tim's one about the display settings.

    • Edited by liquidambar Friday, July 26, 2013 5:46 PM new test
    Friday, July 26, 2013 1:14 PM
  • A bit more about the bug with large text at 150% or 200%

    It's easy to show that SetCursorPos changes the coordinates. When using only screen coordinates :
    150% : SetCursorPos(100,100) moves the cursor to (67,67), that is (pos*100)/150
    200% : SetCursorPos(100,100) moves the cursor to (50,50), that is (pos*100)/200

    But SetCursorPos is not the only function to be altered by large text. ClientToScreen and ScreenToClient are probably also wrong. When moving the cursor to one precise point of the client area (when the window is maximized), we can see that :
    150% : SetCursorPos(100,100) moves the cursor to (67,59)
    200% : SetCursorPos(100,100) moves the cursor to (50,39)
    As if the height of the title bar was not well calculated.

    When the window is not maximized, the error is bigger, probably because the title bar is bigger, as well as the edge size. A bit more curious, the error depends also on the position of the top left corner of the client window.

    Another function returns wrong values. The calls GetDeviceCaps(hdc, HORZSIZE) and GetDeviceCaps(hdc, VERTSIZE) return (on my own machine) :
    150% : 22.7 x 12.7 cm instead of 34 x 19 (dim*100/150)
    200% : 17.00 x 9.5 cm instead of 34 x 19 (dim*100/200)

    When selecting 125%, the bug disappears. The cursor is always moved to the right position, and the screen size in millimeters is the proper one.

    The problem has been reported with the two following graphics cards :
    - NVIDIA GeForce GTX 560M (Windows 8 Pro 64)
    - NVIDIA GeForce GT 620M (Windows 8 Home 64)
    Maybe there is no problem with other cards.

    I hope this information will help. I can make some more tests if needed.

    Saturday, July 27, 2013 11:48 AM
  • This is documented behavior. Since your app isn't written and marked that it handles high DPI systems appropriately Windows tries to do that for you by magnifying the pixels and pretending to the app that it is on a low dpi system. This works for basic scenarios, but has edge case issues where the two resolutions conflict.

    See Writing High-DPI Win32 Applications (Windows) and Tutorial: Writing High-DPI Win32 Applications

    --Rob

    Saturday, July 27, 2013 3:18 PM
  • Thanks for the links about DPI aware applications. I wasn't aware of all these functions. I'll read these pages with great care. But my programs are old ones, and they don't have any manifest file.

    They are old, but however, long before Vista, they could adapt to any screen size : graphics display, texts, bitmaps, tool bars, and even dialog boxes automatically change in my programs according to the screen size. I've worked a lot for that. With a better quality (essentially for bitmaps and fonts) than when magnifying. At least, I believe so. Moreover, my users can choose which elements to magnify, if they want. And this has been working for ages, since Windows 95.

    With Windows 8, the choice 125% enlarges the title bar, the tooltips, the menu bar and menus (what is more comfortable, I agree), and doesn't touch the rest. Good for me. But the choice 150% magnifies the whole client window, what is not good for my programs. In a card game, there is just the place to display every element. I take care of that, and the different elements are as big as they can be. There is no scroll. All must be on screen. No way to magnify a tool bar (for example) without losing other elements, or making them too small.

    I made a tablet mode for small screens, in order to set dimensions in centimeters and ensure that user can touch the elements in good conditions. I don't want anybody else to do that for me. This is why I need the real screen size.

    Do you confirm that there is no way to tell Windows that I don't want my program to be magnified ?

    Saturday, July 27, 2013 7:16 PM
  • Do you confirm that there is no way to tell Windows that I don't want my program to be magnified ?

    Exactly the opposite. You can apply a manifest stating that the app is DPI aware. Windows applies DPI virtualization only to apps which do not say they are DPI aware.

    Details are in the docs I linked.

    --Rob

    Sunday, July 28, 2013 5:00 AM
  • Good, it makes sense. Thanks for your kindness, I'm quite a beginner in the dpi field.

    Still, I think I've understood that above 120 dpi (that is, 150% and more), Windows goes back to 96,96 dpi, draws to a smaller screen, and at the end magnifies the whole of it (DPI virtualization). At least for non DPI aware applications.

    It's what happens for example on Windows 8, with the choice 200%. The screen size allowed by Windows is on my machine : 683 x 384 pixels. As my program used to work on Windows 95 with 640 x 480 screens, it's more or less OK. It chooses the smallest font and the worst display settings. And then the screen is magnified. Yes, but what a bad result, compared with a normal display at 100% or 125%!

    And if I add the fact that the mouse cursor is always moved to the wrong positions (only with Windows 8), I don't think I'll ever advice the 150% mode or more. And I'm not going to rewrite more than 1 million lines of code for a result that will not be better than the 100% or 125% size. Anyway, in the display settings of Windows, users can change the size of elements like menus, title bar, and so on. I think it's a better solution than virtualization. And it should be up to developers to improve themselves the quality of their programs according to the different screen sizes.

    But I may be wrong somewhere...

    Sunday, July 28, 2013 7:49 AM
  • If as Rob suggested, you add the manifest setting to your application to say that it's DPI aware, does that resolve the problem, or do you then have other issues?
    Sunday, July 28, 2013 8:29 AM
  • GREAT! IT WORKS!

    Encouraged by Rob and David, I tried to use the function called SetProcessDPIAware (found in User32.dll). While it is not recommended on the function page, it seems to work. Either with the 150% or the 200% option. Either with Windows 7 or 8. And the cursor now moves to the right position.

    I thought I was going to have many things to do after having declared my program DPI aware (as written in the tutorial pages). But I think my program already does the job. My buttons are ownerdraw, everything is resized dynamically. My dialog boxes set their size according to the screen size (or user's preferences). So, that is it. Now, with the 150% or 200% settings, menus, tool tips, title bar and common boxes are bigger. But the rest doesn't change.

    To help others, I call SetProcessDPIAware() at the beginning of WinMain, before creating the window.

    Well, thanks to all of you. You are brilliant. And all my apologies for being so slow to understand.

    Sunday, July 28, 2013 11:15 AM
  • Corollary

    Now, as reported above, there is probably a little bug in SetCursorPos with Windows 8 (Home and Pro), in dpi virtualization mode. With a very simple non dpi-aware program, one can show that moving the mouse cursor with SetCursorPos to a precise point will not work properly with the 150% or 200% option. This could be a fatal issue for old desktop programs that could run rather well on Windows 7, but no longer on Windows 8. Still, such programs must be rare.

    As far as I'm concerned, I must say thank you to this bug! My users could have run my programs for years with the 150% choice and a low dpi display. And I would have never been aware of the problem. I had tested the 125% choice, but not higher. We never test enough...

    Do I need to report the bug in SetCursorPos somewhere else? Maybe it has already been fixed in 8.1.

    Monday, July 29, 2013 2:09 PM
  • Now, as reported above, there is probably a little bug in SetCursorPos with Windows 8 (Home and Pro), in dpi virtualization mode. With a very simple non dpi-aware program, one can show that moving the mouse cursor with SetCursorPos to a precise point will not work properly with the 150% or 200% option. This could be a fatal issue for old desktop programs that could run rather well on Windows 7, but no longer on Windows 8. Still, such programs must be rare.

    Do I need to report the bug in SetCursorPos somewhere else? Maybe it has already been fixed in 8.1.

    Have you tried it with the 8.1 preview to see if it's any different there?

    As for reporting the issue, the only sure-fire way is to phone MS support and try to raise the issue that way. However, perhaps Rob is still monitoring this thread and could comment further on it?

    Monday, July 29, 2013 3:06 PM
  • I'm glad to hear that setting your app as DPI aware fixes the problem for you. Having apps which handle high DPI scenarios properly is the ideal solution. Unfortunately the vast majority of old apps do not do so and so become unusable when the user needs high DPI. This has always been an issue for users who raise the DPI so they can see the screen better, and raising the DPI becomes more widely necessary as high resolution systems become more popular (and as the population ages: my eye doc keeps telling me I'll need glasses for fine print soon).

    The DPI Virtualization system enables old, non-DPI aware apps to display (mostly) properly on high DPI systems even when those apps weren't coded for high DPI.

    As you (and the docs I linked previously) note, this is only mostly properly. The common cases hit by most apps should just work, but there are edge cases such as the SetCursorPos problem you ran into. This is a known issue: it is the class of problem discussed at Drag and Drop and Other Input Issues .

    --Rob

    Tuesday, July 30, 2013 1:35 AM
  • For one: The pair of calls GetCursorPos/SetCursorPos will almost always move the cursor slightly when DPI is virtualized for the app, because there is a precision loss. E.g. on 125% if mouse is at 123/123, app will get 98/98, but setting 98/98 will actually move it to 122/122.

    For two: OP's app would never hit this issue if he popped the tooltip in documented way (TTM_POPUP), not by using this trick. But I already wrote that about a dozen of posts above.

    Tuesday, July 30, 2013 9:18 AM
  • Thanks for all your replies.

    For David, no, I've not tried Windows 8.1 yet. As a developer, I keep one machine for one Windows version. So, I'd need to buy a... 1,2, ... 7th machine. Maybe soon or later, anyway.

    Yes, I agree with Rob that DPI virtualization is better than nothing, and it helps old programs to still be used, while they would be displayed too small on high resolution screens.

    As for Jan's reply, forget about the tool tip problem I reported above, it was not a relevant example. But on my programs (card games), I also need to move the cursor to precise areas (according to player on lead), and the problem is not a loss of 1 point. On Windows 8, with non-dpi aware programs in 150% mode, it really doesn't work at all, with a loss of 50% in the final positions. In the 200% mode, it's a loss of 100%.

    And it was working fine with Windows 7, because the user who reported the problem to me had played with my program (in DPI virtualization mode) for more than one year, on Windows 7. With no problem. And when he updated to Windows 8, keeping his 150% display, the bug appeared : no way to move the cursor to the right place, with a big loss at each movement. The bug is reproducible on my own laptops.

    I made a very simple program to test the bug. I run it on Windows 7 (150%) : no problem, I can draw a spot and move the mouse cursor right to this spot. But the same program doesn't work on Windows 8 (150%). SetCursorPos(100,100) moves the cursor to (67,59). A loss of 50% on the x axis, and the same on the y axis, with a small offset due (I think) to the height of the title bar.

    Still, not many programs use SetCursorPos, and maybe this is why the bug has not been reported yet. I don't know if it's really worth it fixing it. But sometimes a little bug hides a more important problem somewhere else...

    Tuesday, July 30, 2013 11:31 AM
  • As a developer, I keep one machine for one Windows version. So, I'd need to buy a... 1,2, ... 7th machine. Maybe soon or later, anyway.

    As a developer, you are entitled to exciting FREE offers: VMware player, Virtual Box or the "client Hyper-V" of Windows 8. Only your disk space limits how many VMs you can have. Win 8.1 runs on VMware very well.

    -- pa

    Tuesday, July 30, 2013 11:44 AM
  • Thanks for the information, I'll have a look at these free offers.
    Tuesday, July 30, 2013 11:50 AM

  • I also have an older app that used this "trick" to force the cursor to update when a user pressed the Ctrl key. In my case the Windows 8 computer used for testing is a Home version and the offending DPI is 125%. I test on this computer for each release and am fairly certain it was not having this problem until recently. The computer has been set to 125% DPI for a long time. 

    This is definitely a bug in Windows 8. Older apps that are not DPI-aware were broken by this bug if they use the "trick" of calling GetCursorPos then SetCursorPos without changing the coordinates. Windows should have made the appropriate conversions for a non-DPI-aware apps and things should have continued to work. If this were just a pixel or two error in the conversion it would be no big deal. The jump is much greater than that - on the order of 60 pixels or more.

    jdm

    Monday, August 19, 2013 2:37 PM
  • We're not talking "slightly" here - it's on the order of 60 pixels. Clearly, Win8 is not doing the conversion properly in either of GetCursorPos or SetCursorPos.

    jdm

    Monday, August 19, 2013 2:39 PM
  • I'm glad you report the same problem with Windows 8. The new point is that it seems to occur even with the 125% setting. On my machine, it appears only with 150% and 200%, because below, Windows doesn't start the virtualization mode. Maybe, this mode depends on the screen size and resolution.

    My tests show that only SetCursorPos is concerned. The function seems to forget to translate its coordinates into virtualization mode and therefore moves to a wrong position. Then, GetCursorPos seems to be wrong too, but actually, it returns the right location (considering the error made by SetCursorPos).

    As for the GetCursorPos/SetCursorPos trick, your message made me think a bit more about it. Any program displaying active areas may need to automatically reactivate the area beneath the mouse cursor (when changing the background page for example) even though the mouse cursor did not move. To do so, an easy way is to send a full MOUSEMOVE message (with key state and everything) by just moving the cursor to its actual position. So, now, I think that there may be quite a lot of programs that use this trick. And, as you say, it's not a question of 1 pixel or 2. Such non-DPI programs definitely won't work on Windows 8 and virtualization mode.

    It would be interesting if we could have here the confirmation that this bug has been reported as a MAJOR BUG to Microsoft's developers, and that it has been fixed (or will be, if confirmed) in Windows 8.1. The new public release is coming soon. It would be a pity not to have fixed the problem by then.

    Friday, August 30, 2013 10:52 AM