我想在 Windows 计算机的右下角显示文本(任务栏被隐藏)。我希望文本可见但没有背景。
执行此操作的正确 Windows API 是什么?
我想到的方法是制作一个常规窗口并使其背景透明,并使其始终位于其他窗口之上。理想情况下,我不希望窗口阻止单击,而是让单击和鼠标事件转到下面的窗口。
有更好的 API 可以做到这一点吗?
如何在桌面上显示透明窗口且不遮挡点击?(可以设置位置显示在右下角)
将 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);
}