3

我有一个程序可以截取监视器的屏幕截图,并可以选择在快照中包含鼠标光标。原始功能仅适用于一台显示器。绘制鼠标光标时,它目前仅在主监视器上正确显示。但是,我不知道如何将它放置在任何其他显示器上。请参阅此过程结束时的注释。

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;

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

4

1 回答 1

3

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

上面的映射同样适用于所有显示器。

请注意,我使用了自己的符号,因为我发现您的单字母变量具有误导性。更不用说这些变量的含义在函数期间会发生变化。我看着你,R。这总是痛苦的秘诀。

另外,您不需要删除调用时交给您的位图句柄GetIconInfo吗?并且一些错误检查不会出错。

于 2013-06-02T20:25:23.337 回答