![]() |
Delphi-Version: 5
Der Screenshot zeigt den Mauszeiger nicht, wenn er auf den zweiten Monitor verschoben
Der Screenshot zeigt den Mauszeiger nicht, wenn er auf den zweiten Monitor verschoben wird
Ich habe in letzter Zeit viel mit Screenshots (für ein Remotedesktopsystem) gearbeitet und bin gerade auf ein Problem gestoßen, während ich versuche, die Unterstützung für mehrere Monitore zu implementieren. Während das Aufnehmen des Screenshots in Ordnung ist, setzt die Methode, mit der ich den Cursor zeichne, nur 1 Bildschirm voraus. Wenn ich den Zeiger auf einem zusätzlichen Bildschirm positioniere (wenn ich einen Screenshot dieses zusätzlichen Bildschirms mache), wird der Cursor NICHT angezeigt. Ich bewege den Zeiger auf den Hauptbildschirm und es wird angezeigt (natürlich an der falschen Stelle, weil es der falsche Bildschirm ist). Mein Code ist ganz unten.
Delphi-Quellcode:
program Test;
{$APPTYPE CONSOLE} {$R *.res} uses Windows, vcl.Graphics, SysUtils; function GetCursorInfo2: TCursorInfo; var hWindow: HWND; pt: TPoint; dwThreadID, dwCurrentThreadID: DWORD; begin Result.hCursor := 0; ZeroMemory(@Result, SizeOf(Result)); if GetCursorPos(pt) then begin Result.ptScreenPos := pt; hWindow := WindowFromPoint(pt); if IsWindow(hWindow) then begin dwThreadID := GetWindowThreadProcessId(hWindow, nil); dwCurrentThreadID := GetCurrentThreadId; if (dwCurrentThreadID <> dwThreadID) then begin if AttachThreadInput(dwCurrentThreadID, dwThreadID, True) then begin Result.hCursor := GetCursor; AttachThreadInput(dwCurrentThreadID, dwThreadID, False); end; end else Result.hCursor := GetCursor; end; end; end; procedure TakeScreenshot(var Bmp: TBitmap; WndHdc: HDC; Width, Height, Left, Top: Integer); const CAPTUREBLT = $40000000; var DesktopCanvas: TCanvas; MyCursor: TIcon; CursorInfo: TCursorInfo; IconInfo: TIconInfo; DC: HDC; begin DC := GetDC(WndHdc); try if (DC = 0) then Exit; Bmp.Width := Width; Bmp.Height := Height; DesktopCanvas := TCanvas.Create; try DesktopCanvas.Handle := DC; BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, DesktopCanvas.Handle, Left, Top, SRCCOPY or CAPTUREBLT); MyCursor := TIcon.Create; try CursorInfo := GetCursorInfo2; if CursorInfo.hCursor <> 0 then begin MyCursor.Handle := CursorInfo.hCursor; GetIconInfo(CursorInfo.hCursor, IconInfo); Bmp.Canvas.Draw(CursorInfo.ptScreenPos.X - IconInfo.xHotspot, CursorInfo.ptScreenPos.Y - IconInfo.yHotspot, MyCursor); end; finally MyCursor.ReleaseHandle; MyCursor.Free; end; finally DesktopCanvas.Free; end; finally if (DC <> 0) then ReleaseDC(0, DC); end; end; function EnumDisplayMonitors(dc: HDC; rect: PRect; EnumProc: pointer; lData: Integer): Boolean; stdcall; external user32 name 'EnumDisplayMonitors'; type TMonInfo = record h: THandle; DC: HDC; R: TRect; end; var MonList: array of TMonInfo; function MonitorEnumProc(hMonitor: THandle; hdcMonitor: HDC; lprcMonitor: DWORD; dwData: Integer): Boolean; stdcall; var I, Width, Height, Left, Top: Integer; Bmp: TBitmap; begin I := High(MonList) + 1; SetLength(MonList, I + 1); MonList[I].h := hMonitor; MonList[I].DC := hdcMonitor; MonList[I].R := PRect(lprcMonitor)^; Left := PRect(lprcMonitor)^.Left; Top := PRect(lprcMonitor)^.Top; Width := PRect(lprcMonitor)^.Width; Height := PRect(lprcMonitor)^.Height; Bmp := TBitmap.Create; try TakeScreenshot(Bmp, hdcMonitor, Width, Height, Left, Top); Bmp.SaveToFile('C:\Screen' + IntToStr(I + 1) + '.bmp'); finally Bmp.Free; end; Result := True; end; procedure Main; var S: string; I: Integer; begin Writeln('Number of monitors: ' + IntToStr(High(MonList) + 1) + #13#10); Writeln('-----------------'); for I := 0 to High(MonList) do with MonList[I] do begin S := #13#10 + 'Handle: ' + IntToStr(h) + #13#10 + 'Dc: ' + IntToStr(DC) + #13#10 + 'Size: ' + IntToStr(R.Right) + 'x' + IntToStr(R.Bottom) + #13#10; Writeln(S); Writeln('-----------------'); end; end; begin try EnumDisplayMonitors(0, nil, Addr(MonitorEnumProc), 0); Main; Writeln(#13#10 + 'Connected: ' + IntToStr(GetSystemMetrics(SM_CMONITORS)) + #13#10); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. |
AW: Der Screenshot zeigt den Mauszeiger nicht, wenn er auf den zweiten Monitor versch
Hallo,
Du fotografierst den Cursor mit? Würde es nicht auch gehen die Fotos ohne den Cursor zu machen und ihn dann selber lokal zu zeichnen? Position und Status kann man ja abfragen. |
AW: Der Screenshot zeigt den Mauszeiger nicht, wenn er auf den zweiten Monitor versch
Nee, und das macht er ja schon (siehe TakeScreenshot),
also er macht ein Foto, schaut wo die Maus rumschwirrt und was für einen Zeiger die hat und malt sie auch auf das Bild drauf. :zwinker: Man könnte nun mit dem Debugger schauen ob die Position simmt und ob auch ein Bild des Zeigers ausgelesen wurde. Für Letzteres könnte man testweise auch mal mit einer festen Position den Zeiger auf's Bild malen und für Ersteres entweder ein Ersatzbild oder z.B. zuerst einen Punkt/Kreis an die Stelle und dann darauf den Zeiger. |
AW: Der Screenshot zeigt den Mauszeiger nicht, wenn er auf den zweiten Monitor versch
Zitat:
Das ist ja richtig Clever den aktuellen Cursor als Bild auszulesen. Ich würde ihn aber erst nach dem übertragen aufs Bild malen, sicher machst Du das hier nur zum Testen. Ist auf dem zweiten Monitor eine andere DPI Einstellung oder Zoom/Lesehilfe aktiviert? Wie groß ist die Abweichung von der erwarteten Position? |
AW: Der Screenshot zeigt den Mauszeiger nicht, wenn er auf den zweiten Monitor versch
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz