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

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

Снимок частично закрытого окна [D6, WinXP]


Страницы:   1 2

Bora.ru ©   (2007-09-17 20:32:00) 

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


Charger   (2008-05-12 12:16:00) [1]

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


Charger   (2008-04-08 16:07:00) [2]

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


Charger   (2008-04-08 16:05:00) [3]

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

В висте то далеко, есть пример поближе. В ХР, 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);

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


Eraser   (2008-04-08 14:31:00) [4]

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


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

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


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

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

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


Инс   (2007-09-18 22:41:00) [7]


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

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

Remarks

This function is similar to WM_PRINT.


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


homm   (2007-09-18 22:13:00) [8]

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

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


Инс   (2007-09-18 22:10:00) [9]


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

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


Инс   (2007-09-18 22:02:00) [10]


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

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


homm   (2007-09-18 21:48:00) [11]

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

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


Инс   (2007-09-18 21:39:00) [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:05:00) [13]

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

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


Инс   (2007-09-18 20:48:00) [14]


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

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


homm   (2007-09-18 20:26:00) [15]

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


homm   (2007-09-18 20:25:00) [16]

      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);


Инс   (2007-09-18 20:11:00) [17]

Можно. Только есть масса особенностей. Лучше всего обычно работает 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;

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


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

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


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


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

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


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

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


Страницы:   1 2

Наверх

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