我正在使用DeferWindowPos功能进行一系列窗口大小调整。假设我已经打开了DeferWindowPos句柄,并且调用了DeferWindowPos几次,现在我想要取消所有内容:不要调用EndDeferWindowPos。我尝试过CloseHandle(hDWP),但它不起作用(崩溃)。如果我只是从我的函数返回,我认为它会泄漏一个句柄。可以在不调用EndDeferWindowPos的情况下终止DeferWindowPos吗?
// Initialize
HDWP hDWP = BeginDeferWindowPos( ... )
for( ... )
{
// Calculate new rectangle
CRect dcNew;
...
// Oh,now I want to return from my function, I want to cancel everything
// Accumulate
hDWP = DeferWindowPos( hDWP, hWnd, 0,
rcNew.left,
rcNew.top,
rcNew.Width(),
rcNew.Height(),
SWP_NOZORDER );
}
// Finally
BOOL bResult = EndDeferWindowPos( hDWP );
如果这是不可能的,我会简单地将它们累积在一个临时载体中,并在最后调用Defer的东西,当我确定我想要完成它们时。
答案 0 :(得分:0)
答案 1 :(得分:0)
“如果这是不可能的,我会简单地将它们累积在临时载体中,并在最后调用Defer的东西,当我确定我想要全部完成它们。”
这是正确的解决方案。您对在BeginDeferWindowPos
,DeferWindowPos
和EndDeferWindowPos
之间重新定位哪些窗口犹豫不决有什么看法?这似乎更多地涉及您可以使用适当的锁定解决的线程问题。
Arkadiy的答案不会“取消”任何内容。据我了解Win32 documentation,,你无法将显示/隐藏操作与重新定位操作结合起来。换句话说,你不取消操作,显示/隐藏操作只是优先,那些是将要执行的操作。
我在托管库中封装显示/隐藏和重新定位:Framework Class Library Extension。
具体RepositionWindows()
功能位于Whathecode.System.Windows.WindowManager,它负责显示/隐藏和重新定位。
/// <summary>
/// Reposition a set of windows in one operation.
/// TODO: Handle any scenarios where repositioning windows fails.
/// </summary>
/// <param name="toPosition">The windows to reposition.</param>
/// <param name="changeZOrder">
/// When true, the windows's Z orders are changed to reflect the order of the toPosition list.
/// The first item in the list will appear at the top, while the last item will appear at the bottom.
/// </param>
public static void RepositionWindows( List<RepositionWindowInfo> toPosition, bool changeZOrder = false )
{
bool changeVisibility = toPosition.Any( w => w.HasVisibilityChanged() );
if ( changeVisibility )
{
RepositionWindows( toPosition, false, true );
}
RepositionWindows( toPosition, changeZOrder, false );
}