2008年12月25日 星期四

如何自訂印表機紙張大小

以下為印表機透過程式進行設定,包含自定紙張大小,切換印表機,取得預設印表機名稱等 //直接指定紙張大小函式
procedure PageSet(sPagName: String;PaperWidth,PaperLength: integer; PrintIndex : integer; PrinterName : string);
var
Device, Driver, Port: array [0..80] of Char;
DevMode: THandle;
pDevmode: PDeviceMode;
i : integer;
begin
   Printer.PrinterIndex := PrintIndex;
   // Get printer device name etc.
   Printer.GetPrinter(Device, Driver, Port, DevMode);
   // force reload of DEVMODE
   Printer.SetPrinter(Device, Driver, Port, 0);
   // get DEVMODE handle
   Printer.GetPrinter(Device, Driver, Port, DevMode);
   if DevMode <> 0 then begin
     // lock it to get pointer to DEVMODE record
     pDevMode := Windows.GlobalLock(DevMode);
     if pDevmode <> nil then begin
       try
         with pDevmode^ do begin
             // modify form
             StrLCopy(dmFormName, PChar(sPagName), CCHFORMNAME - 1);
              dmFields := dmFields or DM_FORMNAME or DM_PAPERWIDTH or DM_PAPERLENGTH;
            // tell printer driver that dmFormname field contains
            // data it needs to inspect.
            dmPaperWidth := PaperWidth;
            dmPaperLength := PaperLength;
         end;
       finally
         Windows.GlobalUnlock(Devmode); //unlock devmode handle.
       end;
     end;
   end;
end;

//切換印表機函式
procedure SetDefaultPrinter1(NewDefPrinter: string);
var
ResStr: array[0..255] of Char;
begin
   StrPCopy(ResStr, NewdefPrinter);
   WriteProfileString('windows', 'device', ResStr);
   StrCopy(ResStr, 'windows');
   SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, Longint(@ResStr));
end;

//取得目前印表機名稱
Function GetDefaultPrinterName : String;
var
iSize : Integer;
sIniFile, sSection, sKeyName : PChar;
begin
   iSize := 256;
   sIniFile := 'win.ini';
   sSection := 'windows';
   sKeyName := 'device';
   SetLength(Result,iSize);
   GetPrivateProfileString(sSection,sKeyName,nil,PChar(Result),iSize,sIniFile);
   Result := Copy(Result, 0, Pos(',',Result)-1);
end;

//使用範例如下
//裡面的ComboBox1是貼出來的元件,建議可以動態產生
procedure TFMstSAL01_AD_TEST.InfoButton2Click(Sender: TObject);
var
DefaultPrintName : string; //原來預設印表機的名稱
i, indexDefaultPrint : integer;
begin
inherited;
//新增切換紙張
//出貨郵標的名稱叫5*3,規格是寬4.33英吋(1100mm)、高3.00英吋()
try
   ComboBox1.Items.Assign(Printer.Printers);
   DefaultPrintName := GetDefaultPrinterName;
   i := 0;
   indexDefaultPrint := 9999;
   while i + 1 <= ComboBox1.Items.Count do
   begin
     showmessage(UpperCase(ComboBox1.Items[i]));
     //以下做法維將印表機名稱固定判斷印表機是否存在
     //也可以用DefaultPrintName帶入預設印表機名稱
     if UpperCase('PNT02') = UpperCase(ComboBox1.Items[i]) then
     begin
        indexDefaultPrint := i;
        break;
     end;
     i := i + 1;
   end;

   if indexDefaultPrint = 9999 then
   begin
     ShowMessage('找不到名稱為"PNT02"的印表機名稱,請檢查設定!!!');
     Exit;
   end;

   SetDefaultPrinter1('PNT02');

   //直接指定大小
   PageSet('5*3' , 1100, 762, indexDefaultPrint, 'PNT02');
   //設定為中一刀大小
   //PageSet('中一刀' , 2159, 1397, indexDefaultPrint, DefaultPrintName);
   //設定為A4大小
   //PageSet('Letter' , 2159, 2794, indexDefaultPrint, DefaultPrintName);
   //以下為eep列印報表函式
   RepClient2.Print(Null, VarArrayOf(['SHNO']), VarArrayOf([cdsMaster.FieldByName('SHNO').AsString]), False);
finally
  // PageSet('Letter' , 2159, 2794, indexDefaultPrint, DefaultPrintName);
  //將印表機制預設印表機設定回原來的印表機
  SetDefaultPrinter1(PCHAR(DefaultPrintName));
end;
end;