C display tansparent text on any background

85 Views Asked by At

I want to show the GPU and CPU usage/temperature on the right upper corner as text on every opened window, like desktop, explorer, internet browser,... My problem is, I can display the text only with a background but can not make them transparent.

I draw the text with following code:

int WINAPI main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{   
    HWND desktopHandle = GetDesktopWindow();
    HDC desk = GetDC(desktopHandle);
    const char text[] = "Hello!";
    RECT lprec = { 900 , 200, 500, 500 };
    int dres;

    while(1) 
    {
        Sleep(1);
        dres = DrawText(desk, text, -1, &lprec, DT_BOTTOM | DT_INTERNAL | DT_NOCLIP); // | DT_INTERNAL | DT_NOCLIP
        //dres = TextOutA(desk, 200, 200, text, lstrlenA(text));
        if(dres == 0) printf("Test: %i, [%llu]\r\n", dres, GetLastError());
        UpdateWindow(desktopHandle);
        InvalidateRect(desktopHandle, &lprec, 1 );
        RedrawWindow(desktopHandle, &lprec, NULL, RDW_ERASE | RDW_INVALIDATE);
        //SelectObject(desk, oldFont);

        SetLayeredWindowAttributes(desktopHandle, 0x000000, 0, 2);

        if(kbhit())
        {
            //DeleteObject(font);
            ReleaseDC(desktopHandle, desk);
            return 0;
        }
    }
}

Here is a small image from my desktop how it looks like: Image from Desktop

If the winnapi can not do this, external C librarys was also ok. I read something about SFML but I do not know if this is what I search.

1

There are 1 best solutions below

2
Erz On

I found a way. Add WS_POPUP for full transparency. If required, set the GUI to foreground.

Code:

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

int main() {
    // Register GUI
    WNDCLASS wc = {0};
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = GetModuleHandle(NULL);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszClassName = "MyWindowClass";
    RegisterClass(&wc);

    // Create GUI
    HWND hwnd = CreateWindowEx(
        WS_EX_LAYERED | WS_EX_TRANSPARENT,
        "MyWindowClass",
        "GUI title",
        WS_OVERLAPPED | WS_SYSMENU ,     // Add WS_POPUP to hide gui
        100, 100,                       // X, Y-Pos
        500, 300,                       // width, high
        NULL,                           
        NULL,                           
        GetModuleHandle(NULL),          
        NULL
    );

    // Make GUI transparent 0-255 (0 is maximal)
    SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 128, LWA_COLORKEY | LWA_ALPHA);

    const char text[] = "Hello!";
    RECT lprec = { 10 , 10, 500, 300 };
    HDC desk = GetDC(hwnd);
    SetBkMode(desk, TRANSPARENT);
    //SetTextColor(desk, 0x00FFFFFF); //white
    SetTextColor(desk, 0x000000FF); 

    // Show text
    ShowWindow(hwnd, SW_SHOWNORMAL);
    UpdateWindow(hwnd);

    MSG msg; 
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        DrawText(desk, text, -1, &lprec, DT_BOTTOM | DT_INTERNAL | DT_NOCLIP); // | DT_INTERNAL | DT_NOCLIP
    }
    return 0;
}