我有一个WPF应用程序可以捕捉到屏幕边缘(我只是设置窗口的.Top或.Left,如果你在屏幕边缘的20个像素内),但我最近添加了WPF SDK团队提供的一些代码"混乱"与窗口铬合金,虽然它工作得很好(截图),它导致"snapto"意外地移动窗口(例如:当它应该直接向下捕捉到底部时它跳到左边)
我把它缩小到他们对WM_NCCALCSIZE的处理......这真的很奇怪,因为他们基本上什么都不做,他们只是说他们处理它,然后返回0.
根据WM_NCCALCSIZE的文档,这应该只会导致整个窗口被视为客户端(没有非客户端边缘),但不知何故,这也意味着每当我的快照代码将窗口移动到屏幕底部时它也向左移动大约134个像素......(移动到其他边缘有类似的副作用),只要我按住鼠标拖动它,它就会从它应该的位置来回闪烁.如果我对WM_NCCALCSIZE处理进行注释,则snap-to以它应该的方式工作(但表单看起来不正确).
我已经尝试了WM_NCCALCSIZE处理程序中的所有功能,但是我无法阻止它向左跳...当然,只有在窗口大小发生变化时才会调用WM_NCCALCSIZE,所以我不明白它是如何导致的这首先是!
PS如果你想真正看到代码,它已经在CodePlex上,在两个文件中,查找_HandleNCCalcSize和OnWindowLocationChanged
发生这种情况的原因是处理WM_NCCALCSIZE
更改窗口的整体大小...但是如果您正在移动窗口,在WM_MOVE
或期间WM_WINDOWPOSCHANGED
(对应于WPF WindowPositionChanged
事件)更改您的位置会导致另WM_NCCALCSIZE
一条消息...
在进行更改WM_NCCALCSIZE
(甚至只是断言你处理了消息)会导致另一个调用WM_MOVE
...这会使你进入一个循环,其中positionchanged消息的"FROM"部分保持不变(使窗口从它开始的地方"跳转"到你以后调整它的位置WM_MOVE
,因为它改变回来之后WM_NCCALCSIZE
).
你要做的就是服从雷蒙德陈而是处理WM_WINDOWPOSCHANGING
.它发生在这些其他消息之前,这样它们就不会相互干扰!