Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.03.09;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.012 c
10-1143624416
pavel_guzhanov
2006-03-29 13:26
2008.03.09
Как изменить шрифт в excel


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


15-1201870682
oxffff
2008-02-01 15:58
2008.03.09
A million licenses of RAD Studio for Russia


10-1132058772
ForgotPass
2005-11-15 15:46
2008.03.09
COM-объект FlashGet ("JetCar.Netscape")


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