Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.05.31;
Скачать: CL | DM;

Вниз

Снимок частично закрытого окна   Найти похожие ветки 

 
Bora.ru   (2007-09-17 20:32) [0]

Можно ли получить полный скриншот окна, если его определенную часть перекрывает другое окно? Или это принципиально невозможно?


 
Anatoly Podgoretsky ©   (2007-09-17 20:33) [1]

> Bora.ru  (17.09.2007 20:32:00)  [0]

Принципиально не возможно, только выводить на другое окно.


 
homm ©   (2007-09-17 21:28) [2]

> [1] Anatoly Podgoretsky ©   (17.09.07 20:33)
> Принципиально не возможно,

… но есть всякие частные случаи. Можно поиграться с SendMessage(WM_PAINT, 0, DC)


 
Dimaxx ©   (2007-09-18 00:11) [3]

А если попробовать получить хэндл активного окна, сделать активным нужное, снять скрин и "вернуть" активное приложение в фокус? Разве не сработает?


 
Dimaxx ©   (2007-09-18 00:13) [4]

Тьфу, хэндл не активного, а перекрывающего окна...


 
Германн ©   (2007-09-18 01:09) [5]


> Dimaxx ©   (18.09.07 00:13) [4]

Ждём-с ещё одно "Тьфу" :-)


 
Dimaxx ©   (2007-09-18 14:04) [6]

Хватит и одного "тьфу". Вернуть "на место" надо именно активное. :)


 
Инс ©   (2007-09-18 20:11) [7]

Можно. Только есть масса особенностей. Лучше всего обычно работает PrintWindow но сразу же получаем ограничение Win2000. Есть еще сообщение WM_PRINT но далеко не все окна его правильно обрабатывают. Можно попробывать еще что-то вроде такого:

type
 PPaintData = ^TPaintData;
 TPaintData = record
   Parent: HWND;
   DC: HDC;
 end;

procedure PaintWindowToDC(Wnd: HWND; Bmp: TBitmap);
var
 R: TRect;
 PD: TPaintData;

 function EnumWnd(Wnd: HWND; P: PPaintData): bool; stdcall;
 var
   SDC: integer;
   R: TRect;
   PD: TPaintData;
 begin
   try
     GetWindowRect(Wnd, R);
     Windows.ScreenToClient(P.Parent, R.TopLeft);
     SDC:= SaveDC(P.DC);
     try
       SetViewportOrgEx(P.DC, R.Left, R.Top, nil);
       SendMessage(Wnd, WM_ERASEBKGND, integer(P.DC), 0);
       SendMessage(Wnd, WM_PAINT, integer(P.DC), 0);
       PD.Parent:= Wnd;
       PD.DC:= P.DC;
       EnumChildWindows(Wnd, Addr(EnumWnd), integer(@PD));
     finally
       RestoreDC(P.DC, SDC);
     end;
     Result:= true;
   except
     Result:= false;
   end;
 end;

begin
 GetClientRect(Wnd, R);
 Bmp.Width:= R.Right;
 Bmp.Height:= R.Bottom;
 PD.Parent:= Wnd;
 Bmp.Canvas.Lock;
 try
   PD.DC:= Bmp.Canvas.Handle;
   SendMessage(Wnd, WM_ERASEBKGND, integer(PD.DC), 0);
   SendMessage(Wnd, WM_PAINT, integer(PD.DC), 0);
   EnumChildWindows(Wnd, Addr(EnumWnd), integer(@PD));
 finally
   Bmp.Canvas.Unlock;
 end;
end;

Функция не моя (копирайт - Набережных Сергей), сам не пробовал.


 
homm ©   (2007-09-18 20:25) [8]

      SetViewportOrgEx(P.DC, R.Left, R.Top, nil);
      SendMessage(Wnd, WM_ERASEBKGND, integer(P.DC), 0);
      SendMessage(Wnd, WM_PAINT, integer(P.DC), 0);


Не хватает еще, как минимум
SendMessage(Wnd, WM_PRINT, integer(P.DC), PRF_CLIENT);


 
homm ©   (2007-09-18 20:26) [9]

SendMessage(Wnd, WM_PRINT, integer(P.DC), PRF_CLIENT);
Т.е. наоборот,
PRF_NONCLIENT


 
Инс ©   (2007-09-18 20:48) [10]


> Не хватает еще, как минимум

Ну да, логично, но если использовать WM_PRINT, то можно вообще одной строкой кода отделаться.


 
homm ©   (2007-09-18 21:05) [11]

> [10] Инс ©   (18.09.07 20:48)
> Ну да, логично, но если использовать WM_PRINT, то можно
> вообще одной строкой кода отделаться.

Как раз нельзя. Принт понимают куда меньшее количество контролов, чем WM_PAINT, integer(P.DC). И уж совсем филосовское понимание сообщений у RichEdit, которому вообще все по барабану.


 
Инс ©   (2007-09-18 21:39) [12]


> [11] homm ©   (18.09.07 21:05)

Однажды, кстати, столкнулся с проблемой, где один контрол никак не хотел себя рисовать правильно, какое бы сообщение (WM_PAINT, WM_PRINT) ему не посылать. Причем контрол какой-то самопальный. Там проблема была оказалось в том, что в обработчике WM_PAINT прорисовка осуществлялась не на DC, который был передан в качестве параметра. Автор компонента заново получал DC с помощью GetDC(Handle) и рисовал на нем. Что получалось в результате вполне понятно - возвращался пустой квадрат, а контрол перерисовывался. Но PrintWindow, как ни странно, выдавал правильный результат. Интересно, как он работает, судя по этому эксперименту, не через WM_PRINT, как можно было бы подумать...


 
homm ©   (2007-09-18 21:48) [13]

> [12] Инс ©   (18.09.07 21:39)
> Интересно, как он работает, судя по этому эксперименту,
> не через WM_PRINT

Как ни странно,Ю в справке сказано, что именно через WM_PRINT. Вполне возможно врут :)


 
Инс ©   (2007-09-18 22:02) [14]


> Вполне возможно врут :)

Черт его знает. Видимо не врут, просто алгоритм сложнее, чем мы его себе представляем. GetWindowText тоже через WM_GETTEXT работает, но посылка сообщения почему-то дает правильный результат постабильнее...


 
Инс ©   (2007-09-18 22:10) [15]


> Вполне возможно врут :)

Скорее всего на более низком уровне PrintWindow работает, чем просто отослать сообщение.


 
homm ©   (2007-09-18 22:13) [16]

> [14] Инс ©   (18.09.07 22:02)
> Видимо не врут, просто алгоритм сложнее, чем мы его себе
> представляем.

Помоему в описании была (лень снова открывть) фраза «similar to WM_PRINT» :)


 
Инс ©   (2007-09-18 22:41) [17]


> [16] homm ©   (18.09.07 22:13)

А уж как мне лень, блин, кто бы мог только представить... :)

Remarks

This function is similar to WM_PRINT.


Плюс, я в [7] наврал немного. В WinXP она только появилась, если верить MSDN.


 
Charger ©   (2008-04-07 18:26) [18]

ап. :(
Приведенная функция PaintWindowToDC вообще ничего не снимает с приложения, только размеры определяет. Или я не правильно её вызываю?
PaintWindowToDC(wnd,image1.Picture.Bitmap);

Как я понял, проблема топика не решена?


 
Игорь Шевченко ©   (2008-04-08 10:02) [19]

не все йогурты умеют себя выводить на произвольный DC


 
Eraser ©   (2008-04-08 14:31) [20]

интересно, на каком принципе в висте превьюшки для панели задач сделаны?
одно точно, что винап, с включенным modern-skin там отображается без этого скина )


 
Charger ©   (2008-04-08 16:05) [21]

Ну то что не все, примем на веру, хотя поясните, какое приложение не выводит.
Вышеназванная функция ВООБЩЕ ничего не выводит.  Ни у какого приложения, даже не перекрытого. Ну непорядок это.

В висте то далеко, есть пример поближе. В ХР, Aston shell, тоже показывает превьюшки. Кстати от Винампа там только квадратик виден... но калькулятор, блокнот, окно прогресса тотал командера и прочее и прочее (кроме некоторых игр) выводит в актуальном состоянии. Вот КАК? На сайте Астона сказали, что не могут сказать этого. )
 WinSign показывает только следующие мессаги окну, когда для него генерится миниатюра:
000443:000209FC "Заголовок"  WM_PAINT Sent   (0,0)-(858,955)
000444:000209FC "Заголовок"  WM_NCPAINT Sent   wp=00000001!
000445:000209FC "Заголовок"  WM_GETTEXT Sent   510 bytes at 0012E014
000446:000209FC "Заголовок"  WM_PAINT Dispatched   (0,0)-(858,955)
000447:000209FC "Заголовок"  WM_PAINT Dispatched   (0,0)-(858,955)

Обычные сообщения, но когда я такое посылаю, WinSign показывает не тот результат, что-то вроде

000440:00140A4C "Form1"  WM_PAINT Sent   lp=0012F558!  (0,0)-(0,0)
000441:00140A4C "Form1"  WM_NCPAINT Sent   wp=00000001!
000442:00140A4C "Form1"  WM_PAINT Sent   wp=56011EE4!  (0,0)-(0,0)
 шлю кодом
SendMessage(wnd, WM_PAINT,0,longInt(@R));
SendMessage(wnd, WM_NCPAINT,1,0);

В общем не получается. Подскажите где неправ.


 
Charger ©   (2008-04-08 16:07) [22]

И еще, может кто-то разобратся в статье: http://www.fengyuan.com/article/wmprint.html ?


 
Charger ©   (2008-05-12 12:16) [23]

Удалено модератором
Примечание: Создание пустых сообщений



Страницы: 1 вся ветка

Текущий архив: 2009.05.31;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.013 c
2-1239706578
Kolan
2009-04-14 14:56
2009.05.31
Как запретить автоудаление подчиненных объектов?


2-1239329769
trueTRIx
2009-04-10 06:16
2009.05.31
Как заменить курсор на свой


15-1237875001
Урсулапов_
2009-03-24 09:10
2009.05.31
Программа, которая распознает тип файла без расширения


15-1235984413
Dennis I. Komarov
2009-03-02 12:00
2009.05.31
Web Server Application +CGI + Cookie


15-1237966822
Немо
2009-03-25 10:40
2009.05.31
Как воевал - с_порно, как надо?