SDL2 调用函数 阻塞

 

调用 SDL_CreateWindowFrom 时阻塞,原因:窗体(或控件)挂起时,调用GetWindowTextLength()等windows API时,会阻塞

 

 1 int
 2 WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
 3 {
 4     HWND hwnd = (HWND) data;
 5     LPTSTR title;
 6     int titleLen;
 7 
 8     /* Query the title from the existing window */
 9     // 注释掉
10     /*titleLen = GetWindowTextLength(hwnd);
11     title = SDL_stack_alloc(TCHAR, titleLen + 1);
12     if (title) {
13         titleLen = GetWindowText(hwnd, title, titleLen);
14     } else {
15         titleLen = 0;
16     }
17     if (titleLen > 0) {
18         window->title = WIN_StringToUTF8(title);
19     }
20     if (title) {
21         SDL_stack_free(title);
22     }*/
23 
24     if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) {
25         return -1;
26     }
27 
28 #if SDL_VIDEO_OPENGL_WGL
29     {
30         const char *hint = SDL_GetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT);
31         if (hint) {
32             /* This hint is a pointer (in string form) of the address of
33                the window to share a pixel format with
34             */
35             SDL_Window *otherWindow = NULL;
36             SDL_sscanf(hint, "%p", (void**)&otherWindow);
37 
38             /* Do some error checking on the pointer */
39             if (otherWindow != NULL && otherWindow->magic == &_this->window_magic)
40             {
41                 /* If the otherWindow has SDL_WINDOW_OPENGL set, set it for the new window as well */
42                 if (otherWindow->flags & SDL_WINDOW_OPENGL)
43                 {
44                     window->flags |= SDL_WINDOW_OPENGL;
45                     if(!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) {
46                         return -1;
47                     }
48                 }
49             }
50         }
51     }
52 #endif
53     return 0;
54 }

 

static int
SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created)
{
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    SDL_WindowData *data;

    /* Allocate the window data */
    data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
    if (!data) {
        return SDL_OutOfMemory();
    }
    data->window = window;
    data->hwnd = hwnd;
    data->hdc = GetDC(hwnd);
    data->created = created;
    data->mouse_button_flags = 0;
    data->videodata = videodata;
    data->initializing = SDL_TRUE;

    window->driverdata = data;

    /* Associate the data with the window */
    if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) {
        ReleaseDC(hwnd, data->hdc);
        SDL_free(data);
        return WIN_SetError("SetProp() failed");
    }

    /* Set up the window proc function */
#ifdef GWLP_WNDPROC
    data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
    if (data->wndproc == WIN_WindowProc) {
        data->wndproc = NULL;
    } else {
        SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc);
    }
#else
    data->wndproc = (WNDPROC) GetWindowLong(hwnd, GWL_WNDPROC);
    if (data->wndproc == WIN_WindowProc) {
        data->wndproc = NULL;
    } else {
        SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR) WIN_WindowProc);
    }
#endif

    /* Fill in the SDL window with the window data */
    {
        RECT rect;
        if (GetClientRect(hwnd, &rect)) {
            int w = rect.right;
            int h = rect.bottom;
            if ((window->w && window->w != w) || (window->h && window->h != h)) {
                /* We tried to create a window larger than the desktop and Windows didn't allow it.  Override! */
                RECT rect;
                DWORD style;
                BOOL menu;
                int x, y;
                int w, h;

                /* Figure out what the window area will be */
                style = GetWindowLong(hwnd, GWL_STYLE);
                rect.left = 0;
                rect.top = 0;
                rect.right = window->w;
                rect.bottom = window->h;
                menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL);
                AdjustWindowRectEx(&rect, style, menu, 0);
                w = (rect.right - rect.left);
                h = (rect.bottom - rect.top);
                x = window->x + rect.left;
                y = window->y + rect.top;

                SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, w, h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE);
            } else {
                window->w = w;
                window->h = h;
            }
        }
    }
    {
        POINT point;
        point.x = 0;
        point.y = 0;
        if (ClientToScreen(hwnd, &point)) {
            window->x = point.x;
            window->y = point.y;
        }
    }
    {
        DWORD style = GetWindowLong(hwnd, GWL_STYLE);
        if (style & WS_VISIBLE) {
            window->flags |= SDL_WINDOW_SHOWN;
        } else {
            window->flags &= ~SDL_WINDOW_SHOWN;
        }
        if (style & (WS_BORDER | WS_THICKFRAME)) {
            window->flags &= ~SDL_WINDOW_BORDERLESS;
        } else {
            window->flags |= SDL_WINDOW_BORDERLESS;
        }
        if (style & WS_THICKFRAME) {
            window->flags |= SDL_WINDOW_RESIZABLE;
        } else {
            window->flags &= ~SDL_WINDOW_RESIZABLE;
        }
#ifdef WS_MAXIMIZE
        if (style & WS_MAXIMIZE) {
            window->flags |= SDL_WINDOW_MAXIMIZED;
        } else
#endif
        {
            window->flags &= ~SDL_WINDOW_MAXIMIZED;
        }
#ifdef WS_MINIMIZE
        if (style & WS_MINIMIZE) {
            window->flags |= SDL_WINDOW_MINIMIZED;
        } else
#endif
        {
            window->flags &= ~SDL_WINDOW_MINIMIZED;
        }
    }
    if (GetFocus() == hwnd) {
        window->flags |= SDL_WINDOW_INPUT_FOCUS;
        SDL_SetKeyboardFocus(data->window);

        if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
            RECT rect;
            GetClientRect(hwnd, &rect);
            ClientToScreen(hwnd, (LPPOINT) & rect);
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
            ClipCursor(&rect);
        }
    }

    /* Enable multi-touch */
    if (videodata->RegisterTouchWindow) {
        videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH|TWF_WANTPALM));
    }

    /* Enable dropping files */
    // 注释掉
    /*DragAcceptFiles(hwnd, TRUE);*/

    data->initializing = SDL_FALSE;

    /* All done! */
    return 0;
}

 

posted @ 2016-02-26 18:36  菩提树~今生  阅读(1391)  评论(1)    收藏  举报