多显示器截图 - 定位鼠标光标

时间:2013-06-02 20:13:29

标签: delphi cursor position

我有一个程序,它截取监视器的屏幕截图,并可选择在快照中包含鼠标光标。原始功能仅适用于一台显示器。绘制鼠标光标时,它当前仅在主监视器上正确显示。但是,我无法弄清楚如何将它放在任何其他显示器上。请参阅本程序结束时的评论。

procedure ScreenShot(var Bitmap: TBitmap; const MonitorNum: Integer;
  const DrawCursor: Boolean; const Quality: TPixelFormat);
var
  DC: HDC;
  C: TCanvas;
  R: TRect;
  CursorInfo: TCursorInfo;
  Icon: TIcon;
  IconInfo: TIconInfo;
  M: TMonitor;
  CP: TPoint;
begin
  M:= Screen.Monitors[MonitorNum];
  DC:= GetDC(GetDesktopWindow);
  try
    C:= TCanvas.Create;
    try
      C.Handle:= DC;
      R:= M.BoundsRect;
      Bitmap.Width:= R.Width;
      Bitmap.Height:= R.Height;
      Bitmap.PixelFormat:= Quality;
      Bitmap.Canvas.CopyRect(Rect(0,0,R.Width,R.Height), C, R);
    finally
      C.Free;
    end;
  finally
    ReleaseDC(GetDesktopWindow, DC);
  end;
  if DrawCursor then begin
    R:= Bitmap.Canvas.ClipRect;
    Icon:= TIcon.Create;
    try
      CursorInfo.cbSize:= SizeOf(CursorInfo);
      if GetCursorInfo(CursorInfo) then
      if CursorInfo.Flags = CURSOR_SHOWING then
      begin
        Icon.Handle:= CopyIcon(CursorInfo.hCursor);
        if GetIconInfo(Icon.Handle, IconInfo) then
        begin
          CP:= CursorInfo.ptScreenPos;

          //Transition mouse position...?
          CP.X:= CP.X + M.Left;
          CP.Y:= CP.Y + M.Top;  //No difference?

          Bitmap.Canvas.Draw(
            CP.X - Integer(IconInfo.xHotspot) - R.Left,
            CP.Y - Integer(IconInfo.yHotspot) - R.Top,
            Icon);
        end;
      end;
    finally
      Icon.Free;
    end;
  end;
end;

如何根据我正在使用的显示器正确转换鼠标位置?

1 个答案:

答案 0 :(得分:3)

您正在将屏幕坐标MonitorRect.Left映射到位图坐标0。同样,MonitorRect.Top0。因此,如果光标的屏幕位置为CursorPos,那么您将其映射到CursorPos.X - MonitorRect.LeftCursorPos.Y - MonitorRect.Top。然后你还需要考虑热点,但你似乎已经知道如何做到这一点。

上述映射同样适用于所有监视器。

请注意,我使用了自己的符号,因为我发现你的单个字母变量误导。更不用说在功能期间这些变量的含义发生变化的事实。我看着你,R。这总是一种痛苦的方法。

此外,当您致电GetIconInfo时,是否需要删除发给您的位图句柄?并且一些错误检查不会有问题。