I have been doing a lot of work lately with taking screenshots (for a remote desktop system) and just stumbled across a problem while I'm trying to implement support for multiple monitors. While taking the screenshot is OK, the method I'm using to draw the cursor only presumes 1 screen. If I position the pointer on an additional screen (when taking a screenshot of that additional screen), the cursor does NOT show. I move the pointer to the main screen and it shows (of course in the wrong spot because it's the wrong screen).
My code is entirely below. When specifying MonitorID, 0 = entire screen (all monitors), 1 = main screen, 2 = additional screen..... etc.....
I just need to determine the correct X/Y position of the pointer according to which screen is currently active.
JD Solutions
My code is entirely below. When specifying MonitorID, 0 = entire screen (all monitors), 1 = main screen, 2 = additional screen..... etc.....
I just need to determine the correct X/Y position of the pointer according to which screen is currently active.
Code:
procedure DrawScreenCursor(var Bmp: TBitmap; const MonitorID: Integer);
var
R: TRect;
CursorInfo: TCursorInfo;
Icon: TIcon;
IconInfo: TIconInfo;
begin
R:= Bmp.Canvas.ClipRect;
Icon:= TIcon.Create;
try
//MonitorID: 0=ALL screens, 1=MAIN screen, 2=ADDITIONAL screen, etc....
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
//Draw cursor image on screenshot image
Bmp.Canvas.Draw(
CursorInfo.ptScreenPos.x - Integer(IconInfo.xHotspot) - R.Left,
CursorInfo.ptScreenPos.y - Integer(IconInfo.yHotspot) - R.Top,
Icon
);
end;
end;
finally
Icon.Free;
end;
end;
function TakeScreenshot(var bmp: TBitmap; MonitorNumber: Integer): Boolean;
const
CAPTUREBLT = $40000000;
var
DesktopCanvas: TCanvas;
DC: HDC;
Left, Top: Integer;
begin
Result := False;
if (MonitorNumber > Screen.MonitorCount) then
Exit;
DC:= GetDC(0);
try
if (DC = 0) then
Exit;
if (MonitorNumber = 0) then begin
Bmp.Width := Screen.DesktopWidth;
Bmp.Height := Screen.DesktopHeight;
Left := Screen.DesktopLeft;
Top := Screen.DesktopTop;
end else begin
Bmp.Width := Screen.Monitors[MonitorNumber-1].Width;
Bmp.Height := Screen.Monitors[MonitorNumber-1].Height;
Left := Screen.Monitors[MonitorNumber-1].Left;
Top := Screen.Monitors[MonitorNumber-1].Top;
end;
DesktopCanvas := TCanvas.Create;
try
DesktopCanvas.Handle := DC;
Result := BitBlt(
Bmp.Canvas.Handle,
0,
0,
Bmp.Width,
Bmp.Height,
DesktopCanvas.Handle,
Left,
Top,
SRCCOPY or CAPTUREBLT
);
Result:= True;
finally
DesktopCanvas.Free;
end;
finally
if (DC <> 0) then
ReleaseDC(0, DC);
end;
end;
function ScreenShot(Bmp: TBitmap; const DrawCursor: Boolean;
const Quality: TPixelFormat; const Monitor: Integer): Bool;
begin
Result:= TakeScreenshot(Bmp, Monitor);
if Result then
if DrawCursor then
DrawScreenCursor(Bmp, Monitor);
end;
JD Solutions