在Windows平滑窗口调整大小(使用Direct2D 1.1)? [英] Smooth window resizing in Windows (using Direct2D 1.1)?

查看:752
本文介绍了在Windows平滑窗口调整大小(使用Direct2D 1.1)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这让我感到,在Windows中调整窗口的大小不像我想要的那样光滑(这是Windows程序的一般情况,而不只是我自己的Visual Studio是一个很好的例子)。它使操作系统及其程序感觉脆弱和便宜(是的,我关心程序和用户界面如何感觉),以同样的方式,我关心的声音和感觉关闭汽车门,这是建立质量的反映),在我看来影响整体用户体验,最终影响品牌的感觉。



重新绘制窗口内容根本不保持与鼠标运动期间调整大小。每当我调整窗口大小时,都会出现口吃/闪烁效果,这似乎是由于在绘制新的调整大小的内容之前在新的调整大小的窗口框架中重绘的窗口的先前大小的内容。 p>

我正在构建一个使用Direct2D 1.1绘制其UI的Win32应用程序(x64),并且考虑到Direct2D的速度,我认为应该没有必要在。



当最大化一个小窗口时,以前的大小效果是特别明显的(因为窗口大小的差异足够大以容易地对比旧内容的图像,因为它在较大窗口的左上角短暂地闪烁,随后新内容被绘制在其上)。



这是什么似乎发生了:


  1. (假设屏幕上有一个完全呈现的窗口,尺寸500×500像素)。

  2. 我最大化了窗口:

  3. 窗口框架最大化

  4. 旧500 x 500


  5. $ b

    我想知道是否有任何方法来减轻这个(即摆脱步骤4) - 通过拦截一个Windows消息,例如 - 并避免窗口重新绘制与新的大小与旧的内容之前最终重新呈现新内容。这就像Windows做窗口重绘本身,使用已经有可用的任何图形,之前它困扰要求我提供更新的内容与WM_PAINT消息或类似的。





    编辑:似乎 WM_WINDOWPOSCHANGING / WM_SIZING 提供对新大小数据的早期访问,但我仍然无法抑制旧内容的绘画。



    我的 WndProc 看起来像这样:

      LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
    switch(message)
    {
    case WM_ERASEBKGND:
    return 1;
    case WM_PAINT:
    PAINTSTRUCT ps;
    BeginPaint(hWnd,& ps);
    D2DRender();
    EndPaint(hWnd,& ps);
    return 0;
    case WM_SIZE:
    if(DeviceContext& wParam!= SIZE_MINIMIZED)
    {
    D2DResizeTargetBitmap();
    D2DRender();
    }
    返回0;
    case WM_DISPLAYCHANGE:
    D2DRender();
    return 0;
    case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
    }
    return DefWindowProc(hWnd,message,wParam,lParam);
    }

    窗口没有 CS_HREDRAW CS_VREDRAW 设置。 swapchain是双缓冲的,并且使用SyncInterval = 0进行 Present 调用。



    我知道重新创建swapchain缓冲区每次窗口大小更改创建一些开销相比,在静态窗口表面上的平滑重绘。然而,口吃不是由于这种情况引起的,因为即使在窗口调整大小期间禁用缓冲器调整大小并且简单地缩小现有窗口内容(即使 make c> CreateSwapChainForHwnd 当调用 CreateSwapChainForHwnd ,请确保已将交换链描述 Scaling 属性设置为 DXGI_SCALING_NONE 。这只支持在Windows 7平台更新,所以你可能需要回到默认 DXGI_SCALING_STRETCH (后者是导致闪烁)。


    It annoys me that the resizing of windows in Windows is not as "smooth" as it I'd like it to be (this is the case with Windows programs in general, not just my own. Visual Studio is a good example). It makes the OS and its programs feel "flimsy" and "cheap" (yes, I care about how programs and user interfaces feel, in the same way I care about the sound and feel of closing a car door. It's a reflection of build quality), which in my view affects the overall UX and ultimately the perception of the brand.

    The redrawing of window contents simply does not keep up with mouse movement during resize. Whenever I resize a window, there is a "stuttering" / "flickering" effect, seemingly due to the previous-size-contents of the window being redrawn in the new, resized window frame before the new, resized contents are drawn.

    I am building a Win32 application (x64) that uses Direct2D 1.1 to draw its UI, and given the speed of Direct2D, i think it should be unnecessary to suffer such artifacts in an OS in 2014. I am on Windows 8.1 myself, but targeting Windows 7 and up with this application.

    The "previous size" effect is especially discernible when maximizing a small window (since the difference in window size is sufficiently great to easily contrast the image of the old content as it flashes briefly in the upper left corner of the larger window with the new content subsequently being painted over it).

    This is what appears to be going on:

    1. (Let's say there's a fully rendered window on screen, size 500 x 500 pixels).
    2. I maximize the window:
    3. The window frame is maximized
    4. The old 500 x 500 content is drawn in the new frame, before..
    5. ..the maximized window is repainted with properly sized content.

    I'm wondering if there's any way to mitigate this (i.e. get rid of step 4) - via intercepting a Windows Message, for example - and avoid the window being repainted at the new size with the old content before the final re-rendering of the new content happens. It's like Windows does the window redrawing itself, using whatever graphics it already has available, BEFORE it bothers to ask me to provide updated content with a WM_PAINT message or similar.

    Can it be done?

    Edit: It seems that WM_WINDOWPOSCHANGING / WM_SIZING provides "early access" to the new size data, but I still haven't managed to suppress the painting of the old content.

    My WndProc looks like this:

    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_ERASEBKGND:
            return 1;
        case WM_PAINT:
            PAINTSTRUCT ps;
            BeginPaint(hWnd, &ps);
            D2DRender();
            EndPaint(hWnd, &ps);
            return 0;
        case WM_SIZE:
            if (DeviceContext && wParam != SIZE_MINIMIZED)
            {
                D2DResizeTargetBitmap();
                D2DRender();
            }
            return 0;
        case WM_DISPLAYCHANGE:
            D2DRender();
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    

    The window does not have CS_HREDRAW or CS_VREDRAW set. The swapchain is double buffered and the Present call is made with SyncInterval = 0.

    I am aware that recreating the swapchain buffers every time the window size changes does create some overhead compared to plain redrawing on a static window surface. However, the "stuttering" is not caused by that, as it happens even when buffer resizing is disabled and existing window contents are simply scaled during window resizing (although that does make it keep up better with mouse movement).

    解决方案

    When calling CreateSwapChainForHwnd, ensure that you have set the swap chain description Scaling property to DXGI_SCALING_NONE. This is only supported on Windows 7 with the Platform Update, so you may need to fall back to the default DXGI_SCALING_STRETCH (the latter is what is causing the flickering).

    这篇关于在Windows平滑窗口调整大小(使用Direct2D 1.1)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆