• 第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);
        }
    }
     
  • 相关阅读:
    一道比较有趣的题
    笑话两则
    时钟
    组策略 简单介绍
    网页乱码问题ASP.NET
    同性恋的公鸡
    SQL中CASE函数_可解决编程中空表检索的一些问题
    百万网?
    黑客 故事
    word有趣问题集锦
  • 原文地址:https://www.cnblogs.com/5iedu/p/4695166.html
Copyright © 2020-2023  润新知