Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2009.05.31;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "WinAPI";
Текущий архив: 2009.05.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.006 c
3-1222062150
Юрий Катунов
2008-09-22 09:42
2009.05.31
Сортировка в DBGrid


15-1237877089
{RASkov}
2009-03-24 09:44
2009.05.31
Настройка сетевого принтера


2-1239687223
Ulugbek
2009-04-14 09:33
2009.05.31
как сделать Max lenght Field в DbGride?


9-1180082560
@!!ex
2007-05-25 12:42
2009.05.31
Переброска изображения между Рендеринг Таргетами.


4-1188989858
Cj
2007-09-05 14:57
2009.05.31
Как получить путь к файлу...





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский