Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.06.2011, 23:35   #11
Silver_S
Форумчанин
 
Регистрация: 14.03.2011
Сообщений: 104
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
ничего подобного про С++ то не надо говорить.
WinAPI использует это соглашение о вызове, но не С++.
Проверил в C++Builder® XE. функции, у которых имеется директива _fastcall, передают параметры по одноименному соглашению, используемому в делфи. Без этой директивы, т е. по умолчанию, параметры передаются по соглашению stdcall.

Последний раз редактировалось Silver_S; 17.06.2011 в 00:29.
Silver_S вне форума Ответить с цитированием
Старый 16.06.2011, 23:50   #12
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

Silver_S
Массив я планировал заменить списком. Тут он не нужен.
А вот то, что функция называлась CallWindowProc, это забавно :D Сменил - ошибка та же. Только теперь в функцию один раз входит и вылетает (раньше и правда рекурсия была)
Вот хук (максимально урезал его) и лог из формы
Код:
uses
  Windows, messages, Classes, SysUtils;

var
  HookHandle: HHOOK = 0;
  pnt: Cardinal;


function MyWndProc(PrevWndProc: Pointer; Wnd: HWnd; Msg, wParam: Word; lParam: LRESULT): LRESULT;
begin
  SendMessage(FindWindow(nil, 'Form1'), WM_USER+2, Integer(pnt),0);
  result:=CallWindowProc(Pointer(pnt), Wnd, msg, wParam, lParam);
end;

function CBTProc(CODE, WParam, LParam: DWORD): DWORD; stdcall;
var
  wnd: HWND;
begin
  if CODE < 0 then
  begin
    result := CallNextHookEx(HookHandle, CODE, WParam, LParam);
    exit;
  end;

  wnd := WParam;
  if CODE = HCBT_ACTIVATE then
  begin
    if wnd = 0 then
    begin
      result := CallNextHookEx(HookHandle, CODE, WParam, LParam);
      exit;
    end;

    SendMessage(FindWindow(nil, 'Form1'), WM_USER+1, wnd,0);

    pnt:=GetWindowLongPtr(wnd, GWLP_WNDPROC);
    SendMessage(FindWindow(nil, 'Form1'), WM_USER+2, pnt,0);
    SetWindowLongPtr(wnd, GWL_WNDPROC, Integer(@MyWndProc));

    result:=0;
  end;

  if CODE = HCBT_DESTROYWND then
  begin
     SendMessage(FindWindow(nil, 'Form1'), WM_USER+2, 9999,0);
  end;

  result := CallNextHookEx(HookHandle, CODE, WParam, LParam);
end;

procedure SetHook(wnd: HWND); stdcall; export;
var
  pid: Cardinal;
begin
  pid:=GetWindowThreadProcessId(wnd);
  if HookHandle=0 then
    HookHandle:=SetWindowsHookEx(WH_CBT, @CBTProc, hInstance, pid);
end;

procedure DelHook; stdcall; export;
begin
  if HookHandle <> 0 then UnhookWindowsHookEx(HookHandle);
   HookHandle:=0;
end;

function IsActive:boolean; stdcall; export;
begin
  Result:=true;
  if HookHandle=0 then
    Result:=false;
end;
Вот лог из формы
Цитата:
6753294 found
DLL injected succesfully
6753294 window sent message
2036958 - это из обработки ACTIVATE
2036958 - это из новой функции (т.е. это нужный указатель)
TwiX вне форума Ответить с цитированием
Старый 17.06.2011, 00:16   #13
Silver_S
Форумчанин
 
Регистрация: 14.03.2011
Сообщений: 104
По умолчанию

У каждого окна, возможно, изначально была своя уникальная процедура окна, так как визуальные библиотеки (VCL etc) активно используют SetWindowLongPtr. Вы же отдаете все параметры в процедуру, сохраненную в pnt. Думаю, массив нужен. Чтоб для каждого окна вы могли вызвать его оригинальную процедуру.
Должно быть примерно так:
Код:
MyWndProc(Wnd: HWnd; Msg, wParam, lParam: LongInt): LRESULT; stdcall;
У вас 2 вызова SendMessage в ACTIVATE, поэтому handle 2036958 приходит 2 раза.

Если все заработает, то ваш лог сообщений может просто "захлебнуться", так как окну шлются десятки - тысячи сообщений ежесекундно. Лучше сделать просто счетчик.

Последний раз редактировалось Silver_S; 17.06.2011 в 00:40.
Silver_S вне форума Ответить с цитированием
Старый 17.06.2011, 00:41   #14
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

Зачем масив - мне бы хотя бы с одним окном разобраться? Активейт происходит только при одном клике на блокнот. Там же меняется его обработчик. Потом блокнот заходит в обработчик - поэтому 2036958 два раза - проверял.
Знаю, что должен захлебнуться. Но блокнот просто падает. Даже если убрать SendMessage из обработчика
TwiX вне форума Ответить с цитированием
Старый 17.06.2011, 01:00   #15
Silver_S
Форумчанин
 
Регистрация: 14.03.2011
Сообщений: 104
По умолчанию

Каждый элемент окна - поля ввода, кнопки - с точки зрения работы Windows тоже окна, имеющие handle и свой WndProc. Ставя хук на процесс, вы ставите хук на все его окна, а не только на основное и всем им меняете WndProc.
Silver_S вне форума Ответить с цитированием
Старый 17.06.2011, 01:03   #16
TwiX
Участник клуба
 
Аватар для TwiX
 
Регистрация: 28.07.2009
Сообщений: 1,510
По умолчанию

Спасибо и на этом...
Не совсем понял почему на все эл-ты. Ведь я же на главное окно ставлю.
+Если убрать замену и посмотреть, что за сообщения будут приходить из Activate, то там будет только одно сообщение при однократном клике на блокнот.
Как сделать с массивом?

UPD: Написал я через массив. Проблема в том, что в wnd у моего обработчика совсем не тот хендл, который нужен. Как из обработчика получить хендл?

UPD2: Сегодня переписал заново, сначала потестив на собственном окне, заработало))) Наверно забыл stdcall когда в десятый раз копировал функцию из msdn и изменял её с C на делфи=)

Последний раз редактировалось TwiX; 17.06.2011 в 13:49.
TwiX вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
H2269 Overriding virtual method 'TForm1.WndProc' has lower visibility (private) than base class 'TForm' AlexanderSatorin Общие вопросы Delphi 2 27.06.2010 10:08
Слетает ОС Медсестра Операционные системы общие вопросы 13 16.05.2010 01:51
Слетает верстка... lastalert HTML и CSS 6 02.05.2010 17:14
Смена WndProc в рантайме VVVadim Win Api 1 28.04.2009 18:16