Форум: "Основная";
Текущий архив: 2008.08.24;
Скачать: [xml.tar.bz2];
ВнизКак получиьт изображение окна? Найти похожие ветки
← →
@!!ex © (2007-12-06 21:27) [0]Задача.
Есть несколько открытых окон. Некоторые видны полностью, некоторые частично перекрыты, некоторые вообще не видны под другими окнами.
Задача в том, чтобы в программе получит скриншот для всех окон.
Способ точно есть, но я даже не представляю куда копать.
← →
Черный Шаман (2007-12-06 21:42) [1]Тебе скриншот всего десктопа или каждого из окон?
← →
@!!ex © (2007-12-06 21:43) [2]> [1] Черный Шаман (06.12.07 21:42)
Каждого окна.
← →
ANTPro © (2007-12-06 22:02) [3]> [2] @!!ex © (06.12.07 21:43)
Бежать по всем верхним видимым окнам и сохранять нарисованное на DC?
← →
@!!ex © (2007-12-06 22:03) [4]Нашел вот такой код:
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;
Но он задачку не решает.
Это все равно скриншот не окна, а области где это окно расположено. Соответственно, если поверх окна есть другое окно, изображение будет содержать это "другое" окно.
Он получает область окна, но если оно перекрыто, то получается
← →
@!!ex © (2007-12-06 22:06) [5]> [3] ANTPro © (06.12.07 22:02)
Не понял...
← →
turbouser © (2007-12-06 22:09) [6]
> @!!ex © (06.12.07 22:06) [5]
Перебираешь все окна, выставляешь их на передний план и затем скриншот.
ps
честно говоря, непонятная затея...
← →
@!!ex © (2007-12-06 22:11) [7]> [6] turbouser © (06.12.07 22:09)
Если выставлять их на передний план, то юзер видит как это все происходит. Да и обратно окно уже не вернуть....
Затея банальна - делаю менеджер окон.
← →
turbouser © (2007-12-06 22:29) [8]
> @!!ex © (06.12.07 22:11) [7]
> Затея банальна - делаю менеджер окон.
И при этом обязательно иметь скриншот?
В висте есть такая возможность, не спорю, в мсдн наверняка
можно найти информацию на эту тему.
Но вот под 2к/ХР - сильно сомневаюсь, что такое возможно.
← →
@!!ex © (2007-12-06 23:02) [9]> [8] turbouser © (06.12.07 22:29)
Я же в [0] сказал что возможно... :(
Не верите, см. TopDesk
← →
Инс (2007-12-06 23:06) [10]
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:09) [11]> [10] Инс (06.12.07 23:06)
Хм. А вы уверены, что этот код работает?
А если окно не обрабатывает сообщение WM_PRINT?
Во всяком случае у меня получилось 12 белых прямоугольников после сохранения....
PrintWindow - это что? В хелпе не нашел...
← →
Ins © (2007-12-06 23:12) [12]
> Хм. А вы уверены, что этот код работает?
С большинством окон работает, даже где-то в каком-то своем проекте использовал.
> PrintWindow - это что? В хелпе не нашел...
Плохо искали. В MSDN
← →
@!!ex © (2007-12-06 23:13) [13]> [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;
← →
@!!ex © (2007-12-06 23:14) [14]> Плохо искали. В MSDN
НЕту MSDN под рукой. :(
поищу в онлайн MSDN"e.
← →
homm © (2007-12-06 23:15) [15]> [9] @!!ex © (06.12.07 23:02)
> Я же в [0] сказал что возможно... :(
Ну раз сказал :)
Жаль что майкросовт об этом не знала, когда 9х и 2к писала :(
← →
@!!ex © (2007-12-06 23:18) [16]> [15] homm © (06.12.07 23:15)
Так я не от балды сказал. :)
Есть пример работающей программы, которая это делает.
← →
homm © (2007-12-06 23:23) [17]> [16] @!!ex © (06.12.07 23:18)
> Есть пример работающей программы, которая это делает.
в ХП ?
← →
@!!ex © (2007-12-06 23:24) [18]> [17] homm © (06.12.07 23:23)
Да. Вроде в 2000 она тоже работает. TopDesk
← →
homm © (2007-12-06 23:25) [19]> [18] @!!ex © (06.12.07 23:24)
Вроде?
← →
@!!ex © (2007-12-06 23:27) [20]> [19] homm © (06.12.07 23:25)
Под XP она работает. Если я правильно помню, под 2000 тоже.
← →
@!!ex © (2007-12-06 23:27) [21]Ты так докапываешься, какбудто я себя зарекомендовал как брехун редкостный.
← →
homm © (2007-12-06 23:34) [22]> [20] @!!ex © (06.12.07 23:27)
http://soft.mydiv.net/win/download-TopDesk.html
???
у меня при запуске она посемуто все окна передернула на верх по очереди в нужных размеров. Не догадываешся, зачем? :)
← →
@!!ex © (2007-12-06 23:35) [23]Инс, спасибо!
PrintWindow делает то что нужно!! Правда работает непрозрачно, явно чето над окнами творит, но результата достигает! что и нужно!
← →
@!!ex © (2007-12-06 23:36) [24]> [22] homm © (06.12.07 23:34)
При запуске чего?
← →
homm © (2007-12-06 23:37) [25]> [24] @!!ex © (06.12.07 23:36)
При запуске TopDesk.
← →
turbouser © (2007-12-06 23:39) [26]
> homm © (06.12.07 23:34) [22]
Я же говорил :))
← →
@!!ex © (2007-12-06 23:41) [27]> [25] homm © (06.12.07 23:37)
Ну и как окна которые были видимы при запуске TopDesk скажутся на переключении окон в процессе работы?
Фича в том, что даже если окно обновилось на заднем фоне, то при переключении с помощью TopDesk"а оно все равно будет с корректной информацией.
← →
@!!ex © (2007-12-06 23:42) [28]> Я же говорил :))
Ты был не прав.
Читай 27. В процессе работы он никакие окна на передний план не выносит.
← →
@!!ex © (2007-12-06 23:53) [29]Ну короч вопрос решенный.
PrintWindow получает изображения любого окна.
Единственно, после работы нужно InvalidateRect(0,nil,true); сделатЬ, чтобы изображение на экране было нормальное.
← →
homm © (2007-12-06 23:54) [30]> [27] @!!ex © (06.12.07 23:41)
> Фича в том, что даже если окно обновилось на заднем фоне,
> то при переключении с помощью TopDesk"а оно все равно будет
> с корректной информацией.
Мое мнение: обновление происходит раз при старте, и когда контекст переключен на другую поверхность, и с первичным можно делать все, что угодно, ставя окна на паредний план.
← →
@!!ex © (2007-12-06 23:55) [31]> [30] homm © (06.12.07 23:54)
PrintWindow работает заметно быстрее чем перебор окон у TopDesk"a. так что это не правильный метод, ИМХО
← →
homm © (2007-12-06 23:58) [32]> [31] @!!ex © (06.12.07 23:55)
> PrintWindow работает заметно быстрее чем перебор окон у
> TopDesk"a
Справку по PrintWindow внимательно читал? Устраивают ограничения? Ты вроде хотел, что-бы в 2к тоже работало.
← →
turbouser © (2007-12-07 00:55) [33]
> @!!ex ©
Заставил таки меня влезть в мсдн :-)
← →
KSergey © (2007-12-07 07:10) [34]Прикольно, при этом написано, что WM_PRINT поддержана на NT 4.0 and later, а вот PrintWindow - XP and .NET Server.
Однако же: This function [PrintWindow] is similar to WM_PRINT
← →
ЗапомниСынок (2007-12-07 09:32) [35]Я в свое время хотел написать простенький бот для PartyPoker, пытался считывать инфу со стола, несколько дней возился, пытаясь снять скрин-шот с закрытого окна, так и не удалось. Оказывается плохо искал...
← →
@!!ex © (2007-12-07 10:58) [36]> [34] KSergey © (07.12.07 07:10)
Может быть фича в том, что PrintWindow хитро окна перебирает. Во всяком случае визуально это очень быстрая операция. Скорее всего такой перебор возможен только через хитрую функциЮ, которой раньше не было.
> [35] ЗапомниСынок (07.12.07 09:32)
Не факт, что с закрытыми окнами будет работать, с перекрытыми точно работает. Еще вопрос как оно будет с StayOnTop. Но это легко проверяется.
← →
@!!ex © (2007-12-07 11:00) [37]С invisible окон тоже скриншот снимается! *COOL* :)
← →
Sapersky (2007-12-07 14:15) [38]Есть ещё такая библиотека SPrintWindow, которая, как утверждает автор, может работать и в 2000, но она, похоже, так и не вышла из состояния "беты". С учётом того, что используется хакерский метод (собственный драйвер), это вызывает определённые опасения...
http://expire.free.fr/board/index.php?showtopic=109
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2008.08.24;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.041 c