Multi-monitor screenshot - positioning mouse cursor

守給你的承諾、 提交于 2020-07-08 19:23:39

问题


I have a procedure which takes a screenshot of a monitor and optionally includes the mouse cursor in the snapshot. The original function was only for one monitor. When drawing the mouse cursor, it currently shows properly only on the Main Monitor. But, I can't figure out how to position it on any other monitor. See the comments towards the end of this procedure.

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;

How do I transition the mouse position properly depending on which monitor I'm using?


回答1:


You are mapping screen coord MonitorRect.Left to bitmap coord 0. And likewise, MonitorRect.Top to 0. So, if the cursor's screen position is CursorPos then you map that to CursorPos.X - MonitorRect.Left and CursorPos.Y - MonitorRect.Top. And then you also need to account for the hot spot, but you already seem to know how to do that.

The mapping above applies equally to all monitors.

Note that I used my own notation because I found your single letter variables mis-leading. Not to mention that fact that the meaning of these variables changes during the function. I'm look at you, R. That's always a recipe for pain.

Also, don't you need to delete the bitmap handles that are handed to you when you call GetIconInfo? And some error checking wouldn't go amiss.



来源:https://stackoverflow.com/questions/16886862/multi-monitor-screenshot-positioning-mouse-cursor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!