Конференция "WinAPI" » окно рядом с другим приложением [D7]
 
  • SKIPtr © (05.01.13 05:56) [0]
    драсте
    не могу получить чтоб мое окно распологалось рядом с другим окном

    моя программа запустила хук WH_CBT
    хук сформировав строку где есть код комады и хендл окна получившего сообщения
    передаю эту строку своей програме через
    SendMessage(...WM_COPYDATA,
    на принемающей программе
    расшифровав и когда код HCBT_MOVESIZE я выполняю чтение кординат через GetWindowRect и установку кординат у своего окна чтоб было рядом с тем окном

    то появилась проблема
    моя пробрамма устанавливает кординаты относительно кординат  которые были до перемещени

    как мне сделать чтоб программа ставила относительно новых кординат
  • Dimka Maslov © (06.01.13 11:19) [1]
    Событие WM_WINDOWPOSCHANGING возникает тогда, когда окно только собирается сменить положение, когда у него ещё старые координаты. А вот WM_WINDOWPOSCHANGED - когда координаты уже сменились.

    Следовательно, можно попытаться сделать хук WH_GETMESSAGE и перехватывать WM_WINDOWPOSCHANGED для нужного окна.
  • Dimka Maslov © (06.01.13 11:21) [2]
    А в MSDNe про HCBT_MOVESIZE сказано, что "A window is about to be moved or sized". Другими словами, это как раз реакция на WM_WINDOWPOSCHANGING, когда координаты ещё старые.
  • SKIPtr © (06.01.13 19:51) [3]
    ой как плохо
    в  WH_CBT просто  есть команда HCBT_MOVESIZE ее и отлавливать
    а в WH_GETMESSAGE прийдет только HC_ACTION

    это что получаеться если прийдет HCBT_MOVESIZE нужно будет дождаться HC_ACTION и тогда выполнять чтение кординат
  • Styx (06.01.13 20:11) [4]

    > прийдет только HC_ACTION

    Главное, что прийдёт само сообщение WM_WINDOWPOSCHANGED - его и ловите/обрабатывайте.
    А HCBT_MOVESIZE вообще не нужен.
  • DVM © (06.01.13 20:27) [5]
    Я думаю одним WM_WINDOWPOSCHANGED не обойтись. Вероятно еще видимость окна надо отслеживать и скрывать свою прилипалу вместе с родительским окном. Возможно еще какие сообщения надо.
  • SKIPtr © (06.01.13 21:50) [6]

    > Возможно еще какие сообщения надо.

    так вот у меня было  HCBT_MOVESIZE
    после получания этого сообщения получаю кординаты окна и выставляю кординаты у себя


    > Главное, что прийдёт само сообщение WM_WINDOWPOSCHANGED

    но это сообщение не несет что сделали с окном
    нужно следить что окно создано разрушено свернуто или перемещено
  • Styx (06.01.13 22:12) [7]

    > но это сообщение не несет что сделали с окном

    Как это не несёт?
    http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms632652(v=vs.85).aspx
  • DVM © (07.01.13 00:41) [8]

    > SKIPtr ©   (06.01.13 21:50) [6]


    > нужно следить что окно создано разрушено свернуто или перемещено

    касательно перемещения и изменения z-order WM_WINDOWPOSCHANGED как раз подходит, хотя имхо правильнее WM_MOVE, а для размера WM_SIZE, но это не принципиально. А для разрушения, сворачивания и пр есть другие сообщения, как я уже сказал.
  • Styx (07.01.13 00:53) [9]
    2DVM
    А чем для размера WM_WINDOWPOSCHANGED плох?
  • DVM © (07.01.13 11:24) [10]

    > Styx   (07.01.13 00:53) [9]


    > А чем для размера WM_WINDOWPOSCHANGED плох?

    Почему плох? Совсем не плох.
  • Styx (07.01.13 14:08) [11]
    А, значит, я неправильно запятые понял :)
  • SKIPtr © (10.01.13 21:14) [12]
    прошу прощения но что то у меня не получаеться
    я в хуке написал

    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';
           {else l := '' }
         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 передаеться нормально
    а вот тип сообщения не передаеться
    что я сделал не так
  • DVM © (10.01.13 23:30) [13]

    > 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;
     {$EXTERNALSYM tagMSG}
     TMsg = tagMSG;
     MSG = tagMSG;



    в Windows.pas

    В-четвертых, зачем все эти выкрутасы со строкой в WM_COPYDATA?
  • SKIPtr © (11.01.13 18:10) [14]

    > во-первых исправь (обрати внимание на типы параметров),
    > сейчвс это ошибки не вызывает но вызовет потом.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';
           {else l := '' }
         end;
         s :=  s + ' ' + l;


    а дальше строку через сообщение WM_COPYDATA


    > что такое TPMsg

    среди примеров нашел
    а до этого обьявил TPMsg = ^TMsg


    > зачем все эти выкрутасы со строкой в WM_COPYDATA?

    передаю даные полученые хуком моей програме через текстовую строку

    но самое главное из поле message
    не получаеться получить переменые
    WM_WindowPosChanging ; WM_WindowPosChanged ;
    WM_SIZE ; WM_MOVE ; WM_CHAR ; WM_SYSCOMMAND ;
    а ведь это мне нужно получить
  • DVM © (11.01.13 22:03) [15]

    > SKIPtr ©   (11.01.13 18:10) [14]


    >
    > этот вариант я делал не пошло
    > потом заметил что имя переменой совпадает с именем типа
    > подумал это ошибка и исправил
    >

    что значит не пошло? То, что имя параметра совпадает с именем типа - ничего страшного, если совпадение смущает можно параметр переименовать, но типы надо именно такие иначе под 64 бит будут проблемы.


    > вот как передаю

    способ конечно оригинальный, но зачем это все? И это и дальше все выкрутасы со строками? Можно прекрасно обойтись без строк, просто передавая структуру с WM_COPYDATA со всеми необходимыми полями. Вот прямо PMsg и передавал бы.

    Ты не показал весь код ловушки, поэтому сложно судить где у тебя ошибка, судя по всему в hokm() у тебя управление передается? Посмотри отладчиком, что содержится в PMsg(lParam)^.message, есть ли там корректные коды сообщений.

    Еще замечание такое:
    SendMessage (hd, WM_COPYDATA, 0, LongInt(@cd));
    LongInt на LPARAM замени
  • SKIPtr © (12.01.13 02:25) [16]

    > Ты не показал весь код ловушки, поэтому сложно судить где
    > у тебя ошибка,

    вот как текст с моими черновыми вариантами

    uses
     SysUtils, Windows, Classes, Messages;

    {$R *.res}

    type
     TPMsg = ^TMsg;

    var
    { h,} kc, km : thandle;
     hd : hwnd;

    function hokc(Code: integer; WParam: WPARAM; LParam: LPARAM):LRESULT stdcall;
    var
     {capt:array[0..255] of char;}
     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;
    {function hokm(Code: integer; WParam: WPARAM; LParam: LPARAM):DWORD stdcall;}
    var
     s, l : string;
     cd : TCopyDataStruct;
     Wnd: hwnd;
     b : integer;
     msg:^TMessage;
     m:cardinal;
    begin
      {if code =  HCBT_ACTIVATE then }
       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';
           {else l := '' }
         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

    {kc := SetWindowsHookEx(WH_CBT, @hokc, hInstance, 0); {включаем ловушку}
    km := SetWindowsHookEx(WH_GETMESSAGE, @hokm, hInstance, 0); {включаем ловушку}

    end;

    procedure StpH;
    begin

    {UnhookWindowsHookEx(kc); }
    UnhookWindowsHookEx(km);

    end;

    exports StarH index 1;
    exports StpH index 2;

    begin
      hd := FindWindow('Tmesag', nil)

    end.




    > Посмотри отладчиком, что содержится в PMsg(lParam)^.message,

    я ставил раньше ставил останов программы
    но возникала какая то ошибка во время выполнения
    поэтому я воставил преобразование переменной b в строку
    значение переменой разные
    когда hokm работала вместе с hokc дистребьюторы двух сообщений рядом совпадают
  • DVM © (12.01.13 11:46) [17]

    > SKIPtr ©   (12.01.13 02:25) [16]

    вот сюда посмотри http://www.delphimaster.ru/articles/hooks/ там как раз в примере 2 есть передача параметров из dll с ловушкой в основное приложение
  • SKIPtr © (12.01.13 16:24) [18]

    > в примере 2 есть передача параметров из dll с ловушкой в
    > основное приложение

    передавать параметры с хука програме мне больше нравиться через сообщения а не через файл
    меня интересует почему у меня хук не ловит сообщения WM_WINDOWPOSCHANGED и WM_MOVE
    они мне нужны
  • Styx (12.01.13 17:22) [19]
    Попробуйте WH_CALLWNDPROC
 
Конференция "WinAPI" » окно рядом с другим приложением [D7]
Есть новые Нет новых   [134430   +2][b:0][p:0.003]