А вот интересно, в Win9x/ME можно подменить оконную функцию (чужую разумеется)? У меня что-то не получается (в ME). Либо она не подменяется, либо программа (та которой подменяют) "вылетает" с ошибкой. Хотя в XP всё работает отлично. На других версиях не проверял. Есть соображения?
Windows 95/98/Me: The SetWindowLong function may fail if the window specified by the hWnd parameter does not belong to the same process as the calling thread.
а что тогда означает: можно подменить оконную функцию (чужую разумеется)? или это: либо программа (та которой подменяют) "вылетает" Насколько я понял, ты все-таки меняешь из другого процесса (из другой программы - той, которой подменяют)
Из другой. Только это библиотека, которую процесс сам и загружает. И вроде бы всё просто, меняй что хочешь на здоровье. Тестовая програмка, имитирующая нужный процесс, всё прекрасно загружает, и работает с подменённой функцией отлично. А тот процесс, что мне нужен, после подмены выпадает в осадок (причём, что интересно, только в WinME, в XP всё отлично). Вот я и думаю, в чём тут дело.
Я уже запутался, что, куда и откуда ты грузишь Попробуй как я делал: 1.Запускаю exe 2.Из exe загружаю dll с хуком 3.В dll нахожу интересующее меня окно (его hWnd) 4.Для этого hWnd инсталлирую хук на WH_CALLWNDPROC 5.В CallWndProc (в этой же dll) по первому же вызову с нужным мне hWnd я определяюсь, что нахожусь в пространстве процесса, которому принадлежит hWnd 6.Теперь из CallWndProc загружаю вторую dll (LoadLibrary) с новой оконной процедурой, она грузится в пространство этого hWnd. 7.Из первой же dll, пока она ещё в пространстве этого hWnd, вызываю ф-цию из второй dll (RedirectWndProc), которая делает SetWindowLong с GWL_WNDPROC. 8. Деинсталлирую хук, на всяк случай FreeLibrary для первой dll и завершаю exe. Всё. P.S. По месту должны быть вставлены Sleep, чтобы dll с хуком успела загрузиться перед вызовом её функций, и соответственно она должна быть с разделяемыми секциями.
Извиняюсь, что запутал. Вот всё по пунктам: Есть программа, главному окну которой, нужно подменить оконную функцию. Эта программа сама загружает мою DLL (никаких exe и хуков, чтобы попасть в процесс этой программы, не требуется) с помощью LoadLibraryEx. В моей DLL содержится новая оконная функция, из которой вызывается CallWindowProc. По DLL_PROCESS_ATTACH, вызывается SetWindowLong, устанавливающая новую (мою) оконную функцию. Вопрос: Почему так получается, что в Windows XP всё работает, а в Windows ME программа вылетает с ошибкой? При этом программа-эмулятор (написанная мной) первой программы, точно также загружающая мою DLL, прекрасно работает в обеих версиях Windows. Вот хотелось бы узнать, возможные причины ошибок в Windows ME, при том что их нет в Windows XP. P.S. Надеюсь не запутал ещё больше =)
Всё оказалось до ужаса просто. Стек! Выходя из процедуры сабклассинга, нужно чистить стек, освобождая 16 байт, иначе всё падает, но, как выяснилось не везде. У меня XP(SP2), у товарища тоже самое, у меня работало без "retn 10h", у него нет. Вот такие чудеса...
Sl4v4 А что в этом удивительного? Стек нужно чистить не только в 9xMe и не только в WndProc Коль скоро у тебя stdcall. А то, что в XP не падает - так это известный факт, что стек можно оставить несбалансированным (в определенных границах). Т.е. можно от фонаря внутри WndProc добавить инструкцию add esp,NNNN. Насколько помню, NNNN где-то в пределах 40.