Глобально перехватить движение окна - PullRequest
6 голосов
/ 25 августа 2009

У меня проблемы с подключением к глобальной системе. Я хочу получать уведомления, когда окно перемещается, как можно раньше, и изменять размер окна. Это означает, что крюк CBT HCBT_MOVESIZE не будет разрезать его, это происходит только после перемещения окна. Я хочу зафиксировать фактическое движение окна и иметь возможность изменять размер окна во время перемещения.

Хуки устанавливаются из DLL, а функция обратного вызова находится внутри этой DLL. Это то, что я пробовал.

  • WH_CALLWNDPROC. Он предупреждает меня, когда окно перемещается (WM_MOVING получено для окон из других приложений), но я не могу изменить содержимое сообщения.
  • WH_CALLWNDPROCRET То же, что и WH_CALLWNDPROC.
  • CBT крюк HCBT_MOVESIZE. Событие происходит с опозданием.
  • WH_GETMESSAGE. Никогда не получайте WM_MOVE, WM_MOVING или WM_WINDOWPOSCHANGING. Этот хук позволит мне изменить сообщения.

Обновление : кажется, что перехватчики событий Windows позволяют мне его захватывать:

hWinEventHook = SetWinEventHook(EVENT_SYSTEM_MOVESIZESTART,    
    EVENT_SYSTEM_MOVESIZEEND, NULL, WinEventProc, 
    0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);

Однако это создает другую проблему: изменение размера окна с помощью SetWindowPos() не работает (оно меняет размер в порядке, но сразу же возвращается к его предыдущему размеру), даже если я использую SWP_NOSENDCHANGING. Идеи?

Обновление 2 : кажется, что подклассы работают, но Visual Studio падает после каждого запуска программы (как и многие другие окна). Это хорошо работает, если я устанавливаю точки останова и прохожу через «отмену подклассов», но не тогда, когда я запускаю программу самостоятельно. Идеи?

У меня есть хук CBT (он был там раньше), и всякий раз, когда HCBT_ACTIVATE отправляется для нового окна, я удаляю все предыдущие подклассы, используя SetWindowLongPtr() (это также должно работать на 64-битной версии), а затем создать подкласс нового окна. Если я ставлю точку останова где-нибудь и сразу возобновляю сеанс, когда он прерывается, все работает нормально. Однако, когда у меня нет точек останова, Visual Studio аварийно завершает работу при выходе из программы.

Ответы [ 2 ]

1 голос
/ 25 августа 2009

Крючки довольно тяжелые. Вы хотите использовать их только тогда, когда это абсолютно необходимо.

Тем не менее, вы можете использовать один из основных хуков просто для того, чтобы войти в процесс. Оказавшись в этом процессе, вы можете создать подкласс для интересующего вас окна и обрабатывать сообщения о размерах в вашем подклассе, а не пытаться перехватить все на уровне хука.

В зависимости от того, что вы хотите сделать в ответ на изменение размера, вам может потребоваться межпроцессное взаимодействие.

1 голос
/ 25 августа 2009

Хм, я бы подумал, что HCBT_MOVESIZE - это именно то, что вы хотите, учитывая, что MSDN говорит это о перехватах CBT:

The system calls this function before activating, creating, destroying,
minimizing, maximizing, moving, or sizing a window.

и, в частности:

HCBT_MOVESIZE
    A window is about to be moved or sized.

(эти цитаты взяты из http://msdn.microsoft.com/en-us/library/ms644977%28VS.85%29.aspx)

... поэтому я бы подумал, что вы получите вызов HCBT_MOVESIZE вовремя. Функция ловушки, которая обрабатывает HCBT_MOVESIZE, также может возвращать целое число, чтобы система могла определить, разрешена или запрещена операция. Следовательно, учитывая, что хук HCBT_MOVESIZE должен получить параметр для предотвращения операции, я бы сказал, что он вызывается до того, как произошло событие перемещения.

Вы действительно уверены, что функция ловушки вызывается после события перемещения? Если вы выполняете вызов GetWindowRect для конкретного дескриптора в вашей функции подключения, равняется ли возвращаемый прямоугольник прямоугольнику, который передается функции подключения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...