Delphi: GetCursorPos problem on Windows 8.1 with scaling
Question by Guest | 2015-07-19 at 04:14
I have an application which is written in Delphi 5 and has been working well for years.
I now have a problem on systems running windows 8.1 with high definition screens where scaling is set higher than 100%.
Part of the application allows the user to select the color of individual pixels on an image.
To make it easier I use a zoom box which displays a zoomed section of the main image.
When the cursor is over the main image, a smaller zoomed image with a crosshair is displayed.
When screen scaling is active, the zoom box no longer displays the area surrounding the cursor position but rather seems to be relative to the 0,0 point of the screen.
Here is the code I am using.
procedure TAutoFillForm.Timer1Timer(Sender: TObject); var Srect, Drect, DisplayArea: TRect; iWidth, iHeight, DmX, DmY: Integer; iTmpX, iTmpY: Real; C: TCanvas; hDesktop: Hwnd; CursorPosition, ImageLoc: TPoint; Col, CrossHairCol: TColor; MaxWidth, MaxHeight, iTop, iLeft: Integer; DC: HDC; ImageRect:Trect; begin If not IsIconic(Application.Handle) then begin hDesktop:=GetDesktopWindow; GetCursorPos(CursorPosition); ImageLoc:=Image1.ClientToScreen(Point(0,0)); // Label9.Caption:= 'Cursor X = ' + // IntToStr(CursorPosition.x) + // ' : Cursor Y = ' + IntToStr(CursorPosition.Y) + // ' : ScreenDPI = ' + IntToStr(ScreenDPI) + // ' DPI = ' + IntToStr(Screen.PixelsPerInch) + // ' Image X = ' + IntToStr(ImageLoc.x) + // ' Image Y = ' + IntToStr(ImageLoc.y); MaxWidth:=Image1.Width; MaxHeight:=Image1.Height; DisplayArea:=Rect(ImageLoc.x,ImageLoc.y, ImageLoc.x+MaxWidth,ImageLoc.y+MaxHeight); If (PtInRect(DisplayArea,CursorPosition)) and (CheckBox2.Checked) then begin If Image2.Visible=False then Image2.Visible:=True; iWidth:=Image2.Width; iHeight:=Image2.Height; Drect:=Rect(0,0,iWidth,iHeight); iTmpX:=iWidth / (TrackBar1.Position * 4 ); iTmpY:=iHeight / (TrackBar1.Position * 4); GetCursorPos(CursorPosition); Srect:=Rect(CursorPosition.x,CursorPosition.y, CursorPosition.x,CursorPosition.y); InflateRect(Srect,Round(iTmpX),Round(iTmpY)); // move Srect if outside visible area of the screen If Srect.Left<0 then OffsetRect(Srect,-Srect.Left,0); If Srect.Top<0 then OffsetRect(Srect,0,-Srect.Top); If Srect.Right>Screen.DesktopWidth then OffsetRect(Srect,-(Srect.Right-Screen.DesktopWidth),0); If Srect.Bottom>Screen.DesktopHeight then OffsetRect(Srect,0,-(Srect.Bottom-Screen.DesktopHeight)); C:=TCanvas.Create; try C.Handle:=GetDC(0); Image2.Canvas.CopyRect(Drect,C,Srect); finally ReleaseDC(hDesktop, C.Handle); C.Free; end; If CheckBox2.Checked=True then begin // show crosshair with Image2.Canvas do begin DC := CreateDC('DISPLAY',nil,nil,nil); Col := GetPixel(DC,CursorPosition.X,CursorPosition.Y); DeleteDC(DC); // set color to be visible over current area CrossHairCol:=MainForm.VisibleContrast(Col); Image2.Canvas.Pen.Color:= CrossHairCol; DmX:=TrackBar1.Position * 2 * (CursorPosition.X-Srect.Left); DmY:=TrackBar1.Position * 2 * (CursorPosition.Y-Srect.Top); MoveTo(DmX - (iWidth div 8),DmY); // - LineTo(DmX + (iWidth div 8),DmY); // - MoveTo(DmX,DmY - (iHeight div 8)); // | LineTo(DmX,DmY + (iHeight div 8)); // | end; // with image1.Canvas end; // show crosshair Application.ProcessMessages; end // Cursor not inside area else begin // cursor inside area If Image2.Visible=True then Image2.Visible:=False; end; end; // IsIconic end;
Thanks in advance for your help.
Related Topics
Windows: How to make Hibernation available
Tutorial | 0 Comments
Delphi/Lazarus: Retrieve Cursor Position relative to Form/Window
Tip | 0 Comments
Windows Batch Script: Computer Shutdown
Tutorial | 2 Comments
Lazarus: Detect Operating System (Compiler Switch)
Tutorial | 0 Comments
Delphi: System-Wide HotKey
Tutorial | 1 Comment
Put Windows via Script into Hibernation or Sleep Mode
Tutorial | 0 Comments
Original Delphi is too expensive - Are there Alternatives?
Question | 3 Answers
Important Note
Please note: The contributions published on askingbox.com are contributions of users and should not substitute professional advice. They are not verified by independents and do not necessarily reflect the opinion of askingbox.com. Learn more.
Participate
Ask your own question or write your own article on askingbox.com. That’s how it’s done.
What do you mean with "seams to be relative to the 0,0 point of the screen"?
I can imagine that you have to use a factor for the right pixel position. When the image is scaled, a normal pixel from before is more than one 100 percent pixel. So, perhaps, you have to read out the scale factor and adjust this to display the right position.
By the way, you are talking about Windows 8.1. Have you also tested the scaling on other Windows versions?
2015-07-20 at 02:21