SetBkMode(hdc,TRANSPARENT)不起作用

时间:2012-08-05 07:01:58

标签: c winapi text gdi

当我在下面的代码中使用SetBkMode(hdc, TRANSPARENT);时,我在调整主窗口大小时会产生以下效果(因此当孩子收到WM_PAINT消息时):

enter image description here

问题是:当我调整主窗口的大小时,我想,“查找:”的旧区域会被删除。但它仍然存在。

如果我不使用SetBkMode(hdc, TRANSPARENT);,我就没有这个问题。它看起来像:

enter image description here

,即它有白色背景。此外,如果我使用SetBkMode(hdc, TRANSPARENT);,在调整主窗口大小之前,它看起来与上面相同。所以我认为SetBkMode(hdc, TRANSPARENT);在这里不起作用。

hwnd是一个样式为SS_BITMAP的静态子项。

你知道为什么会出现这个问题吗?

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;

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

2 个答案:

答案 0 :(得分:0)

尝试使用“固定”矩形。例如

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

这个想法是你在错误的位置(一次)和正确的位置(两次)绘制文本,而背景只更新一次。关于部分代码,不能多说。

答案 1 :(得分:0)

问题是windows没有更新静态控件后面的控件(及时),你现在负责它的内容。所以你想使用父母提供的背景。那么请让父母在子窗口中为您绘制它:

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

其中

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

现在绘制你喜欢的任何内容,我建议你使用TRANSPARENT后台模式。

请使用样式WS_CLIPCHILDRENWS_CLIPSIBLINGS创建所有子窗口,然后这些问题会立即显现,并避免闪烁。