关于打印机 —— DEVCAPS2 程序代码分析

/*-----------------------------------------------------------------------------------------------
DEVCAPS2.C -- Displays Device Capability Information (Version 2)
-----------------------------------------------------------------------------------------------*/
#include<windows.h>
#include"resource.h"

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
void DoBasicInfo(HDC,HDC,int,int);
void DoOtherInfo(HDC,HDC,int,int);
void DoBitCodedCaps(HDC,HDC,int,int,int);

typedef struct
{
    int iMask;
    TCHAR *szDesc;
}
BITS;

#define IDM_DEVMODE 1000  //定义设备属性菜单项目ID

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int nCmdShow)
{
    static TCHAR szAppName[] = TEXT("DevCaps2");
    HWND hwnd;
    MSG msg;
    WNDCLASS wndcls;

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

    RegisterClass(&wndcls);

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

    ShowWindow(hwnd,nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    static TCHAR szDevice[32],szWindowText[64];
    static int cxChar,cyChar,nCurrentDevice = IDM_SCREEN,nCurrentInfo = IDM_BASIC;
    static DWORD dwNeeded,dwReturned;
    static PRINTER_INFO_4 *pinfo4;
    static PRINTER_INFO_5 *pinfo5;
    DWORD i;
    HDC hdc,hdcInfo;
    HMENU hMenu;
    HANDLE hPrint;
    PAINTSTRUCT ps;
    TEXTMETRIC tm;

    switch(msg)
    {
    case WM_CREATE:
        hdc = GetDC(hwnd);  //获取窗口设备环境句柄
        SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));  //将等宽系统字体选入设备环境
        GetTextMetrics(hdc,&tm);  //获取字体尺寸
        cxChar = tm.tmAveCharWidth;  //字体平均宽度
        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(GetVersion() & 0x80000000)  //Windows98
        {

            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(i = 0;i < dwReturned;i++)  //追加打印机名称到弹出菜单
            {
                AppendMenu(hMenu,(i + 1) % 16 ? 0 : MF_MENUBARBREAK,i + 1,
                            pinfo5[i].pPrinterName);
            }
            free(pinfo5);  //释放pinfo结构
        }
        else  //Window NT
        {

            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(i = 0;i < dwReturned;i++)
            {
                AppendMenu(hMenu,(i + 1) % 16 ? 0 : MF_MENUBARBREAK,i + 1,
                            pinfo4[i].pPrinterName);
            }
            free(pinfo4);
        }

        AppendMenu(hMenu,MF_SEPARATOR,0,NULL);  //添加分隔条
        AppendMenu(hMenu,0,IDM_DEVMODE,TEXT("Properties"));  //添加属性"Properties"菜单项

        wParam = IDM_SCREEN;

    case WM_COMMAND:
        hMenu = GetMenu(hwnd);  //获取菜单句柄

        if(LOWORD(wParam) == IDM_SCREEN ||  //如果选择了"Screen"
            LOWORD(wParam) < IDM_DEVMODE)   //或是选择了菜单中列出的某个打印机名称
        {
            CheckMenuItem(hMenu,nCurrentDevice,MF_UNCHECKED);  //先取消先前的选中标记
            nCurrentDevice = LOWORD(wParam);  //获取当前选中的菜单项
            CheckMenuItem(hMenu,nCurrentDevice,MF_CHECKED);  //为当前选中的菜单项添加选中标记
        }
        else if(LOWORD(wParam) == IDM_DEVMODE)  //如果选中了"Properties"打印机属性菜单项
        {
            GetMenuString(hMenu,nCurrentDevice,szDevice,
                        sizeof(szDevice) / sizeof(TCHAR),MF_BYCOMMAND);  //将菜单项标识指定的当前选中的打印机名称赋给szDevice字符数组
            if(OpenPrinter(szDevice,&hPrint,NULL))  //打开选中的打印机,并获取打印机的句柄
            {
                PrinterProperties(hwnd,hPrint);  //启动打印机属性对话框
                ClosePrinter(hPrint);  //关闭打印机
            }
        }
        else //如果打开了"Capabilities"弹出菜单
        {
            CheckMenuItem(hMenu,nCurrentInfo,MF_UNCHECKED);  //去掉之前的选中标记
            nCurrentInfo = LOWORD(wParam);  //检测当前选中的Info菜单项
            CheckMenuItem(hMenu,nCurrentInfo,MF_CHECKED);  //为当前选中的Info菜单项打上选中标记
        }
        InvalidateRect(hwnd,NULL,TRUE);  //使客户区无效,重绘窗口
        return 0;

    case WM_INITMENUPOPUP:
        if(lParam) == 0)  //等价于HIWORD(lParam)==0(表示此菜单为非系统菜单)
                          //且LOWORD(lParam)==0(表示打开的是第一个弹出菜单,此处是"Device"弹出菜单)
            EnableMenuItem(GetMenu(hwnd),IDM_DEVMODE,
                            nCurrentDevice == IDM_SCREEN ? MF_GRAYED : MF_ENABLED);  //如果选中的是"Screen"菜单项,就将"Properties"菜单项无效,否则使其有效
        return 0;

    case WM_PAINT:
        lstrcpy(szWindowText,TEXT("Device capabilities:"));  //将字符串拷贝到窗口标题栏

        if(nCurrentDevice == IDM_SCREEN)  //检测当前选中的设备,如果是"Screen"
        {
            lstrcpy(szDevice,TEXT("DISPLAY"));  //将设备名称字符串"DISPLAY"赋给szDevice 字符数组
            hdcInfo = CreateIC(szDevice,NULL,NULL,NULL);  //获取显示器的设备环境信息
        }
        else  //检测当前选中的设备如果是某一个菜单中列出的打印机
        {
            hMenu = GetMenu(hwnd);
            GetMenuString(hMenu,nCurrentDevice,szDevice,
                        sizeof(szDevice),MF_BYCOMMAND);  //将菜单项标识指定的当前选中的打印机名称赋给szDevice 字符数组
            hdcInfo = CreateIC(NULL,szDevice,NULL,NULL);  //获取打印机设备环境信息
        }

        lstrcat(szWindowText,szDevice);  //将szDevice中存储的设备名称追加到窗口标题栏
        SetWindowText(hwnd,szWindowText);  //更新窗口标题栏

        hdc = BeginPaint(hwnd,&ps);  //获取设备环境句柄
        SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));  //将系统等宽字体选入设备环境

        if(hdcInfo)
        {
            switch(nCurrentInfo)
            {
            case IDM_BASIC:
                DoBasicInfo(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:
                DoBitCodedCaps(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,msg,wParam,lParam);
}

void DoBasicInfo(HDC hdc,HDC hdcInfo,int cxChar,int cyChar)
{
    static struct
    {
        int nIndex;
        TCHAR *szDesc;
    }
    info[] =
    {
        HORZSIZE,        TEXT ("HORZSIZE        Width in millimeters:"),
        VERTSIZE,        TEXT ("VERTSIZE        Height in millimeters:"),
        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:"),
        PDEVICESIZE,     TEXT ("PDEVICESIZE     Size of device structure:"),
        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 width:"),
        PHYSICALHEIGHT,  TEXT ("PHYSICALHEIGHT  Printer page pixel height:"),
        PHYSICALOFFSETX, TEXT ("PHYSICALOFFSETX Printer page x offset:"),
        PHYSICALOFFSETY, TEXT ("PHYSICALOFFSETY Printer page y offset:")
    };

    int i;
    TCHAR szBuffer[80];

    for(i = 0;i < sizeof(info) / sizeof(info[0]);i++)
        TextOut(hdc,cxChar,(i + 1) * cyChar,szBuffer,
            wsprintf(szBuffer,TEXT("%-45s%8d"),info[i].szDesc,
                GetDeviceCaps(hdcInfo,info[i].nIndex)));
}

void DoOtherInfo(HDC hdc,HDC hdcInfo,int cxChar,int cyChar)
{
    static BITS clip[] =
    {CP_RECTANGLE,TEXT("CP_RECTANCKE Can Clip To Rectangle:")};

    static BITS raster[] =
    {
        RC_BITBLT,       TEXT ("RC_BITBLT       Capable of simple 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:"),
        RC_GDI20_OUTPUT, TEXT ("RC_GDI20_OUTPUT Has 2.0 output calls:"),
        RC_DI_BITMAP,    TEXT ("RC_DI_BITMAP    Supports DIB to memory:"),
        RC_PALETTE,      TEXT ("RC_PALETTE      Supports a palette:"),
        RC_DIBTODEV,     TEXT ("RC_DIBTODEV     Supports bitmap conversion:"),
        RC_BIGFONT,      TEXT ("RC_BIGFONT      Supports fonts >64K:"),
        RC_STRETCHBLT,   TEXT ("RC_STRETCHBLT   Supports StretchBlt:"),
        RC_FLOODFILL,    TEXT ("RC_FLOODFILL    Supports FloodFill:"),
        RC_STRETCHDIB,   TEXT ("RC_STRETCHDIB   Supports 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)")
    };

    int i;
    TCHAR szBuffer[80];

    TextOut(hdc,cxChar,cyChar,szBuffer,
            wsprintf(szBuffer,TEXT("%-24s%04XH"),TEXT("DRIVERVERSION:"),
                GetDeviceCaps(hdcInfo,DRIVERVERSION)));

    TextOut(hdc,cxChar,2 * cyChar,szBuffer,
            wsprintf(szBuffer,TEXT("%-24s%-40s"),TEXT("TECHNOOGY:"),
                szTech[GetDeviceCaps(hdcInfo,TECHNOLOGY)]));

    TextOut(hdc,cxChar,4 * cyChar,szBuffer,
            wsprintf(szBuffer,TEXT("CLIPCAPS(Clipping capabilities)")));

    for(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")));

    TextOut(hdc,cxChar,8 * cyChar,szBuffer,
            wsprintf(szBuffer,TEXT("RASTERCPAS(Raster capabilityies)")));

    for(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 DoBitCodedCaps(HDC hdc,HDC hdcInfo,int cxChar,int cyChar,int iType)
{
    static BITS curves[] =
     {
          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:")
     } ;
     
     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:"),
          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:"),
          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)[];
         int iSize;
     }
     bitinfo[] =
     {
         CURVECAPS,
             TEXT("CURVECAPS(Curve Capabilities)"),
             (BITS(*)[])curves,sizeof(curves) / sizeof(curves[0]),
             LINECAPS,TEXT("LINECAPS(Line Capabilities)"),
             (BITS(*)[])lines,sizeof(lines) / sizeof(lines[0]),
             POLYGONALCAPS,TEXT("POLYGONALCAPS(Polygonal Capabilities)"),
             (BITS(*)[])poly,sizeof(poly) / sizeof(poly[0]),
             TEXTCAPS,TEXT("TEXTCAPS(Text Capabilities)"),
             (BITS(*)[])text,sizeof(text) / sizeof(text[0])
     };
    
     static TCHAR szBuffer[80];
     BITS (*pbits)[] = bitinfo[iType].pbits;
     int i,iDevCaps = GetDeviceCaps(hdcInfo,bitinfo[iType].iIndex);

     TextOut(hdc,cxChar,cyChar,bitinfo[iType].szTitle,
            lstrlen(bitinfo[iType].szTitle));

     for(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")));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值