65.9K
CodeProject 正在变化。 阅读更多。
Home

矩阵打印类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (13投票s)

2014 年 2 月 25 日

CPOL

4分钟阅读

viewsIcon

32546

downloadIcon

1558

一个 C++ 类,可以轻松地以清晰定义的行和列打印文本

Sample printout using Pristina font.

使用 Pristina 字体进行的示例打印输出。网格线仅用于演示。第一行文本显示了字体的正常外观。其余的文本是使用 CMatrixPrinter 类设置的字体。

引言

我有一堆数据,这些数据最好以排列整齐的行和列来显示,并且所有数据都右对齐,以便小数点在同一列中对齐。GDI API 没有内置的功能来实现右对齐文本,尽管可以通过巧妙地使用前导空格来模拟。但这只在您使用固定宽度字体时有效。一旦您使用可变宽度字体,所有您精心布局的格式都会失效。

本文介绍的 CMatrixPrinter 类旨在解决此问题。它是一个包装类,包装了一个 HDC 打印机设备上下文句柄。它具有设置打印矩阵的成员函数。它还具有将文本输出到特定行和列的函数,可以左对齐或右对齐。并且您选择使用哪种字体无关紧要,因为几乎所有字体都可以正常工作。

Using the Code

公共成员函数

构造函数

CMatrixPrinter(const TCHAR * DocName, LPDEVNAMES pDevNames, LPDEVMODE pDevMode = NULL)
CMatrixPrinter(const TCHAR * DocName, const TCHAR * Device, 
               const TCHAR * Driver = _T("WINSPOOL"), LPDEVMODE pDevMode = NULL)
CMatrixPrinter(const TCHAR * DocName, HDC hDC)
CMatrixPrinter(const DOCINFO & DocInfo, HDC hDC)

CMatrixPrinter 类中有四个构造函数。它们要么创建打印机设备上下文,要么包装提供的设备上下文。然后,它们调用 StartDoc() 和 StartPage() API。它们还将文本背景模式设置为 TRANSPARENT。

参数

DocName

指向包含文档文件名(字符串)的指针。

pDevNames

指向用于创建打印机设备上下文的 DEVNAMES 结构的指针。

pDevMode

指向用于初始化打印机设备上下文的可选 DEVMODE 结构的指针。

Device

指向打印机设备名称(如打印管理器所示)的字符串指针。

驱动程序

指向打印提供程序名称的字符串指针,默认为“WINSPOOL”。

hDC

打印机设备上下文的句柄。

DocInfo

指向 DOCINFO 结构的引用,该结构包含文档文件名和输出文件名。

析构函数

~CMatrixPrinter(void)

调用 EndPage() 和 EndDoc() API。如果设备上下文是在构造函数中创建的,则还调用 DeleteDC()。

矩阵设置函数

int SetRows(int Rows, const TCHAR * FontFaceName = NULL)
int SetColumns(int Columns, const TCHAR * FontFaceName = NULL)

这两个函数用于设置矩阵。它们尝试设置指定行数或列数,但由于字体的创建方式,可能不会完全精确。SetRows 计算所需的列数,SetColumns 计算所需的行数。使用 CMatrixPrinter::GetMatrixSize() 来获取确切的行数和列数。

参数

Rows

请求在矩阵中显示的行数。

Columns

请求在矩阵中显示的列数。

FontFaceName

指向指定字体类型名称的字符串指针。如果此指针为 NULL 或为空字符串,CMatrixPrinter 将使用它找到的第一个等宽字体。

返回值

如果函数成功,则返回值为正数。

如果函数失败,则返回值为零。

文本放置函数

int PlaceTextL(const TCHAR * Text, int Row, int LeftColumn)
int PlaceTextR(const TCHAR * Text, int Row, int RightColumn)

使用这些函数将文本放置在矩阵中。文本将根据指定的列左对齐或右对齐。

参数

文本

指向包含要放置文本的字符串的指针。

文本将放置的行或线号。

LeftColumn

文本中最左侧字符将放置的列。

RightColumn

文本中最右侧字符将放置的列。

返回值

函数返回实际打印的字符数。如果文本的任一端超出矩阵范围,此值可能小于文本长度。

分页函数

int NextPage(void)

调用 EndPage() 和 StartPage() API 以将打印推进到下一页。

返回值

返回新页码。

属性函数

int GetPrintJobID(void)

检索文档的打印作业标识符。这是 StartDoc() API 返回的值。

返回值

打印作业标识符。

int GetPageNumber(void)

检索当前页码。

返回值

当前页码。

SIZE GetMatrixSize(void)

获取打印矩阵的尺寸。cx 值是页面上的列数,cy 值是页面上的行数。

返回值

一个包含矩阵尺寸的 SIZE 结构。

RECT GetGlyphRect(int Row, int Column)

获取矩阵内字形矩形的位置和大小(以像素为单位)。

参数

包含字形矩形的行号。

Column

包含字形矩形的列号。

类型转换运算符

operator HDC(void)

使用此运算符可以检索包装的打印机设备上下文句柄。

返回值

设备上下文的句柄。

示例代码

此示例代码是用于生成本文开头示例图片的同一段代码。

int _tmain(int argc, _TCHAR* argv[])
{
    // Setup and call a print dialog
    PRINTDLG pd = {0};
    pd.lStructSize = sizeof(PRINTDLG);
    pd.Flags |= PD_RETURNDC;

    PrintDlg(&pd);

    // Wrap the device context returned from the printer
    // dialog into a CMatrixPrinter class object.
    CMatrixPrinter mp(_T("Matrix Printer Test"), pd.hDC);

    // Setup the matrix using a variable width font
    mp.SetRows(60, _T("Pristina"));

    // Draw the demo grid lines to highlight our matrix
    HPEN Pen = CreatePen(PS_DOT, 1, RGB(128, 128, 128));
    HPEN OldPen = (HPEN)SelectObject(mp, Pen);
    for (int x = 0; x < mp.GetMatrixSize().cx; ++x)
    {
        for (int y = 0; y < mp.GetMatrixSize().cy; ++y)
        {
            RECT rc = mp.GetGlyphRect(y, x);
            Rectangle(mp, rc.left, rc.top, rc.right, rc.bottom);
        }
    }
    SelectObject(mp, OldPen);

    // First place the normal text on row 1 to show what
    // the font looks like normally when drawn normally.
    RECT rc = mp.GetGlyphRect(1, 1);
    TextOut(mp, rc.left, rc.top, Text, _tcslen(Text));

    // Then place the same text in our matrix on row 2
    // to show what it looks like now.
    mp.PlaceTextL(Text, 2, 1);

    // Now put some numbers in a column, right justified on column 20
    for (int i = 0; i < _countof(Numbers); ++i)
    {
        TextColour TC(mp, Numbers[i] < 0.0 ? RGB(255, 0, 0) : RGB(0, 0, 255));
        mp.PlaceTextR(pja::CBuilder<>(_T("${0}"), Fixed(Numbers[i], 2)).c_str(), i + 4, 20);
    }

	return 0;
}
© . All rights reserved.