Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как получиьт изображение окна?


Страницы:   1 2

@!!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]

Тебе скриншот всего десктопа или каждого из окон?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо