0

I am trying to draw a radiobutton with a transparent background using a subclassed radiobutton & WM_PAINT. I know how to do this using the TransparentBlt function & an off-screen (back)buffer.

My problem is that intially the radiobutton by default draws some text & circle (see image 1). My WM_PAINT message only consists of BeginPaint() and EndPaint(). When i minimize the window and afterwards activate the window again, the default text & circle get replaced by a black square like you would expect (see image 2).

The yellow window is also painted in the same manner using WM_PAINT.

Both procedures return 1 for WM_ERASEBKGND and return 0 for WM_PAINT as required for custom painting & double buffering.

Is this normal behaviour? I found a "fix" by using WS_EX_TRANSPARENT, but I would like to understand first why the radiobutton initially gets painted like that to determine if this is the right fix for me.

Thanks in advance.

Radiobutton creation:

MControlRect rect(0, 0, 100, 20);
unsigned long style = WS_CHILD | BS_AUTORADIOBUTTON;

if (isGroupStarter) {
    style += WS_GROUP;
}

::HWND hWnd = _create(pControlParent, WC_BUTTON, style, rect);

::WNDPROC systemProc = (::WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC);
::SetWindowLong(hWnd, GWL_WNDPROC, (long)customRadiobuttonProcedure);
::SetWindowLong(hWnd, GWL_USERDATA, (long)systemProc);

::UpdateWindow(hWnd);

::ShowWindow(hWnd, SW_SHOW);

Radiobutton procedure:

switch (msg) {

        case WM_ERASEBKGND:
        {

            return 1;

            break;
        }

        case WM_NCPAINT:
        {

            return 0;

            break;
        }

        case WM_PAINT:
        {


            ::PAINTSTRUCT ps;
            ::HDC hdc = ::BeginPaint(hWnd, &ps);

            ::EndPaint(hWnd, &ps);

            return 0;

            break;
        }
    }


    ::WNDPROC defaultWindowProc = (::WNDPROC)::GetWindowLong(hWnd, GWL_USERDATA);

    return ::CallWindowProc(defaultWindowProc, hWnd, msg, wParam, lParam);

Image 1: initial radiobutton painted

Image 2: radiobutton after minimize > show again

  • Maybe you are subclassing it *after* it is displayed for the first time? – user7860670 Dec 03 '17 at 20:03
  • Don't have us guess, show a [mcve]. – IInspectable Dec 03 '17 at 20:09
  • @VTT thanks for the suggestion. I thought of that aswell, but I don't believe that is what is happening right now. (See edit of how I create my radiobutton). – Joey Muiser Dec 03 '17 at 20:19
  • You should never use `SetWindowLong`, use `SetWindowLongPtr` instead, same for `Get`. – user7860670 Dec 03 '17 at 20:24
  • 2
    And you shouldn't be using `SetWindowLongPtr` either to [subclass controls](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773183.aspx). This has been wrong for more than a decade and a half. Anyway, the code doesn't comprise a [mcve]. – IInspectable Dec 03 '17 at 20:27
  • 2
    Many standard controls paint outside of `WM_PAINT` by directly drawing into a device context under some circumstances. The only safe way to do what you want is to use owner draw or custom draw. This will disable the default painting code of the underlying control, giving you complete control. – zett42 Dec 03 '17 at 21:03

0 Answers0