哪个Windows API可用于在屏幕顶部制作透明文本?

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

我想在 Windows 计算机的右下角显示文本(任务栏被隐藏)。我希望文本可见但没有背景。

执行此操作的正确 Windows API 是什么?

我想到的方法是制作一个常规窗口并使其背景透明,并使其始终位于其他窗口之上。理想情况下,我不希望窗口阻止单击,而是让单击和鼠标事件转到下面的窗口。

有更好的 API 可以做到这一点吗?

windows winapi widget windows-runtime c++-winrt
1个回答
0
投票

如何在桌面上显示透明窗口且不遮挡点击?(可以设置位置显示在右下角)

将 CreateWindowEx 与

WS_EX_TRANSPARENT
WS_EX_LAYERED
一起使用。并使用
UpdateLayeredWindow
设置窗口的透明度。
WS_EX_TRANSPARENT
将允许您鼠标穿透。

但是有一个问题。使用

Textout
Drawtext
输出文本时,文本的透明度与窗口的透明度相同。这意味着当窗口完全透明时,文本和窗口都不可见。 所以我们需要使用gdiplus来分别设置窗口和文字的透明度。

Graphics::Clear 方法 将 Graphics 对象(背景)清除为指定的颜色。 结构体BLENDFUNCTION

SourceConstantAlpha
(文本)可以指定要在整个源位图上使用的alpha透明度值。

这是完整的代码,它基于这个线程

#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")
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    const wchar_t CLASS_NAME[] = L"Sample Window Class";
    WNDCLASS wc = { };

    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    RegisterClass(&wc);

    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    HDC hdc{};
    //Initialize GDI+
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT, CLASS_NAME, NULL, WS_POPUP,
        0, 0, 1000, 600, NULL, NULL, hInstance, NULL);

    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(800, 600, 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 = { 550, 300 };
    SIZE szWnd = { 800, 600 };
    POINT ptSrc = { 0, 0 };
    UpdateLayeredWindow(hWnd, hdc, &ptLocation, &szWnd, memdc, &ptSrc, 0, &blend, ULW_ALPHA);
    SelectObject(hdc, original);

    DeleteObject(bmp);
    DeleteObject(memdc);
    if (hWnd == NULL)
    {
        return 0;
    }
    ShowWindow(hWnd, nCmdShow);
    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

我们来看看效果:

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