我正在使用 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 东西,当我确定我想要完成它们时。


我看到的任何类型的“中止”功能的唯一参考是:

如果多窗口位置结构中的任何窗口设置了 SWP_HIDEWINDOW 或 SWP_SHOWWINDOW 标志,则不会重新定位任何窗口。

这是从这里来的。


“如果这不可能,我会简单地将它们累积在一个临时向量中,并在最后调用 Defer 东西,当我确定我想要完成它们时。”

这将是正确的解决方案。对于在和之间重新定位哪些窗口犹豫不决BeginDeferWindowPos,您的论点是什么这似乎更多地与线程问题有关,您可以使用适当的锁定来解决该问题。DeferWindowPosEndDeferWindowPos

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 );
}

它们不会被重新定位,但它们仍然会被隐藏/显示,对吗?据我所知,您根本无法在同一通话中显示/隐藏和重新定位。

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部