F
flyballball
Unregistered / Unconfirmed
GUEST, unregistred user!
开发环境2000professional,DELPHI6.0 打印机为EPSON 1600KIII
我先做了一个打印程序(exe形式),代码通过了,并能正常执行.可以自定义纸张的大小.但将代码以DLL 形式实现后(具体函数代码内容不变), 用一测试程序调用dll的函数后打印,却没有实现自定义纸张功能.请高手们赐教给点建议,这个事情很急,困扰了我很久.
下面的函数是在2000下加入一个自定义的单式这个程序在dll中的,通过调试可以确定他实现了加入自定义单式的功能
function Init_Print(FormNameChar;Height:Integer;Width:Integer):Integer;stdcall;
var
PrintDevice, PrintDriver, PrintPort : array[0..255] of Char;
hDMode : THandle;
hPrinter: THandle;
FormInfo: TFormInfo1;
PaperSize: TSize;
PaperRect: TRect;
errcode: integer;
s: string;
begin
Printer.GetPrinter(PrintDevice, PrintDriver, PrintPort, hDMode);
OpenPrinter(PrintDevice, hPrinter, nil);
if hPrinter = 0 then
raise Exception.Create('Failed to open printer!');
//设置纸张格式结构参数
FormInfo.Flags := FORM_USER;
FormInfo.pName := FormName;
PaperSize.cx := Width;
PaperSize.cy := Height;
PaperRect.Left := 0;
PaperRect.Top := 0;
PaperRect.Right := Width;
PaperRect.Bottom := Height;
FormInfo.Size := PaperSize;
FormInfo.ImageableArea := PaperRect;
if not AddForm(hPrinter, 1, @FormInfo) then
begin
errcode := GetLastError;
if errcode <> ERROR_FILE_EXISTS then
// Form name exists?
begin
case errcode of
ERROR_ACCESS_DENIED: s := 'Access is denied';
ERROR_INVALID_HANDLE: s := 'The handle is invalid';
ERROR_NOT_READY: s := 'The device is not ready';
ERROR_CALL_NOT_IMPLEMENTED:
s := 'Function "AddForm" is not supported on this system';
else
s := 'Failed to add a Form (paper) name!';
end;
raise Exception.Create(s);
end;
end;
ClosePrinter(hPrinter);
Result :=1;
end;
然后我用下面的这个Set_Print函数取出我上面加入2000中的自定义单式
function Set_Print(pNameChar;Height:Integer;Width:Integer):Integer;stdcall;
var
Device, Driver, Port: array[0..80] of Char;
DevMode: THandle;
pDevmode: PDeviceMode;
iPaperSize : integer;
begin
// Get printer device name etc.
Printer.GetPrinter(Device, Driver, Port, DevMode);
// 强制重新加载 DEVMODE
Printer.SetPrinter(Device, Driver, Port, 0) ;
// 得到 DEVMODE handle
Printer.GetPrinter(Device, Driver, Port, DevMode);
if DevMode <> 0 then
begin
// lock it to get pointer to DEVMODE record
pDevMode := GlobalLock( DevMode );
if pDevmode <> nil then
try
with pDevmode^do
begin
// 装载进要使用的纸张格式
StrLCopy( dmFormName, pName, CCHFORMNAME-1 );
// 指定打印机的应确定的长宽
dmPaperWidth := Width;
dmPaperLength := Height;
dmFields := dmFields or DM_FORMNAME or DM_PAPERWIDTH or DM_PAPERLENGTH;
end;
finally
GlobalUnlock( Devmode );
// unlock devmode handle.
end;
end;
Result :=1;
end;
最后我在测试程序中做打印测试
InitPrint(Pchar(edit3.Text),StrToInt(edit2.Text),StrToInt(edit1.Text));
SetPrint(PChar(edit3.Text),StrToInt(edit2.Text),StrToInt(edit1.Text));
with Printerdo
begin
begin
Doc;
Canvas.TextOut(10,10,'Hello, My Friend!');
EndDoc;
end;
这是结果却没有按照预期的实现自定义打印。 而同样的set_print代码在我另做的exe方式的程序中却可以实现自定义打印。
我实在是想不出问题出在哪里 为什么set_print已dll方式实现就不行??
我问了好久这个问题,没人能给我回答,请高手多多帮忙!!
我先做了一个打印程序(exe形式),代码通过了,并能正常执行.可以自定义纸张的大小.但将代码以DLL 形式实现后(具体函数代码内容不变), 用一测试程序调用dll的函数后打印,却没有实现自定义纸张功能.请高手们赐教给点建议,这个事情很急,困扰了我很久.
下面的函数是在2000下加入一个自定义的单式这个程序在dll中的,通过调试可以确定他实现了加入自定义单式的功能
function Init_Print(FormNameChar;Height:Integer;Width:Integer):Integer;stdcall;
var
PrintDevice, PrintDriver, PrintPort : array[0..255] of Char;
hDMode : THandle;
hPrinter: THandle;
FormInfo: TFormInfo1;
PaperSize: TSize;
PaperRect: TRect;
errcode: integer;
s: string;
begin
Printer.GetPrinter(PrintDevice, PrintDriver, PrintPort, hDMode);
OpenPrinter(PrintDevice, hPrinter, nil);
if hPrinter = 0 then
raise Exception.Create('Failed to open printer!');
//设置纸张格式结构参数
FormInfo.Flags := FORM_USER;
FormInfo.pName := FormName;
PaperSize.cx := Width;
PaperSize.cy := Height;
PaperRect.Left := 0;
PaperRect.Top := 0;
PaperRect.Right := Width;
PaperRect.Bottom := Height;
FormInfo.Size := PaperSize;
FormInfo.ImageableArea := PaperRect;
if not AddForm(hPrinter, 1, @FormInfo) then
begin
errcode := GetLastError;
if errcode <> ERROR_FILE_EXISTS then
// Form name exists?
begin
case errcode of
ERROR_ACCESS_DENIED: s := 'Access is denied';
ERROR_INVALID_HANDLE: s := 'The handle is invalid';
ERROR_NOT_READY: s := 'The device is not ready';
ERROR_CALL_NOT_IMPLEMENTED:
s := 'Function "AddForm" is not supported on this system';
else
s := 'Failed to add a Form (paper) name!';
end;
raise Exception.Create(s);
end;
end;
ClosePrinter(hPrinter);
Result :=1;
end;
然后我用下面的这个Set_Print函数取出我上面加入2000中的自定义单式
function Set_Print(pNameChar;Height:Integer;Width:Integer):Integer;stdcall;
var
Device, Driver, Port: array[0..80] of Char;
DevMode: THandle;
pDevmode: PDeviceMode;
iPaperSize : integer;
begin
// Get printer device name etc.
Printer.GetPrinter(Device, Driver, Port, DevMode);
// 强制重新加载 DEVMODE
Printer.SetPrinter(Device, Driver, Port, 0) ;
// 得到 DEVMODE handle
Printer.GetPrinter(Device, Driver, Port, DevMode);
if DevMode <> 0 then
begin
// lock it to get pointer to DEVMODE record
pDevMode := GlobalLock( DevMode );
if pDevmode <> nil then
try
with pDevmode^do
begin
// 装载进要使用的纸张格式
StrLCopy( dmFormName, pName, CCHFORMNAME-1 );
// 指定打印机的应确定的长宽
dmPaperWidth := Width;
dmPaperLength := Height;
dmFields := dmFields or DM_FORMNAME or DM_PAPERWIDTH or DM_PAPERLENGTH;
end;
finally
GlobalUnlock( Devmode );
// unlock devmode handle.
end;
end;
Result :=1;
end;
最后我在测试程序中做打印测试
InitPrint(Pchar(edit3.Text),StrToInt(edit2.Text),StrToInt(edit1.Text));
SetPrint(PChar(edit3.Text),StrToInt(edit2.Text),StrToInt(edit1.Text));
with Printerdo
begin
begin
Doc;
Canvas.TextOut(10,10,'Hello, My Friend!');
EndDoc;
end;
这是结果却没有按照预期的实现自定义打印。 而同样的set_print代码在我另做的exe方式的程序中却可以实现自定义打印。
我实在是想不出问题出在哪里 为什么set_print已dll方式实现就不行??
我问了好久这个问题,没人能给我回答,请高手多多帮忙!!