取消DeferWindowPos

时间:2009-01-30 13:12:21

标签: c++ windows mfc

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

2 个答案:

答案 0 :(得分:0)

我看到的对任何“中止”功能的唯一引用是:

  

如果有任何窗户   多窗口位置结构   有SWP_HIDEWINDOW或   SWP_SHOWWINDOW标志设置,没有   窗户重新定位。

这来自here

答案 1 :(得分:0)

“如果这是不可能的,我会简单地将它们累积在临时载体中,并在最后调用Defer的东西,当我确定我想要全部完成它们。”

这是正确的解决方案。您对在BeginDeferWindowPosDeferWindowPosEndDeferWindowPos之间重新定位哪些窗口犹豫不决有什么看法?这似乎更多地涉及您可以使用适当的锁定解决的线程问题。

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