3

Screenshot: https://i.stack.imgur.com/5NKZI.jpg

Hello, I am trying to set png with alpha channel on top of static control, but transparent pixels always fill white or black color.

It's not critical if the image is on top of the static control or just drawn on main window.

If you have some ideas please give feedback.
THX

Sorry I should have post code before

//First try loading icon with transparency to static control or button:
//static control;

HWND hL;
HICON iStick;
case WM_CREATE:
iStick = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 0, 0, LR_LOADTRANSPARENT);
hL = CreateWindow(L"STATIC", NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP/*SS_ICON*/, 193, 290, 32, 32, hwnd, NULL, hInst, NULL);
SendMessage(hL, STM_SETIMAGE, IMAGE_ICON, (LPARAM)iStick);
//SendMessage(hL, STM_SETICON, IMAGE_ICON, (LPARAM)iStick);

//Second try to draw on background 32bit bmp A8R8G8B8 : 

PAINTSTRUCT ps;
HDC hdc;
RECT r;
static HDC membit;
static BITMAP bm;

case WM_CREATE:
    SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_TOPMOST | WS_EX_LAYERED);
    SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE |SWP_NOSIZE);
    SetLayeredWindowAttributes(hWnd, 0, (255 * 100) / 100, LWA_ALPHA);
    hStick = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP15));
    GetObject(hStick, sizeof(bm), &bm);
    membit = CreateCompatibleDC(hdc);
    SelectObject(membit, hStick);
    ReleaseDC(hWnd, hdc);

case WM_CTLCOLOREDIT:
    SetTextColor((HDC)wParam, RGB(65, 65, 65));      //
    return 0;

//MakeStaticbackground transparent
case WM_CTLCOLORSTATIC:       
    SetBkMode((HDC)wParam, TRANSPARENT);             //  
    SetTextColor((HDC)wParam, RGB(38, 205, 247));    //
    return (BOOL)GetStockObject(NULL_BRUSH);    

case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);

    GetClientRect(hWnd, &r);

    FillRect(hdc, &r, hBrush);
    SetBkMode(hdc, TRANSPARENT);

    BLENDFUNCTION BlendFunction;
    BlendFunction.AlphaFormat = AC_SRC_ALPHA;
    BlendFunction.BlendFlags = 0;
    BlendFunction.BlendOp = AC_SRC_OVER;
    BlendFunction.SourceConstantAlpha = 255;

    //BitBlt(hdc, 500, 280, bm.bmWidth, bm.bmHeight, membit, 0, 0, SRCCOPY);

    AlphaBlend(hdc, 500, 280, bm.bmWidth, bm.bmHeight, membit, 0, 0, 32, 32, BlendFunction);

    //TransparentBlt(hdc, 500, 300, 32, 32, membit, 32, 32, 32, 32, RGB(255, 255, 255));

    EndPaint(hWnd, &ps);

    break;

case WM_ERASEBKGND:
    return (LRESULT)1;

And more which I don`t remember but background pixels always fill white or black colour.

Borys Shobat
  • 258
  • 1
  • 3
  • 13

1 Answers1

0

I think you just want transparency, not alpha channel. You would need LWA_COLORKEY instead of LWA_ALPHA

SetLayeredWindowAttributes(hWnd, window_background_brush, 255, LWA_COLORKEY);

This will replace window_background_brush with transparent color. If background brush is not set, you need to set, preferably white color. Also it's better to use icon otherwise you end up with rough edges. Here is sample code for drawing icon:

HDC hDC = ::GetDC(m_hWnd);
HICON hicon = (HICON)LoadImage(NULL, "fullpath.ico", IMAGE_ICON, w, h, LR_LOADFROMFILE);
DrawIconEx(hDC, x, y, hicon, w, h, 0, NULL, DI_NORMAL);
DestroyIcon(hicon);
::ReleaseDC(m_hWnd, hDC);
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • Thanks Barmak your code works well, but I used your code in function which polls joystick 60 times per second I got this: http://i.imgur.com/jha99iQ.gif?1 HDC hDC = ::GetDC(hwnd); DrawIconEx(hDC, 193 + (js.lX / 22), 290 + (js.lY / 22), iStick, 32, 32, 0, NULL, DI_NORMAL); DrawIconEx(hDC, 340 + (js.lZ / 22), 290 + (js.lRz / 22), iStick, 32, 32, 0, NULL, DI_NORMAL); //DestroyIcon(iStick); ReleaseDC(hwnd, hDC); – Borys Shobat Apr 10 '15 at 09:25
  • Excellent. But there is a lot of flicker, or maybe that's caused by taking screen shot. I thought you needed transparency for background image but that doesn't seem to be the case. I would remove `WS_EX_LAYERED` and `SetLayeredWindowAttributes`. Draw the background image with normal bitmap. Only draw those moving black sprites with icon. Also add `WS_CLIPCHILDREN`. If there is still flicker you may try ExcludeClipRect to manually exclude the control region in paint. – Barmak Shemirani Apr 10 '15 at 12:00