Как перехватить сообщение windows

Тема в разделе "WASM.WIN32", создана пользователем CrazyFun, 3 ноя 2011.

  1. CrazyFun

    CrazyFun New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2005
    Сообщения:
    129
    Какие есть способы кроме хуков и замены оконных функций через SetWindowlong? Сейчас использую комбинацию этих двух методов.
    Задача в изменении поведения окон в проекте на Deiphi(VCL) при минимизации. Отслеживать очередь сообщений потока бесполезно так как сообщение о минимизации видимо отправляется в оконную процедуру напрямую её (процедуры) вызовом. Хочется не пустить сообщение к окну , для этого я подменяю оконную функцию после срабатыванию хука на вызов любой оконной функции в контексте потока.
     
  2. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    GetMessage и все ниже стоящие ... перехватываешь и будет тебе дело.
     
  3. CrazyFun

    CrazyFun New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2005
    Сообщения:
    129
    GetMessage извлекает сообщение из очереди сообщений. Судя по моим экспериментам сообщение о минимизации окна не проходит через очередь сообщений приложения.
     
  4. onSide

    onSide New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2008
    Сообщения:
    476
    Spy++ в помощь.
     
  5. CrazyFun

    CrazyFun New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2005
    Сообщения:
    129
    Spy++? Это же для отладки. Зочем он мне?
     
  6. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    перехват GetMessage и иже с ним....CrazyFun проходит
     
  7. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    CrazyFun
    открой spy++ и поймешь зачем
    только не закрывай сразу
     
  8. CrazyFun

    CrazyFun New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2005
    Сообщения:
    129
    И как я с помощью Spy++ изменю поведение Vcl окна? Мне его грузить как dll? Или предлагать юзеру запустить и самостоятельно рулить дальше?

    GetMessage извлекает сообщение из очереди. Сообщение которое мне нужно не пустить к окну - WM_SYSCOMMAND c wParam = SC_MINIMIZE не ставится в очередь. Я могу его перехватить хуком но не могу его хуком изменить.
     
  9. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    ну так посмори что ставится в момвент минимизации
    Бред
     
  10. CrazyFun

    CrazyFun New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2005
    Сообщения:
    129
    Я знаю что ставится в момент минимизации. Меня не устраивают методы перехваты в виде хуков или подмены оконной процедуры.

    Да не все сообщения проходят через очередь. Внезапно да. В MSDN описаны Nonqueued Messages.
     
  11. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    CrazyFun
    Вряд ли для минимизации используется Nonqueued Messages. Был какой-то кошерный монитор виндовых сообщений. Spy++ - это так, поделка. Надо отмониторить все, что шлется окну во время минимизации.
     
  12. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Winspector попробуй
     
  13. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    эврика!)
     
  14. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
  15. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    При сабклассинге можно же фальсифицировать данные.
     
  16. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    WH_GETMESSAGE тоже позволяет подменять данные.
    WH_CALLWNDPROC может быть тоже позволяет..
     
  17. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Результаты в студию. Или будет беспредметный разговор ни о чем. А про Дельфи вообще лучше спрашивать и смотреть на профильных форумах. Там все очень по-другому.
     
  18. CrazyFun

    CrazyFun New Member

    Публикаций:
    0
    Регистрация:
    26 сен 2005
    Сообщения:
    129
    Дельфийского кода и IDE дома нет, повторил на VS2010. Создал шаблонный оконный проект Win32, установил хук типа


    Код (Text):
    1.     Hook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, 0, GetCurrentThreadId() );
    2.     // Main message loop:
    3.     while (GetMessage(&msg, NULL, 0, 0))
    4.     {
    5.         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    6.         {
    7.             TranslateMessage(&msg);
    8.             DispatchMessage(&msg);
    9.         }
    10.     }
    11.  
    12.     UnhookWindowsHookEx(Hook);


    Вот код процедуры хука. MessageBox появляется только по ветке SC_RESTORE, в отладчике тоже встает только туда.

    Код (Text):
    1. LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
    2. {
    3.     PMSG pMsg = (PMSG)lParam;
    4.     if (code == HC_ACTION)
    5.     {
    6.         if (pMsg->message == WM_SYSCOMMAND)
    7.             switch(pMsg->wParam)
    8.             {
    9.                 case SC_MINIMIZE:
    10.                     MessageBox(NULL, (LPCWSTR)L"SC_MINIMIZE", (LPCWSTR)L"WM_SYSCOMMAND", MB_OK);
    11.                     break;
    12.                 case SC_RESTORE:
    13.                     MessageBox(NULL, (LPCWSTR)L"SC_RESTORE", (LPCWSTR)L"WM_SYSCOMMAND", MB_OK);
    14.                     break;
    15.             }
    16.     }
    17.     return CallNextHookEx(Hook, code, wParam, lParam);
    18. }


    Хук типа WH_CALLWNDPROC позволяет отловить сообщение, но не позволяет его модифицировать
    (чтобы это обойти я подменяю оконную функцию, после обработки сообщения возвращаю).

    Отрывок из лога Spy++. Если я правильно понимаю то S - значит Send а не Post, тоесть какраз сообщение идущее в обход очереди

    <00048> 00201582 S WM_SYSCOMMAND uCmdType:SC_MINIMIZE xPos:1149 yPos:151
    <00049> 00201582 S WM_KILLFOCUS hwndGetFocus:dntknw:null)
    <00050> 00201582 R WM_KILLFOCUS
    <00051> 00201582 S WM_IME_SETCONTEXT fSet:0 iShow:C000000F
    <00052> 00201582 S WM_IME_NOTIFY dwCommand:IMN_CLOSESTATUSWINDOW dwCommand:00000001 dwData:00000000
    <00053> 00201582 R WM_IME_NOTIFY
    <00054> 00201582 R WM_IME_SETCONTEXT
    <00055> 00201582 S WM_WINDOWPOSCHANGING lpwp:003EF3E4
    <00056> 00201582 S WM_GETMINMAXINFO lpmmi:003EF008
    <00057> 00201582 R WM_GETMINMAXINFO lpmmi:003EF008
    <00058> 00201582 R WM_WINDOWPOSCHANGING
    <00059> 00201582 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:003EF3BC
    <00060> 00201582 R WM_NCCALCSIZE fuValidRect:0000 lpncsp:003EF3BC
    <00061> 00201582 S WM_WINDOWPOSCHANGED lpwp:003EF3E4
    <00062> 00201582 S WM_MOVE xPos:33536 yPos:33536
    <00063> 00201582 R WM_MOVE
    <00064> 00201582 S WM_SIZE fwSizeType:SIZE_MINIMIZED nWidth:0 nHeight:0
    <00065> 00201582 R WM_SIZE
    <00066> 00201582 R WM_WINDOWPOSCHANGED
    <00067> 00201582 S WM_NCACTIVATE fActive:False
    <00068> 00201582 R WM_NCACTIVATE fDeactivateOK:True
    <00069> 00201582 S WM_ACTIVATE fActive:WA_INACTIVE fMinimized:True hwndPrevious:dntknw:null)
    <00070> 00201582 R WM_ACTIVATE
    <00071> 00201582 S WM_ACTIVATEAPP fActive:False dwThreadID:0000113C
    <00072> 00201582 R WM_ACTIVATEAPP
    <00073> 00201582 R WM_SYSCOMMAND
    <00074> 00201582 P WM_NCMOUSELEAVE
     
  19. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Так почему не обойтись одним сабклассингом?
     
  20. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Да Send идет напрямую в процедуру окна. (Минуя очередь)-чушь) - оно синхронное. Шлется SendMessage.
    Думаю S - это оно самое