I found this code in stackoverflow and it really draws a rectangle on a transparent window using a bitmap. But somehow I cannot change the transparency of the rectangle. More precisely, I can, but it gets darker. As if the bitmap itself has a black background. How do I make the rectangle transparent?
void paintRect(HDC hdc, RECT dim, COLORREF penCol, COLORREF brushCol, int opacity)
{
HDC tempHDC = CreateCompatibleDC(hdc);
BITMAPINFO bitmapInfo;
ZeroMemory(&bitmapInfo, sizeof(BITMAPINFO));
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = dim.right - dim.left;
bitmapInfo.bmiHeader.biHeight = dim.bottom - dim.top;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
bitmapInfo.bmiHeader.biSizeImage = (dim.right - dim.left) * (dim.bottom - dim.top) * 4;
HBITMAP hBitmap = CreateDIBSection(tempHDC, &bitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0x0);
SelectObject(tempHDC, hBitmap);
SetDCPenColor(tempHDC, RGB(0, 0, 255));
SetDCBrushColor(tempHDC, RGB(0, 0, 255));
FillRect(tempHDC, &dim, CreateSolidBrush(RGB(0, 0, 255)));
BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 };
AlphaBlend(hdc, dim.left, dim.top, dim.right, dim.bottom, tempHDC, dim.left, dim.top, dim.right, dim.bottom, blend);
}
Full code
#include <Windows.h>
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow);
LRESULT CALLBACK windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
WNDCLASS windowClass {};
windowClass.lpfnWndProc = windowProc;
windowClass.hInstance = hInstance;
windowClass.lpszClassName = L"Keystrokes";
windowClass.style = CS_NOCLOSE;
windowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
if (!RegisterClass(&windowClass))
{
return 0;
}
HWND hwnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW, L"Keystrokes", L"Keystrokes", WS_POPUP, 0, 0, 148, 140, 0, 0, hInstance, 0);
if (!hwnd)
{
return 0;
}
SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 0, LWA_COLORKEY);
ShowWindow(hwnd, nCmdShow);
MSG msg {};
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
void paintRect(HDC hdc, RECT dim, COLORREF penCol, COLORREF brushCol, int opacity)
{
HDC tempHDC = CreateCompatibleDC(hdc);
BITMAPINFO bitmapInfo;
ZeroMemory(&bitmapInfo, sizeof(BITMAPINFO));
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = dim.right - dim.left;
bitmapInfo.bmiHeader.biHeight = dim.bottom - dim.top;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
bitmapInfo.bmiHeader.biSizeImage = (dim.right - dim.left) * (dim.bottom - dim.top) * 4;
HBITMAP hBitmap = CreateDIBSection(tempHDC, &bitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0x0);
SelectObject(tempHDC, hBitmap);
SetDCPenColor(tempHDC, RGB(0, 0, 255));
SetDCBrushColor(tempHDC, RGB(0, 0, 255));
FillRect(tempHDC, &dim, CreateSolidBrush(RGB(0, 0, 255)));
BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255, 0 };
AlphaBlend(hdc, dim.left, dim.top, dim.right, dim.bottom, tempHDC, dim.left, dim.top, dim.right, dim.bottom, blend);
}
LRESULT CALLBACK windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_LBUTTONDOWN:
{
SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
break;
case WM_MBUTTONDOWN:
{
PostQuitMessage(0);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hwnd, &ps);
paintRect(hDC, { 0, 0, 48, 48 }, RGB(255, 0, 0), RGB(255, 255, 255), 255);
EndPaint(hwnd, &ps);
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

