Потом решили что-то похожее, но для OpenGL, и вот "снова здравствуйте": по ходу дела решил скопировать содержимое панели (TPanel) на картинку (было лень возиться с центровкой текста, которая отлично работает в стандартном TStaticText), первым делом попробовал простой BlitBit, что предсказуемо не сработало.
Потом решил дернуть "кусок скриншота"...
- Код: Выделить всё
function CaptureScreenRect(aRect: TRect): TBitMap;
var
ScreenDC: HDC;
begin
Result := TBitMap.Create;
with Result, aRect do
begin
Result := TBitMap.Create;
Result.Width := aRect.Right - aRect.Left;
Result.Height := aRect.Bottom - aRect.Top;
ScreenDC := CreateDC(PChar('DISPLAY'), nil, nil, nil);
try
BitBlt(Result.Canvas.Handle, 0, 0, Result.Width, Result.Height, ScreenDC, aRect.Left, aRect.Top, SRCCOPY);
finally
ReleaseDC(0, ScreenDC);
end;
end;
end;
..это сработало лучше, но мне нужна возможность дергать содержимое "Невидимого окна". желательно чтобы панель или другой визуальный компонент вообще были не связаны с формой .
Немного погуглив нашел два "хитрых" варианта "создания скриншота панели" ...
- Код: Выделить всё
Function PanelToBmp ( Panel:TPanel):TBitmap;
VAR
bmp : tBitmap;
DC : HDC;
Begin
bmp := tBitmap.Create;
bmp.width := Panel.ClientWidth;
bmp.Height := Panel.ClientHeight;
DC := GetDc ( Panel.Handle );
Bitblt(bmp.canvas.handle, 0, 0, Panel.Width, Panel.Height, Dc, 0, 0, SRCCOPY);
Releasedc (Panel.handle,dc);
result := bmp;
End;
- Код: Выделить всё
Function CopyPanelToBitmap(Panel:TPanel): TBitmap;
var
Bitmap: TBitmap;
ControlCanvas: TControlCanvas;
begin
Bitmap := TBitmap.Create;
ControlCanvas := TControlCanvas.Create;
try
Bitmap.Width := Panel.ClientWidth;
Bitmap.Height := Panel.ClientHeight;
ControlCanvas.Control := Panel;
BitBlt(Bitmap.Canvas.Handle, 0, 0, Bitmap.Width, Bitmap.Height,
ControlCanvas.Handle, 0, 0, SRCCOPY);
// Теперь у вас есть содержимое Panel1 в Bitmap
finally
ControlCanvas.Free;
end;
Result:= Bitmap;
end;
На удивление оба почти рабочие ... Почему "почти" ? Потому что скриншот загадочным образом не включает в себя изображение вставленного в панель TImage. Можно было-бы решить проблему "в ручном режиме " (или через обход дерева контролов ) но это уже полная кустарщина и колхоз.
Так что нашел более другой путь ...

- Код: Выделить всё
B := tBitmap.Create;
b.SetSize(Panel1.ClientWidth,Panel1.ClientHeight);
Panel1.PaintTo(B.Canvas.Handle, 0, 0);
Так работает и по идее это вообще универсальное решение.
Controls.TWinControl.PaintTo
procedure PaintTo(DC: HDC; X, Y: Integer); overload;
procedure PaintTo(Canvas: TCanvas; X, Y: Integer); overload;
Тест выглядит как то так . ( вторая панелька в левом углу "первичный клон на картинке" который я потом тиражирую в "мозаичную тестовую галерею" )

Зы
Разумеется, дальше я планирую не "лепить горбатого" в начале клонируя целиком "готовую панель" на битмап, а сразу вставить надпись формируемую с помощью TStaticText в битмап через PaintTo при создании миниатюры элемента галереи , но именно этот пример отлично показывает универсальность метода PaintTo .