-----------------------------------------------------------------------
                      [BUG/PRB.] VFP 9.0 FIX - FIX THE CURSOR POSITION IS TOO SMALL
                                 January 2024
                 -----------------------------------------------------------------------
                                     CCB



1. BUG:

     In vfp9, the cursor position is too small when set scaling to greater than 100% on Windows 10.

     The bug occurs on Windows 8.1 and Windows 10, it also occurs when we uncheck the checkbox "Use Windows XP Style DPI Scaling"
     on Windows Vista, Windows 7 and Windows 8, it does not occur on early Windows XP.

     The bug was reported by Atma Negara.

     In vfp9, when we set scaling to 125%, the cursor position is too small, please refer to the picture testcursorposition125-vfp9.jpg:


2. CAUSE:

     There are some BUGs in the following code.


3. RESOLUTION:

     We can write some code to fix the BUG.

     Fun773929 :: ; proc near
             push ebp                                                        ;0x00773929 :        55
             mov ebp , esp                                                   ;0x0077392a :        8bec
             sub esp , 048h                                                  ;0x0077392c :        83ec48
             push ebx                                                        ;0x0077392f :        53
             push esi                                                        ;0x00773930 :        56
             push edi                                                        ;0x00773931 :        57
             mov esi , eax                                                   ;0x00773932 :        8bf0
             lea edi ,  dword ptr [ ebp - 72 ]                               ;0x00773934 :        8d7db8
             movsd                                                           ;0x00773937 :        a5
             movsd                                                           ;0x00773938 :        a5
             movsd                                                           ;0x00773939 :        a5
             lea eax ,  dword ptr [ ebp - 72 ]                               ;0x0077393a :        8d45b8
             movsd                                                           ;0x0077393d :        a5
             call Fun467464                                                  ;0x0077393e :        e8213bcfff
             mov  eax , dword ptr [ ebp - 60 ]                               ;0x00773943 :        8b45c4
             sub  eax , dword ptr [ ebp - 68 ]                               ;0x00773946 :        2b45bc
             pushd 03h                                                       ;0x00773949 :        6a03
             cdq                                                             ;0x0077394b :        99
             pop ecx                                                         ;0x0077394c :        59
             idiv ecx                                                        ;0x0077394d :        f7f9
             test edx , edx                                                  ;0x0077394f :        85d2
             jne Label773956                                                 ;0x00773951 :        7503
             inc  dword ptr [ ebp - 60 ]                                     ;0x00773953 :        ff45c4

     Label773956 ::
             pushd 00h                                                       ;0x00773956 :        6a00
             mov  byte ptr [ ebp - 56 ] , 0FFh                               ;0x00773958 :        c645c8ff
             mov  byte ptr [ ebp - 54 ] , 0FFh                               ;0x0077395c :        c645caff
             mov  byte ptr [ ebp - 55 ] , 0FFh                               ;0x00773960 :        c645c9ff
             call  GetDC                                       ;0x00773964 :        ff15b4729100
             mov ebx , eax                                                   ;0x0077396a :        8bd8
             test ebx , ebx                                                  ;0x0077396c :        85db
             je Label773a0e                                                  ;0x0077396e :        0f849a000000
             pushd 07h                                                       ;0x00773974 :        6a07
             push ebx                                                        ;0x00773976 :        53
             call  SetROP2                                     ;0x00773977 :        ff1518769100
             push ecx                                                        ;0x0077397d :        51
             mov edi , esp                                                   ;0x0077397e :        8bfc
             lea esi ,  dword ptr [ ebp - 56 ]                               ;0x00773980 :        8d75c8
             movsw                                                           ;0x00773983 :        66a5
             pushd 01h                                                       ;0x00773985 :        6a01
             pushd 00h                                                       ;0x00773987 :        6a00
             mov  dword ptr [ ebp - 12 ] , eax                               ;0x00773989 :        8945f4
             movsb                                                           ;0x0077398c :        a4
             call Fun423df7                                                  ;0x0077398d :        e86504cbff
             mov  esi , SelectObject                           ;0x00773992 :        8b35f4769100
             push eax                                                        ;0x00773998 :        50
             push ebx                                                        ;0x00773999 :        53
             call esi                                                        ;0x0077399a :        ffd6
             pushd 05h                                                       ;0x0077399c :        6a05
             mov  dword ptr [ ebp - 8 ] , eax                                ;0x0077399e :        8945f8
             call  GetStockObject                              ;0x007739a1 :        ff15f0769100
             push eax                                                        ;0x007739a7 :        50
             push ebx                                                        ;0x007739a8 :        53
             call esi                                                        ;0x007739a9 :        ffd6
             push  dword ptr [ ebp + 8 ]                                     ;0x007739ab :        ff7508
             lea edi ,  dword ptr [ ebp - 72 ]                               ;0x007739ae :        8d7db8
             mov  dword ptr [ ebp - 4 ] , eax                                ;0x007739b1 :        8945fc
             call Fun43aee1                                                  ;0x007739b4 :        e82875ccff
             mov  edx , dword ptr [ ebp + 8 ]                                ;0x007739b9 :        8b5508
             lea eax ,  dword ptr [ ebp - 28 ]                               ;0x007739bc :        8d45e4
             call Fun42e782                                                  ;0x007739bf :        e8beadcbff


     ;
     ;                 ------------------------------------------------------------
     ;                      VFP 9.0 FIX - FIX THE CURSOR POSITION IS TOO SMALL
     ;                                 October 2018
     ;                 ------------------------------------------------------------
     ;                                     CCB
     ;
     ; In vfp9, fix the cursor position is too small when set scaling to greater than 100% on Windows 10.
     ;
     ; 2018/10/16, by ccb
     ;

     Label7739c4_x1_start ::
             mov eax , dword ptr [ ebp - 28 + 00h ]
             cmp dword ptr vfpa_sys9010_data,00h
             je Label7739c4_x1_end
             mov ecx,dword ptr vfpa_getdpiforwindow_dpi
             cmp ecx,dword ptr vfpa_getdpiforsystem_dpi
             jbe Label7739c4_x1_end
             push dword ptr vfpa_getdpiforsystem_dpi
             push dword ptr vfpa_getdpiforwindow_dpi
             push eax
             call MulDiv
             mov dword ptr [ ebp - 28 + 00h ] , eax
     Label7739c4_x1_end ::

     Label7739c4_y1_start ::
             mov eax , dword ptr [ ebp - 28 + 04h ]
             cmp dword ptr vfpa_sys9010_data,00h
             je Label7739c4_y1_end
             mov ecx,dword ptr vfpa_getdpiforwindow_dpi
             cmp ecx,dword ptr vfpa_getdpiforsystem_dpi
             jbe Label7739c4_y1_end
             push dword ptr vfpa_getdpiforsystem_dpi
             push dword ptr vfpa_getdpiforwindow_dpi
             push eax
             call MulDiv
             mov dword ptr [ ebp - 28 + 04h ] , eax
     Label7739c4_y1_end ::

     Label7739c4_x2_start ::
             mov eax , dword ptr [ ebp - 28 + 08h ]
             cmp dword ptr vfpa_sys9010_data,00h
             je Label7739c4_x2_end
             mov ecx,dword ptr vfpa_getdpiforwindow_dpi
             cmp ecx,dword ptr vfpa_getdpiforsystem_dpi
             jbe Label7739c4_x2_end
             push dword ptr vfpa_getdpiforsystem_dpi
             push dword ptr vfpa_getdpiforwindow_dpi
             push eax
             call MulDiv
             mov dword ptr [ ebp - 28 + 08h ] , eax
     Label7739c4_x2_end ::

     Label7739c4_y2_start ::
             mov eax , dword ptr [ ebp - 28 + 0Ch ]
             cmp dword ptr vfpa_sys9010_data,00h
             je Label7739c4_y2_end
             mov ecx,dword ptr vfpa_getdpiforwindow_dpi
             cmp ecx,dword ptr vfpa_getdpiforsystem_dpi
             jbe Label7739c4_y2_end
             push dword ptr vfpa_getdpiforsystem_dpi
             push dword ptr vfpa_getdpiforwindow_dpi
             push eax
             call MulDiv
             mov dword ptr [ ebp - 28 + 0Ch ] , eax
     Label7739c4_y2_end ::
             lea eax ,  dword ptr [ ebp - 28 ]


             push eax                                                        ;0x007739c4 :        50
             call  CreateRectRgnIndirect                       ;0x007739c5 :        ff15f0759100
             mov edi , eax                                                   ;0x007739cb :        8bf8
             push edi                                                        ;0x007739cd :        57
             push ebx                                                        ;0x007739ce :        53
             call  SelectClipRgn                               ;0x007739cf :        ff1550769100


     ;
     ;                 ------------------------------------------------------------
     ;                      VFP 9.0 FIX - FIX THE CURSOR POSITION IS TOO SMALL
     ;                                 October 2018
     ;                 ------------------------------------------------------------
     ;                                     CCB
     ;
     ; In vfp9, fix the cursor position is too small when set scaling to greater than 100% on Windows 10.
     ;
     ; 2018/10/16, by ccb
     ;

     ;         push  dword ptr [ ebp - 60 ]                                    ;0x007739d5 :        ff75c4
     ;         push  dword ptr [ ebp - 64 ]                                    ;0x007739d8 :        ff75c0
     ;         push  dword ptr [ ebp - 68 ]                                    ;0x007739db :        ff75bc
     ;         push  dword ptr [ ebp - 72 ]                                    ;0x007739de :        ff75b8

     Label7739d5_y2_start ::
             mov eax,dword ptr [ ebp - 60 ]
             cmp dword ptr vfpa_sys9010_data,00h
             je Label7739d5_y2_end
             mov ecx,dword ptr vfpa_getdpiforwindow_dpi
             cmp ecx,dword ptr vfpa_getdpiforsystem_dpi
             jbe Label7739d5_y2_end
             push dword ptr vfpa_getdpiforsystem_dpi
             push dword ptr vfpa_getdpiforwindow_dpi
             push eax
             call MulDiv
     Label7739d5_y2_end ::
             push eax

     Label7739d8_x2_start ::
             mov eax,dword ptr [ ebp - 64 ]
             cmp dword ptr vfpa_sys9010_data,00h
             je Label7739d8_x2_end
             mov ecx,dword ptr vfpa_getdpiforwindow_dpi
             cmp ecx,dword ptr vfpa_getdpiforsystem_dpi
             jbe Label7739d8_x2_end
             push dword ptr vfpa_getdpiforsystem_dpi
             push dword ptr vfpa_getdpiforwindow_dpi
             push eax
             call MulDiv
     Label7739d8_x2_end ::
             push eax

     Label7739db_y1_start ::
             mov eax,dword ptr [ ebp - 68 ]
             cmp dword ptr vfpa_sys9010_data,00h
             je Label7739db_y1_end
             mov ecx,dword ptr vfpa_getdpiforwindow_dpi
             cmp ecx,dword ptr vfpa_getdpiforsystem_dpi
             jbe Label7739db_y1_end
             push dword ptr vfpa_getdpiforsystem_dpi
             push dword ptr vfpa_getdpiforwindow_dpi
             push eax
             call MulDiv
     Label7739db_y1_end ::
             push eax

     Label7739de_x1_start ::
             mov eax,dword ptr [ ebp - 72 ]
             cmp dword ptr vfpa_sys9010_data,00h
             je Label7739de_x1_end
             mov ecx,dword ptr vfpa_getdpiforwindow_dpi
             cmp ecx,dword ptr vfpa_getdpiforsystem_dpi
             jbe Label7739de_x1_end
             push dword ptr vfpa_getdpiforsystem_dpi
             push dword ptr vfpa_getdpiforwindow_dpi
             push eax
             call MulDiv
     Label7739de_x1_end ::
             push eax


             push ebx                                                        ;0x007739e1 :        53
             call  Rectangle                                   ;0x007739e2 :        ff15ec769100
             push edi                                                        ;0x007739e8 :        57
             call  DeleteObject                                ;0x007739e9 :        ff15d4769100
             push  dword ptr [ ebp - 4 ]                                     ;0x007739ef :        ff75fc
             push ebx                                                        ;0x007739f2 :        53
             call esi                                                        ;0x007739f3 :        ffd6
             push  dword ptr [ ebp - 8 ]                                     ;0x007739f5 :        ff75f8
             push ebx                                                        ;0x007739f8 :        53
             call esi                                                        ;0x007739f9 :        ffd6
             push  dword ptr [ ebp - 12 ]                                    ;0x007739fb :        ff75f4
             push ebx                                                        ;0x007739fe :        53
             call  SetROP2                                     ;0x007739ff :        ff1518769100
             push ebx                                                        ;0x00773a05 :        53
             pushd 00h                                                       ;0x00773a06 :        6a00
             call  ReleaseDC                                   ;0x00773a08 :        ff15b0729100

     Label773a0e ::
             pop edi                                                         ;0x00773a0e :        5f
             pop esi                                                         ;0x00773a0f :        5e
             pop ebx                                                         ;0x00773a10 :        5b
             leave                                                           ;0x00773a11 :        c9
             ret 04h                                                         ;0x00773a12 :        c20400

     Now in VFP Advanced, when we set scaling to 125%, the cursor position is normal, please refer to the picture testcursorposition125-vfpa.jpg:


4. APPLIES TO:

     VFP 6.0.8167.0
     VFP 6.0.8961.0 (SP5)

     VFP 7.0.0.9262
     VFP 7.0.0.9465 (SP1)

     VFP 8.0.0.2521
     VFP 8.0.0.3117 (SP1)

     VFP 9.0.0.2412
     VFP 9.0.0.3504 (SP1)
     VFP 9.0.0.4611 (SP2)
     VFP 9.0.0.5015 (SP2)
     VFP 9.0.0.5411 (SP2)
     VFP 9.0.0.5721 (SP2)
     VFP 9.0.0.5815 (SP2)
     VFP 9.0.0.6303 (SP2)
     VFP 9.0.0.6602 (SP2)
     VFP 9.0.0.7423 (SP2)

     The bug has been fixed in VFP Advanced.

     IMPORTANT NOTE FOR WINDOWS 10:
     The GetDpiForSystem and GetDpiForWindow Windows APIs are only on Windows 10 version 1607 (August 2, 2016) or later,
     the bug has been fixed on Windows 10 version 1607 (August 2, 2016) or later,
     so recommend to upgrade to Windows 10 version 1607 (August 2, 2016) or later.
     If there is no the registry key "HKEY_CURRENT_USER\Control Panel\Desktop\Win8DpiScaling" in the Windows registry,
     the GetDpiForWindow Windows API always returns 96,
     so we MUST create the following registry key:
     [HKEY_CURRENT_USER\Control Panel\Desktop]
     "Win8DpiScaling"=dword:00000000
     and then the GetDpiForWindow Windows API can return correct value.


5. REFERENCE WEBSITES:

     1, baiyujia.com:
     http://www.baiyujia.com
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix57.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix40.asp
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix56.asp

     2, foxite.com:
     https://www.foxite.com/archives/native-draganddrop-visual-win10-0000460950.htm


6. OTHER:

     For reference only, there is no guarantees.

     Any questions or suggestions, please send me an email at ccb2000@163.com.