Форум: "Начинающим";
Текущий архив: 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