【问题标题】:winapi How to draw opaque text on a transparent window background?winapi 如何在透明窗口背景上绘制不透明文本?
【发布时间】:2020-06-07 22:15:04
【问题描述】:

使用 Windows API,我尝试在半透明背景上绘制不透明文本。使用SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 128, LWA_ALPHA);WS_EX_LAYERED 的窗口样式,我设法使整个 窗口半透明,但也包括文本。 如何保持文本不透明和背景半透明?

【问题讨论】:

  • 您需要通过UpdateLayeredWindow 使用每个像素的 Alpha,而不是整个窗口的单个 Alpha 设置。
  • 谢谢。我探索了 UpdateLayeredWindow,但没有任何工作,包括我找到的示例代码,所以我放弃了。
  • @AndrWeisR 请不要放弃,看我贴的答案,希望对你有用。

标签: winapi


【解决方案1】:

为了在分层窗口中执行“正确”的 alpha,您需要通过调用 UpdateLayeredWindow 为窗口管理器提供 PARGB 位图。

试试下面的代码,它对我有用。

#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);
}

调试:

更多详情可以参考@Koro's answer

【讨论】:

    猜你喜欢
    • 2016-12-02
    • 2011-07-26
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 2018-07-06
    相关资源
    最近更新 更多