Создание текстовой метки с прозрачным фоном с помощью WinAPI - PullRequest
3 голосов
/ 30 августа 2011

Можно ли создать метку с прозрачным фоном в окне, используя только команды 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

Ответы [ 2 ]

7 голосов
/ 30 августа 2011

Я нашел кое-что, что, кажется, работает, хотя, поскольку я очень плохо знаком с программированием на чистом WinAPI, это может быть очень плохой практикой, и я бы не знал!

Я обрабатываю сообщение WM_CTLCOLORSTATIC, как показано:

case WM_CTLCOLORSTATIC:

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

    return (LRESULT)GetStockObject(NULL_BRUSH);

Это дает эффект того, что мой ярлык появляется поверх моего изображения с прозрачным фоном.

0 голосов
/ 15 ноября 2013

Я не могу комментировать, но я думаю, что вы должны посмотреть на этот ответ Криса Бекке: Прозрачные элементы управления Win32 во всех версиях Windows , это сработало для меня, и мне даже не нужно быловызов InvalidateRect .Я надеюсь, что это будет полезно.Для ответа Криса потребуется шаблонная кисть , посмотрите в этом ответе .

...