![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Снимок частично закрытого окна [D6, WinXP]
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]Тьфу, хэндл не активного, а перекрывающего окна...