如何将表单作为图像复制到剪贴板

时间:2010-07-06 22:50:03

标签: delphi delphi-2007

我需要将一个表单(Delphi 2007)作为图像复制到剪贴板,以将用户可以看到的内容粘贴到word文档中。剪贴板部分确实不是问题。问题是如何获取表单的位图。

搜索已经出现了多个选项。

所有这些选项似乎都有不同的问题。我发现的大部分信息似乎都已过时。我似乎没有任何好的资源来比较不同的选项和足够的细节供我做出选择。关于选择哪种选择的任何建议。

我已经在我的表单上尝试了这些,但它们似乎都运行正常,我只是想避免出现问题。有关解决方案的建议吗?

更新:GetFormImage存在哪些潜在问题?
Andreas问GetFormImage的问题是什么。希望什么都没有,这是我想要得到答案的一部分。让我担心的是,我的许多搜索结果似乎都在暗示使用GetFormImage的创造性替代方案。我希望这些答案可以清除水域。

我会很高兴得到很多投票的回答说 - GetFormImage曾经有过一些问题,但现在没有理由不使用它。 : - )

关于GetFormImage的实际问题。对于某些用户来说,一个问题是只有表单的可见部分才会出现在图像中(即,您无法捕获隐藏或重叠的窗口)。这对我来说并不是一个问题,因为我的整个表格都是可见的。

1)更大的问题涉及表单控件所需的特定支持。 Delphi 4 Fixes and Known issues page列表中包含此条目(请注意,它列为“延迟到下一个”)。我找不到显示已解决的QC条目:

  

区域:vcl \ core vcl classes

     

参考编号:1088(已发布:1998年12月16日)
  状态:推迟到下一个   Rel Date Reported:8/6/98严重性:   常见类型:基本
  功能失败问题:

     

问题在于GetFormImage大多数嵌套窗口控件如组合框等都被绘制为空白。

2)我也在使用DevExpress控件。有一次他们的控件(在2006年底修复)did not support the PaintTo GetFormImage正在使用的消息。这在我正在使用的DevExpress版本中修复,但是它引发了我的其他问题,我使用的其他控件可能无法正常工作的可能性是什么?

3)这是最近的(2010)post on the Embarcadero Groups。用户在使用GetFormImage时遇到问题,他们在屏幕上显示的部分图表没有出现在最终图像中。他们还需要包含表单标题(我没有),他们采用了Canvas.CopyRect方法outlined in this post

4)以下是TExcellentImagePrinter页面的引用。如果需要,我可以毫无问题地购买他们的产品。该组件看起来像它最近在2002年更新(虽然有一个Delphi 2007试用版)。我不知道我是否真的需要走这个方向。

  

您可以尝试使用GetFormImage或   Form.Print。尝试删除ComboBox   在表单上,​​然后调用GetFormImage   或Form.Print。 如果你得到了   打印输出,你看到的文本   组合框?没有?没有人   其他!这只是一个小例子   你将遇到的问题   打印VCL表格。

     

您也可以尝试使用Borland's   TI-3155“更好的打印方式   形式“。我在工作时写过TI   Borland作为止损措施。而   它将打印组合框文本,它   许多打印机都会失败,它不能   如果您的用户有,则打印整个表单   调整表格大小,无法打印   隐藏在视图之外的表单   位于屏幕的一部分。该   代码基本上生成一个截图,   并且可靠地打印图像   可能想看一看   我们的TExcellentImagePrinter产品!   为什么?简单地说,它可能需要一个   几千行低级别   图形代码以获取要打印的位图   在Windows下。

1 个答案:

答案 0 :(得分:10)

我不知道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

您始终可以使用“打印屏幕”:

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;