如何通过程序选择指定的打印机打印(200分)

  • 主题发起人 主题发起人 gwm110
  • 开始时间 开始时间
G

gwm110

Unregistered / Unconfirmed
GUEST, unregistred user!
问题出现在Printer.PrintIndex:=i;选择了打印机打印后,可以打印,但是打印机所设置的纸张和质量的属性全是调用的默认打印机的属性,怎样可以实现选择了该打印机打印机就调用该打印机的设置属性打印!高分求教!
 
就没人能回答我这个问题吗!用printsetupdialog这种控件设置后是能选择打印机打印的,但问题是我现在需要用程序来直接实现,不通过更改默认打印机,请哪位高人指点呀,分不够可以再加!
 
procedure TForm2.Button1Click(Sender: TObject);
var
OldPrinter:TPrinter;
begin
OldPrinter:=printers.SetPrinter(PreviewBox1.Printer.Printer);
try
if PrinterSetupDialog1.Execute then
PreviewBox1.printer.NewPage;
finally
printers.SetPrinter(OldPrinter);
end;
end;
 
我是做打印机服务器程序,不会有人工去干预的,所以用PrinterSetupDialog1这种控件是明显不适合的,有没有不用类似的控件,直接在程序中选择打印的!希望ball_cao能指点一下
 
用 Grid++Report 应该可以做到,其 IGRPrinter 接口可以设置打印机名称及其它打印参数。
 
我想说一下,我做的组合图片的打印机服务器程序,基本不太可能用到上面的控件,有没有方式用API函数,或者其他方式,指定一台打印机(非默认的)后,该打印机就会调用该打印机的默认配置属性进行打印!而不会去取默认打印机的配置属性!
 
我遇到的问题是这样的:
客户一台机器联两台打印机,一台的票据打印机,一台的普通打印机。在同一个系统里面,当用户打印发票是系统自动调用票据打印机,当用户打印统计表的时候刚自动用普通打印机。工作原理就是不断地根据模块功能设置两台打印中一台为默认打印机。具体代码如下:
1.取得所有安装在本机上的打印机:
procedure TForm1.GetPrinterNames;
var
buffer: TPrinterBuffer;
currPos,n: integer;
printerName: string;
begin
PrinterNames.Free;
PrinterNames := TStringList.Create;
if GetProfileString(PChar('PrinterPorts'), nil, '', buffer, MAXPRINTERBUFFER) > 0 then
begin
currPos := 0;
n := 0;
while (true)do
begin
n := n + 1;
printerName := ParseNames(buffer, currPos);
if printerName <> '' then
begin
printerName := IntToStr(n) + ': ' + PrinterName;
PrinterNames.Add(printerName);
end else
break;
end;
end;
end;

function TForm1.ParseNames(const namebuffer: TPrinterBuffer;
var startPos: integer): string;
var
i, j, NameLength: integer;
str: string;
begin
result := '';
if (startPos > High(namebuffer)) or (namebuffer[startPos] = Chr(0)) then
exit;
for i := startPos to High(namebuffer)do
begin
if namebuffer = Chr(0) then
begin
nameLength := i - startPos;
SetLength(str, nameLength);
for j := 0 to nameLength - 1do
str[j+1] := namebuffer[startPos + j];
result := str;
startPos := i + 1;
break;
end;
end;
end;

2.设置打印机为默认打印机:
function TForm1.SetDefaultPrinter(const PrinterName: String): boolean;
var
s2 : string;
dum1 : Pchar;
xx, qq : integer;
const
cs1 : pchar = 'Windows';
cs2 : pchar = 'Device';
cs3 : pchar = 'Devices';
cs4 : pchar = #0;
begin
try
xx := 254;
GetMem( dum1, xx);
Result := False;
qq := GetProfileString(cs3,pchar(printerName), #0, dum1, xx);
if (qq > 0)and(trim(strpas(dum1)) <> '')then
begin
s2 := PrinterName + ',' + strpas(dum1);
while GetProfileString(cs1, cs2, cs4, dum1, xx) > 0do
WriteProfileString( cs1, cs2, #0);
WriteProfileString( cs1, cs2, pchar(s2));
Result := True;
end;
finally
FreeMem(dum1);
end;
end;
 
修改默认打印机的方法在不太频繁更换打印机的时候是可行的,但是如果要频繁跟换打印机就不太适合了,跟改一下默认打印机操作系统处理时间挺长,容易暂停程序!
 
自己頂一個,希望做過類似系統的大大指導一下!
 
没有问题,我现在的系统是在三台不同的打印机(LQ300K+,LQ635K,HP2200LaserJet)不断的切换。给一个动态设置函数:
procedure TPublic.SetDefaultPrinter(PrinterName: String);
var
j: Integer;
Device : PChar;
Driver : Pchar;
Port : Pchar;
HdeviceMode: Thandle;
aPrinter : TPrinter;
begin
Printer.PrinterIndex := -1;
getmem(Device, 255) ;
getmem(Driver, 255) ;
getmem(Port, 255) ;
aPrinter := TPrinter.create;
for j := 0 to Printer.printers.Count-1do
begin
if Printer.printers[j] = PrinterName then
begin
aprinter.printerindex := j;
aPrinter.getprinter(device, driver, port, HdeviceMode) ;
StrCat(Device, ',') ;
StrCat(Device, Driver ) ;
StrCat(Device, Port ) ;
WriteProfileString('windows', 'device', Device) ;
StrCopy( Device, 'windows' ) ;
SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0 , Longint(@Device)) ;
end;
end;
Freemem(Device, 255) ;
Freemem(Driver, 255) ;
Freemem(Port, 255) ;
aPrinter.Free;
end;

注意: 在调用本函数给PrinterName赋值时一定要与你的系统内相应的打印机名称相同
 
说明一下在我的系统中各个打印机的用途:
LQ300K+:车票打印机
LQ635K:路单打印机
HP2200:报表打印机
至于相应的纸张设置我已经在本论坛给出了答案
 
接口是:
一个并口,2个USB
 
应该可以实行这个功能,我电脑上的软件,就能自动打印到非默认打印机,只要第一次设置需要的打印机,打印时不用选择打印机,不用修改默认打印机。
 
看看微软的这个文档吧,也许有帮助:
<如何编程打印到FMC中非默认打印机>
http://support.microsoft.com/kb/166129/zh-cn
 
function GetPrnNameToIndex(PrnName: widestring): Integer;
//根据打印机 名称 转换成 序号
begin
result := printer.Printers.IndexOf(prnname);
end;

//设置当前打印机
printer.PrinterIndex := GetPrnNameToIndex(form3.CmbSelectPrn.text);
procedure SetPaperSize(X, Y: Integer);
// &micro;&yen;&Icirc;&raquo;0.1mm
{Question:
How can I change the papersize of my print job?
Answer:
One way to change printer settings at the start
of a print job is to change the printer's devicemode
structure.
See: TDEVMODE in the Delphi 1.02 help file or DEVMODE
in the Delphi 2.01 help file for other settings you can
change (providing the print driver supports the change).
The following example, contains code to change the papersize and
the paper bin that is uses:}
var
Device: array[0..255] of char;
Driver: array[0..255] of char;
Port: array[0..255] of char;
hDMode: THandle;
PDMode: PDEVMODE;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(Device, Driver, Port, hDMode);
if hDMode <> 0 then
begin
pDMode := GlobalLock(hDMode);
if pDMode <> nil then
begin
if (x = 0) or (y = 0) then
begin
{Set to legal}
pDMode^.dmFields := pDMode^.dmFields or dm_PaperSize;
{pDMode^.dmPaperSize := DMPAPER_LEGAL;
changed by wulianmin}
{pDMode^.dmPaperSize := DMPAPER_FANFOLD_US;
}
PDMode^.dmPaperSize := DMPAPER_A4;
end
else
begin
{Set to custom size}
pDMode^.dmFields := pDMode^.dmFields or
DM_PAPERSIZE or
DM_PAPERWIDTH or
DM_PAPERLENGTH;
pDMode^.dmPaperSize := DMPAPER_USER;
pDMode^.dmPaperWidth := x {SomeValueIn Tenths Of A Millimeter};
pDMode^.dmPaperLength := y {SomeValueIn Tenths Of A Millimeter};
end;
(*
{Set the bin to use}
pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
pDMode^.dmDefaultSource := DMBIN_MANUAL;
*)
GlobalUnlock(hDMode);
end;
end;
Printer.PrinterIndex := Printer.PrinterIndex;
//&Ograve;&Ocirc;&Iuml;&Acirc;&iquest;&ordf;&Ecirc;&frac14;&acute;ò&Oacute;&iexcl;
end;

procedure SetCopies(Copies: Integer);
//&Eacute;è&Ouml;&Atilde;&acute;ò&Oacute;&iexcl;·&Yacute;&Ecirc;&yacute;
var
ADevice, ADriver, APort: string;
ADeviceMode: THandle;
DevMode: PDeviceMode;
begin
SetLength(ADevice, 255);
SetLength(ADriver, 255);
SetLength(APort, 255);
{ If ADeviceMode is zero, a printer driver is not loaded. Therefore,
setting PrinterIndex forces the driver to load. }
if ADeviceMode = 0 then
begin
Printer.PrinterIndex := Printer.PrinterIndex;
Printer.GetPrinter(PChar(ADevice), PChar(ADriver), PChar(APort),
ADeviceMode);
end;

if ADeviceMode <> 0 then
begin
DevMode := GlobalLock(ADeviceMode);
try
DevMode^.dmFields := DevMode^.dmFields or DM_Copies;
DevMode^.dmCopies := Copies;
finally
GlobalUnlock(ADeviceMode);
end;
end
else
raise Exception.Create('&Icirc;&THORN;·¨&Eacute;è&Ouml;&Atilde;&acute;ò&Oacute;&iexcl;·&Yacute;&Ecirc;&yacute;');
end;

procedure TForm1.SetNowPrinter;//我的支票打印按钮下,打印前的设置代码。
begin
//&Eacute;è&Ouml;&Atilde;&micro;±&Ccedil;°&acute;ò&Oacute;&iexcl;&raquo;ú
printer.PrinterIndex := GetPrnNameToIndex(form3.CmbSelectPrn.text);
//&frac12;&oslash;&Ouml;&frac12;·&frac12;&Ecirc;&frac12;
case form3.RgPagerFX.ItemIndex of
0: printer.Orientation := poPortrait;
//&ordm;á&Iuml;ò&frac12;&oslash;&Ouml;&frac12;&pound;&not;×&Yacute;&Iuml;ò&acute;ò&Oacute;&iexcl;
1: printer.Orientation := poLandscape;
//×&Yacute;&Iuml;ò&frac12;&oslash;&Ouml;&frac12;&pound;&not;&ordm;á&Iuml;ò&acute;ò&Oacute;&iexcl;
end;
//&Ouml;&frac12;&Otilde;&Aring;&acute;ó&ETH;&iexcl;
case form3.RgPagerSize.ItemIndex of
0: SetPaperSize(0, 0);
1: SetPaperSize(strtoint(form3.EdtX.text), strtoint(form3.edty.Text));
end;
//&Aacute;&ordf;&Ecirc;&yacute;
case notetype of
2: SetCopies(form3.SeSkJzd.Value);
3: SetCopies(form3.SeFkjzd.Value);
4: setcopies(form3.SeDh.Value);
end;

end;

我的程序里是这样的,打印正常,直接打印。一开始设置一下用哪个打印机,进纸方向,纸张大小等,打印时直接取设置值,再用函数设置打印设置。
你根据情况试试。
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3637866
试试这个程序,在你的机器上,软件中设置某票据打印到非默认打印机后,打印时,是否真的打印到该默认打印机上,试试打印两次,横向,纵向,看看设置是否生效。
 
后退
顶部