根据此 Microsoft knowledge base question (KB267240) 中的信息,我尝试在从 TWebBrowser 打印时实现自定义页眉和页脚.知识库文章很有帮助,甚至包括一个冗长的代码示例,但是,代码示例是用 C++ 编写的,而不是 Delphi,所以我不得不自己尝试将必要的数据结构转换为 Delphi 代码。我不太相信我已经正确转换了我需要的那部分代码。
这可能是那篇文章中最重要的部分,它解释了我下面代码中的参数 vaIn 应该包含什么:
When you use an OLECMDID enumeration of the OLECMDID_PRINT element together with the ExecWB method, you can specify extended printing information by passing in the SAFEARRAY structure through the VARIANT argument pvaIn. This SAFEARRAY data type takes a maximum of five items:
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;
最佳答案
这会打印自定义页眉/页脚。自定义 header 不适用于 OLECMDID_PRINTPREVIEW
,但它们确实适用于 OLECMDID_PRINT
。关键是使用 VT_ARRAY 或 VT_BYREF
,因为 TVariantArg
必须通过引用传递。
代码来源:TEmbeddedWB 在 https://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;
关于delphi - 如何使用OleVariant 参数来打印TWebBrowser 对话框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18117021/