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

Вниз

Win98 + AlphaBlend = ?   Найти похожие ветки 

 
Dib@zol ©   (2008-02-11 09:24) [0]

Доброго времени суток экспертам!

В который раз решил почесать ухо пяткой - на этот раз пытаюсь реализовать прозрачность окон в Windows 98. Первоначальный план действий таков:
 1. ДЛЛ-инжектом переопределить API-функцию EndPaint.
 2. В функции, на которую подменяем, сначала вызвать BitBLT: копируем с DC, указанного в структуре PAINTSTRUCT, на некий промежуточный DC, на который повешен DIB с разрешением, равным экранному (координаты, куда копировать, будут полуены с помошью GetWindowRect). После этого выполнить оригинальный EndPaint.
 3. Повторить для всех окон (EnumWindows в массив + GetWindowThreadProcessID).
 4. Вывести часть промежуточного DC, ограниченную нашим окном, на сопстно окно, с заданным альфаканалом.

Ну тык вот, комментарии и вопросы:
С самого начала, я хотел использовать WM_PRINT, т.к. PrintWindow в Win98 не поддерживается. Однако, как показала практика, WM_PRINT не поддерживается также - DefWindowProc на него никак не реагирует (не выводит в указанный DC картинку окна). Может быть, для его использования в 98-м надо соблюсти некоторые условия? Если кто-нибудь располагает подобной инфой, отпишитесь, какие (про то, что его обработчик можно дописать самостоятельно с помощью softICE, я знаю - юмористы идут лесом). Ещё хочется знать, использует ли DefWindowProc тот же EndPaint, и в каких случаях. Например, я не знаю, как отрисовывается неклиентская область окна в системном обработчике WM_NCPAINT. Если DefWindowProc завершает отрисовку не с помощью EndPaint, а чем-нибудь другим, прошу привести имя этой функции, для того, чтоб в проге её тоже перекрыть. Затем, вопрос про то, зачем такие сложности: нет бы взял обычный БитБЛТ и просто надстраивал полученную картинку при перемещении? На это отвечаю - это не будет прозрачностью в полном смысле слова, т.к. лежащее внизу окно вполне может ещё сто раз перерисоваться, а на состоянии нашего окна это никак не отразится (перерисовываться, лёжа ниже нашего окна оно будет потому что в WNDCLASSEX у нас стоит флаг WS_EX_TRANSPARENT - по заверениям МСДН, он заставляет все нижележащие перерисовываться, "не замечая" окна с этим флагом). Более того, на десктопе могут появиться новые окна, или исчезнуть старые, что на нашем окне тогда тоже будет не заметно. Тут, кстати, проблема - как отловить их создание и уничтожение, по видимому нужно будет пользовать глобальные хуки.
И наконец, внимание главный вопрос: нельзя ли всё описанное сделать как-нибудь проще? Ведь при копировании, скажем, методом перетаскивания, перемещаемая группа файлов становится полупрозрачной, и свободно может перемещаться за курсором по экрану, не сжирая 70% процессорного времени. Если кто-нибудь знает, как это реализуется, огромная просьба поделиться. Наверняка, это какая-нибудь недокументированная функция. Если же альтернативного способа нет - тогда прошу высказать соображения относительно того, верно ли составлен первоначальный план, и какие у него могут быть "подводные камни". А то оч весело будет потратить на код всю неделю, а потом выяснить, что из-за упущения какой-нибудь мизерной детали прога при запуске рухнет нафиг и повалит за собой систему :)

уф, вроде всё.


 
Ins ©   (2008-02-11 12:01) [1]

А зачем сейчас заморачиваться на Win98?


 
Dib@zol ©   (2008-02-11 12:58) [2]

Ну вообще мне это нужно чисто для себя. ХР недолюбливаю по религиозным соображениям. Всё никак не могу оставить мечту написать генератор вистяного UI для 98-го %)


 
Игорь Шевченко ©   (2008-02-11 13:18) [3]


> юмористы идут лесом


Сдается мне, что лесом пойдет кто-то еще


 
Sapersky   (2008-02-11 13:47) [4]

На Королевстве была статья по реализации прозрачности окон в 98. Как конкретно там сделано - не помню, особо не вчитывался.
Кстати, API-функция AlphaBlend (если собираешься её использовать) под Win98 работает нестабильно, на некоторых видеокартах может вообще приводить к вылету программы.


 
{RASkov} ©   (2008-02-11 13:53) [5]

> может вообще приводить к вылету программы

Отсюда следует: А оно вообще нужно..... и без того "глючную ось"(по сравнению с ХР, например) - делать еще менее стабильной????
:о)


 
Dib@zol ©   (2008-02-11 13:57) [6]

А я AlphaBlend и не собираюсь использовать. Я просто повешу на промежуточный DC DIB-битмап, получу сцылку на первый его байт и буду смешивать вручную. Тем более так оно быстрее.


 
Ins ©   (2008-02-11 14:01) [7]


> На Королевстве была статья по реализации прозрачности окон
> в 98.

Вот она:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=30

Но если в 1999-м это и было актуально, то сейчас... Для самообразования разве что. Хотя ИМХО, лучше купить себе штангу. Будет так же тяжело, но полезно для здоровья :)


 
Sapersky   (2008-02-11 14:59) [8]

при копировании, скажем, методом перетаскивания, перемещаемая группа файлов становится полупрозрачной, и свободно может перемещаться за курсором по экрану, не сжирая 70% процессорного времени.

В принципе, может быть та же AlphaBlend. Я несколько поторопился записать её в "глюкавые" - проверял только попиксельную прозрачность, с альфа-каналом, а при выводе копируемых файлов используется фиксированный коэффициент для всей картинки. Возможно, в этом режиме она работает стабильнее. И достаточно быстро за счёт того, что умеет рисовать на DC, не нужен промежуточный буфер.


 
Dib@zol ©   (2008-02-11 16:10) [9]

> [7] Ins ©   (11.02.08 14:01)

Пример любопытный. однако это и есть тот самый "просто BitBLT". Поэтому он мне не подходит :(

В общем, надо писать ДЛЛку для внедрения. Поделитесь плиз, у кого есть теория по данному (DLL-инжект и подмена функций API) вопросу! Ибо в Гугле я нашёл только код. Теоретическая часть либо отсутствует, либо слишком невразумительна.


 
ketmar ©   (2008-02-11 16:17) [10]

>[9] Dib@zol © (2008-02-11 16:10:00)
а будет у тебя, бриллиантовый, огромная проблема с hijacking в Win9x. потому что, яхонтовый, страницы керналя в win9x не copy-on-write. остаётся только подмена IAT (сам найдёшь?), и это не есть удобно.

теория состоит из:
а) как сделать dll-injector (статей выше крыши, разной степени идиотичности и умности);
б) формата PE и IAT в частности (снова статей немеряно);
в) … всё, аднака.

---
Understanding is not required. Only obedience.


 
Dib@zol ©   (2008-02-12 10:19) [11]

Итак, уря товарищи - ДЛЛь написана. Теперь появился еще один вопрос: как её дебажить? Особенно когда она уже была спроецирована в чужое АП, проработала некоторое время и вызвала еррор :)

Принцип работы таков: ставится глобальный хук на сообщения. И наша ДЛЛь проецируетсо в АП всех процессов, принимающих сообщения, и инициализируется. В инициализации мы лезем в таблицу импорта данного процесса и подменяем EndPaint на свою функцию, которая перед тем, как вызвать оригинальный EndPaint, передаёт на скормленный ей ранее DC все данные с DC "жертвы". Вроде в теории всё хорошо, но вот проблема:

procedure LibraryProc(Reason: Integer);
begin
 case Reason of
   DLL_THREAD_ATTACH:
     begin
       InterceptFunctions;
     end;

   DLL_THREAD_DETACH:
     begin
       MessageBox(0, "Detaching!", "Notify", 0);
       UninterceptFunctions;
     end;
 end;
end;


Это нечто наподобие WindowProc, только для ДЛЛ. Ну тык вот:

begin
 DLLProc:=@LibraryProc;
 Hk:=SetWindowsHookEx(WH_CALLWNDPROC, @CwdProc, HInstance, 0);
end.


Я в DLLProc прописываю адрес етой нашей LibraryProc - а ноль реакции :( Я при приёме этих "сообщений" заставил выводить МесседжБокс - а фигушки :( Не выводится... Что я делаю не так?


 
Dib@zol ©   (2008-02-12 12:39) [12]

Up.


 
ketmar ©   (2008-02-12 13:22) [13]

>[11] Dib@zol © (2008-02-12 10:19:00)
>как её дебажить?

логи писать.

>в DLLProc прописываю адрес етой нашей LibraryProc
а что это за бред вообще у тебя в DLLProc написан? ты можешь внятно пояснить, нафига ты пытаешься на каждый поток заинитить перехватчик и потом отпустить?

---
Understanding is not required. Only obedience.


 
Dib@zol ©   (2008-02-12 13:38) [14]

Могу. DLL_PROCESS_ATTACH и DLL_PROCESS_DETACH тоже не пашут, и я выложил код, в котором пытался добиться вызова функции перехвата.

А про логи - у меня при AV всё рушится нафик и файл есссно не закрывается. Лог теряецо целиком. Вот почитал в соседней ветске про FlushFileBuffers - ок, будем пробовать.


 
ketmar ©   (2008-02-12 13:58) [15]

>[14] Dib@zol © (2008-02-12 13:38:00)
>у меня при AV всё рушится нафик и файл есссно не закрывается

изверг. лог-файл открывается и закрывается для каждой записи. ибо лог. ибо отладка.

DLL_PROCESS_ATTACH «пахать» и не может, потому как кто его зовёт-то?

далее. «не пашут» — неинформативно. в 17-й строке ошибка. вроде не первый день на форуме, а опять на грубость нарываешься…

---
Understanding is not required. Only obedience.


 
Ins ©   (2008-02-12 14:01) [16]

После DLLProc:=@LibraryProc; вставь вызов этой процедуры с параметром  DLL_PROCESS_ATTACH.


 
Sapersky   (2008-02-12 14:57) [17]

Теперь появился еще один вопрос: как её дебажить?

Можно написать тестовое приложение, которое "само отдаётся", т.е. просто грузит эту самую DLL безо всяких внедрений. Это, конечно, не совсем "боевой" режим, зато c нормальной отладкой.



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

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

Наверх





Память: 0.51 MB
Время: 0.04 c
15-1201715595
oxffff
2008-01-30 20:53
2008.03.09
Ищу работу.


15-1201856014
GRAND25
2008-02-01 11:53
2008.03.09
Динамо - обладатель Кубка Первого Канала!


4-1184561505
MultIfleX
2007-07-16 08:51
2008.03.09
"Системная" панель ??


2-1202810874
Аян
2008-02-12 13:07
2008.03.09
нужна подсказка


2-1202756973
Jimmy
2008-02-11 22:09
2008.03.09
Событие при перемещении формы





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