How to make transparent window using UpdateLayeredWindow ?

asked 2021-11-24T18:51:23.603+00:00
T B 46 Reputation points

Hi, I hope you are doing good.
I am working in UnrealEngine and I want to make a transparent background by color, for example black color. I have tryed in two different ways.

  1. I am using SetLayeredWindowAttributes, the black color disspear but there is some grey object that becomes semy transparent. As far as I understand it's because this uses 24bit colors. Please correct me if I am wrong. This is the code I have used: SetWindowLongPtr(hwnd, GWL_STYLE, WS_VISIBLE);
    SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TRANSPARENT);
    RECT rect;
    GetWindowRect(hwnd, &rect);
    SetWindowPos(hwnd, HWND_TOPMOST, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_SHOWWINDOW);
    SetLayeredWindowAttributes(hwnd, 0, 0, LWA_ALPHA);
    SetWindowLong(hwnd, -20, 524288 | 32);
    SetLayeredWindowAttributes(hwnd, RGB(0,0,0), 255, LWA_COLORKEY);
    const MARGINS margins{ -1 };
    DwmExtendFrameIntoClientArea(hwnd, &margins);
    HRGN rgn;
    DWM_BLURBEHIND blur;
    rgn = CreateRectRgn(rect.left, rect.top, rect.right, rect.bottom);
    blur.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
    blur.fEnable = true; //why the fuck else would i use this -.-
    blur.fTransitionOnMaximized = true; //why not...?
    blur.hRgnBlur = rgn;
    DwmEnableBlurBehindWindow(hwnd, &blur);
    DwmExtendFrameIntoClientArea(hwnd, &margins);
  2. I am using UpdateLayeredWindow but I get a full transparent window like is getting no image.
    HDC hdc = GetDC(hwnd);
    HDC hdc1 = CreateCompatibleDC(hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);
    HBITMAP hBmpOld = (HBITMAP)SelectObject(hdc, hBitmap);
    SelectObject ( hdc, hBitmap );
    if (hdc)
    
    {
    HGDIOBJ hPrevObj = 0;
    POINT ptDest = {0, 0};
    POINT ptSrc = {0, 0};
    SIZE client = {rect.right - rect.left, rect.bottom - rect.top};
    BLENDFUNCTION blendFunc = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
     UpdateLayeredWindow(hwnd, hdc1, &ptDest, &client, hdc, &ptSrc, RGB(0, 0, 0), &blendFunc, ULW_COLORKEY);
     SelectObject(hdc, hBmpOld);
     DeleteObject(hBitmap);
     DeleteDC(hdc);
     ReleaseDC(NULL, hdc1);
    
    }

Any help is apreciated. Thankyou very much !

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
1,890 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
2,617 questions
No comments
{count} votes

Accepted answer
  1. answered 2021-11-24T20:43:14.623+00:00
    Castorix31 65,331 Reputation points

    A test with a .JPG with UpdateLayeredWindow and white color as transparent color =>

    152338-little-girl.gif

    Remove the space at S leep (bug in this editor...)

    #include <windows.h>  
    #include <tchar.h>  
      
    #include "gdiplus.h"  
    using namespace Gdiplus;  
    #pragma comment(lib, "gdiplus.lib")  
      
    #include <Urlmon.h> // URLDownloadToCacheFile  
    #pragma comment (lib, "Urlmon")  
      
    #include <shlwapi.h> // SHCreateStreamOnFile  
    #pragma comment (lib, "shlwapi")  
      
    #pragma comment(linker,"\"/manifestdependency:type='win32' \  
    name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \  
    processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")  
      
    HINSTANCE hInst;  
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  
    int nWidth = 600, nHeight = 400;  
      
    BOOL SetPicture(HWND hWnd, HBITMAP hBmp, COLORREF nColor);  
      
    int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)  
    {  
    	GdiplusStartupInput gdiplusStartupInput;  
    	ULONG_PTR gdiplusToken;  
    	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);  
      
    	hInst = hInstance;  
    	WNDCLASSEX wcex =  
    	{  
    		sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, WndProc, 0, 0, hInst, LoadIcon(NULL, IDI_APPLICATION),  
    		LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, TEXT("WindowClass"), NULL,  
    	};  
    	if (!RegisterClassEx(&wcex))  
    		return MessageBox(NULL, TEXT("Cannot register class !"), TEXT("Error"), MB_ICONERROR | MB_OK);  
    	int nX = (GetSystemMetrics(SM_CXSCREEN) - nWidth) / 2, nY = (GetSystemMetrics(SM_CYSCREEN) - nHeight) / 2;  
    	HWND hWnd = CreateWindowEx(WS_EX_NOREDIRECTIONBITMAP | WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_NOACTIVATE, wcex.lpszClassName, TEXT("Test"), WS_POPUP | WS_VISIBLE, nX, nY, nWidth, nHeight, NULL, NULL, hInst, NULL);  
    	if (!hWnd)  
    		return MessageBox(NULL, TEXT("Cannot create window !"), TEXT("Error"), MB_ICONERROR | MB_OK);  
    	ShowWindow(hWnd, SW_SHOWNORMAL);  
    	UpdateWindow(hWnd);  
    	MSG msg;  
    	while (GetMessage(&msg, NULL, 0, 0))  
    	{  
    		TranslateMessage(&msg);  
    		DispatchMessage(&msg);  
    	}  
    	return (int)msg.wParam;  
    }  
      
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
    {  
    	static HWND hWndButton = NULL, hWndStatic = NULL;  
    	int wmId, wmEvent;  
    	switch (message)  
    	{  
    	case WM_CREATE:  
    	{	  
    		WCHAR wsURL[MAX_PATH] = TEXT("https://image.ibb.co/buLv2e/Little_Girl3.jpg");  
    		WCHAR wsFilename[MAX_PATH];  
    		HRESULT hr = URLDownloadToCacheFile(NULL, wsURL, wsFilename, ARRAYSIZE(wsFilename), 0x0, NULL);  
    		if (SUCCEEDED(hr))  
    		{  
    			IStream* pStream = NULL;  
    			hr = SHCreateStreamOnFile(wsFilename, STGM_READ | STGM_SHARE_DENY_WRITE, &pStream);  
    			if (SUCCEEDED(hr))  
    			{  
    				HBITMAP hBitmap = NULL;  
    				Gdiplus::Bitmap* pBitmap = new Gdiplus::Bitmap(pStream);  
    				if (pBitmap)  
    				{  
    					pBitmap->GetHBITMAP(Gdiplus::Color(255, 255, 255), &hBitmap);  
    					SetPicture(hWnd, hBitmap, RGB(255, 255, 255));					  
    				}  
    			}  
    		}		  
    		return 0;  
    	}  
    	break;  
    	case WM_NCHITTEST:  
    	{  
    		return HTCAPTION;  
    	}  
    	break;  
    	case WM_NCRBUTTONDOWN:  
    	{		  
    		S leep(200);  
    		DestroyWindow(hWnd);  
    	}  
    	break;  
    	case WM_DESTROY:  
    	{  
    		PostQuitMessage(0);  
    		return 0;  
    	}  
    	break;  
    	default:  
    		return DefWindowProc(hWnd, message, wParam, lParam);  
    	}  
    	return 0;  
    }  
      
    BOOL SetPicture(HWND hWnd, HBITMAP hBmp, COLORREF nColor)  
    {  
    	BITMAP bm;  
    	GetObject(hBmp, sizeof(bm), &bm);  
    	SIZE szBmp = { bm.bmWidth, bm.bmHeight };  
      
    	HDC hDCScreen = GetDC(NULL);  
    	HDC hDCMem = CreateCompatibleDC(hDCScreen);  
    	HBITMAP hBmpOld = (HBITMAP)SelectObject(hDCMem, hBmp);  
      
    	BLENDFUNCTION blend = { 0 };  
    	blend.BlendOp = AC_SRC_OVER;  
    	blend.SourceConstantAlpha = 255;  
    	//blend.AlphaFormat = AC_SRC_OVER;  
    	blend.AlphaFormat = AC_SRC_ALPHA;  
      
    	RECT rc;  
    	GetWindowRect(hWnd, &rc);  
      
    	POINT ptSrc = { 0 };  
    	POINT ptDest = { rc.left, rc.top };  
    	BOOL bRet = UpdateLayeredWindow(  
    		hWnd,  
    		hDCScreen,  
    		&ptDest,  
    		&szBmp,  
    		hDCMem,  
    		&ptSrc,  
    		nColor,  
    		&blend,  
    		//ULW_ALPHA);  
    		ULW_COLORKEY);  
      
    	SelectObject(hDCMem, hBmpOld);  
    	DeleteDC(hDCMem);  
    	ReleaseDC(NULL, hDCScreen);  
    	return bRet;  
    }  
      
      
    

0 additional answers

Sort by: Most helpful