第13章 使用打印机_13.1 打印基础

13.1 打印基础

13.1.1 打印和后台处理

说明:

(1)此图的GDI模块的程序是16位的,打印驱动程序也是16位的。

(2)spooler为windows提供的后台打印处理程序。可能用户有更好硬件或后台打印处理程序,那么可以去掉Windows自带的spooler,以加快打印速度,因为打印机输出可以不被存储在硬盘上,而是直接输出到打印机,或被硬件或软件后台打印处理程序截获。

(3)如果不使用Windows后台打印处理程序,GDI模块不会把来自设备驱动的打印输出存在文件。而是直接传到打印机并口或串口。

(4)如果打印机驱动程序不要求分带,图元文件也不会被创建,GDI只是把绘图函数直接传给驱动程序。或者也可能是应用程序承担起打印机输出分带的责任,但这样的打印代码将变得非常复杂,这样做的好处是不用产生图元文件,GDI只是负责把每条带的函数传给打印机驱动程序。

13.1.2 打印机设备环境

(1)获取设备环境句柄:

①hdc = Create(NULL,szDeviceName,NULL,pInitializationData);

    A、szDeviceName是打印机设备名称

    B、pInitializationData一般为NULL

②调用PrintDlg(lppd)产生打印对话框并从结构体的PRINTDLG可获设备环境句柄。

(2)“默认”或“当前”打印机:只能有一台打印机被设为默认打印机。

(3)枚举打印机:EnumPrinters,结果放在PRINTER_INFO_x(x为数字)结构数组中。

参数

含义

Flags

PRINTER_ENUM_LOCAL:枚举本地打印机

PRINTER_ENUM_NAME:枚举由name参数指定的打印机。NULL时为可用打印机

PRINTER_ENUM_SHARE:共享打印机

PRINTER_ENUM_DEFAULT:Win95默认的打印机

PRINTER_ENUM_CONNECTIONS:网络连接列表中的打印机

PRINTER_ENUM_NETWORK:枚举通过网络连接的打印机——Level为1

PRINTER_ENUM_REMOTE:通过网络连接的打印机和打印服务器。Level为1

Name

vbNullString表示枚举同本机连接的打印机。否则由标志和级别决定

Level

指定欲枚举结构的类型

1:由name参数标志设置决定

2或5:name为欲对其打印机进行枚举的服务器的名字或为vbNullString

4:PRINTER_ENUM_LOCA、PRINTER_ENUM_CONNECTIONS有效,name须为vbNullString

pPrinterEnum

是一个包含PRINTER_ENUM_x结构的缓冲区

cbBuf

pPrinterEnum缓冲区中的字符数量

pcbNeeded

用于保存请求的缓冲区长度,或者实际读入的字节数量

pcReturned

返回pPtrinterEnum缓冲区中PRINTER_ENUM_x结构体的数量。

【GetPrinterDC程序】

/*----------------------------------------------------------------------------------
GETPNTDC.C ——GetPrinterDC function
----------------------------------------------------------------------------------*/
//#pragma warning(disable: 4996)  //win8.1以上GetVersion己过时,加上这句关闭句
#include <windows.h>
#include <VersionHelpers.h>  //VS2013用来判断系统版本的头文件
HDC GetPrinterDC(void)
{
    DWORD  dwNeeded, dwReturned;
    HDC    hdc;
    PRINTER_INFO_4   *pinfo4;
    PRINTER_INFO_5   *pinfo5;

    if (!IsWindowsXPOrGreater())
        //  if (GetVersion() && 0x80000000)   //Windows98
    {
        EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 5, NULL, 0, &dwNeeded, &dwReturned); //获取所需缓冲区的字节数和所需结构体的数量
        pinfo5 = malloc(dwNeeded); //分配所需的字节数
        EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 5, (PBYTE)pinfo5, dwNeeded, &dwNeeded, &dwReturned);
        hdc = CreateDC(NULL, pinfo5->pPrinterName, NULL, NULL); //pinfo5为打1个打印机,pinfo5+1为第2个打印机
        free(pinfo5);
    } else
    {
        EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwReturned);
        pinfo4 = malloc(dwNeeded);
        EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (PBYTE)pinfo4, dwNeeded, &dwNeeded, &dwReturned);
        hdc = CreateDC(NULL, pinfo4->pPrinterName, NULL, NULL);
        free(pinfo4);
    }
    return hdc;
}
//#pragma warning (default : 4996)
13.1.3 DEVCAPS程序修订版

 【效果图】

 

/*---------------------------------------------------------
DEVCAPS2.C -- Displays Device Capabilities Information(Version 2)
(c) Charles Petzold, 1998
---------------------------------------------------------*/
#include <windows.h>
#include "resource.h"
#include <VersionHelpers.h>
#define IDM_DEVMODE 1000
typedef struct
{
    int iMask;
    TCHAR* szDesc;
} BITS;
void DoBaseInfo(HDC, HDC, int, int);
void DoOtherInfo(HDC, HDC, int, int);
void DoBitCodeCaps(HDC, HDC, int, int, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT("DevCaps2");
    HWND         hwnd;
    MSG          msg;
    WNDCLASS     wndclass;

    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = szAppName;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
                   szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName, NULL,
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static TCHAR       szDevice[32], szWindowText[64];
    static int         cxChar, cxCaps, cyChar;
    static int         nCurrentDevice = IDM_SCREEN,
        nCurrentInfo = IDM_BASIC;

    DWORD              dwNeeded, dwReturned;
    PRINTER_INFO_4 *   pinfo4;
    PRINTER_INFO_5 *   pinfo5;
    HMENU              hMenu;
    HANDLE             hPrint;
    HDC         hdc, hdcInfo;
    PAINTSTRUCT ps;
    TEXTMETRIC  tm;

    switch (message)
    {
    case WM_CREATE:
        hdc = GetDC(hwnd);

        GetTextMetrics(hdc, &tm);
        cxChar = tm.tmAveCharWidth;
        cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
        cyChar = tm.tmHeight + tm.tmExternalLeading;

        ReleaseDC(hwnd, hdc);
    case WM_SETTINGCHANGE:
        hMenu = GetSubMenu(GetMenu(hwnd), 0);
        while (GetMenuItemCount(hMenu) > 1)
            DeleteMenu(hMenu, 1, MF_BYPOSITION);

        //获取所有本地和远程打印机
        if (!IsWindowsXPOrGreater()) //XP以下
        {
            EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5, NULL, 0, &dwNeeded, &dwReturned);
            pinfo5 = malloc(dwNeeded);
            EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 5, (PBYTE)pinfo5, dwNeeded, &dwNeeded, &dwReturned);
            for (int i = 0; i < (int)dwReturned; i++)
            {
                AppendMenu(hMenu, (i + 1) % 16 ? 0 : MF_MENUBARBREAK, i + 1, pinfo5[i].pPrinterName);
            }
            free(pinfo5);
        } else
        {
            EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &dwNeeded, &dwReturned);
            pinfo4 = malloc(dwNeeded);
            EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 4, (PBYTE)pinfo4, dwNeeded, &dwNeeded, &dwReturned);
            for (int i = 0; i < (int)dwReturned; i++)
            {
                AppendMenu(hMenu, (i + 1) % 16 ? 0 : MF_MENUBARBREAK, i + 1, pinfo4[i].pPrinterName);
            }
            AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
            AppendMenu(hMenu, 0, IDM_DEVMODE, TEXT("Properties"));
            free(pinfo4);
        }

        wParam = IDM_SCREEN;   //默认选项
        //继续执行下云
    case WM_COMMAND:
        hMenu = GetMenu(hwnd);
        if (LOWORD(wParam) == IDM_SCREEN || LOWORD(wParam) <IDM_DEVMODE) //选择屏幕或打印机
        {
            CheckMenuItem(hMenu, nCurrentDevice, MF_UNCHECKED);
            nCurrentDevice = LOWORD(wParam);
            CheckMenuItem(hMenu, nCurrentDevice, MF_CHECKED);
        } else if (LOWORD(wParam) == IDM_DEVMODE)  //选择属性菜单项
        {
            GetMenuString(hMenu, nCurrentDevice, szDevice, sizeof(szDevice) / sizeof(TCHAR), MF_BYCOMMAND);
            if (OpenPrinter(szDevice, &hPrint, NULL))  //获取打印机句柄
            {
                PrinterProperties(hwnd, hPrint);
                ClosePrinter(hPrint);
            }
        }                                              //Capabilities 下的菜单项设置
        else
        {

            CheckMenuItem(hMenu, nCurrentInfo, MF_UNCHECKED);
            nCurrentInfo = LOWORD(wParam);
            CheckMenuItem(hMenu, nCurrentInfo, MF_CHECKED);
        }
        InvalidateRect(hwnd, NULL, TRUE);
        return 0;
    case WM_INITMENUPOPUP: //lParam菜单ID
        if (lParam == 0) //Device菜单
        {
            EnableMenuItem(GetMenu(hwnd), IDM_DEVMODE, (nCurrentDevice == IDM_SCREEN) ? MF_GRAYED : MF_ENABLED);
        }
        return 0;
    case WM_PAINT:

        lstrcpy(szWindowText, TEXT("Device Capabilities:"));
        if (nCurrentDevice == IDM_SCREEN)
        {
            lstrcpy(szDevice, TEXT("Display"));
            hdcInfo = CreateIC(szDevice, NULL, NULL, NULL);
        } else
        {
            hMenu = GetMenu(hwnd);
            GetMenuString(hMenu, nCurrentDevice, szDevice, sizeof(szDevice), MF_BYCOMMAND);
            hdcInfo = CreateIC(NULL, szDevice, NULL, NULL);
        }
        lstrcat(szWindowText, szDevice);
        SetWindowText(hwnd, szWindowText);

        hdc = BeginPaint(hwnd, &ps);
        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
        if (hdcInfo)
        {
            switch (nCurrentInfo)
            {
            case IDM_BASIC:
                DoBaseInfo(hdc, hdcInfo, cxChar, cyChar);
                break;
            case IDM_OTHER:
                DoOtherInfo(hdc, hdcInfo, cxChar, cyChar);
                break;
            case IDM_CURVE:
            case IDM_LINE:
            case IDM_POLY:
            case IDM_TEXT:
                DoBitCodeCaps(hdc, hdcInfo, cxChar, cyChar, nCurrentInfo - IDM_CURVE);
                break;
            }
            DeleteDC(hdcInfo);
        }

        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}
void DoBaseInfo(HDC hdc, HDC hdcInfo, int cxChar, int cyChar)
{
    struct
    {
        int     iIndex;
        TCHAR * szDesc;
    }
    info[] =
    {
        HORZSIZE, TEXT("HORZSIZE        Width in millimeters:"),          //显示的宽度(mm)
        VERTSIZE, TEXT("VERTSIZE        Height in millimeters:"),         //显示的高度(mm)
        HORZRES, TEXT("HORZRES         Width in pixels:"),               //(显示的宽度(像素)
        VERTRES, TEXT("VERTRES         Height in raster lines:"),        //显示的高度(像素)
        BITSPIXEL, TEXT("BITSPIXEL       Color bits per pixel:"),          //每像素的颜色位数(位/像素)
        PLANES, TEXT("PLANES          Number of color planes:"),        //调色板的个数
        NUMBRUSHES, TEXT("NUMBRUSHES      Number of device brushes:"),      //设备内置画刷的数量
        NUMPENS, TEXT("NUMPENS         Number of device pens:"),         //设备内置画笔的数量
        NUMMARKERS, TEXT("NUMMARKERS      Number of device markers:"),      //设备内置标记数
        NUMFONTS, TEXT("NUMFONTS        Number of device fonts:"),        //设备内置字体数
        NUMCOLORS, TEXT("NUMCOLORS       Number of device colors:"),       //设备色彩深度(>8位/像素)?
        PDEVICESIZE, TEXT("PDEVICESIZE     Size of device structure:"),      //PDEVICE内部结构的大小
        ASPECTX, TEXT("ASPECTX         Relative width of pixel:"),       //用于画线的设备像素的相对宽度
        ASPECTY, TEXT("ASPECTY         Relative height of pixel:"),      //用于画线的设备像素的相对高度
        ASPECTXY, TEXT("ASPECTXY        Relative diagonal of pixel:"),    //画线设备对角线长度
        LOGPIXELSX, TEXT("LOGPIXELSX      Horizontal dots per inch:"),      //每逻辑英寸的水平像素数
        LOGPIXELSY, TEXT("LOGPIXELSY      Vertical dots per inch:"),        //每逻辑英寸的垂直像素数
        SIZEPALETTE, TEXT("SIZEPALETTE     Number of palette entries:"),     //调色板中的入口数
        NUMRESERVED, TEXT("NUMRESERVED     Reserved palette entries:"),      //系统调色板中保留的入口数目
        COLORRES, TEXT("COLORRES        Actual color resolution:"),       //设备的实际颜色分辨率(位/像素)
        PHYSICALWIDTH, TEXT("PHYSICALWIDTH   Printer page pixel "),      //页面的物理宽度(dpi)
        PHYSICALHEIGHT, TEXT("PHYSICALHEIGHT  Printer page pixel height:"),     //页面的物理高度(dpi)
        PHYSICALOFFSETX, TEXT("PHYSICALOFFSETX Printer page x offset:"),         //可打印区的水平偏移
        PHYSICALOFFSETY, TEXT("PHYSICALOFFSETY Printer page y offset:")          //可打印区的垂直偏移
    };
    TCHAR szBuffer[80];
    for (int i = 0; i<sizeof(info) / sizeof(info[0]); i++)
    {
        TextOut(hdc, cxChar, cyChar*(i + 1), szBuffer,
                wsprintf(szBuffer, TEXT("%-45s%8d"), info[i].szDesc, GetDeviceCaps(hdcInfo, info[i].iIndex)));
    }
}
void DoOtherInfo(HDC hdc, HDC hdcInfo, int cxChar, int cyChar)
{
    static BITS clip[] =
    {
        CP_RECTANGLE, TEXT("CP_RECTANGLE    Can Clip To Rectangle:") //设备是否支持剪切为一个矩形
    };
    static BITS raster[] = {
        RC_BITBLT, TEXT("RC_BITBLT       Capable of simple BitBlt:"),     //支持BitBlt传送位图函数
        RC_BANDING, TEXT("RC_BANDING      Requires banding support:"),     //需要联合支持
        RC_SCALING, TEXT("RC_SCALING      Requires scaling support:"),     //支持缩放
        RC_BITMAP64, TEXT("RC_BITMAP64     Supports bitmaps >64k:"),        //支持大于64K位图
        RC_GDI20_OUTPUT, TEXT("RC_GDI20_OUTPUT Has 2.0 output calls:"),         //支持16位Windows 2.0特征
        RC_DI_BITMAP, TEXT("RC_DI_BITMAP    Supports DIB to memory:"),       //支持SetDIBits和GetDIBits函数
        RC_PALETTE, TEXT("RC_PALETTE      Supports a palette:"),           //支持指定一个基于调色板的设备
        RC_DIBTODEV, TEXT("RC_DIBTODEV     Supports bitmap conversion:"),   //支持SetDIBitsToDevice函数
        RC_BIGFONT, TEXT("RC_BIGFONT      Supports fonts >64k:"),          //字体可大于64K
        RC_STRETCHBLT, TEXT("RC_STRECTCHBLT  Supports StretchBlt:"),          //支持StrectBlt函数
        RC_FLOODFILL, TEXT("RC_FLOODFILL    Supports FloodFill:"),           //支持连续填充
        RC_STRETCHDIB, TEXT("RC_STRETCHEDIB   Supports StretchDIBits:")        //支持StretchDIBits函数
    };
    static TCHAR * szTech[] = {
        TEXT("DT_PLOTTER(Vector plotter)"),         //矢量绘图仪
        TEXT("DT_RASDISPLAY (Raster display)"),     //光栅显示器
        TEXT("DT_RASPRINTER (Raster printer)"),     //光栅打印机
        TEXT("DT_RASCAMERA (Raster camera)"),       //光栅照相机
        TEXT("DT_CHARSTREAM (Character stream)"),   //字符流
        TEXT("DT_METAFILE (Metafile)"),             //图元文件
        TEXT("DT_DISPFILE (Display file)"),         //显示器文件
    };
    TCHAR szBuffer[80];
    //在第1行显示驱动程序版本:
    TextOut(hdc, cxChar, cyChar, szBuffer,
            wsprintf(szBuffer, TEXT("%-24s %04XH"), TEXT("DriverVersion:"),
            GetDeviceCaps(hdcInfo, DRIVERVERSION)));
    //在第2行设备技术:
    TextOut(hdc, cxChar, 2 * cyChar, szBuffer,
            wsprintf(szBuffer, TEXT("%-24s %-40s"), TEXT("Technology:"),
            szTech[GetDeviceCaps(hdcInfo, TECHNOLOGY)]));
    //第4行显示设备支持剪切性能的标志
    TextOut(hdc, cxChar, 4 * cyChar, szBuffer,
            wsprintf(szBuffer, TEXT("CLIPCAPS(Clipping capabilities)")));
    //第6行开始显示是否支持Clipping capabilities
    for (int i = 0; i < sizeof(clip) / sizeof(clip[0]); i++)
        TextOut(hdc, 9 * cxChar, (i + 6)*cyChar, szBuffer,
        wsprintf(szBuffer, TEXT("%-45s %3s"), clip[i].szDesc,
        GetDeviceCaps(hdcInfo, CLIPCAPS)&clip[i].iMask ? TEXT("Yes") : TEXT("No")));
    //第8行
    TextOut(hdc, cxChar, 8 * cyChar, szBuffer,
            wsprintf(szBuffer, TEXT("RASTERCAPS(Raster capabilities)")));
    //第10行显示光栅性能
    for (int i = 0; i < sizeof(raster) / sizeof(raster[0]); i++)
        TextOut(hdc, 9 * cxChar, (i + 10)*cyChar, szBuffer,
        wsprintf(szBuffer, TEXT("%-45s %3s"), raster[i].szDesc,
        GetDeviceCaps(hdcInfo, RASTERCAPS)&raster[i].iMask ? TEXT("Yes") : TEXT("No")));
}
void DoBitCodeCaps(HDC hdc, HDC hdcInfo, int cxChar, int cyChar, int iType)
{
    static BITS curves[] = {
        CC_NONE, TEXT("CC_NONE       No support to curve:"),           //是否支持绘制曲线
        CC_CIRCLES, TEXT("CC_CIRCLES    Can do circles:"),                //支持绘制圆
        CC_PIE, TEXT("CC_PIE        Can do pie wedges:"),             //支持绘制扇形
        CC_CHORD, TEXT("CC_CHORD      Can do chord arcs:"),             //支持绘制弦
        CC_ELLIPSES, TEXT("CC_ELLIPSES   Can do ellipses:"),               //支持绘制椭圆
        CC_WIDE, TEXT("CC_WIDE       Can do wide borders : "),         //支持绘制宽边框
        CC_STYLED, TEXT("CC_STYLED     Can do styled borders:"),         //支持绘制带风格的边界
        CC_WIDESTYLED, TEXT("CC_WIDESTYLED Can do wide and styled borders:"),//支持绘制宽且带风格的边界
        CC_INTERIORS, TEXT("CC_INTERIORS  Can do interiors:"),              //支持内部填充
        CC_ROUNDRECT, TEXT("CC_ROUNDRECT  Can do round rect:")              //支持绘制圆角矩形
    };
    static BITS lines[] = {
        LC_POLYLINE, TEXT("LC_POLYLINE   Can do polyline:"),              //是否支持绘制折线
        LC_MARKER, TEXT("LC_MARKER     Can do markers:"),               //是否支持绘制标记符
        LC_POLYMARKER, TEXT("LC_POLYMARKER Can do polymarkers:"),           //是否支持绘制多种标记符
        LC_WIDE, TEXT("LC_WIDE       Can do wide lines:"),            //是否支持绘制宽线
        LC_STYLED, TEXT("LC_STYLED     Can do styled lines:"),          //是否支持绘制带风格的线段
        LC_WIDESTYLED, TEXT("LC_WIDESTYLED Can do wide and styled lines:"), //是否支持绘制宽的且带风格的线段
        LC_INTERIORS, TEXT("LC_INTERIORS  Can do interiors:")              //是否支持内部填充
    };
    static BITS poly[] =
    {
        PC_POLYGON, TEXT("PC_POLYGON     Can do alternate fill polygon:"),      //支持绘制交错填充多边形
        PC_RECTANGLE, TEXT("PC_RECTANGLE   Can do rectangle:"),                   //支持绘制矩形
        PC_WINDPOLYGON, TEXT("PC_WINDPOLYGON Can do winding number fill polygon:"), //支持绘制折线式填充多边形
        PC_SCANLINE, TEXT("PC_SCANLINE    Can do scanlines:"),                   //支持绘制扫描线
        PC_WIDE, TEXT("PC_WIDE        Can do wide borders:"),                //支持宽边界
        PC_STYLED, TEXT("PC_STYLED      Can do styled borders:"),              //支持带风格的边界
        PC_WIDESTYLED, TEXT("PC_WIDESTYLED  Can do wide and styled borders:"),     //支持宽的且带风格的边界
        PC_INTERIORS, TEXT("PC_INTERIORS   Can do interiors:")                    //支持内部填充
    };
    static BITS text[] =
    {
        TC_OP_CHARACTER, TEXT("TC_OP_CHARACTER Can do character output precision:"),      //支持字符输出精度
        TC_OP_STROKE, TEXT("TC_OP_STROKE    Can do stroke output precision:"),         //支持笔画输出精度
        TC_CP_STROKE, TEXT("TC_CP_STROKE    Can do stroke clip precision:"),          //支持笔画剪切精度
        TC_CR_90, TEXT("TC_CP_90        Can do 90 degree character rotation:"),   //支持字符作90旋转
        TC_CR_ANY, TEXT("TC_CR_ANY       Can do any character rotation:"),         //支持字符任意角度旋转
        TC_SF_X_YINDEP, TEXT("TC_SF_X_YINDEP  Can do scaling independent of X and Y:"), //支持x和y方向的独立缩放
        TC_SA_DOUBLE, TEXT("TC_SA_DOUBLE    Can do doubled character for scaling:"),  //支持把字符放大一倍
        TC_SA_INTEGER, TEXT("TC_SA_INTEGER   Can do integer multiples for scaling:"),  //支持整数倍缩放
        TC_SA_CONTIN, TEXT("TC_SA_CONTIN    Can do any multiples for exact scaling:"),//支持任何倍数的严格缩放
        TC_EA_DOUBLE, TEXT("TC_EA_DOUBLE    Can do double weight characters:"),       //支持字符加重
        TC_IA_ABLE, TEXT("TC_IA_ABLE      Can do italicizing:"),                    //支持斜字体
        TC_UA_ABLE, TEXT("TC_UA_ABLE      Can do underlining:"),                    //支持下划线
        TC_SO_ABLE, TEXT("TC_SO_ABLE      Can do strikeouts:"),                     //支持删除线
        TC_RA_ABLE, TEXT("TC_RA_ABLE      Can do raster fonts:"),                   //支持光栅字体
        TC_VA_ABLE, TEXT("TC_VA_ABLE      Can do vector fonts:")                    //支持矢量字体
    };
    static struct
    {
        int iIndex;
        TCHAR* szTitle;
        BITS(*pbits)[]; //pbits为一个数组的指针,元素类型为BTIS,本例中pbits指向curveslinespoly	ext等数组。
        int iSize;
    } bitinfo[] = {
        CURVECAPS, TEXT("CURVCAPS(Curve Capabiities)"), (BITS(*)[])curves, sizeof(curves) / sizeof(curves[0]),
        LINECAPS, TEXT("LINECAPS(Line  Capabiities)"), (BITS(*)[])lines, sizeof(lines) / sizeof(lines[0]),
        POLYGONALCAPS, TEXT("POLYGONALCAPS(Polygonal Capabiities)"), (BITS(*)[])poly, sizeof(poly) / sizeof(poly[0]),
        TEXTCAPS, TEXT("TEXTCAPS(Curve Capabiities)"), (BITS(*)[])text, sizeof(text) / sizeof(text[0])
    };
    static TCHAR szBuffer[80];
    BITS(*pbits)[] = bitinfo[iType].pbits;
    int  iDevCaps = GetDeviceCaps(hdcInfo, bitinfo[iType].iIndex);
    TextOut(hdc, cxChar, cyChar, bitinfo[iType].szTitle, lstrlen(bitinfo[iType].szTitle));
    for (int i = 0; i < bitinfo[iType].iSize; i++)
    {
        TextOut(hdc, cxChar, (i + 3)*cyChar, szBuffer,
                wsprintf(szBuffer, TEXT("%-55s %3s"), (*pbits)[i].szDesc,
                iDevCaps&(*pbits)[i].iMask ? TEXT("Yes") : TEXT("No")));
    }
}

//resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 DevCaps2.rc 使用
//
#define IDM_SCREEN                      40001
#define IDM_BASIC                       40002
#define IDM_OTHER                       40003
#define IDM_CURVE                       40004
#define IDM_LINE                        40005
#define IDM_POLY                        40006
#define IDM_TEXT                        40007
// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        102
#define _APS_NEXT_COMMAND_VALUE         40013
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

//DevCaps2.rc

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""
"
""
END
3 TEXTINCLUDE
BEGIN
"
"
""
END
#endif    // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
DEVCAPS2 MENU
BEGIN
POPUP "&Device"
BEGIN
MENUITEM "&Screen", IDM_SCREEN
END
POPUP "&Capabilities"
BEGIN
MENUITEM "&Basic Information", IDM_BASIC
MENUITEM "&Other Information", IDM_OTHER
MENUITEM "&Curve Capabilities", IDM_CURVE
MENUITEM "&Line Capabilities", IDM_LINE
MENUITEM "&Polygonal Capabilities", IDM_POLY
MENUITEM "&Text Capabilities", IDM_TEXT
END
END
#endif    // 中文(简体,中国) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

13.1.4 PrinterProperties函数调用

(1)获取指定的打印机句柄:OpenPrinter (szDevice, &hPrint, NULL)

(2)生成打印机属性对话框:PrinterProperties

(2)关闭指定的打印机对象:ClosePrinter:

13.1.5 检查BitBlt能力——视频显示器与打印机在使用GDI上的最重要区别!

(1)GetDeviceCaps(hdc,RC_BITBLT);检测是否具备位块传送能力。

(2)大多数点阵、激光或喷墨打印机具备这种能力,但绘图仪不具备

(3)不具备位块传送能力的设备,也就不支持以下这些GDI函数:CreateCompatibleDC、CreateCompatibleBitmap、PatBlt、BitBlt、StretchBlt、GrayString、DrawIcon、SetPixel、GetPixel、FloodFill、ExtFloodFill、FillRgn、FrameRgn、InvertRgn、PaintRgn、FillRect、FrameRect、InvertRect等。

13.1.6 最简单的打印程序

(1)DOCINFO结构体

字段

含义

cbSize

结构体的字节大小

lpszDocName

要打印的文档名称,会出现在打印机作业队列中。

lpszOutput

输出文件的名称。如果为NULL,会弹出保存对话框

lpszDatatype

代表某种数据类型的字符串

fwType

打印工作的其它信息

(2)打印流程

   ①CreateDC或PrintDlg获得打印机设备环境句柄,并确保打印驱动库模块载入内存。

   ②StartDoc; //打印作业开始

        StartPage //第1页

       //GDI绘图(如TextOut):GDI函数会被存储在硬盘的图元文件上

       EndPage  //把硬盘的上图元文件读入设备驱动程序中,并根据技术“分带”技术将

                     //绘图函数通过打印机驱动程序中OutPut函数转化为打印机的输出,同

                     //时创建临时打印文件,在此过程中会频繁调用异常终止过程,以判断是

                      //否有异常或是否要中止打印。

  StartPage //第2页

  EndPage

  ……      //第n页

  EndDoc    //打印作业结束

【FormFeed 程序】

/*-----------------------------------------------------
FORMFEED.C  —— Advances printer to next page
(c) Charles Petzold,1998
-------------------------------------------------------*/
#include <windows.h>
HDC GetPrinterDC(void);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int iCmdShow)
{
    static DOCINFO di = { sizeof(DOCINFO), TEXT("FormFeed") };
    HDC            hdcPrint = GetPrinterDC();
    if (hdcPrint != NULL)
    {
        if (StartDoc(hdcPrint, &di)>0)    //开始一个打印作业
            if (StartPage(hdcPrint)>0 && EndPage(hdcPrint)>0) //StartPage标记一页的开始
                //EndPage标记一页的结束
                EndDoc(hdcPrint);        //结束打印作业
        DeleteDC(hdcPrint);
    }
}
 
原文地址:https://www.cnblogs.com/5iedu/p/4695166.html