如何从控件中制作禁用图像?
How to make disabled image from control?
我整理了这段代码,它从控件创建了一个灰度位图:
procedure TForm1.PseudoDisableControl(const AWinControl: TWinControl; const AImage: TImage);
var
Bmp: TBitmap;
function Control2Bitmap(Control_: TWinControl): TBitmap;
// http://delphidabbler.com/tips/24
begin
Result := TBitmap.Create;
with Result do
begin
Height := Control_.Height;
Width := Control_.Width;
Canvas.Handle := CreateDC(nil, nil, nil, nil);
Canvas.Lock;
Control_.PaintTo(Canvas.Handle, 0, 0);
Canvas.Unlock;
DeleteDC(Canvas.Handle);
end;
end;
type
PRGB32Array = ^TRGB32Array;
TRGB32Array = packed array [0 .. MaxInt div SizeOf(TRGBQuad) - 1] of TRGBQuad;
procedure MakeGrey(Bitmap: TBitmap);
//
var
w, h: integer;
y: integer;
sl: PRGB32Array;
x: integer;
grey: byte;
begin
Bitmap.PixelFormat := pf32bit;
w := Bitmap.Width;
h := Bitmap.Height;
for y := 0 to h - 1 do
begin
sl := Bitmap.ScanLine[y];
for x := 0 to w - 1 do
with sl[x] do
begin
grey := (rgbBlue + rgbGreen + rgbRed) div 3;
rgbBlue := grey;
rgbGreen := grey;
rgbRed := grey;
end;
end;
end;
begin
Bmp := Control2Bitmap(AWinControl);
try
MakeGrey(Bmp);
AImage.AutoSize := True;
AImage.Picture.Bitmap := Bmp;
finally
Bmp.Free;
end;
end;
这会产生这样的结果,例如:
但是,我需要让图像看起来像一个禁用的控件:
我怎样才能做到这一点?
编辑: MBo 的解决方案对我来说效果很好,系数为 3。但是,使用轨迹栏控件(来自 TMS 的TAdvTrackbar
),轨迹栏左侧:
您可以使用如下公式生成对比度降低的浅灰色图片:
grey := (rgbBlue + rgbGreen + rgbRed + 2 * 255) div (3 + 2); // try also 1 instead of 2
但是,如果 windows 主题使用了另一种残疾人颜色编码方案怎么办?
您可以通过提供句柄截取任何 window 的屏幕截图:
function ScreenshotDisabledWindow(const AWindow: HWND;
out AScreenshotBitmap: TBitmap): boolean;
var
_Canvas: TCanvas;
r, t: TRect;
_WindowEnabled: boolean;
begin
Result := False;
if AWindow = 0 then
Exit;
_WindowEnabled := IsWindowEnabled(AWindow);
_Canvas := TCanvas.Create;
_Canvas.Handle := GetWindowDC(GetDesktopWindow);
try
if _WindowEnabled then
EnableWindow(AWindow, False);
if AWindow <> 0 then
GetWindowRect(AWindow, t);
r := Rect(0, 0, t.Right - t.Left, t.Bottom - t.Top);
AScreenshotBitmap.Width := t.Right - t.Left;
AScreenshotBitmap.Height := t.Bottom - t.Top;
AScreenshotBitmap.Canvas.CopyRect(r, _Canvas, t);
Result := True;
finally
ReleaseDC(0, _Canvas.Handle);
FreeAndNil(_Canvas);
EnableWindow(AWindow, _WindowEnabled);
end;
end;
你这样称呼它:
var
_Image: TBitmap;
begin
_Image := TBitmap.Create;
try
if not ScreenshotDisabledWindow(Button1.Handle, _Image) then
raise Exception.Create('Invalid handle provided???');
Image1.Picture.Assign(_Image);
finally
FreeAndNil(_Image);
end;
我整理了这段代码,它从控件创建了一个灰度位图:
procedure TForm1.PseudoDisableControl(const AWinControl: TWinControl; const AImage: TImage);
var
Bmp: TBitmap;
function Control2Bitmap(Control_: TWinControl): TBitmap;
// http://delphidabbler.com/tips/24
begin
Result := TBitmap.Create;
with Result do
begin
Height := Control_.Height;
Width := Control_.Width;
Canvas.Handle := CreateDC(nil, nil, nil, nil);
Canvas.Lock;
Control_.PaintTo(Canvas.Handle, 0, 0);
Canvas.Unlock;
DeleteDC(Canvas.Handle);
end;
end;
type
PRGB32Array = ^TRGB32Array;
TRGB32Array = packed array [0 .. MaxInt div SizeOf(TRGBQuad) - 1] of TRGBQuad;
procedure MakeGrey(Bitmap: TBitmap);
//
var
w, h: integer;
y: integer;
sl: PRGB32Array;
x: integer;
grey: byte;
begin
Bitmap.PixelFormat := pf32bit;
w := Bitmap.Width;
h := Bitmap.Height;
for y := 0 to h - 1 do
begin
sl := Bitmap.ScanLine[y];
for x := 0 to w - 1 do
with sl[x] do
begin
grey := (rgbBlue + rgbGreen + rgbRed) div 3;
rgbBlue := grey;
rgbGreen := grey;
rgbRed := grey;
end;
end;
end;
begin
Bmp := Control2Bitmap(AWinControl);
try
MakeGrey(Bmp);
AImage.AutoSize := True;
AImage.Picture.Bitmap := Bmp;
finally
Bmp.Free;
end;
end;
这会产生这样的结果,例如:
但是,我需要让图像看起来像一个禁用的控件:
我怎样才能做到这一点?
编辑: MBo 的解决方案对我来说效果很好,系数为 3。但是,使用轨迹栏控件(来自 TMS 的TAdvTrackbar
),轨迹栏左侧:
您可以使用如下公式生成对比度降低的浅灰色图片:
grey := (rgbBlue + rgbGreen + rgbRed + 2 * 255) div (3 + 2); // try also 1 instead of 2
但是,如果 windows 主题使用了另一种残疾人颜色编码方案怎么办?
您可以通过提供句柄截取任何 window 的屏幕截图:
function ScreenshotDisabledWindow(const AWindow: HWND;
out AScreenshotBitmap: TBitmap): boolean;
var
_Canvas: TCanvas;
r, t: TRect;
_WindowEnabled: boolean;
begin
Result := False;
if AWindow = 0 then
Exit;
_WindowEnabled := IsWindowEnabled(AWindow);
_Canvas := TCanvas.Create;
_Canvas.Handle := GetWindowDC(GetDesktopWindow);
try
if _WindowEnabled then
EnableWindow(AWindow, False);
if AWindow <> 0 then
GetWindowRect(AWindow, t);
r := Rect(0, 0, t.Right - t.Left, t.Bottom - t.Top);
AScreenshotBitmap.Width := t.Right - t.Left;
AScreenshotBitmap.Height := t.Bottom - t.Top;
AScreenshotBitmap.Canvas.CopyRect(r, _Canvas, t);
Result := True;
finally
ReleaseDC(0, _Canvas.Handle);
FreeAndNil(_Canvas);
EnableWindow(AWindow, _WindowEnabled);
end;
end;
你这样称呼它:
var
_Image: TBitmap;
begin
_Image := TBitmap.Create;
try
if not ScreenshotDisabledWindow(Button1.Handle, _Image) then
raise Exception.Create('Invalid handle provided???');
Image1.Picture.Assign(_Image);
finally
FreeAndNil(_Image);
end;