• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            VC數(shù)據(jù)庫編程中的打印控制
            2003-12-4加入  來自賽迪網(wǎng)  作者李佑民  1條評論  點擊2287
                   
              VC數(shù)據(jù)庫編程中的打印控制比較復(fù)雜,但它也給程序員最大的靈活性,而這種靈活性正是我們需要的。因為各行業(yè)、部門的報表一般都不太規(guī)整,特別是表頭部分,二、三重嵌套的情況很常見。下面我們就開發(fā)中碰到的一些問題與同行們探討。 

              Document/View框架之外的打印 

              熟悉VC的程序員都知道Microsoft 的AppWizard生成的應(yīng)用程序框架中,可以選擇免費的打印及打印預(yù)覽功能,但前提是必須選擇Document/View結(jié)構(gòu)。然而我們的數(shù)據(jù)庫應(yīng)用中一般都不需要一個文檔類來保存文檔,因為數(shù)據(jù)庫(源)就是我們的文檔,數(shù)據(jù)一般是在一個對話框或視中與用戶交互,編輯或修改結(jié)果直接通過數(shù)據(jù)庫引擎寫回數(shù)據(jù)庫中。我們的程序主框架要么是基于對話框的、要么是基于無文檔類的單視(或多視)結(jié)構(gòu),在這種情況下,AppWizard 在打印控制部分并不能給我們?nèi)魏螏椭荒茏约贺?fù)責(zé)完成打印控制。 

              總結(jié)起來,一次打印操作要遵循以下步驟: 

              1.得到或生成打印設(shè)備場景,可通過顯示打印對話框讓用戶選擇打印機(jī)與紙張等設(shè)置,也可在程序中直接取系統(tǒng)缺省打印機(jī)設(shè)置,然后根據(jù)報表格式設(shè)置紙張大小和打印方向; 

              2.開始在該設(shè)備場景中的一次打印作業(yè),實際打印報表內(nèi)容,終止打印作業(yè); 

              3.清除打印設(shè)備場景,完成本次打印操作。 

              在下面的例子中,我們在一個對話框中讓用戶選擇打印某個報表,沒有顯示打印設(shè)置對話框,而是直接取系統(tǒng)缺省打印機(jī)設(shè)置,然后根據(jù)報表格式設(shè)置紙張大小和打印方向。之所以這樣做是因為各行業(yè)、部門的報表格式一般都是至上而下的統(tǒng)一格式。函數(shù)DoPreparePrintDC()、DoPrint()和DoClearPrintDC()分別對應(yīng)上述的三個步驟: 

              BOOL CMyDialog::DoPreparePrintDC() 

              // 準(zhǔn)備打印場景 

              { 

               #define  FONTSIZE 14 

               // 獲取打印機(jī)的設(shè)備屬性 

               CPrintDialog dlgPrint( FALSE ); 

               // 得到當(dāng)前系統(tǒng)缺省打印機(jī)設(shè)置 

               if(!dlgPrint.GetDefaults()) return FALSE; 

               LPDEVMODE pDM=dlgPrint.GetDevMode(); 

               if(pDM==NULL) return FALSE; 

               ::GlobalUnlock(pDM); 

               // 聯(lián)結(jié)打印DC,m—hDC是定義為HDC m—hDC的類成員變量 

               m—hDC=dlgPrint.CreatePrinterDC(); 

               // m—DC是定義為CDC m—DC的類成員變量 

               if(!m—DC.Attach(m—hDC) return FALSE; 

               // 設(shè)置打印標(biāo)志 

               m—DC.m—bPrinting=TRUE; 

               short cxInch=m—DC.GetDeviceCaps(LOGPIXELSX); 

               short cyInch=m—DC.GetDeviceCaps(LOGPIXELSY); 

               // 建立打印字體,m—fontPrint 是定義為CFont m_fontPrint的類成員變量 

               if(!m—fontPrint.CreateFont(MulDiv(FONTSIZE, -cyInch, 72),0,0,0, FW—NORMAL,0,0,0, GB2312—CHARSET, OUT—CHARACTER—PRECIS, CLIP—CHARACTER—PRECIS,DEFAULT—QUALITY, DEFAULT—PITCH|FF—DONTCARE, HFONTNAME) 

               return FALSE; 

               return TRUE;} 

              void CDlgDataPrint::DoClearPrintDC() 

              // 清除打印場景 

              { m—fontPrint.DeleteObject(); 

               m—DC.Detach(); 

               ::DeleteDC( m—hDC );} 

              void CDlgDataPrint::DoPrint() 

              // 實際打印輸出 

              { if(DoPreparePrintDC()==FALSE) return; 

               // 開始一次打印作業(yè) 

               CString str; 

               str.LoadString(AFX—IDS—APP—TITLE); 

               DOCINFO di; 

               ::ZeroMemory (&di, sizeof (DOCINFO)); 

               di.cbSize=sizeof (DOCINFO); 

               di.lpszDocName=str; 

               m—DC.StartDoc(&di); 

               m—DC.StartPage(); 

               // 將打印字體選進(jìn)設(shè)備場景 

               CFont* pOldFont=m—DC.SelectObject(&m—fontPrint); 

               // 輸出報表,建議用CDC::DrawText()函數(shù)便于控制打印范圍 

               ... 

               // 終止打印作業(yè) 

               m—DC.EndPage(); 

               m—DC.EndDoc(); 

               m—DC.SelectObject(pOldFont); 

               // 清除打印場景 

               DoClearPrintDC();} 

              表格問題 

              對格式固定或表頭、表體比較復(fù)雜的情況,特別是有嵌套表格的情況下,我們認(rèn)為先將打印結(jié)果以文本形式寫入一臨時文件,然后再對文件進(jìn)行打印輸出的方法會使事情簡單一些。因為這樣在程序中就可以只關(guān)心數(shù)據(jù)(表體)的輸出,而表頭則可以固定格式存入數(shù)據(jù)庫。 

              但是,我們在對文本形式的報表進(jìn)行打印輸出時卻發(fā)現(xiàn)一個有趣的現(xiàn)象,有時輸出結(jié)果的相鄰兩行表格豎線不能對齊,而有時又可以。原來是 Windows 圖形輸出的問題,只要我們在建立打印字體時,字體的高度是偶數(shù)就可保證豎線對齊,如果是奇數(shù)則不能對齊。知道了原因,在建立打印字體時只需加入如下代碼即可: 

              ... 

              #define  FONTSIZE 14 

              #define  HFONTNAME ″宋體″ 

              // 建立打印字體,m—fontPrint是定義為CFont m—fontPrint的類成員變量 

              int nFontHeight=MulDiv(FONTSIZE,-cyInch, 72); 

              if(nFontHeight % 2) nFontHeight++; 

              if(!m—fontPrint.CreateFont(nFontHeight, 0, 0, 0, FW—NORMAL, 0, 0,0,GB2312—CHARSET, OUT—CHARACTER—PRECIS, CLIP—CHARACTER—PRECIS,DEFAULT—QUALITY, DEFAULT—PITCH | FF—DONTCARE, HFONTNAME)) 

               return FALSE; 

              ... 

              還有一點小技巧,輸出文本形式的報表時,對報表的橫線只需要輸出其正常高度的二分之一或三分之一,這樣報表看起來更緊湊美觀。這也是我們在前面建議用CDC::DrawText()進(jìn)行繪制輸出的原因。 
            Posted on 2005-11-11 14:31 艾凡赫 閱讀(754) 評論(0)  編輯 收藏 引用 所屬分類: ADO編程技術(shù)
            久久九九免费高清视频| 91精品国产高清91久久久久久| 欧美久久精品一级c片片| 国产精品美女久久久久av爽| 九九久久精品国产| 亚洲中文字幕无码久久2020| 久久亚洲国产中v天仙www| 午夜精品久久影院蜜桃| AAA级久久久精品无码片| 亚洲精品99久久久久中文字幕| 77777亚洲午夜久久多喷| 伊人久久成人成综合网222| 99久久精品日本一区二区免费| 久久天天躁狠狠躁夜夜2020 | 久久影院久久香蕉国产线看观看| 久久精品国产久精国产一老狼| 亚洲国产成人久久精品动漫| 久久人人爽人人爽人人av东京热 | 婷婷综合久久狠狠色99h| 欧美精品国产综合久久| 国产精品欧美久久久久天天影视| 97久久精品人妻人人搡人人玩| 人妻无码精品久久亚瑟影视| 久久久99精品一区二区| 国产精品岛国久久久久| 色欲久久久天天天综合网 | 色综合久久中文字幕综合网| 日韩精品久久久久久| AV色综合久久天堂AV色综合在| 香蕉久久夜色精品升级完成| 无码八A片人妻少妇久久| 一级做a爰片久久毛片毛片| 国产69精品久久久久99| 天天爽天天爽天天片a久久网| 久久最新精品国产| 精品久久久久久无码人妻热 | 69久久夜色精品国产69| 久久久无码精品亚洲日韩蜜臀浪潮| 久久精品国产99国产精品亚洲 | 久久99精品国产麻豆不卡| 国产精品欧美久久久久无广告|