- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个带有“正在加载”文本的掩码窗口,以提醒用户我的应用程序处于繁忙状态。
为此,我首先创建了一个表单:
作为第二步,我想创建另一个表单,但这个表单将具有动态内容。我需要创建一个带有一些状态文本的透明位图,并使用 UpdateLayeredWindow 将窗口绘制为文本。
看看我想要的结果:
请记住:在某些情况下文本会有所不同,例如:
这就是我需要动态位图生成的原因。
问题
如何创建带有文本的透明位图并在带有 UpdateLayeredWindow 的表单上使用它?
我正在尝试这个,但没有成功(尝试将 Button5 和 Label2 放在表单上的代码):
procedure Inc(var p: pointer);
begin
p := Pointer(Integer(p) + 1);
end;
var
s: string;
frm: TForm;
f: HFont;
tx: HDC;
bmp, old: HBITMAP;
rc: TRect;
h: BITMAPINFOHEADER;
pvBits: Pointer;
t: tagBITMAPINFO;
x,y: integer;
a, r, g, b: byte;
sz: TSize;
p: tpoint;
BlendFunction: TBlendFunction;
begin
tx := CreateCompatibleDC(0);
s := label2.Caption;
f := SelectObject(tx, label2.Font.Handle);
fillchar(rc, SizeOf(rc), 0);
DrawText(tx, PChar(s), length(s), rc, DT_CALCRECT);
fillchar(h, SizeOf(h), 0);
pvBits := nil;
h.biSize := SizeOf(h);
h.biWidth := rc.Right - rc.Left;
h.biHeight := rc.Bottom - rc.Top;
h.biPlanes := 1;
h.biBitCount := 32;
h.biCompression := BI_RGB;
FillChar(t, SizeOf(t), 0);
t.bmiHeader := h;
bmp := CreateDIBSection(tx, t, 0, pvBits, 0, 0);
old := SelectObject(tx, bmp);
if old > 0 then
begin
SetTextColor(tx, $00FFFFFF);
SetBkColor(tx, $00000000);
SetBkMode(tx, TRANSPARENT);
DrawText(tx, PChar(s), length(s), rc, DT_NOCLIP);
r := GetRValue($FF);
g := GetGValue($FF);
b := GetBValue($FF);
for x := 0 to h.biWidth-1 do
for y := 0 to h.biHeight-1 do
begin
a := Byte(pvBits^);
Inc(pvBits);
Byte(pvBits^) := (b * a) shr 8;
Inc(pvBits);
Byte(pvBits^) := (g * a) shr 8;
Inc(pvBits);
Byte(pvBits^) := (r * a) shr 8;
Inc(pvBits);
Byte(pvBits^) := a;
end;
SelectObject(tx, old);
end;
SelectObject(tx, f);
deleteDC(tx);
sz.cx := h.biWidth;
sz.cy := h.biHeight;
p := Point(0,0);
BlendFunction.BlendOp := AC_SRC_OVER;
BlendFunction.BlendFlags := 0;
BlendFunction.SourceConstantAlpha := 255;
BlendFunction.AlphaFormat := AC_SRC_ALPHA;
frm := TForm.CreateNew(self);
frm.BorderStyle := bsNone;
frm.Position := poOwnerFormCenter;
frm.Show;
UpdateLayeredWindow(frm.Handle, 0, nil, @sz, bmp, @p, 0, @BlendFunction, ULW_ALPHA);
end;
最佳答案
假设您可以使用 Delphi 中的 Windows API 函数(因为您已标记 winapi
),一种简单的方法是:
CreateDIBSection()
创建 32 位位图FillRect()
填充背景,DrawText()
绘制文本UpdateLayeredWindow()
使用该位图通过直接修改从 CreateDIBSection()
返回的位图位来修复 Alpha。请注意,UpdateLayeredWindow()
需要预乘 alpha,因此您必须提前将 RGB 分量乘以 alpha 值。
以下代码是 C 语言,但希望能给您带来启发:
LPVOID pBits; // bits from CreateDIBSection
const int width, height; // size of bitmap
const int alpha; // level of transparency
RGBQUAD* pPtr = (RGBQUAD*)pBits;
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x, ++pPtr)
{
pPtr->rgbBlue = (alpha * pPtr->rgbBlue) / 255;
pPtr->rgbGreen = (alpha * pPtr->rgbGreen) / 255;
pPtr->rgbRed = (alpha * pPtr->rgbRed) / 255;
pPtr->rgbReserved = alpha;
}
}
关于delphi - 创建透明位图并UpdateLayeredWindow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19572760/
我正在使用 UpdateLayeredWindow 创建一个分层窗口,并且我已经为子控件实现了绘图逻辑。我的问题是每次 uI 发生变化时,整个框架都需要重新绘制。我想知道是否有一种方法可以只重绘窗口的
我正在使用 UpdateLayeredWindow 来显示应用程序窗口。我已经创建了自己的自定义按钮,并且想创建自己的静态文本。问题是,当我尝试在 hdc 上绘制文本时,DrawText 或 Text
我正在使用分层窗口,它们似乎会造成相当大的性能损失(我的一个核心已完全使用)。有什么方法可以调整分层窗口的性能吗? Direct2D 是可行的替代方案吗? (我的分层窗口需要有每个像素的 alpha)
我在我的 MFC 应用程序中设置了一个分层窗口。我已经设置了我自己的 CDialog 派生,以允许我自定义窗口呈现方式的各个部分。一切正常,直到我开始担心最小化和最大化。 如果您单击最小化或最大化,则
我的程序中有一个分层窗口,它(在视觉上)似乎工作正常,但 UpdateLayeredWindow 的返回代码应该是成功时的非零值。在我的例子中,它是 0,GetLastError 返回 87,这是一个
我这里有一个奇怪的问题。我正在使用分层窗口显示半透明的启动屏幕(.png 文件)。它适用于某些机器,但不适用于其他机器。在它不起作用的机器上,GetLastError 返回 317(这不是很有帮助)。
我在客户区有一个透明背景的应用程序,它被绘制成黑色,因为窗口没有分层。在每个 WM_PAINT 消息中,我对内存 DC 执行 BitBlt,之后我将内存 DC 与 UpdateLayeredWindo
我是一名优秀的程序员,十分优秀!