多监视器屏幕截图 - 定位鼠标光标
问题描述:
我有一个程序,它需要一个监视器的屏幕截图,并且可以在快照中包含鼠标光标。原始功能仅适用于一台显示器。当绘制鼠标光标时,它目前仅在主监视器上正确显示。但是,我无法弄清楚如何将它放置在任何其他显示器上。请参阅此过程结束时的注释。多监视器屏幕截图 - 定位鼠标光标
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;
如何根据我使用的显示器正确地转换鼠标位置?
答
您正在将屏幕坐标MonitorRect.Left
映射到位图坐标0
。同样,MonitorRect.Top
到0
。所以,如果光标的屏幕位置是CursorPos
那么您将其映射到CursorPos.X - MonitorRect.Left
和CursorPos.Y - MonitorRect.Top
。然后你也需要考虑热点,但你似乎已经知道如何做到这一点。
上面的映射同样适用于所有监视器。
请注意,我使用自己的符号,因为我发现你的单个字母变量错误的领先。更不要说这些变量的含义在函数中发生变化的事实。我看着你,R
。这总是一个痛苦的秘诀。
此外,当您拨打GetIconInfo
时,是否需要删除交给您的位图手柄?而一些错误检查不会失误。
呃拍得好,这个'+'本来是一个''''它做到了。如果你删除了这两行,它就不起作用 - 它只会让光标显示在光标位于主显示器上,但不显示截屏的实际显示器。 –
哦,我明白了,你用了两次R! R的值是位图rect,它总是固定在0,0。 –
这是值得回收的,因为'如果DrawCursor然后开始'标志着一个不同的代码块的开始。因此,我留下了一个简短的名字,比如'R'。 –