Как я копирую форму как изображение к буферу обмена

Я должен скопировать форму (Delphi 2007) к буферу обмена как изображение для вставки то, что пользователь видит в документ слова. Часть буфера обмена не является действительно проблемой. Вопросы состоят в том, как получить битовый массив для формы.

Поиск поднял несколько опций.

  • Назовите GetFormImage
  • Используйте API-функцию PrintWindow, которая является частью GDI +
  • Отправьте сообщение WM_PRINT
  • Скопируйте Холст для текущей формы с помощью Холста. CopyRect
  • Я также нашел компонент под названием TExcellentFormPrinter, который имеет решение, которое требует к работам лучше, чем любая из этих опций, но я не знаю, какой метод он использует.

Все эти опции, кажется, имеют различные проблемы. Большая часть информации, которую я нахожу, кажется, устарела. Я не могу казаться никаким хорошим источником, который сравнивает различные варианты с достаточным количеством детали для меня для совершения выбора. Любой совет, на который опция пойти с.

Я попробовал их на своей форме, и они все, кажется, работают хорошо, я просто стараться избегать проблем в будущем. Совет, на какой решение пойти с?

Обновление: какие потенциальные проблемы с GetFormImage?
Andreas спросил, что проблема с GetFormImage. Надо надеяться, ничто больше, которое является частью того, на что я пытаюсь получить ответ. То, что имеет меня затронутый, является столь многими моими результатами поиска, кажется, предлагают творческие альтернативы использованию GetFormImage. Я надеялся, что ответы разрешат воды немного.

Я был бы действительно доволен ответом, который получил много голосов, которые сказали - GetFormImage раньше имел некоторые проблемы, но нет никакой причины не использовать его теперь.:-)

Относительно фактической проблемы с GetFormImage. Одной проблемой для некоторых пользователей была только видимая часть формы, появится в изображении (т.е. Вы не можете получить скрытое или перекрытое окно). Это не действительно проблема для меня, поскольку моя вся форма видима.

1) Большие проблемы имеют дело с определенной поддержкой, требуемой от средств управления на Вашей форме. Delphi 4 Фиксирует, и Известный список страницы проблем имеет эту запись (обратите внимание, что это перечислено, как "Подчинено Затем"). Я не мог найти запись королевского адвоката, которая показала разрешенный:

Область: vcl\core vcl классы

Ссылочный номер: 1088 (опубликованный: 16.12.98)
Состояние: подчиненный затем
О Дате рэла Сообщают: Серьезность 06.08.98: Тип, с которым Обычно Встречаются: Основной
Проблема отказа функциональности:

Проблемой является с GetFormImage большинство средств управления окнами вложенного множества как поля комбинированного списка, и т.д. оттянуты пробел.

2) Я также использую средства управления DevExpress. Когда-то их средства управления (зафиксированный в конце 2006) не поддерживали сообщения PaintTo, что GetFormImage использовал. Это фиксируется в выпуске DevExpress, который я использую, но он поднимает другие вопросы со мной, каков шанс, что другое управление, которое я использую, не может работать правильно?

3) Вот более свежее (2010) сообщение на Embarcadero Groups. Пользователь испытывал затруднения с помощью GetFormImage, где часть графика, который они показывали на экране, не появилась в заключительном изображении. Им также была нужна включенная подпись формы (который я не делаю), и они взяли Холст. Подход CopyRect обрисовал в общих чертах в этом сообщении.

4) Вот кавычка от страницы TExcellentImagePrinter. У меня не было бы проблемы при покупке их продукта в случае необходимости. Там компонент похож на него, обновился в 2002 (Существует пробная версия Delphi 2007 хотя). Я не могу сказать, должен ли я действительно пойти то направление или нет.

Можно попытаться использовать GetFormImage или Форму. Печать. Попытайтесь раскрыть ComboBox на форме, затем назовите GetFormImage или Форму. Печать. Если Вы получаете распечатку, Вы видите текст в ComboBox? Нет? Ни делает кого-либо еще! Это - только небольшой пример проблем, с которыми Вы встретитесь при печати форм VCL.

Можно также попытаться использовать TI-3155 Borland "Лучший способ распечатать форму". Я записал TI, когда я работал в Borland временной мерой. В то время как это распечатает текст поля комбинированного списка, это перестанет работать на многих принтерах, это не может распечатать всю форму, если Ваш пользователь изменил размер формы, и это не может распечатать формы, которые скрыты от представления, или расположен частично от экрана. Код в основном производит снимок экрана, и распечатать изображение надежно, Вы, вероятно, хотели бы смотреть на наш продукт TExcellentImagePrinter! Почему? Проще говоря, это может потребовать, чтобы несколько тысяч строк кода низкокачественной графики заставили битовые массивы печатать хорошо в соответствии с Windows.

10
задан Mark Elder 7 July 2010 в 16:01
поделиться

1 ответ

Я не знаю, в чем проблема используется с GetFormImage , но вариант, который вы не пробовали (по крайней мере, явно), - это

procedure TForm1.FormClick(Sender: TObject);
var
  bm: TBitmap;
begin

  bm := TBitmap.Create;
  try
    bm.SetSize(ClientWidth, ClientHeight);
    BitBlt(bm.Canvas.Handle, 0, 0, ClientWidth, ClientHeight, Canvas.Handle, 0, 0, SRCCOPY);
    Clipboard.Assign(bm);
  finally
    bm.Free;
  end;

end;

. Однако почти во всех случаях я ожидал бы того же результата, что и

bm := GetFormImage;
try
  Clipboard.Assign(bm);
finally
  bm.Free;
end;

. (Кроме того, процедура Canvas.CopyRect использует StretchBlt , который, как я ожидаю, даст тот же результат, что и BitBlt , когда не применяется растягивание.)

Метод 2

Вы всегда можете использовать Print Screen:

procedure TForm1.FormClick(Sender: TObject);
begin
  keybd_event(VK_SNAPSHOT, 1, 0, 0);
end;

Это также захватит рамку и строку заголовка. Если вы хотите получить только клиентскую область, вы можете обрезать изображение:

procedure TForm1.FormClick(Sender: TObject);
var
  bm, bm2: TBitmap;
  DX, DY: integer;
begin
  Clipboard.Clear;
  keybd_event(VK_SNAPSHOT, 1, 0, 0);
  repeat
    Application.ProcessMessages;
  until Clipboard.HasFormat(CF_BITMAP);
  bm := TBitmap.Create;
  try
    bm.Assign(Clipboard);
    bm2 := TBitmap.Create;
    try
      bm2.SetSize(ClientWidth, ClientHeight);
      DX := (Width - ClientWidth) div 2;
      DY := GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYSIZEFRAME );
      BitBlt(bm2.Canvas.Handle, 0, 0, ClientWidth, ClientHeight, bm.Canvas.Handle, DX, DY, SRCCOPY);
      Clipboard.Assign(bm2);
    finally
      bm2.Free;
    end;
  finally
    bm.Free;
  end;
end;
10
ответ дан 4 December 2019 в 01:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: