【问题标题】:How to use OleVariant parameters to TWebBrowser Print dialog?如何使用 OleVariant 参数到 TWebBrowser 打印对话框?
【发布时间】:2013-08-08 02:34:55
【问题描述】:

根据Microsoft knowledge base question (KB267240) 中的信息,我正在尝试在从 TWebBrowser 打印时实现自定义页眉和页脚。知识库文章很有帮助,甚至包含一个冗长的代码示例,但是,代码示例是用 C++ 而不是 Delphi 编写的,所以我不得不自己尝试将必要的数据结构转换为 Delphi 代码。我不太确定我是否正确转换了我需要的部分代码。

这可能是那篇文章中最重要的部分,它解释了我在下面的代码中的参数 vaIn 中应该包含的内容:

当您使用 OLECMDID_PRINT 元素的 OLECMDID 枚举时 与 ExecWB 方法一起,您可以指定扩展打印 通过 VARIANT 传入 SAFEARRAY 结构的信息 参数 pvaIn。此 SAFEARRAY 数据类型最多需要五个 项目:

1) A string (BSTR) that contains a custom header.
2) A string (BSTR) that contains a custom footer.
3) ...

当我运行我编写的代码时,它成功删除了原始页眉和页脚,但没有用我的新页眉和页脚字符串替换它,所以我想知道我的代码是否在某些方面不正确(或几种方法),或者如果我根本不希望它工作,因为我使用的是 IE 9,而不是编写知识库文章时最新的 4-6 范围内的版本。

var
  vaIn, vaOut: OleVariant;
begin
    vaIn := VarArrayCreate([0,1], varOleStr); 
    vaIn[0] := VarAsType('new header', VarOleStr); //header
    vaIn[1] := VarAsType('new footer', VarOleStr); //footer

    // Show print-preview dialog 
    WebBrowser1.ControlInterface.ExecWB(OLECMDID_PRINTPREVIEW,
      OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut);
end;

【问题讨论】:

  • 在示例中,他们使用了一个 VT_VARIANT 数组。试试VarArrayCreate([0, 1], varVariant) 或干脆VarArrayOf(['new header', 'new footer'])

标签: delphi ole twebbrowser delphi-xe4


【解决方案1】:

这使用自定义页眉/页脚打印。自定义标头不适用于OLECMDID_PRINTPREVIEW,但它们确实适用于OLECMDID_PRINT。关键是使用VT_ARRAY or VT_BYREF,因为TVariantArg 必须通过引用传递。

代码来源:TEmbeddedWBhttps://github.com/7even11/Delphi-EmbeddedWB

procedure PrintWithHeaderFooter(ControlInterface: IWebBrowser2; Header, Footer: PWideChar; Options: OLECMDEXECOPT);
var
  saBound: TSafeArrayBound;
  psaHeadFoot: PSafeArray;
  vaIn, vaOut: TVariantArg;
  vHeadStr, vFootStr: TVariantArg;
  rgIndex: LongInt;
begin
  try
    saBound.lLbound := 0;
    saBound.cElements := 2;
    psaHeadFoot := SafeArrayCreate(VT_VARIANT, 1, saBound);
    vHeadStr.vt := VT_BSTR;
    vHeadStr.bstrVal := SysAllocString(Header);
    vFootStr.vt := VT_BSTR;
    vFootStr.bstrVal := SysAllocString(Footer);
    rgIndex := 0;
    OleCheck(SafeArrayPutElement(psaHeadFoot, rgIndex, vHeadStr));
    rgIndex := 1;
    OleCheck(SafeArrayPutElement(psaHeadFoot, rgIndex, vFootStr));
    vaIn.vt := VT_ARRAY or VT_BYREF;
    vaIn.parray := psaHeadFoot;
    ControlInterFace.ExecWB(OLECMDID_PRINT, Options,
      OleVariant(vaIn), OleVariant(vaOut));
    if vHeadStr.bstrVal <> nil then
      SysFreeString(vHeadStr.bstrVal);
    if vFootStr.bstrVal <> nil then
      SysFreeString(vFootStr.bstrVal);
  except
  end;
end;

procedure Print(ControlInterface: IWebBrowser2; bHideSetup: Boolean = False; bCustomHeaderFooter: Boolean = False; Header: string = ''; Footer: string = '');
var
  vaIn, vaOut: OleVariant;
begin
  if DocumentLoaded(ControlInterface.Document) then
  begin
    if bCustomHeaderFooter then
    begin
      if bHideSetup then
        PrintWithHeaderFooter(ControlInterface, TaskAllocWideString(Header), TaskAllocWideString(Footer), OLECMDEXECOPT_DONTPROMPTUSER)
      else
        PrintWithHeaderFooter(ControlInterface, TaskAllocWideString(Header), TaskAllocWideString(Footer), OLECMDEXECOPT_PROMPTUSER);
    end
    else
      if bHideSetup then
        ControlInterface.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, vaIn, vaOut)
      else
        ControlInterface.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER, vaIn, vaOut)
  end;
end;

【讨论】:

    猜你喜欢
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多