• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Получение Screen на системе с несколькими мониторами

  • Автор темы Barmutik
  • Дата начала
B

Barmutik

Привет всем!

Может кто сталкивался.. есть система с несколькими мониторами.. разного разрешения.. нужно в зависимости от выбранного монитора снять его срин.

Заранее спасибо...
 
S

sab0tage

Хм, интересно, никогда об этом не думал...
Код:
procedure ScreenShot(x : integer; y : integer; Width : integer; Height : integer; bm : TBitMap);
var
dc: HDC; lpPal : PLOGPALETTE;
begin
{test width and height}
if ((Width = 0) OR (Height = 0)) then exit;
bm.Width := Width;
bm.Height := Height;
{get the screen dc}
dc := GetDc(0);
if (dc = 0) then exit;
{do we have a palette device?}
if (GetDeviceCaps(dc, RASTERCAPS) AND RC_PALETTE = RC_PALETTE) then
begin
{allocate memory for a logical palette}
GetMem(lpPal, sizeof(TLOGPALETTE) + (255 * sizeof(TPALETTEENTRY)));
{zero it out to be neat}
FillChar(lpPal^, sizeof(TLOGPALETTE) + (255 * sizeof(TPALETTEENTRY)), #0);
{fill in the palette version}
lpPal^.palVersion := $300;
{grab the system palette entries}
lpPal^.palNumEntries :=GetSystemPaletteEntries(dc,0,256,lpPal^.palPalEntry);
if (lpPal^.PalNumEntries <> 0) then
begin
{create the palette}
bm.Palette := CreatePalette(lpPal^);
end;
FreeMem(lpPal, sizeof(TLOGPALETTE) + (255 * sizeof(TPALETTEENTRY)));
end;
{copy from the screen to the bitmap}
BitBlt(bm.Canvas.Handle,0,0,Width,Height,Dc,x,y,SRCCOPY);
{release the screen dc}
ReleaseDc(0, dc);
end; (* ScreenShot *)
В таком варианте снимок будет с активного экрана или с обеих? Если в GetDc(0); вместо 0 отправить другой параметр..

Жалко нету под рукой такой системы ...
 
B

Barmutik

Спасибо за вариант .. но я уже придумал решение .. сам никогда с таким не сталкивался .. но вот тут и пришлось ... вот как я делал .. не факт что самый лучший вариант:

Код:
procedure GetMonitorScreenshot(Image: TImage; Monitor: TMonitor); 
var 
Canvas: TCanvas; 
SrcRect, DestRect: TRect; 
begin 
if Monitor = nil then 
with Screen do 
begin 
SrcRect := Rect(DesktopLeft, DesktopTop, 
DesktopLeft + DesktopWidth, DesktopTop + DesktopHeight); 
DestRect := Rect(0, 0, DesktopWidth, DesktopHeight); 
end 
else 
with Monitor do 
begin 
SrcRect := Rect(Left, Top, Left + Width, Top + Height); 
DestRect := Rect(0, 0, Width, Height); 
end; 
Canvas := TCanvas.Create; 
try 
Image.Picture.Bitmap.Width := 0; 
Image.Picture.Bitmap.Height := 0; 


Canvas.Handle := GetDC(0);	
Image.Picture.Bitmap.Width := DestRect.Right; 
Image.Picture.Bitmap.Height := DestRect.Bottom; 
Image.Width := DestRect.Right; 
Image.Height := DestRect.Bottom; 
Image.Canvas.CopyMode := srcCopy; 
Image.Canvas.CopyRect(DestRect, Canvas, SrcRect); 
finally 
Canvas.Free; 
end; 
end;

Для убыстрения уже вариации на эту тему следуют....
 
S

sab0tage

Ну теже яйца, только в профиль :)
Canvas.Handle := GetDC(0); - Просто интересно было, хэндл активного монитора или их связки.
Тоесть, что происходит при выполнении твоего/моего кода Скрин снимается с активного экрана одного монитора, или весь вывод вместе, без разницы сколько мониторов? (Где бы попробовать...)
 
B

Barmutik

Если не указвать монитор то всего зараз ... а если указываеш то конкретного .. работает даже если разные разрешения на мониторах ...

Меня грызут сомнения чт оможет с GetDC(0) не всё верно .. в хелпе написано что дя многих мониторов использовать CreateDC and EnumerateMonitors ...
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!