-
драсте не могу получить чтоб мое окно распологалось рядом с другим окном
моя программа запустила хук WH_CBT хук сформировав строку где есть код комады и хендл окна получившего сообщения передаю эту строку своей програме через SendMessage(...WM_COPYDATA, на принемающей программе расшифровав и когда код HCBT_MOVESIZE я выполняю чтение кординат через GetWindowRect и установку кординат у своего окна чтоб было рядом с тем окном
то появилась проблема моя пробрамма устанавливает кординаты относительно кординат которые были до перемещени
как мне сделать чтоб программа ставила относительно новых кординат
-
Событие WM_WINDOWPOSCHANGING возникает тогда, когда окно только собирается сменить положение, когда у него ещё старые координаты. А вот WM_WINDOWPOSCHANGED - когда координаты уже сменились.
Следовательно, можно попытаться сделать хук WH_GETMESSAGE и перехватывать WM_WINDOWPOSCHANGED для нужного окна.
-
А в MSDNe про HCBT_MOVESIZE сказано, что "A window is about to be moved or sized". Другими словами, это как раз реакция на WM_WINDOWPOSCHANGING, когда координаты ещё старые.
-
ой как плохо в WH_CBT просто есть команда HCBT_MOVESIZE ее и отлавливать а в WH_GETMESSAGE прийдет только HC_ACTION
это что получаеться если прийдет HCBT_MOVESIZE нужно будет дождаться HC_ACTION и тогда выполнять чтение кординат
-
> прийдет только HC_ACTION
Главное, что прийдёт само сообщение WM_WINDOWPOSCHANGED - его и ловите/обрабатывайте. А HCBT_MOVESIZE вообще не нужен.
-
Я думаю одним WM_WINDOWPOSCHANGED не обойтись. Вероятно еще видимость окна надо отслеживать и скрывать свою прилипалу вместе с родительским окном. Возможно еще какие сообщения надо.
-
> Возможно еще какие сообщения надо.
так вот у меня было HCBT_MOVESIZE после получания этого сообщения получаю кординаты окна и выставляю кординаты у себя
> Главное, что прийдёт само сообщение WM_WINDOWPOSCHANGED
но это сообщение не несет что сделали с окном нужно следить что окно создано разрушено свернуто или перемещено
-
-
> SKIPtr © (06.01.13 21:50) [6]
> нужно следить что окно создано разрушено свернуто или перемещено
касательно перемещения и изменения z-order WM_WINDOWPOSCHANGED как раз подходит, хотя имхо правильнее WM_MOVE, а для размера WM_SIZE, но это не принципиально. А для разрушения, сворачивания и пр есть другие сообщения, как я уже сказал.
-
2DVM А чем для размера WM_WINDOWPOSCHANGED плох?
-
> Styx (07.01.13 00:53) [9]
> А чем для размера WM_WINDOWPOSCHANGED плох?
Почему плох? Совсем не плох.
-
А, значит, я неправильно запятые понял :)
-
прошу прощения но что то у меня не получаеться я в хуке написал Function hokm(Code:Integer; WParam:LongInt; LParam:LongInt):LongInt; stdcall;
begin
wnd := TPMsg(lParam)^.hwnd;
b := TPMsg(lParam)^.message;
l := '';
case b of
WM_WindowPosChanging : l := 'Changing';
WM_WindowPosChanged : l := 'Changed';
WM_SIZE : l := 'SIZE';
WM_MOVE : l := 'MOVE';
WM_CHAR : l := 'char';
WM_SYSCOMMAND : l := 'COMMAND';
end;
s := IntToStr(wnd);
s := s + ' ' + l;
cd.cbData := Length(s);
cd.lpData := PChar(s);
SendMessage (hd, WM_COPYDATA, 0, LongInt(@cd));
result:= CallNextHookEx(km, Code, WParam, LParam); wnd передаеться нормально а вот тип сообщения не передаеться что я сделал не так
-
> SKIPtr © (10.01.13 21:14) [12]
во-первых исправь (обрати внимание на типы параметров), сейчвс это ошибки не вызывает но вызовет потом. Function hokm(Code:Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall; во-вторых, ты тип сообщения нигде и не передаешь в-третьих, что такое TPMsg? Есть же
PMsg = ^TMsg;
tagMSG = record
hwnd: HWND;
message: UINT;
wParam: WPARAM;
lParam: LPARAM;
time: DWORD;
pt: TPoint;
end;
TMsg = tagMSG;
MSG = tagMSG; в Windows.pas В-четвертых, зачем все эти выкрутасы со строкой в WM_COPYDATA?
-
> во-первых исправь (обрати внимание на типы параметров), > сейчвс это ошибки не вызывает но вызовет потом.Function > hokm(Code:Integer; WParam: WPARAM; LParam: LPARAM): LRESULT; > stdcall;
этот вариант я делал не пошло потом заметил что имя переменой совпадает с именем типа подумал это ошибка и исправил > во-вторых, ты тип сообщения нигде и не передаешь
вот как передаю b := TPMsg(lParam)^.message;
case b of
WM_WindowPosChanging : l := 'Changing';
WM_WindowPosChanged : l := 'Changed';
WM_SIZE : l := 'SIZE';
WM_MOVE : l := 'MOVE';
WM_CHAR : l := 'char';
WM_SYSCOMMAND : l := 'COMMAND';
end;
s := s + ' ' + l; а дальше строку через сообщение WM_COPYDATA > что такое TPMsg
среди примеров нашел а до этого обьявил TPMsg = ^TMsg > зачем все эти выкрутасы со строкой в WM_COPYDATA?
передаю даные полученые хуком моей програме через текстовую строку но самое главное из поле message не получаеться получить переменые WM_WindowPosChanging ; WM_WindowPosChanged ; WM_SIZE ; WM_MOVE ; WM_CHAR ; WM_SYSCOMMAND ; а ведь это мне нужно получить
-
> SKIPtr © (11.01.13 18:10) [14]
> > этот вариант я делал не пошло > потом заметил что имя переменой совпадает с именем типа > подумал это ошибка и исправил >
что значит не пошло? То, что имя параметра совпадает с именем типа - ничего страшного, если совпадение смущает можно параметр переименовать, но типы надо именно такие иначе под 64 бит будут проблемы.
> вот как передаю
способ конечно оригинальный, но зачем это все? И это и дальше все выкрутасы со строками? Можно прекрасно обойтись без строк, просто передавая структуру с WM_COPYDATA со всеми необходимыми полями. Вот прямо PMsg и передавал бы.
Ты не показал весь код ловушки, поэтому сложно судить где у тебя ошибка, судя по всему в hokm() у тебя управление передается? Посмотри отладчиком, что содержится в PMsg(lParam)^.message, есть ли там корректные коды сообщений.
Еще замечание такое: SendMessage (hd, WM_COPYDATA, 0, LongInt(@cd)); LongInt на LPARAM замени
-
> Ты не показал весь код ловушки, поэтому сложно судить где > у тебя ошибка,
вот как текст с моими черновыми вариантами uses
SysUtils, Windows, Classes, Messages;
type
TPMsg = ^TMsg;
var
kc, km : thandle;
hd : hwnd;
function hokc(Code: integer; WParam: WPARAM; LParam: LPARAM):LRESULT stdcall;
var
s : string;
cd : TCopyDataStruct;
Wnd: hwnd;
begin
result:= CallNextHookEx(kc, Code, WParam, LParam);
if (code >= 0) and (Code <> 6) then
begin
s := 'CBT ' + IntToStr(Code);
s := s + ' ' + IntToStr(WParam) + ' a';
cd.cbData := Length(s);
cd.lpData := PChar(s);
SendMessage ( hd, WM_COPYDATA, 0, LongInt(@cd));
end
end;
Function hokm(Code:Integer; WParam:LongInt; LParam:LongInt):LongInt; stdcall;
var
s, l : string;
cd : TCopyDataStruct;
Wnd: hwnd;
b : integer;
msg:^TMessage;
m:cardinal;
begin
begin
s := 'MSG ' + IntToStr(Code);
wnd := TPMsg(lParam)^.hwnd;
b := TPMsg(lParam)^.message;
l := '';
case b of WM_WindowPosChanging : l := 'Changing';
WM_WindowPosChanged : l := 'Changed';
WM_SIZE : l := 'SIZE';
WM_MOVE : l := 'MOVE';
WM_CHAR : l := 'char';
WM_SYSCOMMAND : l := 'COMMAND';
end;
s := s + ' ' + IntToStr(wnd);
s := s + ' ' + l + ' ' + IntToStr(b) + ' a';
cd.cbData := Length(s);
cd.lpData := PChar(s);
SendMessage (hd, WM_COPYDATA, 0, LongInt(@cd));
result:= CallNextHookEx(km, Code, WParam, LParam);
end
end;
procedure StarH;
begin
km := SetWindowsHookEx(WH_GETMESSAGE, @hokm, hInstance, 0);
end;
procedure StpH;
begin
UnhookWindowsHookEx(km);
end;
exports StarH index 1;
exports StpH index 2;
begin
hd := FindWindow('Tmesag', nil)
end. > Посмотри отладчиком, что содержится в PMsg(lParam)^.message,
я ставил раньше ставил останов программы но возникала какая то ошибка во время выполнения поэтому я воставил преобразование переменной b в строку значение переменой разные когда hokm работала вместе с hokc дистребьюторы двух сообщений рядом совпадают
-
-
> в примере 2 есть передача параметров из dll с ловушкой в > основное приложение
передавать параметры с хука програме мне больше нравиться через сообщения а не через файл меня интересует почему у меня хук не ловит сообщения WM_WINDOWPOSCHANGED и WM_MOVE они мне нужны
-
Попробуйте WH_CALLWNDPROC
-
> Styx (12.01.13 17:22) [19]
вот в интернете нашел WH_GETMESSAGE возникает когда сообщение в очереди а действие мышы похоже в очередь не ставиться и пишут что поможет WH_CALLWNDPROC но он не может поменять сообщения но мне этого и не надо спасибо пойду пробывать
-
> а действие мышы похоже в очередь не ставиться
Ставится. Действия мыши и клавиатуры кроме как в очередь поставлены быть не могут
-
> SKIPtr © (12.01.13 16:24) [18]
> передавать параметры с хука програме мне больше нравиться > через сообщения а не через файл
ты своим кодом кстати удваиваешь количество сообщений в системе в 2 раза. Отделял бы нужные тебе окна от остальных, а то на каждое сообщение любого окна генерируется еще одно твоему окну, а потом все лавинообразно растет.
-
> ты своим кодом кстати удваиваешь количество сообщений в > системе в 2 раза.
по логике так и должно быть но я смотрю на отщет о том что передано я не вижу дестрибьютор окна в котором выводятся сообщения получаеться окно само себе не передает
-
> SKIPtr ©
я кстати посмотрел WM_WINDOWPOSCHANGED, WM_DESTROY, WM_SIZE, WM_CLOSE, WM_MOVE с помощью WH_GETMESSAGE не перехватываются, но перехватываются с помощью WH_CALLWNDPROC
-
> SKIPtr © (12.01.13 20:34) [23]
> получаеться окно само себе не передает
если бы тебе сообщения не посылались, то ты бы вообще ничего не получал из функции hokm(), сообщений в 2 раза больше и становится в общем и всё еще замедляется так как фактически синхронизируется с твоим окном функцией SendMessage(), которая блокирует поток в котором выполняется hokm()
-
это пока программа для просмотра конечная программа будет проверять дистребьютор сообщения на соответствие окна по его названию это даст возможность что ответ будет посылать только та программа для которой писалась ловушка
-
> сообщений в 2 раза больше и становится в общем и всё еще > замедляется так как фактически синхронизируется с твоим > окном функцией SendMessage()
вот с хуком WH_CALLWNDPROC окажываеться возникает эта проблема в хуке сделал проверку на соответствие дистребьютора в сообщении с дистребьютором окна моей програмы и если они разные то отсылаю сообщение но обнаружил в коде wnd := PMsg(lParam)^.hwnd;
b := PMsg(lParam)^.message; дистребьютор и сообщение поменялись местами > WM_WINDOWPOSCHANGED, WM_DESTROY, WM_SIZE, WM_CLOSE, WM_MOVE > с помощью WH_GETMESSAGE не перехватываются, но перехватываются > с помощью WH_CALLWNDPROC
и WH_CALLWNDPROC то же не перехватилось когда сообщений пришли дугие и вместе с ним приходили кода сообщений как при хуке WH_CBT проверю приходит ли эти сообщеня после выполнения действия если нет то после сообщения WH_CBT буду просто в таймере проверять изменения кординат
|