Почему обработка WM_NCCALCSIZE заставляет мое окно прыгать? - PullRequest
5 голосов
/ 11 октября 2008

У меня есть приложение WPF, которое привязывается к краям экрана (я просто устанавливаю .Top или .Left окна, если вы находитесь в пределах 20 пикселей от края экрана), но недавно я добавил некоторый код , предоставленный WPF SDK Team"связывается" с окном Chrome, и, хотя он отлично работает ( снимок экрана ), он заставляет "snapto" неожиданно перемещать окно (например, он переходит влево когда это должно быть прямо вниз)

Я сузил это до их обработки WM_NCCALCSIZE ... что действительно странно, потому что они в основном ничего не делают, они просто говорят, что обрабатывают это и возвращают 0.

В соответствии с документацией WM_NCCALCSIZE, это должно привести к тому, что все окно будет рассматриваться как клиентское (не имеющее сторонних интерфейсов), но это также означает, что всякий раз, когда мой код привязки перемещает окно вниз, вниз экрана он также перемещается влево примерно на 134 пикселя ... (перемещение к другим краям имеет аналогичные побочные эффекты), и пока я удерживаю мышь, чтобы перетаскивать ее, она мигает назад и вперед от того места, где она должна быть. Если я прокомментирую обработку WM_NCCALCSIZE, оснастка работает так, как должна (но форма выглядит неправильно).

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

P.S. Если вы действительно хотите увидеть код, он уже на CodePlex , в двух файлах найдите _HandleNCCalcSize и OnWindowLocationChanged

Ответы [ 2 ]

6 голосов
/ 04 ноября 2008

Причина, по которой это происходит, заключается в том, что обработка WM_NCCALCSIZE изменяет общий размер окна ... но если вы перемещаете окно, изменяете свою позицию во время WM_MOVE или WM_WINDOWPOSCHANGED (что соответствует WPF WindowPositionChanged событие) вызывает другое WM_NCCALCSIZE сообщение ...

Внесение изменений во время WM_NCCALCSIZE (даже утверждение о том, что вы обработали сообщение) вызывает еще один вызов WM_MOVE ..., который переводит вас в цикл, в котором часть "FROM" сообщения с измененной позицией остается неизменной (создание окно «перепрыгивает» с того места, с которого оно начиналось, в положение, в которое вы настраиваете его во время WM_MOVE снова и снова, когда оно изменяется после WM_NCCALCSIZE).

Правильный путь

Что вам нужно сделать, так это повиноваться Раймонду Чену и справиться с WM_WINDOWPOSCHANGING вместо . Это происходит до этих других сообщений, и таким образом они не мешают друг другу!

0 голосов
/ 11 октября 2008

wParam всегда кажется TRUE (1), а lParam - NCCALCSIZE_PARAMS ...

Цель состоит в том, чтобы сделать именно то, что вы сказали: заставить все окно быть «клиентом», а затем использовать API-интерфейс Vista DWM для расширения фрейма в клиентскую область. Я просто не понимаю, почему он двигается так далеко влево ...

Если я отслеживаю или устанавливаю точку останова на метод HandleNCCalcSize, когда я изменяю размер окна (когда оно находится на краю, так что привязка срабатывает), NCCalcSize вызывается дважды: один раз, где он должен быть, и затем выключается влево, где это заканчивается.

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