winapi 如何在透明的窗口背景上绘制不透明的文本?

问题描述 投票:1回答:1

使用Windows API,我试图在半透明的背景上绘制不透明的文本。使用 SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 128, LWA_ALPHA); 和窗口风格为 WS_EX_LAYERED,我已经设法使 全部 窗口是半透明的,但这也包括文本。我如何保持文本不透明而背景是半透明的?

winapi
1个回答
0
投票

为了在一个分层窗口中做 "适当的 "alpha,你需要通过调用到 UpdateLayeredWindow.

试试下面的代码,对我很有效。

#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <ObjIdl.h>
#include <gdiplus.h>
#include <gdiplusheaders.h>
using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")

#define MAX_WIDTH 800
#define MAX_HEIGHT 600

using namespace std;

void Drawtext(HWND hwnd, HDC hdc);

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    if (message == WM_DESTROY) {

        PostQuitMessage(0);
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
};

HINSTANCE hinst;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
    HWND hWnd;
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;

    //Initialize GDI+
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    hinst = GetModuleHandle(NULL);
    // create a window class:
    WNDCLASS wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hinst;
    wc.lpszClassName = L"win32";

    // register class with operating system:
    RegisterClass(&wc);

    // create and show window:
    hWnd = CreateWindowExW(
        WS_EX_LAYERED | WS_EX_TOPMOST,
        L"win32",
        L"WinSoup",
        WS_POPUP,
        0, 0, 1000, 500,
        nullptr,
        nullptr,
        hInstance,
        nullptr
    );

    if (hWnd == NULL) {
        return 0;
    }

    Drawtext(hWnd, GetDC(hWnd));

    ShowWindow(hWnd, SW_SHOW);


    MSG msg = {};

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

}

void Drawtext(HWND hwnd, HDC hdc)
{
    FontFamily  fontFamily(L"Times New Roman");
    Font        font(&fontFamily, 32, FontStyleRegular, UnitPixel);
    PointF      pointF(30.0f, 10.0f);
    SolidBrush  solidBrush(Color(255, 0, 0, 0));

    Bitmap softwareBitmap(MAX_WIDTH, MAX_HEIGHT, PixelFormat32bppARGB);
    Graphics g(&softwareBitmap);

    g.Clear(Gdiplus::Color(30, 0, 0, 0));  // 30: alpha value 

    g.DrawString(L"Hello Hello Hello Hello Hello Hello Hello Hello", -1, &font, pointF, &solidBrush);

    HBITMAP bmp;
    softwareBitmap.GetHBITMAP(Color(0, 0, 0, 0), &bmp);

    HDC memdc = CreateCompatibleDC(hdc);
    HGDIOBJ original = SelectObject(memdc, bmp);


    BLENDFUNCTION blend = { 0 };
    blend.BlendOp = AC_SRC_OVER;
    blend.SourceConstantAlpha = 255;
    blend.AlphaFormat = AC_SRC_ALPHA;
    POINT ptLocation = { 200, 300 };
    SIZE szWnd = { MAX_WIDTH, MAX_HEIGHT };
    POINT ptSrc = { 0, 0 };
    BOOL l = UpdateLayeredWindow(hwnd, hdc, &ptLocation, &szWnd, memdc, &ptSrc, 0, &blend, ULW_ALPHA);
    int err = GetLastError();
    SelectObject(hdc, original);

    DeleteObject(bmp);
    DeleteObject(memdc);
}

调试。

enter image description here

更多细节,你可以参考 @Koro的回答.

© www.soinside.com 2019 - 2024. All rights reserved.