Alexandre Julliard : winex11.drv: Fix handling of strange window sizes in CreateWindow, with tests.

Lei Zhang thestig at google.com
Tue Jan 22 17:56:13 CST 2008


On Jan 22, 2008 4:01 AM, Alexandre Julliard <julliard at winehq.org> wrote:
> Module: wine
> Branch: master
> Commit: 390ae9cc2845fe002bc2e68c14d104d927af68b1
> URL:    http://source.winehq.org/git/wine.git/?a=commit;h=390ae9cc2845fe002bc2e68c14d104d927af68b1
>
> Author: Alexandre Julliard <julliard at winehq.org>
> Date:   Tue Jan 22 10:16:19 2008 +0100
>
> winex11.drv: Fix handling of strange window sizes in CreateWindow, with tests.
>
> ---
>
>  dlls/user32/tests/win.c   |   79 +++++++++++++++++++++++++++++++++++++++++++++
>  dlls/winex11.drv/window.c |   42 +++++-------------------
>  2 files changed, 88 insertions(+), 33 deletions(-)
>
> diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c
> index 49fe766..d0a9673 100644
> --- a/dlls/user32/tests/win.c
> +++ b/dlls/user32/tests/win.c
> @@ -3733,6 +3733,43 @@ static LRESULT CALLBACK minmax_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM l
>      return 1;
>  }
>
> +static int expected_cx, expected_cy;
> +static RECT expected_rect;
> +
> +static LRESULT CALLBACK winsizes_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
> +{
> +    switch(msg)
> +    {
> +    case WM_GETMINMAXINFO:
> +    {
> +        RECT rect;
> +        GetWindowRect( hwnd, &rect );
> +        ok( !rect.left && !rect.top && !rect.right && !rect.bottom,
> +            "wrong rect %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
> +        return DefWindowProc(hwnd, msg, wp, lp);
> +    }
> +    case WM_NCCREATE:
> +    case WM_CREATE:
> +    {
> +        CREATESTRUCTA *cs = (CREATESTRUCTA *)lp;
> +        RECT rect;
> +        GetWindowRect( hwnd, &rect );
> +        trace( "hwnd %p msg %x size %dx%d rect %d,%d-%d,%d\n",
> +               hwnd, msg, cs->cx, cs->cy, rect.left, rect.top, rect.right, rect.bottom );
> +        ok( cs->cx == expected_cx, "wrong x size %d/%d\n", cs->cx, expected_cx );
> +        ok( cs->cy == expected_cy, "wrong y size %d/%d\n", cs->cy, expected_cy );
> +        ok( rect.right - rect.left == expected_rect.right - expected_rect.left &&
> +            rect.bottom - rect.top == expected_rect.bottom - expected_rect.top,
> +            "wrong rect %d,%d-%d,%d / %d,%d-%d,%d\n",
> +            rect.left, rect.top, rect.right, rect.bottom,
> +            expected_rect.left, expected_rect.top, expected_rect.right, expected_rect.bottom );
> +        return DefWindowProc(hwnd, msg, wp, lp);
> +    }
> +    default:
> +        return DefWindowProc(hwnd, msg, wp, lp);
> +    }
> +}
> +
>  static void test_CreateWindow(void)
>  {
>      WNDCLASS cls;
> @@ -3986,11 +4023,53 @@ static void test_CreateWindow(void)
>      ok(EqualRect(&rc, &rc_minmax), "rects don't match: (%d,%d-%d,%d) and (%d,%d-%d,%d)\n",
>         rc.left, rc.top, rc.right, rc.bottom,
>         rc_minmax.left, rc_minmax.top, rc_minmax.right, rc_minmax.bottom);
> +    DestroyWindow(hwnd);
> +
> +    cls.lpfnWndProc = winsizes_wnd_proc;
> +    cls.lpszClassName = "Sizes_WndClass";
> +    RegisterClass(&cls);
> +
> +    expected_cx = expected_cy = 200000;
> +    SetRect( &expected_rect, 0, 0, 200000, 200000 );
> +    hwnd = CreateWindowExA(0, "Sizes_WndClass", NULL, WS_CHILD, 300000, 300000, 200000, 200000, parent, 0, 0, NULL);
> +    ok( hwnd != 0, "creation failed err %u\n", GetLastError());
> +    GetClientRect( hwnd, &rc );
> +    ok( rc.right == 200000, "invalid rect right %u\n", rc.right );
> +    ok( rc.bottom == 200000, "invalid rect bottom %u\n", rc.bottom );
> +    DestroyWindow(hwnd);
> +
> +    expected_cx = expected_cy = -10;
> +    SetRect( &expected_rect, 0, 0, 0, 0 );
> +    hwnd = CreateWindowExA(0, "Sizes_WndClass", NULL, WS_CHILD, -20, -20, -10, -10, parent, 0, 0, NULL);
> +    ok( hwnd != 0, "creation failed err %u\n", GetLastError());
> +    GetClientRect( hwnd, &rc );
> +    ok( rc.right == 0, "invalid rect right %u\n", rc.right );
> +    ok( rc.bottom == 0, "invalid rect bottom %u\n", rc.bottom );
> +    DestroyWindow(hwnd);
>
> +    expected_cx = expected_cy = -200000;
> +    SetRect( &expected_rect, 0, 0, 0, 0 );
> +    hwnd = CreateWindowExA(0, "Sizes_WndClass", NULL, WS_CHILD, -300000, -300000, -200000, -200000, parent, 0, 0, NULL);
> +    ok( hwnd != 0, "creation failed err %u\n", GetLastError());
> +    GetClientRect( hwnd, &rc );
> +    ok( rc.right == 0, "invalid rect right %u\n", rc.right );
> +    ok( rc.bottom == 0, "invalid rect bottom %u\n", rc.bottom );
>      DestroyWindow(hwnd);
> +
> +    /* top level window */
> +    expected_cx = expected_cy = 200000;
> +    SetRect( &expected_rect, 0, 0, GetSystemMetrics(SM_CXMAXTRACK), GetSystemMetrics(SM_CYMAXTRACK) );
> +    hwnd = CreateWindowExA(0, "Sizes_WndClass", NULL, WS_OVERLAPPEDWINDOW, 300000, 300000, 200000, 200000, 0, 0, 0, NULL);
> +    ok( hwnd != 0, "creation failed err %u\n", GetLastError());
> +    GetClientRect( hwnd, &rc );
> +    ok( rc.right <= expected_cx, "invalid rect right %u\n", rc.right );
> +    ok( rc.bottom <= expected_cy, "invalid rect bottom %u\n", rc.bottom );
> +    DestroyWindow(hwnd);
> +
>      DestroyWindow(parent);
>
>      UnregisterClass("MinMax_WndClass", GetModuleHandle(0));
> +    UnregisterClass("Sizes_WndClass", GetModuleHandle(0));
>
>  #undef expect_menu
>  #undef expect_style
> diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
> index 84209b7..3f65602 100644
> --- a/dlls/winex11.drv/window.c
> +++ b/dlls/winex11.drv/window.c
> @@ -1296,37 +1296,13 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
>      CBT_CREATEWNDA cbtc;
>      CREATESTRUCTA cbcs;
>      BOOL ret = FALSE;
> +    INT cx = cs->cx, cy = cs->cy;
>
>      if (!(data = alloc_win_data( display, hwnd ))) return FALSE;
>
> -    if (cs->cx > 65535)
> -    {
> -        ERR( "invalid window width %d\n", cs->cx );
> -        cs->cx = 65535;
> -    }
> -    if (cs->cy > 65535)
> -    {
> -        ERR( "invalid window height %d\n", cs->cy );
> -        cs->cy = 65535;
> -    }
> -    if (cs->cx < 0)
> -    {
> -        ERR( "invalid window width %d\n", cs->cx );
> -        cs->cx = 0;
> -    }
> -    if (cs->cy < 0)
> -    {
> -        ERR( "invalid window height %d\n", cs->cy );
> -        cs->cy = 0;
> -    }
> -
>      if (hwnd == GetDesktopWindow()) get_desktop_xwin( display, data );
>      else
>      {
> -        /* initialize the dimensions before sending WM_GETMINMAXINFO */
> -        SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
> -        X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER | SWP_NOACTIVATE, NULL );
> -
>          /* create an X window if it's a top level window */
>          if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
>          {
> @@ -1360,16 +1336,16 @@ BOOL X11DRV_CreateWindow( HWND hwnd, CREATESTRUCTA *cs, BOOL unicode )
>          POINT maxSize, maxPos, minTrack, maxTrack;
>
>          WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack);
> -        if (maxTrack.x < cs->cx) cs->cx = maxTrack.x;
> -        if (maxTrack.y < cs->cy) cs->cy = maxTrack.y;
> -        if (cs->cx < 0) cs->cx = 0;
> -        if (cs->cy < 0) cs->cy = 0;
> -
> -        SetRect( &rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
> -        if (!X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER | SWP_NOACTIVATE, NULL ))
> -            return FALSE;
> +        if (maxTrack.x < cx) cx = maxTrack.x;
> +        if (maxTrack.y < cy) cy = maxTrack.y;
>      }
>
> +    if (cx < 0) cx = 0;
> +    if (cy < 0) cy = 0;
> +    SetRect( &rect, cs->x, cs->y, cs->x + cx, cs->y + cy );
> +    if (!X11DRV_SetWindowPos( hwnd, 0, &rect, &rect, SWP_NOZORDER | SWP_NOACTIVATE, NULL ))
> +        return FALSE;
> +
>      /* send WM_NCCREATE */
>      TRACE( "hwnd %p cs %d,%d %dx%d\n", hwnd, cs->x, cs->y, cs->cx, cs->cy );
>      if (unicode)
>
>
>
>

I've having trouble on my dual screen (twinview) setup with this patch.

With a fresh ~/.wine directory, I ran notepad or regedit. The app
starts on the left monitor. When I move the window to the right
monitor, the window is no longer being redrawn.



More information about the wine-devel mailing list