-
драсте не могу получить чтоб мое окно распологалось рядом с другим окном
моя программа запустила хук 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
|