使用 WinAPI 创建具有透明背景的文本标签

Posted

技术标签:

【中文标题】使用 WinAPI 创建具有透明背景的文本标签【英文标题】:Creating a text label with a transparent background using WinAPI 【发布时间】:2011-11-06 21:26:10 【问题描述】:

是否可以仅使用 WinAPI 命令在窗口内创建具有透明背景的标签?

我正在尝试将图像添加到将用作背景图像的对话框窗口,然后在该图像上显示文本。到目前为止,我尝试过的所有内容都显示背景图像顶部的文本标签,并在其周围绘制了一个灰色矩形。

这是迄今为止我的代码示例(显示对话框的整个消息处理程序):

INT_PTR CALLBACK OfferWindowProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
       
    HWND hWndBackground;
    HWND hWndLabel;
    HBRUSH hLabelBackColour = NULL;
      HFONT hfFont;
      HWND hWndTitleLabel;
    HDC hdcStatic = NULL;

    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    
    case WM_INITDIALOG:             

        //Load the background image
        HANDLE hBitmap;
        hBitmap = LoadImage(NULL, L"C:\\Users\\DavidHall\\Documents\\bg.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        if (hBitmap != NULL)
        
            hWndBackground = CreateWindow(L"STATIC", L"image box", WS_CHILD | WS_VISIBLE | SS_BITMAP, 0, 0, 100, 100, hDlg, (HMENU) 2000, NULL, NULL);          
            SendMessage(hWndBackground, STM_SETIMAGE, IMAGE_BITMAP, LPARAM(hBitmap));
                   

        // Create the label using CreateWindowEx
        hfFont = CreateFont(20, 0, 0, 0, fontWeight, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
            DEFAULT_PITCH, L"Verdana");

        hWndTitleLabel = CreateWindowEx( WS_EX_TRANSPARENT, L"STATIC", L"", WS_CHILD | WS_VISIBLE | SS_LEFT | WS_SYSMENU , xPos, yPos, width, height, hwnd, (HMENU) id, hInst, NULL);           

        SendMessage(hWndTitleLabel, WM_SETTEXT, NULL, (LPARAM) labelText.c_str());

        SendMessage(hWndTitleLabel, WM_SETFONT, (WPARAM)hfFont, NULL);  

        return (INT_PTR)TRUE;   

    case WM_CLOSE:
        EndDialog(hDlg, LOWORD(wParam));    

        // Delete the brush - is that correct?
        DeleteObject(hLabelBackColour);
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDCANCEL)
        
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        
        break;
    default:
        break;
    
    return (INT_PTR)FALSE;

我尝试了各种组合,包括:

SetLayeredWindowAttributes SetBkMode(hdc, TRANSPARENT) 处理WM_CTLCOLORSTATIC 消息

【问题讨论】:

关于这个问题的一个注意事项是,我正在使用 WinAPI,因为该项目必须具有非常小的文件大小 - 欢迎任何与 WinAPI 可执行文件大小相当的 GUI 框架的建议! 【参考方案1】:

我发现了一些似乎可行的方法,但由于我对纯 WinAPI 编程非常陌生,这很可能是非常糟糕的做法,我也不知道!

我正在处理 WM_CTLCOLORSTATIC 消息,如图所示:

case WM_CTLCOLORSTATIC:

    hdcStatic = (HDC) wParam; 
    SetTextColor(hdcStatic, RGB(0,0,0));    
    SetBkMode (hdcStatic, TRANSPARENT);

    return (LRESULT)GetStockObject(NULL_BRUSH);

这使我的标签出现在我的图像顶部并带有透明背景。

【讨论】:

你明白了 - 这与 WS_EX_TRANSPARENT 风格相结合就是如何做到这一点。如果您的标签文本发生更改,您需要在背景窗口上使用 InvalidateRect。 @Mark Ransom - 感谢您的确认,这花了我一上午的时间才弄清楚,所以我很想确认我是否正确地将所有内容放在一起,并希望节省其他人的时间未来! 这里也已经回答了:***.com/questions/4495509/…【参考方案2】:

我无法发表评论,但我认为您应该看看 Chris Becke 的这个答案:Win32 transparent controls on all versions of Windows,它对我有用,我什至不需要调用 InvalidateRect。我希望这会有用。克里斯的回答需要pattern brush, look in this answer。

【讨论】:

以上是关于使用 WinAPI 创建具有透明背景的文本标签的主要内容,如果未能解决你的问题,请参考以下文章

背景在具有 counter-tkinter 的单独窗口中透明

在具有透明背景的绘制文本上添加图案覆盖

如何使用 Python 和 GTK 创建具有自定义文本和透明背景的状态图标/系统托盘图标?

设置 WPF 标签内容 Alpha 透明度而不是整个控件的不透明度

如何在 CBitmap 上使用具有透明背景的 CDC 绘制文本?

如何创建具有不透明度的父 div,同时将文本的不透明度保持在 100% [重复]