我试图创建一个带有“正在加载”文本的掩码窗口,以提醒用户我的应用程序处于忙碌状态。
为此,我首先创建了一个表单,其中包含:
- 边框样式= bs无
- 颜色=黑色
- 字母混合=真
- 字母混合值= 180;
作为第二步,我想创建另一个窗体,但这个窗体将具有动态内容。我需要创建一个带有一些状态文本的透明位图,并使用UpdateLayeredWindow将窗口绘制为文本。
看看我想要的结果:
x1c 0d1x的数据
请记住:文本在某些情况下会有所不同,例如:
- 重新计算
- 加载资源
- 加载报表
这就是我需要一个动态位图生成的原因。
问题
如何创建包含文本的透明位图,并在UpdateLayeredWindow窗体上使用它?
我正在尝试这个,但没有成功(尝试代码把一个Button 5和Label 2在一个窗体上):
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;
字符串
1条答案
按热度按时间taor4pac1#
假设您可以从 Delphi 使用Windows API函数(因为您已经标记了
winapi
),一种简单的方法是:CreateDIBSection()
创建32位位图FillRect()
填充背景,DrawText()
绘制文本UpdateLayeredWindow()
一起使用修复alpha是通过直接修改从
CreateDIBSection()
返回的位图位来完成的。请注意,UpdateLayeredWindow()
需要预先乘以alpha,因此您必须提前将RGB分量乘以alpha值。下面的代码是C语言,但希望给予你一些概念:
字符串