![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как получиьт изображение окна?
@!!ex © (2007-12-06 21:27:00)Задача.
Есть несколько открытых окон. Некоторые видны полностью, некоторые частично перекрыты, некоторые вообще не видны под другими окнами.
Задача в том, чтобы в программе получит скриншот для всех окон.
Способ точно есть, но я даже не представляю куда копать.
@!!ex (2007-12-06 23:24:00) [21]> [17] homm © (06.12.07 23:23)
Да. Вроде в 2000 она тоже работает. TopDesk
homm (2007-12-06 23:23:00) [22]> [16] @!!ex © (06.12.07 23:18)
> Есть пример работающей программы, которая это делает.
в ХП ?
@!!ex (2007-12-06 23:18:00) [23]> [15] homm © (06.12.07 23:15)
Так я не от балды сказал. :)
Есть пример работающей программы, которая это делает.
homm (2007-12-06 23:15:00) [24]> [9] @!!ex © (06.12.07 23:02)
> Я же в [0] сказал что возможно... :(
Ну раз сказал :)
Жаль что майкросовт об этом не знала, когда 9х и 2к писала :(
@!!ex (2007-12-06 23:14:00) [25]> Плохо искали. В MSDN
НЕту MSDN под рукой. :(
поищу в онлайн MSDN'e.
@!!ex (2007-12-06 23:13:00) [26]> [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;
Ins (2007-12-06 23:12:00) [27]
> Хм. А вы уверены, что этот код работает?
С большинством окон работает, даже где-то в каком-то своем проекте использовал.
> PrintWindow - это что? В хелпе не нашел...
Плохо искали. В MSDN
@!!ex (2007-12-06 23:09:00) [28]> [10] Инс (06.12.07 23:06)
Хм. А вы уверены, что этот код работает?
А если окно не обрабатывает сообщение WM_PRINT?
Во всяком случае у меня получилось 12 белых прямоугольников после сохранения....
PrintWindow - это что? В хелпе не нашел...
Инс (2007-12-06 23:06:00) [29]
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
@!!ex (2007-12-06 23:02:00) [30]> [8] turbouser © (06.12.07 22:29)
Я же в [0] сказал что возможно... :(
Не верите, см. TopDesk
turbouser (2007-12-06 22:29:00) [31]
> @!!ex © (06.12.07 22:11) [7]
> Затея банальна - делаю менеджер окон.
И при этом обязательно иметь скриншот?
В висте есть такая возможность, не спорю, в мсдн наверняка
можно найти информацию на эту тему.
Но вот под 2к/ХР - сильно сомневаюсь, что такое возможно.
@!!ex (2007-12-06 22:11:00) [32]> [6] turbouser © (06.12.07 22:09)
Если выставлять их на передний план, то юзер видит как это все происходит. Да и обратно окно уже не вернуть....
Затея банальна - делаю менеджер окон.
turbouser (2007-12-06 22:09:00) [33]
> @!!ex © (06.12.07 22:06) [5]
Перебираешь все окна, выставляешь их на передний план и затем скриншот.
ps
честно говоря, непонятная затея...
@!!ex (2007-12-06 22:06:00) [34]> [3] ANTPro © (06.12.07 22:02)
Не понял...
@!!ex (2007-12-06 22:03:00) [35]Нашел вот такой код:
procedure ScreenShot(hWindow: HWND; bm: TBitmap);
var
Left, Top, Width, Height: Word;
R: TRect;
dc: HDC;
lpPal: PLOGPALETTE;
begin
{Check if valid window handle}
if not IsWindow(hWindow) then Exit;
{Retrieves the rectangular coordinates of the specified window}
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;
{get the screen dc}
dc := GetDc(0);
if (dc = 0) then
begin
Exit;
end;
{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,
Left,
Top,
SRCCOPY);
{release the screen dc}
ReleaseDc(0, dc);
end;
Но он задачку не решает.
Это все равно скриншот не окна, а области где это окно расположено. Соответственно, если поверх окна есть другое окно, изображение будет содержать это "другое" окно.
Он получает область окна, но если оно перекрыто, то получается
ANTPro (2007-12-06 22:02:00) [36]> [2] @!!ex © (06.12.07 21:43)
Бежать по всем верхним видимым окнам и сохранять нарисованное на DC?
@!!ex (2007-12-06 21:43:00) [37]> [1] Черный Шаман (06.12.07 21:42)
Каждого окна.
Черный Шаман (2007-12-06 21:42:00) [38]Тебе скриншот всего десктопа или каждого из окон?