我正在使用 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 东西,当我确定我想要完成它们时。
“如果这不可能,我会简单地将它们累积在一个临时向量中,并在最后调用 Defer 东西,当我确定我想要完成它们时。”
这将是正确的解决方案。对于在和之间重新定位哪些窗口犹豫不决BeginDeferWindowPos
,您的论点是什么?这似乎更多地与线程问题有关,您可以使用适当的锁定来解决该问题。DeferWindowPos
EndDeferWindowPos
Arkadiy的回答不会“取消”任何内容。据我对Win32 文档的理解,您根本无法将显示/隐藏操作与重新定位操作结合起来。换句话说,您没有取消操作,显示/隐藏操作只是优先,那些将被执行。
我将显示/隐藏和重新定位封装在托管库中: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 );
}
它们不会被重新定位,但它们仍然会被隐藏/显示,对吗?据我所知,您根本无法在同一通话中显示/隐藏和重新定位。