Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to "Clear" a WinAPI Transparent Window

Tags:

c++

winapi

gdi

I have created a Transparent Checkbox in Win32 C++. I have made it because as far as I know you cant have a transparent checkbox in native win32 and I need to use this checkbox in a NSIS installer.

My Problem: When repainting, I don't know how to erase my transparent background so I can draw on a "clear canvas". This is important when the user changes the text inside the checkbox and I need to repaint it. I guess I have run into the problem everyone must get with transparent windows.

What is the way I can clear my transparent window, Note I am familiar with WinAPI that you cant really clear a window AFAIK because you just repaint over the window. So I am looking for advice on what techniques I can use to redraw the window such as:

  • Send a repaint message to the parent window which will hopefully repaint the parent(which is the sit below the checkbox) withut sending a message down to its children(ie, the checkbox). I've tried this, it make the checkbox have a lot of flickering.
  • Maybe theres a transparent brush/paint function I dont know about that I could use to paint over the whole checkbox window which will essentially clear the window? I've tried this it makes the checkbox window black for some reason?

My code:

case WM_SET_TEXT:
{
        // set checkbox text
        // Technique 1: update parent window to clear this window
        RECT thisRect = {thisX, thisY, thisW, thisH};
        InvalidateRect(parentHwnd, &thisRect, TRUE);
}
break;
case WM_PAINT:
{
     PAINTSTRUCT ps;
     HDC hdc = BeginPaint(hwnd, &ps);
     // Technique 2:
     SetBkMode(hdc, TRANSPARENT);
     Rectangle(hdc, thisX, thisY, thisW, thisH); // doesn't work just makes the window a big black rectangle?
     EndPaint(hwnd, &ps);
}
break;  
like image 953
sazr Avatar asked Jul 13 '12 02:07

sazr


1 Answers

You need to handle the WM_ERASEBBKGND message. Something like the following should work!

case WM_ERASEBKGND:
{
    RECT rcWin;
    RECT rcWnd;
    HWND parWnd = GetParent( hwnd ); // Get the parent window.
    HDC parDc = GetDC( parWnd ); // Get its DC.

    GetWindowRect( hwnd, &rcWnd );
    ScreenToClient( parWnd, &rcWnd ); // Convert to the parent's co-ordinates

    GetClipBox(hdc, &rcWin );
    // Copy from parent DC.
    BitBlt( hdc, rcWin.left, rcWin.top, rcWin.right - rcWin.left,
        rcWin.bottom - rcWin.top, parDC, rcWnd.left, rcWnd.top, SRC_COPY );

    ReleaseDC( parWnd, parDC );
}
break;
like image 120
Ragesh Chakkadath Avatar answered Sep 19 '22 16:09

Ragesh Chakkadath