SetBkMode(hdc, TRANSPARENT) doesn't work

泪湿孤枕 提交于 2020-01-15 11:51:36

问题


When I use SetBkMode(hdc, TRANSPARENT); in the code below, I got the following effect when I resize the main window (and hence when the child receives the WM_PAINT message):

The problem is : When I resize the main window, The old area of "Find:" shoule be erased, I guess. But it just remains there.

If I don't use SetBkMode(hdc, TRANSPARENT);, I don't have this problem. It looks like:

, i.e it has white background. Furthermore, if I use SetBkMode(hdc, TRANSPARENT);, it looks like the same as above, before I resize the main window. So I don't think SetBkMode(hdc, TRANSPARENT); works here.

the hwnd is a static child with style SS_BITMAP.

Do you know why this issue occurs?

switch (message) {
    case WM_PAINT:
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);

        SelectObject(hdc, gDefaultGuiFont);
        SetBkMode(hdc, TRANSPARENT);

        RECT rc;
        GetClientRect(hwnd, &rc);
        DrawText(hdc, _TR("Find:"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

        EndPaint(hwnd, &ps);

        return 0;

     .............
}

回答1:


Try to use "fixed" rectangles. For example

    RECT rc;
    GetClientRect(hwnd, &rc);
    rc.left += ...; rc.top += ...; // shift up-left point
    DrawText(hdc, _TR("Find:"), -1, &rc, DT_SINGLELINE | DT_LEFT | DT_TOP);

The idea is you draw text in wrong position (once) and in right position (twice) while backgound updated only once. Can't say more on part of code.




回答2:


The problem is that windows is not updating the control (in time) that's behind your static control, you are now responsible for it's contents. So you want to use the background provided by the parent. Well just ask the parent to draw it for you in the child window:

RECT rc;
GetClientRectRelative(m_hWnd, GetParent(m_hWnd), &rc);
SetWindowOrgEx(m_mdc, rc.left, rc.top, NULL);
SendMessage(GetParent(m_hWnd), WM_PAINT, (WPARAM)(HDC)m_mdc);
SetWindowOrgEx(m_mdc, 0, 0, NULL);

In which

bool GetClientRectRelative(HWND hWnd, HWND hWndRelativeTo, RECT *pRect)
{
    RECT rcWnd, rcRelativeTo;
    if (!GetClientRect(hWnd, &rcWnd) ||
            !ClientToScreen(hWnd, (POINT*)&rcWnd) ||
            !ClientToScreen(hWnd, (POINT*)&rcWnd + 1) ||
            !GetClientRect(hWndRelativeTo, &rcRelativeTo) || 
            !ClientToScreen(hWndRelativeTo, (POINT*)&rcRelativeTo) ||
            !ClientToScreen(hWndRelativeTo, (POINT*)&rcRelativeTo + 1))
        return false;

    pRect->top = rcWnd.top - rcRelativeTo.top;
    pRect->left = rcWnd.left - rcRelativeTo.left;
    pRect->right = rcWnd.right - rcRelativeTo.left;
    pRect->bottom = rcWnd.bottom - rcRelativeTo.top;

    return true;
}

Now draw anything you like, I suggest you'd use the TRANSPARENT background mode.

Please create all your child windows with the styles WS_CLIPCHILDREN and WS_CLIPSIBLINGS, then these problems will become apparent immediately and you avoid flicker.



来源:https://stackoverflow.com/questions/11814563/setbkmodehdc-transparent-doesnt-work

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!