有沒有能在程式中由設計者寫程式然後使用者只要按列印而不用去再設紙張格式或印表機的方法呢 |
答題得分者是:懷舊的人
|
huangeider
高階會員 發表:288 回覆:492 積分:231 註冊:2003-02-26 發送簡訊給我 |
請教印報表的問題
若寫一套進銷存的軟体
其中有許多的報表格式
像有100種報表格式的話
是不是只有在印表機設100種印表機的自定紙張格式
像這種情形我只知道設100台的不同格式的新增印表機
然後在100台中紙張的default值設成要印的格式
在程式中的quickrep元件page設成default才能印出想要的紙張格式
這樣使用者不是得一直換不同的印表機(像10*10公分的標簽印表機印完想換印
20*20大宗郵件格式的印表機)得一直這樣把要印的格式一直設印表機為預設狀態 實在麻煩
有沒有能在程式中由設計者寫程式
然後使用者只要按列印
而不用去再設紙張格式或印表機的方法呢 aric
|
懷舊的人
高階會員 發表:28 回覆:152 積分:141 註冊:2003-01-08 發送簡訊給我 |
|
huangeider
高階會員 發表:288 回覆:492 積分:231 註冊:2003-02-26 發送簡訊給我 |
引言: 方法是有的,不過請先到報表區討論區把所有的問題討論看一遍看到一篇控制印出紙張的程式如下: Programmer 深度論壇 轉貼: 在 WindowsNT/200 環境下要自訂紙張尺寸所使用的方法與 Win9x 不同, 你必須先為目前的印表機定義一個自訂的 "Form"(呼叫 API: AddForm, 此 API 宣告於 WinSpool 單元中),然後把這個 Form 的名稱設定給 DEVMODES 結構中的 dmFormName 欄位。以下的函式可以直接拿來使用: uses Windows, WinSpool, Printers; (*------------------------------------------------------ Define a new Form (WinNT/2000 only). If FormName already exists, do nothing and return. If failed, an exception will be raised. ------------------------------------------------------*) procedure PrnAddForm(const FormName: string; PaperWidth, PaperLength: integer); 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 := PChar(FormName); PaperSize.cx := PaperWidth; PaperSize.cy := PaperLength; PaperRect.Left := 0; PaperRect.Top := 0; PaperRect.Right := PaperWidth; PaperRect.Bottom := PaperLength; 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); end; (* Set custom paper size for WinNT/2000. Make sure FormName is supported by current printer, You can call PrnAddForm to define a new Form. *) procedure PrnSetPaperSizeNT(FormName: string; PaperWidth, PaperLength: integer); var Device, Driver, Port: array[0..80] of Char; DevMode: THandle; pDevmode: PDeviceMode; begin // 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 := GlobalLock( DevMode ); if pDevmode <> nil then try with pDevmode^ do begin // modify form StrLCopy( dmFormName, PChar(FormName), CCHFORMNAME-1 ); // tell printer driver that dmFormname field contains // data it needs to inspect. dmPaperWidth := PaperWidth; dmPaperLength := PaperLength; dmFields := dmFields or DM_FORMNAME or DM_PAPERWIDTH or DM_PAPERLENGTH; end; finally GlobalUnlock( Devmode ); // unlock devmode handle. end; end; { If } end; procedure TForm1.Button1Click(Sender: TObject); begin PrnAddForm( edFormName.Text, StrToInt(edPaperWidth.Text), StrToInt(edPaperLength.Text) ); PrnSetPaperSizeNT( edFormName.Text, StrToInt(edPaperWidth.Text), StrToInt(edPaperLength.Text) ); Printer.BeginDoc; Printer.Canvas.TextOut(10, 10, 'Printer test!'); Printer.EndDoc; end; 以上我有測試過了有一些問題提出來討論 在 procedure TForm1.Button1Click(Sender: TObject); begin PrnAddForm( edFormName.Text, StrToInt(edPaperWidth.Text), StrToInt(edPaperLength.Text) ); PrnSetPaperSizeNT( edFormName.Text, StrToInt(edPaperWidth.Text), StrToInt(edPaperLength.Text) ); Printer.BeginDoc; Printer.Canvas.TextOut(10, 10, 'Printer test!'); Printer.EndDoc; end; 1 edFormName.Text 只要有key in 文字就可以了(那這個參數也沒有了取出欲使用的印表機名稱的功能了) 2 edPaperWidth.Text 和 edPaperLength.Text 在244*244時是執行的底限 低於 此標準則沒有作用 3 最大的問題是在printer.begindoc 和 printer.enddoc 之間 的列印問題 Printer.BeginDoc; Printer.Canvas.TextOut(10, 10, 'Printer test!'); Printer.EndDoc; 這樣只能印出'printer test'這個字串 要如何套用到自做預覽的form 中印出想印的報表內容呢? aric |
懷舊的人
高階會員 發表:28 回覆:152 積分:141 註冊:2003-01-08 發送簡訊給我 |
這一篇其實和你之前的問題並沒有很直接關係,你說如果有100種報表格式,而你可以新增100台印表機對應到這100種格式,雖然列印時是由預設印表機輸出的,但是 QuickReport 可以在列印之前改變輸出的印表機,而且可寫在程式內,通常是在 QuickRep 的列印之前變更列印的印表機,而且它不會變更預設印表機,你應該到 QuickReport 的網站看看,並且對 QuickRep 這元件多看看,而我要你到報表區看看,顯然你沒看清楚,因為那裡已經有寫出如何取得你設定的100種印表機,而且指定QuickRep要從那一台輸出,請再看看。 發表人 - 懷舊的人 於 2003/03/09 14:16:19
|
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
懷舊的人 兄 所說的 非常認同 不過 這些資訊沒有人整理 所以跳來跳去看有時也會 霧沙沙 哈哈 所以 【Delphi】【求才】HTMLReport程式產生器團員招募 http://delphi.ktop.com.tw/topic.php?TOPIC_ID=26805 應該可以 有這個機會 整合並 使用無需特定應用程式之列印 來處理
建立所謂的 html列印模組 (在此打一下廣告) 哈哈
自己怕忘了 哈哈
QuickReport在Windows2000中自訂報表?
http://delphi.ktop.com.tw/topic.php?topic_id=237 *********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind to make knowledge together!
希望能大家敞開心胸,將知識寶庫結合一起
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
huangeider
高階會員 發表:288 回覆:492 積分:231 註冊:2003-02-26 發送簡訊給我 |
引言: 這一篇其實和你之前的問題並沒有很直接關係,你說如果有100種報表格式,而你可以新增100台印表機對應到這100種格式,雖然列印時是由預設印表機輸出的,但是 QuickReport 可以在列印之前改變輸出的印表機,而且可寫在程式內,通常是在 QuickRep 的列印之前變更列印的印表機,而且它不會變更預設印表機,你應該到 QuickReport 的網站看看,並且對 QuickRep 這元件多看看,而我要你到報表區看看,顯然你沒看清楚,因為那裡已經有寫出如何取得你設定的100種印表機,而且指定QuickRep要從那一台輸出,請再看看。 發表人 - 懷舊的人 於 2003/03/09 14:16:19站長轉貼自 深度論壇 的 cc 發言文章: 先在專案新增一個新單元(名為 WinSpool2), 因為 Delphi 5 無宣告 GetDefaultPrinter (取得預設印表機). unit WinSpool2; interface uses Windows, WinSpool; function GetDefaultPrinter(pszBuffer : PChar; var pcchBuffer : DWORD) : BOOL; stdcall; implementation function GetDefaultPrinter; external winspl name 'GetDefaultPrinterA'; end. // 自動設定紙張大小程式 procedure TForm1.Button6Click(Sender: TObject); var _PPrinterInfo2 : PPrinterInfo2; pPrinterName : PChar; sPrinterName, sFormName : String; hPrinter : THandle; cbNeeded : DWORD; dwBufferSize : DWORD; begin sFormName := 'Letter'; // 取得預設印表機名稱 if not GetDefaultPrinter(nil, dwBufferSize) then begin case GetLastError of // 即使呼叫成功也會有此一錯誤(Buffer 不足), 我只是要取得 Buffer 大小所以忽略此錯誤訊息 ERROR_INSUFFICIENT_BUFFER : ; ERROR_FILE_NOT_FOUND : raise Exception.Create('無預設印表機.'); else raise Exception.Create('GetDefaultPrinter Error, Code : ' IntToStr(GetLastError)); end; end; pPrinterName := nil; try GetMem(pPrinterName, dwBufferSize); GetDefaultPrinter(pPrinterName, dwBufferSize); sPrinterName := StrPas(pPrinterName); // <-- 預設印表機名稱 finally if pPrinterName <> nil then begin FreeMem(pPrinterName, dwBufferSize); pPrinterName := nil; end; end; // 設定印表機的紙張大小名稱 if not WinSpool.OpenPrinter(PChar(sPrinterName), hPrinter, nil) then raise Exception.Create('OpenPrinter Error, Code : ' IntToStr(GetLastError)); WinSpool.GetPrinter(hPrinter, 2, nil, 0, @cbNeeded); _PPrinterInfo2 := nil; try GetMem(_PPrinterInfo2, cbNeeded); WinSpool.GetPrinter(hPrinter, 2, _PPrinterInfo2, cbNeeded, @cbNeeded); with _PPrinterInfo2^.pDevMode^ do begin StrLCopy(dmFormName, PChar(sFormName), CCHFORMNAME - 1); //dmPaperSize := PaperSizeID(sPrinterName, sFormName); dmFields := DM_FORMNAME; // DM_PAPERSIZE end; // 不知為何 SetPrinter 一定會有錯誤 -> GetLastError = ERROR_ACCESS_DENIED // (即使以 Administrator 身份執行), 所以先把 raise 註解掉, Who could explain it for me ? Thanks. if not WinSpool.SetPrinter(hPrinter, 2, _PPrinterInfo2, 0) then ; //raise Exception.Create('SetPrinter Error, Code : ' IntToStr(GetLastError)); finally if _PPrinterInfo2 <> nil then FreeMem(_PPrinterInfo2); _PPrinterInfo2 := nil; end; end; 一般設定紙張大小要在印表機圖示上按 MOUSE 右鍵, 點選列印喜好設定 -> 進階 進入設定視窗設定紙張大小, 上列程式可以以程式設定之(永久設定). 您可以先以手動設定紙張大小為 A3, 在執行程式後查看紙張大小, 喜好設定中的 ~~~Delphi K.Top討論區站長~~ 這篇文章實在是好用 感謝 懷舊的人 兄的指教 也謝謝 jackkcg 兄的灌水 最大的感謝來自 站長 轉貼 cc 兄或姊 的程式碼 再重覆一次給有此印表機設定困擾的人 cc 兄所發表的這部份程式碼只要確定有自訂紙張格式 再套用此程式碼就可以在程式中設定紙張格式嗯 但要記得程式執行完後最好在結束前改回最常用的 a4以免被人家complain aric |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |