全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1385
推到 Plurk!
推到 Facebook!

Delphi開發WEB應用程式列印元件

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-01-29 14:58:19 IP:61.221.xxx.xxx 未訂閱
此為轉貼資料 http://www.powerba.com/develop/delphi/article/20010312007.htm Delphi開發WEB應用程式列印元件(1) ChenHui 中國軟體發展中心 一、引言 近些年來,隨著互聯網的普及和推廣,傳統的單機模式和局域中的c/s模式的應用程式越來越不能滿足資訊共用的要求。因此,一種新的基於瀏覽器的b/s的應用程式的開發方式被提了出來。新的開發方案以其用戶端的免維護、免配置、程式能根據伺服器的資訊能夠自動更新升級;伺服器端多層模式的應有提高處理的效率和安全性越來越被廣大的應用程式的開發者所看好。成爲應用程式開發的一個新的發展方向。在windows的平臺上,人們利用asp來開發服務的顯示介面,而用元件來封裝商業規則,在各種雜誌上利用各種工具進行元件開發也是屢見不鮮。但介紹列印組開發卻不怎麽看到。筆者希望就自已開發列印元件的一點心得體會來抛磚引玉。 二、設想 web列印元件要求是在一次爲某單位開發資訊管理系統中被提及的,這個系統中的一些票據需要列印。這樣,如何對這些票據進行套打成了我們必須解決的問題。 要在用戶端列印一些用戶要求的票據或其他的文字或圖片資料,有兩種方式:一種是利用delphi的active form來生成用戶端的介面,由瀏覽器下載安裝,並在用戶端運行。(這種方式在開發多後臺資料庫中,較爲常用。在國內許多新版本的財務軟體都採用了這種方法,其缺點是對開發人員的要求太高),另一種是開發一個元件在用戶端安裝,然後,由伺服器端來生成vbscript腳本,在用戶端運行、創建相應的元件物件;利用元件物件來進行列印操作。(這種方法只要用戶端的com元件開發完成,使用者只要熟悉vbscript或javascript腳本語言就可能方便的調用)。本文我們主要討論第二種方式。 三、實現 首先、運行delphi 5.0;選擇file功能表中的new,在彈出的對話方塊中選擇activex頁,選擇activex library創建activex庫.然後,再往新建的庫中加入一個automation object,操作步驟同上。在automation object wizard對話方塊中填入元件名prttest3;單擊ok。 然後、在彈出的prttest3.tlb窗口中,選擇iprttest3。單擊右鍵新增一個isinit的property,類型爲long。再繼續增加如下5個method: procedure prtcustompage(pagewidth: integer; pageheight: integer); safecall; procedure prtstart; safecall; procedure prtnewpage; safecall; procedure prtend; safecall; procedure prtdrawline(x1: integer; y1: integer; x2: integer; y2: integer; linewidth: integer); safecall; procedure prtsetfont(const fontname: widestring; fontsize: integer); safecall; procedure prttextrect(valign: integer; halign: integer; rectleft: integer; recttop: integer;rectright: integer; rectbottom: integer; const printstring: widestring); safecall; 它們意義是:prtcustompage 用來設置自定義紙張.傳入的參數自定義紙張的寬度和高度。 prtstart 用來初始化印表機。如果初始化成功,則將屬性isinit置爲真,反之則爲假。 prtnewpage 用來使印表機換頁。 prtend 結束列印任務。 prtdrawline 用來在頁面上繪製一條線。(x1,y1)爲起始點.(x2,y2)爲終止點。linewidth爲列印線的寬度。 prtsetfont 用來設置列印的字體名及大小。 prttextrect 用來指定的方框內的輸出的指定的字串。 Delphi開發WEB應用程式列印元件(2) ChenHui 中國軟體發展中心 四、調用 在腳本中調用這個元件的方法: (1)、利用createobject函數創建一個列印物件。 (2)、調用prtcustompage來指定定制的紙張的大小(以0.1毫米爲基本單位)。如果,不是定制的紙張則不需要調用這個過程(即以列印默認的紙張大小進行列印)。 (3)、調用prtstart進行印表機的初始化工作。如果印表機初始化成功,則會將isinit屬性置爲真,表示初始化成功;否則,表示印表機正在忙或有別的應用程式正在使用印表機,初始化不能成功。 (4)、判斷isinit標誌。如果爲真,則繼續執行列印段。 (5)、執行列印段。可以在利用印表機畫線、和在指定位置輸出文字。 (注:在元件接中的所有位置單位都是0.1毫米。例如.prtobject.prtdrawlien 0,0,1000,1000 表示從左上角(0,0)毫米到右下角(100,100)毫米處,畫一條直線) (6)、利用prtend結束列印任務。 < script language="vbscript"> < !-- sub testprtobject dim prtobject set prtobject=createobject("prttest3.prttest3") prtobject.prtcustompage 1000,1000 prtobject.prtstart if prtobject.isinit then prtobject.prtdrawline 0,0,1000,1000,1 prtobject.prtdrawline 500,700,1000,1000,1 prtobject.prtsetfont "宋體",16 prtobject.prttextrect 2,2,0,0,1000,500,"web應用程式列印測試" prtobject.prtend end if set prtobject=nothing end sub testprtobject() //--> < /script> Delphi開發WEB應用程式列印元件(3) ChenHui 中國軟體發展中心五、代碼解析 在這個元件中,我們所要解決的幾個問題: (1)、在delphi的應用程式設計中自定義打印紙張的設置,delphi中自身帶了一個quickreport的列印設計程式,這個程式在一定的程度上方便了列印的設計,但這個設計程式對於自定義紙張的設定和列印支援卻不是很好。因此,在這個元件中我們採用手工代碼來設定自定義紙張大小。 function tprttest3.initprintpaper:boolean; var device:array [0..cchdevicename-1] of char; driver:array [0..(max_path-1)] of char; port:array [0..32] of char; hdmode:thandle; pdmode:pdevmode; begin result:=true; if prtiscustompaper then begin {設置印表機段} printer.getprinter(device,driver,port,hdmode); if hdmode<>0 then begin try pdmode:=globallock(hdmode); if pdmode<>nil then begin //設定列印的方向爲縱向或橫向 if paperorientation<>0 then pdmode^.dmorientation:=dmorient_landscape else pdmode^.dmorientation:=dmorient_portrait; //設置拷貝份數爲1份. pdmode^.dmcopies:=1; //以毫米爲單位的紙張大小. pdmode^.dmpaperlength:= paperheight*10; pdmode^.dmpaperwidth:=paperwidth*10; //設置紙張類型爲用戶自定義. pdmode^.dmpapersize:=dmpaper_user; end; globalunlock(hdmode); printer.setprinter(device,driver,port,hdmode); except result:=false; end; end else begin result:=false; end; end; end; Delphi開發WEB應用程式列印元件(4) ChenHui 中國軟體發展中心 (2)、列印位置的確定:由於元件是以圖形方式進行列印,這就使得我們可以精確指向列印文件的輸出位置,以便於進行對某些票據的套打。但這樣就産生一個問題,我們是以列印的圖元位置指定輸入位置,還是以列印尺寸來指定位置。顯然,利用圖元來輸出列印位置,對於編制程式來說是比較方便的。但由於一般用戶對圖元的概念並不理解,因此會帶來使用上的困難;而且每一種印表機的分辯率是不一樣的,因此,會出現在不同印表機上列印的效果不一樣的問題。而以列印尺寸來指定位置並在程式中妥善加以處理就不會有上面的問題。具體的處理方法是,由用戶輸入尺寸位置。然後,在列印時,首先取得當前印表機的分辯率(注意:解析度是以每英寸多少圖元爲單位的),再計算得出實際輸入的圖元位置後進行列印,這樣就可以使得元件更加實用,而且,保持列印幅面的一致。具體的函數如下。 function tprttest3.mmtoprintpixel(inputpoint:tpoint):tpoint; begin result.x:=mmtoprintpixelx(inputpoint.x); result.y:=mmtoprintpixely(inputpoint.y); end; function tprttest3.mmtoprintpixelx(inputx:integer):integer; begin if queryprintlogpixel then begin pddix:=getdevicecaps(printer.handle,logpixelsx); pddiy:=getdevicecaps(printer.handle,logpixelsy); queryprintlogpixel:=false; end; result:=trunc(inputx/253.8*pddix 0.5); end; function tprttest3.mmtoprintpixely(inputy:integer):integer; begin if queryprintlogpixel then begin pddix:=getdevicecaps(printer.handle,logpixelsx); pddiy:=getdevicecaps(printer.handle,logpixelsy); queryprintlogpixel:=false; end; result:=trunc(inputy/253.8*pddiy 0.5); end; getdevicecaps:爲windows系統中取得指定設備資訊的函數。函數的原型如下 int getdevicecaps( hdc hdc, // 設置的控制碼 int nindex // 查詢的設備參數。 ); 其中,hdc爲想要查詢的印表機的控制碼,logpixelsx、logpixelsy表示要查詢的內容是印表機橫向、縱向的每英寸的圖元點數。 Delphi開發WEB應用程式列印元件(5) ChenHui 中國軟體發展中心 六、元件的註冊 如果是在delphi編寫了這個元件的,則可以選擇run功能表下的register activex server來進行這個元件的註冊。 對於不開發機器的註冊則可使用:點擊“開始”→“運行”;在運行對話方塊中輸入以下命令: regsvr32 < 檔案名 > 註冊一個activex控制項 regsvr32 /u < 檔案名 > 解除某activex控制項的註冊 七、其他應用 元件的擴展:以上列出的僅僅是編寫這個元件的框架,功能比較有限。根據需要我們還可以添加上畫圓、橢圓,矩形,甚至圖片等功能。有興趣的讀者就請自行添加。 因爲,元件是採用com的方式運行,所以,我們還在windowscript hosts(wsh)中應用這個元件,結合wsh原有(通過ado物件)訪問外部資料庫的能力,就可能做出在windows下功能強大的wsh的腳本程式。 ********************************************************* 哈哈&兵燹 最會的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
系統時間:2024-05-06 0:05:49
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!