-
Задача. Есть несколько открытых окон. Некоторые видны полностью, некоторые частично перекрыты, некоторые вообще не видны под другими окнами. Задача в том, чтобы в программе получит скриншот для всех окон. Способ точно есть, но я даже не представляю куда копать.
-
Тебе скриншот всего десктопа или каждого из окон?
-
> [1] Черный Шаман (06.12.07 21:42)
Каждого окна.
-
> [2] @!!ex © (06.12.07 21:43)
Бежать по всем верхним видимым окнам и сохранять нарисованное на DC?
-
Нашел вот такой код: procedure ScreenShot(hWindow: HWND; bm: TBitmap);
var
Left, Top, Width, Height: Word;
R: TRect;
dc: HDC;
lpPal: PLOGPALETTE;
begin
if not IsWindow(hWindow) then Exit;
GetWindowRect(hWindow, R);
Left := R.Left;
Top := R.Top;
Width := R.Right - R.Left;
Height := R.Bottom - R.Top;
bm.Width := Width;
bm.Height := Height;
dc := GetDc(0);
if (dc = 0) then
begin
Exit;
end;
if (GetDeviceCaps(dc, RASTERCAPS) and
RC_PALETTE = RC_PALETTE) then
begin
GetMem(lpPal,
SizeOf(TLOGPALETTE) +
(255 * SizeOf(TPALETTEENTRY)));
FillChar(lpPal^,
SizeOf(TLOGPALETTE) +
(255 * SizeOf(TPALETTEENTRY)),
#0);
lpPal^.palVersion := $300;
lpPal^.palNumEntries :=
GetSystemPaletteEntries(dc,
0,
256,
lpPal^.palPalEntry);
if (lpPal^.PalNumEntries <> 0) then
begin
bm.Palette := CreatePalette(lpPal^);
end;
FreeMem(lpPal, SizeOf(TLOGPALETTE) +
(255 * SizeOf(TPALETTEENTRY)));
end;
BitBlt(bm.Canvas.Handle,
0,
0,
Width,
Height,
Dc,
Left,
Top,
SRCCOPY);
ReleaseDc(0, dc);
end; Но он задачку не решает. Это все равно скриншот не окна, а области где это окно расположено. Соответственно, если поверх окна есть другое окно, изображение будет содержать это "другое" окно. Он получает область окна, но если оно перекрыто, то получается
-
> [3] ANTPro © (06.12.07 22:02)
Не понял...
-
> @!!ex © (06.12.07 22:06) [5]
Перебираешь все окна, выставляешь их на передний план и затем скриншот. ps честно говоря, непонятная затея...
-
> [6] turbouser © (06.12.07 22:09)
Если выставлять их на передний план, то юзер видит как это все происходит. Да и обратно окно уже не вернуть.... Затея банальна - делаю менеджер окон.
-
> @!!ex © (06.12.07 22:11) [7] > Затея банальна - делаю менеджер окон.
И при этом обязательно иметь скриншот? В висте есть такая возможность, не спорю, в мсдн наверняка можно найти информацию на эту тему. Но вот под 2к/ХР - сильно сомневаюсь, что такое возможно.
-
> [8] turbouser © (06.12.07 22:29)
Я же в [0] сказал что возможно... :( Не верите, см. TopDesk
-
procedure GetWindowBitmap(Wnd: HWND; Bmp: TBitmap);
var
R: TRect;
begin
GetWindowRect(Wnd, R);
Bmp.Width:= R.Right - R.Left;
Bmp.Height:= R.Bottom - R.Top;
Bmp.Canvas.Lock;
try
SendMessage(Wnd, WM_PRINT, Integer(Bmp.Canvas.Handle), PRF_NONCLIENT or PRF_CHECKVISIBLE or
PRF_CLIENT or PRF_ERASEBKGND or PRF_CHILDREN);
finally
Bmp.Canvas.Unlock;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Bitmap: TBitmap;
begin
Bitmap:=TBitmap.Create;
try
GetWindowBitmap(Handle,Bitmap);
Bitmap.SaveToFile('C:\1.bmp');
finally
Bitmap.Free;
end;
end; На XP и выше можно использовать функцию PrintWindow
-
> [10] Инс (06.12.07 23:06)
Хм. А вы уверены, что этот код работает? А если окно не обрабатывает сообщение WM_PRINT? Во всяком случае у меня получилось 12 белых прямоугольников после сохранения....
PrintWindow - это что? В хелпе не нашел...
-
> Хм. А вы уверены, что этот код работает?
С большинством окон работает, даже где-то в каком-то своем проекте использовал.
> PrintWindow - это что? В хелпе не нашел...
Плохо искали. В MSDN
-
> [10] Инс (06.12.07 23:06)
Ваш код действительно работает... Получает скриншот формы. А мой работать не хочет, сохраняет белые квадраты: procedure GetWindowBitmap(Wnd: HWND; Bmp: TBitmap); var R: TRect; begin GetWindowRect(Wnd, R); SetFocus(Wnd); Bmp.Width:= R.Right - R.Left; Bmp.Height:= R.Bottom - R.Top; Bmp.Canvas.Lock; try SendMessage(Wnd, WM_PRINT, Integer(Bmp.Canvas.Handle), PRF_NONCLIENT or PRF_CHECKVISIBLE or PRF_CLIENT or PRF_ERASEBKGND or PRF_CHILDREN); finally Bmp.Canvas.Unlock; end; end;
Function EnumWindowsProc(WND:HWND; LParam:Integer):Boolean; begin if IsWindowVisible(WND)=True then begin GetWindowBitmap(WND,BitMap); BitMap.SaveToFile('C:\Temp\'+IntTOStr(Wnd)+'.bmp'); end; Result:=True; end;
procedure TForm1.FormCreate(Sender: TObject); begin BitMap:=TBitMap.Create; EnumWindows(@EnumWindowsProc,0); BitMap.Free; end;
-
> Плохо искали. В MSDN
НЕту MSDN под рукой. :( поищу в онлайн MSDN'e.
-
> [9] @!!ex © (06.12.07 23:02) > Я же в [0] сказал что возможно... :(
Ну раз сказал :) Жаль что майкросовт об этом не знала, когда 9х и 2к писала :(
-
> [15] homm © (06.12.07 23:15)
Так я не от балды сказал. :) Есть пример работающей программы, которая это делает.
-
> [16] @!!ex © (06.12.07 23:18) > Есть пример работающей программы, которая это делает.
в ХП ?
-
> [17] homm © (06.12.07 23:23)
Да. Вроде в 2000 она тоже работает. TopDesk
-
> [18] @!!ex © (06.12.07 23:24)
Вроде?
|