Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
15-1214988339
Dennis I. Komarov
2008-07-02 12:45
2008.08.24
У ICQ опять чегото поменяли?


15-1215157270
Gleb
2008-07-04 11:41
2008.08.24
Есть работа


15-1215492465
homm
2008-07-08 08:47
2008.08.24
Интеграция .reg-файла в реестр


2-1216717555
Vlad Oshin
2008-07-22 13:05
2008.08.24
то работает, то не работает. Не объясните почему?


2-1216503960
batya-x
2008-07-20 01:46
2008.08.24
глюк





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский